diff --git a/apps/renderer/src/components/feed-certification.tsx b/apps/renderer/src/components/feed-certification.tsx index 2a62d0c15..b62f94b37 100644 --- a/apps/renderer/src/components/feed-certification.tsx +++ b/apps/renderer/src/components/feed-certification.tsx @@ -4,14 +4,14 @@ import { useWhoami } from "~/atoms/user" import { Avatar, AvatarFallback, AvatarImage } from "~/components/ui/avatar" import { Tooltip, TooltipContent, TooltipPortal, TooltipTrigger } from "~/components/ui/tooltip" import { cn } from "~/lib/utils" -import type { TargetModel } from "~/models" +import type { FeedOrListRespModel } from "~/models" import { usePresentUserProfileModal } from "~/modules/profile/hooks" export const FeedCertification = ({ feed, className, }: { - feed: TargetModel + feed: FeedOrListRespModel className?: string }) => { const me = useWhoami() diff --git a/apps/renderer/src/components/feed-icon.tsx b/apps/renderer/src/components/feed-icon.tsx index 1ccb43ef9..86e5db468 100644 --- a/apps/renderer/src/components/feed-icon.tsx +++ b/apps/renderer/src/components/feed-icon.tsx @@ -6,7 +6,7 @@ import { forwardRef, useMemo } from "react" import { getColorScheme, stringToHue } from "~/lib/color" import { getImageProxyUrl } from "~/lib/img-proxy" import { cn, getUrlIcon } from "~/lib/utils" -import type { CombinedEntryModel, FeedModel, TargetModel } from "~/models" +import type { CombinedEntryModel, FeedModel, FeedOrListRespModel } from "~/models" import { PlatformIcon } from "./ui/platform-icon" @@ -76,7 +76,7 @@ export function FeedIcon({ siteUrl, useMedia, }: { - feed?: TargetModel + feed?: FeedOrListRespModel entry?: CombinedEntryModel["entries"] fallbackUrl?: string className?: string diff --git a/apps/renderer/src/components/feed-summary.tsx b/apps/renderer/src/components/feed-summary.tsx index 5194c8f6d..36ff551ce 100644 --- a/apps/renderer/src/components/feed-summary.tsx +++ b/apps/renderer/src/components/feed-summary.tsx @@ -2,7 +2,7 @@ import { WEB_URL } from "@follow/shared/constants" import { FeedIcon } from "~/components/feed-icon" import { cn } from "~/lib/utils" -import type { TargetModel } from "~/models" +import type { FeedOrListRespModel } from "~/models" import { FeedCertification } from "./feed-certification" import { EllipsisHorizontalTextWithTooltip } from "./ui/typography" @@ -12,7 +12,7 @@ export function FollowSummary({ docs, className, }: { - feed: TargetModel + feed: FeedOrListRespModel docs?: string className?: string }) { diff --git a/apps/renderer/src/components/ui/datetime/index.tsx b/apps/renderer/src/components/ui/datetime/index.tsx index 6a55a7a56..e8379ab16 100644 --- a/apps/renderer/src/components/ui/datetime/index.tsx +++ b/apps/renderer/src/components/ui/datetime/index.tsx @@ -80,7 +80,7 @@ export const RelativeTime: FC<{ {/* https://github.com/radix-ui/primitives/issues/2248#issuecomment-2147056904 */} {relative} - {t("words.space")} + {t("space")} {t("words.ago")} diff --git a/apps/renderer/src/database/schemas/feed.ts b/apps/renderer/src/database/schemas/feed.ts index de391b9da..fc039099e 100644 --- a/apps/renderer/src/database/schemas/feed.ts +++ b/apps/renderer/src/database/schemas/feed.ts @@ -1,8 +1,8 @@ -import type { TargetModel } from "~/models" +import type { FeedOrListRespModel } from "~/models" export type DB_FeedUnread = { id: string count: number } -export type DB_Feed = TargetModel & { id: string } +export type DB_Feed = FeedOrListRespModel & { id: string } diff --git a/apps/renderer/src/models/types.ts b/apps/renderer/src/models/types.ts index c28a89a9b..a9b376609 100644 --- a/apps/renderer/src/models/types.ts +++ b/apps/renderer/src/models/types.ts @@ -25,9 +25,10 @@ export type TransactionModel = ExtractBizResponse< export type FeedModel = ExtractBizResponse["data"]["feed"] -export type ListModel = ExtractBizResponse["data"]["list"] - -export type TargetModel = FeedModel | ListModel +type ListModelPoplutedFeeds = ExtractBizResponse["data"]["list"] +export type ListModel = Omit +export type FeedOrListRespModel = FeedModel | ListModelPoplutedFeeds +export type FeedOrListModel = FeedModel | ListModel export type EntryResponse = Exclude< Extract, { code: 0 }>["data"], diff --git a/apps/renderer/src/modules/entry-column/layouts/EntryItemWrapper.tsx b/apps/renderer/src/modules/entry-column/layouts/EntryItemWrapper.tsx index 53f25d616..a4d97e8a3 100644 --- a/apps/renderer/src/modules/entry-column/layouts/EntryItemWrapper.tsx +++ b/apps/renderer/src/modules/entry-column/layouts/EntryItemWrapper.tsx @@ -99,7 +99,7 @@ export const EntryItemWrapper: FC< }, { type: "text" as const, - label: `${t("words.copy")}${t("words.space")}${t("words.entry")} ${t("words.id")}`, + label: `${t("words.copy")}${t("space")}${t("words.entry")} ${t("words.id")}`, click: () => { navigator.clipboard.writeText(entry.entries.id) }, diff --git a/apps/renderer/src/modules/entry-column/layouts/EntryListHeader.tsx b/apps/renderer/src/modules/entry-column/layouts/EntryListHeader.tsx index ace6a4a45..63ed21b75 100644 --- a/apps/renderer/src/modules/entry-column/layouts/EntryListHeader.tsx +++ b/apps/renderer/src/modules/entry-column/layouts/EntryListHeader.tsx @@ -53,7 +53,7 @@ export const EntryListHeader: FC<{
{totalCount || 0} {t("quantifier.piece", { ns: "common" })} {unreadOnly && !isInCollectionList ? t("words.unread") : ""} - {t("words.space", { ns: "common" })} + {t("space", { ns: "common" })} {t("words.items", { ns: "common", count: totalCount })}
diff --git a/apps/renderer/src/modules/entry-column/types.ts b/apps/renderer/src/modules/entry-column/types.ts index f6e7fb6ff..982904677 100644 --- a/apps/renderer/src/modules/entry-column/types.ts +++ b/apps/renderer/src/modules/entry-column/types.ts @@ -1,11 +1,11 @@ import type { FC } from "react" -import type { CombinedEntryModel, TargetModel } from "~/models" +import type { CombinedEntryModel, FeedOrListRespModel } from "~/models" export type UniversalItemProps = { entryId: string entryPreview?: CombinedEntryModel & { - feeds: TargetModel + feeds: FeedOrListRespModel feedId: string } translation?: { diff --git a/apps/renderer/src/modules/panel/cmdk.tsx b/apps/renderer/src/modules/panel/cmdk.tsx index 969fc9797..483182745 100644 --- a/apps/renderer/src/modules/panel/cmdk.tsx +++ b/apps/renderer/src/modules/panel/cmdk.tsx @@ -318,7 +318,7 @@ const SearchResultCount: FC<{ <> {count} {t.common("quantifier.piece")} {t.common("words.local")} - {t.common("words.space")} + {t.common("space")} {t.common("words.record", { count })} )} diff --git a/apps/renderer/src/modules/settings/tabs/lists.tsx b/apps/renderer/src/modules/settings/tabs/lists.tsx index 9fbfed82e..46981c015 100644 --- a/apps/renderer/src/modules/settings/tabs/lists.tsx +++ b/apps/renderer/src/modules/settings/tabs/lists.tsx @@ -40,17 +40,20 @@ import { views } from "~/constants" import { useAuthQuery, useI18n } from "~/hooks/common" import { apiClient } from "~/lib/api-fetch" import { cn, isBizId } from "~/lib/utils" -import type { ListModel } from "~/models" +import type { FeedModel, ListModel } from "~/models" import { ViewSelectorRadioGroup } from "~/modules/shared/ViewSelectorRadioGroup" import { Balance } from "~/modules/wallet/balance" import { Queries } from "~/queries" -import { feedActions, getFeedById, useFeedById } from "~/store/feed" +import { + getFeedById, + useAddFeedToFeedList, + useFeedById, + useRemoveFeedFromFeedList, +} from "~/store/feed" import { useSubscriptionStore } from "~/store/subscription" export const SettingLists = () => { - // const { t: appT } = useTranslation() const t = useI18n() - // const { t } = useTranslation("settings") const listList = useAuthQuery(Queries.lists.list()) const { present } = useModalStack() @@ -342,42 +345,7 @@ export const ListFeedsModalContent = ({ id }: { id: string }) => { const { t } = useTranslation("settings") const [feedSearchFor, setFeedSearchFor] = useState("") - const addMutation = useMutation({ - mutationFn: async (values: string) => { - const feed = await apiClient.lists.feeds.$post({ - json: { - listId: id, - feedId: values, - }, - }) - feedActions.upsertMany([feed.data]) - }, - onSuccess: () => { - toast.success(t("lists.feeds.add.success")) - Queries.lists.list().invalidate() - }, - async onError() { - toast.error(t("lists.feeds.add.error")) - }, - }) - - const removeMutation = useMutation({ - mutationFn: async (feedId: string) => { - await apiClient.lists.feeds.$delete({ - json: { - listId: id, - feedId, - }, - }) - }, - onSuccess: () => { - toast.success(t("lists.feeds.delete.success")) - Queries.lists.list().invalidate() - }, - async onError() { - toast.error(t("lists.feeds.delete.error")) - }, - }) + const addMutation = useAddFeedToFeedList() const allFeeds = useSubscriptionStore((store) => { const feedInfo = [] as { title: string; id: string }[] @@ -395,11 +363,13 @@ export const ListFeedsModalContent = ({ id }: { id: string }) => { }) const autocompleteSuggestions: Suggestion[] = useMemo(() => { - return allFeeds.map((feed) => ({ - name: feed.title, - value: feed.id, - })) - }, [allFeeds]) + return allFeeds + .filter((feed) => !list.feedIds?.includes(feed.id)) + .map((feed) => ({ + name: feed.title, + value: feed.id, + })) + }, [allFeeds, list.feedIds]) const selectedFeedIdRef = useRef() return ( @@ -422,11 +392,11 @@ export const ListFeedsModalContent = ({ id }: { id: string }) => { className="whitespace-nowrap" onClick={() => { if (isBizId(feedSearchFor)) { - addMutation.mutate(feedSearchFor) + addMutation.mutate({ feedId: feedSearchFor, listId: id }) return } if (selectedFeedIdRef.current) { - addMutation.mutate(selectedFeedIdRef.current) + addMutation.mutate({ feedId: selectedFeedIdRef.current, listId: id }) } }} > @@ -438,9 +408,6 @@ export const ListFeedsModalContent = ({ id }: { id: string }) => { - {/* - {t("lists.feeds.id")} - */} {t("lists.feeds.title")} @@ -453,36 +420,41 @@ export const ListFeedsModalContent = ({ id }: { id: string }) => { - {list.feeds?.map((row) => ( - - {/* - {row.id} - */} - - - {row.siteUrl && } - {row.title} - - - -
- -
-
- - - -
- ))} + {list.feedIds?.map((feedId) => )}
) } + +const RowRender = ({ feedId, listId }: { feedId: string; listId: string }) => { + const feed = useFeedById(feedId) as FeedModel + + const removeMutation = useRemoveFeedFromFeedList() + if (!feed) return null + return ( + + + + {feed.siteUrl && } + {feed.title} + + + +
+ +
+
+ + + +
+ ) +} diff --git a/apps/renderer/src/pages/(external)/(with-layout)/list/[id]/index.tsx b/apps/renderer/src/pages/(external)/(with-layout)/list/[id]/index.tsx index f6131d08f..a999c794d 100644 --- a/apps/renderer/src/pages/(external)/(with-layout)/list/[id]/index.tsx +++ b/apps/renderer/src/pages/(external)/(with-layout)/list/[id]/index.tsx @@ -12,6 +12,7 @@ import { usePresentFeedFormModal } from "~/hooks/biz/useFeedFormModal" import { useTitle } from "~/hooks/common" import type { ListModel } from "~/models" import { useFeed } from "~/queries/feed" +import { useFeedById } from "~/store/feed/hooks" export function Component() { const { id } = useParams() @@ -51,7 +52,7 @@ export function Component() { subscriptionCount: feed.data.subscriptionCount, subscriptionNoun: t("feed.follower", { count: feed.data.subscriptionCount }), feedsCount: "feedCount" in feed.data ? feed.data.feedCount : 0, - feedsNoun: t("feed.feeds", { count: listData?.feeds?.length }), + feedsNoun: t("feed.feeds", { count: listData?.feedIds?.length }), appName: APP_NAME, })} @@ -78,23 +79,9 @@ export function Component() {
- {listData.feeds?.slice(0, 5).map((feed) => ( - - - {feed.title} - - - ))} + {listData.feedIds + ?.slice(0, 5) + .map((feedId) => )} {"feedCount" in feed.data && (
{ @@ -117,3 +104,20 @@ export function Component() { ) } + +const FeedRow = ({ feedId }: { feedId: string }) => { + const feed = useFeedById(feedId) + if (!feed) return null + return ( + + + {feed.title} + + + ) +} diff --git a/apps/renderer/src/services/feed.ts b/apps/renderer/src/services/feed.ts index 1f4324098..4b014b2ec 100644 --- a/apps/renderer/src/services/feed.ts +++ b/apps/renderer/src/services/feed.ts @@ -1,23 +1,25 @@ + import { browserDB } from "~/database" -import type { TargetModel } from "~/models/types" +import type { FeedOrListModel } from "~/models/types" import { BaseService } from "./base" import { CleanerService } from "./cleaner" -type TargetModelWithId = TargetModel & { id: string } +type TargetModelWithId = FeedOrListModel & { id: string } class ServiceStatic extends BaseService { constructor() { super(browserDB.feeds) } - override async upsertMany(data: TargetModel[]) { + override async upsertMany(data: FeedOrListModel[]) { const filterData = data.filter((d) => d.id) + CleanerService.reset(filterData.map((d) => ({ type: "feed", id: d.id! }))) return this.table.bulkPut(filterData as TargetModelWithId[]) } - override async upsert(data: TargetModel): Promise { + override async upsert(data: FeedOrListModel): Promise { if (!data.id) return null CleanerService.reset([{ type: "feed", id: data.id }]) return this.table.put(data as TargetModelWithId) diff --git a/apps/renderer/src/store/entry/store.ts b/apps/renderer/src/store/entry/store.ts index 86cc96730..36b267f80 100644 --- a/apps/renderer/src/store/entry/store.ts +++ b/apps/renderer/src/store/entry/store.ts @@ -5,7 +5,7 @@ import { isNil, merge, omit } from "lodash-es" import { runTransactionInScope } from "~/database" import { apiClient } from "~/lib/api-fetch" import { getEntriesParams, omitObjectUndefinedValue } from "~/lib/utils" -import type { CombinedEntryModel, EntryModel, TargetModel } from "~/models" +import type { CombinedEntryModel, EntryModel, FeedOrListRespModel } from "~/models" import { EntryService } from "~/services" import { feedActions } from "../feed" @@ -178,7 +178,7 @@ class EntryActions { } upsertMany(data: CombinedEntryModel[]) { - const feeds = [] as TargetModel[] + const feeds = [] as FeedOrListRespModel[] const entries = [] as EntryModel[] const entry2Read = {} as Record const entryFeedMap = {} as Record diff --git a/apps/renderer/src/store/feed/hooks.ts b/apps/renderer/src/store/feed/hooks.ts index ad28fea66..e0352b6a0 100644 --- a/apps/renderer/src/store/feed/hooks.ts +++ b/apps/renderer/src/store/feed/hooks.ts @@ -1,16 +1,19 @@ +import { useMutation } from "@tanstack/react-query" import { useMemo } from "react" import { useTranslation } from "react-i18next" +import { toast } from "sonner" import { useShallow } from "zustand/react/shallow" import { FEED_COLLECTION_LIST, ROUTE_FEED_IN_FOLDER, ROUTE_FEED_PENDING, views } from "~/constants" import { useRouteParams } from "~/hooks/biz/useRouteParams" -import type { TargetModel } from "~/models" +import { apiClient } from "~/lib/api-fetch" +import type { FeedOrListRespModel } from "~/models" import { getSubscriptionByFeedId } from "../subscription" -import { useFeedStore } from "./store" +import { feedActions, useFeedStore } from "./store" import type { FeedQueryParams } from "./types" -export const useFeedById = (feedId: Nullable): TargetModel | null => +export const useFeedById = (feedId: Nullable): FeedOrListRespModel | null => useFeedStore((state) => (feedId ? state.feeds[feedId] : null)) export const useFeedByIdOrUrl = (feed: FeedQueryParams) => @@ -26,7 +29,7 @@ export const useFeedByIdOrUrl = (feed: FeedQueryParams) => export const useFeedByIdSelector = ( feedId: Nullable, - selector: (feed: TargetModel) => T, + selector: (feed: FeedOrListRespModel) => T, ) => useFeedStore( useShallow((state) => (feedId && state.feeds[feedId] ? selector(state.feeds[feedId]) : null)), @@ -45,7 +48,6 @@ export const useFeedHeaderTitle = () => { switch (currentFeedId) { case ROUTE_FEED_PENDING: { - // TODO: fix this type error return t(views[view].name) } case FEED_COLLECTION_LIST: { @@ -59,3 +61,54 @@ export const useFeedHeaderTitle = () => { } } } + +export const useAddFeedToFeedList = (options?: { onSuccess: () => void; onError: () => void }) => { + const { t } = useTranslation("settings") + return useMutation({ + mutationFn: async (payload: { feedId: string; listId: string }) => { + const feed = await apiClient.lists.feeds.$post({ + json: { + listId: payload.listId, + feedId: payload.feedId, + }, + }) + + feedActions.addFeedToFeedList(payload.listId, feed.data) + }, + onSuccess: () => { + toast.success(t("lists.feeds.add.success")) + + options?.onSuccess?.() + }, + async onError() { + toast.error(t("lists.feeds.add.error")) + options?.onError?.() + }, + }) +} + +export const useRemoveFeedFromFeedList = (options?: { + onSuccess: () => void + onError: () => void +}) => { + const { t } = useTranslation("settings") + return useMutation({ + mutationFn: async (payload: { feedId: string; listId: string }) => { + feedActions.removeFeedFromFeedList(payload.listId, payload.feedId) + await apiClient.lists.feeds.$delete({ + json: { + listId: payload.listId, + feedId: payload.feedId, + }, + }) + }, + onSuccess: () => { + toast.success(t("lists.feeds.delete.success")) + options?.onSuccess?.() + }, + async onError() { + toast.error(t("lists.feeds.delete.error")) + options?.onError?.() + }, + }) +} diff --git a/apps/renderer/src/store/feed/store.ts b/apps/renderer/src/store/feed/store.ts index 37c8257b5..5208f18af 100644 --- a/apps/renderer/src/store/feed/store.ts +++ b/apps/renderer/src/store/feed/store.ts @@ -1,10 +1,17 @@ import { produce } from "immer" +import { omit } from "lodash-es" import { nanoid } from "nanoid" import { whoami } from "~/atoms/user" import { runTransactionInScope } from "~/database" import { apiClient } from "~/lib/api-fetch" -import type { TargetModel, UserModel } from "~/models" +import type { + FeedModel, + FeedOrListModel, + FeedOrListRespModel, + ListModel, + UserModel, +} from "~/models" import { FeedService } from "~/services" import { getSubscriptionByFeedId } from "../subscription" @@ -23,9 +30,16 @@ class FeedActions { set({ feeds: {} }) } - upsertMany(feeds: TargetModel[]) { + upsertMany(feeds: FeedOrListRespModel[]) { runTransactionInScope(() => { - FeedService.upsertMany(feeds) + FeedService.upsertMany( + feeds.map((feed) => { + if (feed.type === "list") { + return omit(feed, ["feeds"]) + } + return feed + }), + ) }) set((state) => produce(state, (state) => { @@ -53,7 +67,7 @@ class FeedActions { } }) - state.feeds[feed.id] = feed + state.feeds[feed.id] = omit(feed, "feeds") as FeedOrListModel } else { // Store temp feed in memory const nonce = feed["nonce"] || nanoid(8) @@ -67,7 +81,7 @@ class FeedActions { ) } - private patch(feedId: string, patch: Partial) { + private patch(feedId: string, patch: Partial) { set((state) => produce(state, (state) => { const feed = state.feeds[feedId] @@ -100,6 +114,27 @@ class FeedActions { }) } + async addFeedToFeedList(listId: string, feed: FeedModel) { + const list = get().feeds[listId] as ListModel + if (!list) return + feedActions.upsertMany([feed]) + + this.patch(listId, { + feedIds: [feed.id, ...list.feedIds], + }) + feedActions.upsertMany([get().feeds[listId]]) + } + + async removeFeedFromFeedList(listId: string, feedId: string) { + const list = get().feeds[listId] as ListModel + if (!list) return + + this.patch(listId, { + feedIds: list.feedIds.filter((id) => id !== feedId), + }) + feedActions.upsertMany([get().feeds[listId]]) + } + // API Fetcher // @@ -136,17 +171,17 @@ class FeedActions { async fetchOwnedLists() { const res = await apiClient.lists.list.$get() - this.upsertMany(res.data) + this.upsertMany(res.data.concat()) return res.data } } export const feedActions = new FeedActions() -export const getFeedById = (feedId: string): Nullable => +export const getFeedById = (feedId: string): Nullable => useFeedStore.getState().feeds[feedId] -export const getPreferredTitle = (feed?: TargetModel | null) => { +export const getPreferredTitle = (feed?: FeedOrListRespModel | null) => { if (!feed?.id) { return feed?.title } diff --git a/apps/renderer/src/store/feed/types.ts b/apps/renderer/src/store/feed/types.ts index d5bde4f2f..6d5d1cf69 100644 --- a/apps/renderer/src/store/feed/types.ts +++ b/apps/renderer/src/store/feed/types.ts @@ -1,15 +1,15 @@ -import type { TargetModel } from "~/models" +import type { FeedOrListModel, FeedOrListRespModel } from "~/models" type FeedId = string export interface FeedState { - feeds: Record + feeds: Record } export interface FeedActions { - upsertMany: (feeds: TargetModel[]) => void + upsertMany: (feeds: FeedOrListRespModel[]) => void clear: () => void - patch: (feedId: FeedId, patch: Partial) => void + patch: (feedId: FeedId, patch: Partial) => void } export type FeedQueryParams = { id?: string; url?: string; isList?: boolean } diff --git a/apps/renderer/src/store/search/types.ts b/apps/renderer/src/store/search/types.ts index c53a583a6..f5491f726 100644 --- a/apps/renderer/src/store/search/types.ts +++ b/apps/renderer/src/store/search/types.ts @@ -1,4 +1,4 @@ -import type { EntryModel, TargetModel } from "~/models" +import type { EntryModel, FeedOrListRespModel } from "~/models" import type { SubscriptionFlatModel } from "../subscription" import type { SearchType } from "./constants" @@ -9,7 +9,7 @@ export interface SearchResult exten } export interface SearchState { - feeds: SearchResult[] + feeds: SearchResult[] entries: SearchResult[] subscriptions: SearchResult[] diff --git a/locales/common/ar-DZ.json b/locales/common/ar-DZ.json index 78c34d91c..33d135b7b 100644 --- a/locales/common/ar-DZ.json +++ b/locales/common/ar-DZ.json @@ -5,6 +5,7 @@ "confirm": "تأكيد", "ok": "موافق", "quantifier.piece": "", + "space": " ", "time.last_night": "الليلة الماضية", "time.the_night_before_last": "الليلة التي قبل الماضية", "time.today": "اليوم", @@ -24,6 +25,5 @@ "words.result": "نتيجة", "words.result_one": "نتيجة", "words.result_other": "نتائج", - "words.space": " ", "words.which.all": "الكل" -} +} \ No newline at end of file diff --git a/locales/common/ar-IQ.json b/locales/common/ar-IQ.json index 09de59417..ce5e0581b 100644 --- a/locales/common/ar-IQ.json +++ b/locales/common/ar-IQ.json @@ -4,6 +4,7 @@ "confirm": "تأكيد", "ok": "موافق", "quantifier.piece": "", + "space": " ", "time.last_night": "الليلة الماضية", "time.the_night_before_last": "الليلة قبل الماضية", "time.today": "اليوم", @@ -23,6 +24,5 @@ "words.result": "نتيجة", "words.result_one": "نتيجة", "words.result_other": "نتائج", - "words.space": " ", "words.which.all": "الكل" -} +} \ No newline at end of file diff --git a/locales/common/ar-KW.json b/locales/common/ar-KW.json index 09de59417..ce5e0581b 100644 --- a/locales/common/ar-KW.json +++ b/locales/common/ar-KW.json @@ -4,6 +4,7 @@ "confirm": "تأكيد", "ok": "موافق", "quantifier.piece": "", + "space": " ", "time.last_night": "الليلة الماضية", "time.the_night_before_last": "الليلة قبل الماضية", "time.today": "اليوم", @@ -23,6 +24,5 @@ "words.result": "نتيجة", "words.result_one": "نتيجة", "words.result_other": "نتائج", - "words.space": " ", "words.which.all": "الكل" -} +} \ No newline at end of file diff --git a/locales/common/ar-MA.json b/locales/common/ar-MA.json index 66293ad4c..491b4cb56 100644 --- a/locales/common/ar-MA.json +++ b/locales/common/ar-MA.json @@ -5,6 +5,7 @@ "confirm": "تأكيد", "ok": "موافق", "quantifier.piece": "", + "space": " ", "time.last_night": "الليلة الماضية", "time.the_night_before_last": "الليلة التي سبقتها", "time.today": "اليوم", @@ -24,6 +25,5 @@ "words.result": "نتيجة", "words.result_one": "نتيجة", "words.result_other": "نتائج", - "words.space": " ", "words.which.all": "الكل" -} +} \ No newline at end of file diff --git a/locales/common/ar-SA.json b/locales/common/ar-SA.json index 0ff14b728..b8d91359a 100644 --- a/locales/common/ar-SA.json +++ b/locales/common/ar-SA.json @@ -5,6 +5,7 @@ "confirm": "تأكيد", "ok": "حسنًا", "quantifier.piece": "", + "space": " ", "time.last_night": "الليلة الماضية", "time.the_night_before_last": "الليلة قبل الماضية", "time.today": "اليوم", @@ -24,6 +25,5 @@ "words.result": "نتيجة", "words.result_one": "نتيجة", "words.result_other": "نتائج", - "words.space": " ", "words.which.all": "الكل" -} +} \ No newline at end of file diff --git a/locales/common/ar-TN.json b/locales/common/ar-TN.json index 013ae1159..b06999667 100644 --- a/locales/common/ar-TN.json +++ b/locales/common/ar-TN.json @@ -4,6 +4,7 @@ "confirm": "تأكيد", "ok": "موافق", "quantifier.piece": "", + "space": " ", "time.last_night": "الليلة الماضية", "time.the_night_before_last": "الليلة التي قبلها", "time.today": "اليوم", @@ -23,6 +24,5 @@ "words.result": "نتيجة", "words.result_one": "نتيجة", "words.result_other": "نتائج", - "words.space": " ", "words.which.all": "الكل" -} +} \ No newline at end of file diff --git a/locales/common/en.json b/locales/common/en.json index d75357d1b..2be3edc21 100644 --- a/locales/common/en.json +++ b/locales/common/en.json @@ -5,6 +5,7 @@ "confirm": "Confirm", "ok": "OK", "quantifier.piece": "", + "space": " ", "time.last_night": "Last Night", "time.the_night_before_last": "The Night Before Last", "time.today": "Today", @@ -28,8 +29,7 @@ "words.result": "result", "words.result_one": "result", "words.result_other": "results", - "words.space": " ", "words.submit": "Submit", "words.update": "Update", "words.which.all": "All" -} +} \ No newline at end of file diff --git a/locales/common/es.json b/locales/common/es.json index 42115fdee..a607af45c 100644 --- a/locales/common/es.json +++ b/locales/common/es.json @@ -5,6 +5,7 @@ "confirm": "Confirmar", "ok": "OK", "quantifier.piece": "", + "space": " ", "time.last_night": "Anoche", "time.the_night_before_last": "Anteanoche", "time.today": "Hoy", @@ -24,6 +25,5 @@ "words.result": "resultado", "words.result_one": "resultado", "words.result_other": "resultados", - "words.space": " ", "words.which.all": "Todo" -} +} \ No newline at end of file diff --git a/locales/common/fi.json b/locales/common/fi.json index 06c594ab2..1ba136037 100644 --- a/locales/common/fi.json +++ b/locales/common/fi.json @@ -4,6 +4,7 @@ "confirm": "Vahvista", "ok": "OK", "quantifier.piece": "", + "space": " ", "time.last_night": "Viime yö", "time.the_night_before_last": "Toissa yö", "time.today": "Tänään", @@ -23,6 +24,5 @@ "words.result": "tulos", "words.result_one": "tulos", "words.result_other": "tulokset", - "words.space": " ", "words.which.all": "Kaikki" -} +} \ No newline at end of file diff --git a/locales/common/fr.json b/locales/common/fr.json index 75ecb72e6..e251a333c 100644 --- a/locales/common/fr.json +++ b/locales/common/fr.json @@ -5,6 +5,7 @@ "confirm": "Confirmer", "ok": "OK", "quantifier.piece": "", + "space": " ", "time.last_night": "La nuit dernière", "time.the_night_before_last": "L'avant-dernière nuit", "time.today": "Aujourd'hui", @@ -24,6 +25,5 @@ "words.result": "résultat", "words.result_one": "résultat", "words.result_other": "résultats", - "words.space": " ", "words.which.all": "Tous" -} +} \ No newline at end of file diff --git a/locales/common/it.json b/locales/common/it.json index 3e46cb39d..a32756e93 100644 --- a/locales/common/it.json +++ b/locales/common/it.json @@ -4,6 +4,7 @@ "confirm": "Conferma", "ok": "OK", "quantifier.piece": "", + "space": " ", "time.last_night": "Ieri sera", "time.the_night_before_last": "L'altra sera", "time.today": "Oggi", @@ -23,6 +24,5 @@ "words.result": "risultato", "words.result_one": "risultato", "words.result_other": "risultati", - "words.space": " ", "words.which.all": "Tutti" -} +} \ No newline at end of file diff --git a/locales/common/ja.json b/locales/common/ja.json index d7c8fd3d4..220c111e9 100644 --- a/locales/common/ja.json +++ b/locales/common/ja.json @@ -5,6 +5,7 @@ "confirm": "確認", "ok": "OK", "quantifier.piece": "個", + "space": "", "time.last_night": "昨夜", "time.the_night_before_last": "一昨夜", "time.today": "今日", @@ -24,6 +25,5 @@ "words.result": "結果", "words.result_one": "結果", "words.result_other": "結果", - "words.space": "", "words.which.all": "すべて" -} +} \ No newline at end of file diff --git a/locales/common/ko.json b/locales/common/ko.json index 03d0a5255..f229ad428 100644 --- a/locales/common/ko.json +++ b/locales/common/ko.json @@ -5,6 +5,7 @@ "confirm": "확인", "ok": "확인", "quantifier.piece": "", + "space": " ", "time.last_night": "어젯밤", "time.the_night_before_last": "그저께 밤", "time.today": "오늘", @@ -27,8 +28,7 @@ "words.result": "결과", "words.result_one": "결과", "words.result_other": "결과들", - "words.space": " ", "words.submit": "제출", "words.update": "업데이트", "words.which.all": "모두" -} +} \ No newline at end of file diff --git a/locales/common/pt.json b/locales/common/pt.json index 4ed5c6847..1588b31b7 100644 --- a/locales/common/pt.json +++ b/locales/common/pt.json @@ -5,6 +5,7 @@ "confirm": "Confirmar", "ok": "OK", "quantifier.piece": "", + "space": " ", "time.last_night": "Ontem à noite", "time.the_night_before_last": "Anteontem à noite", "time.today": "Hoje", @@ -24,6 +25,5 @@ "words.result": "resultado", "words.result_one": "resultado", "words.result_other": "resultados", - "words.space": " ", "words.which.all": "Todos" -} +} \ No newline at end of file diff --git a/locales/common/ru.json b/locales/common/ru.json index 81f46ea1d..5759f5d5f 100644 --- a/locales/common/ru.json +++ b/locales/common/ru.json @@ -4,6 +4,7 @@ "confirm": "Подтвердить", "ok": "ОК", "quantifier.piece": "", + "space": " ", "time.last_night": "Прошлой ночью", "time.the_night_before_last": "Позапрошлой ночью", "time.today": "Сегодня", @@ -23,6 +24,5 @@ "words.result": "результат", "words.result_one": "результат", "words.result_other": "результаты", - "words.space": " ", "words.which.all": "Все" -} +} \ No newline at end of file diff --git a/locales/common/tr.json b/locales/common/tr.json index 8dbd4ffbb..90deaa3f9 100644 --- a/locales/common/tr.json +++ b/locales/common/tr.json @@ -5,6 +5,7 @@ "confirm": "Onayla", "ok": "Tamam", "quantifier.piece": "", + "space": " ", "time.last_night": "Dün Gece", "time.the_night_before_last": "Evvelsi Gece", "time.today": "Bugün", @@ -27,8 +28,7 @@ "words.result": "sonuç", "words.result_one": "sonuç", "words.result_other": "sonuçlar", - "words.space": " ", "words.submit": "Gönder", "words.update": "Güncelle", "words.which.all": "Tümü" -} +} \ No newline at end of file diff --git a/locales/common/zh-CN.json b/locales/common/zh-CN.json index 8c3b8ad93..701674588 100644 --- a/locales/common/zh-CN.json +++ b/locales/common/zh-CN.json @@ -5,6 +5,7 @@ "confirm": "确认", "ok": "好", "quantifier.piece": "条", + "space": "", "time.last_night": "昨晚", "time.the_night_before_last": "前天晚上", "time.today": "今天", @@ -28,8 +29,7 @@ "words.result": "结果", "words.result_one": "结果", "words.result_other": "结果", - "words.space": "", "words.submit": "提交", "words.update": "更新", "words.which.all": "全部" -} +} \ No newline at end of file diff --git a/locales/common/zh-HK.json b/locales/common/zh-HK.json index 5fc00bd52..f17ed39ae 100644 --- a/locales/common/zh-HK.json +++ b/locales/common/zh-HK.json @@ -5,6 +5,7 @@ "confirm": "確認", "ok": "確定", "quantifier.piece": "", + "space": " ", "time.last_night": "昨晚", "time.the_night_before_last": "前晚", "time.today": "今天", @@ -27,8 +28,7 @@ "words.result": "結果", "words.result_one": "結果", "words.result_other": "結果", - "words.space": " ", "words.submit": "提交", "words.update": "更新", "words.which.all": "全部" -} +} \ No newline at end of file diff --git a/locales/common/zh-TW.json b/locales/common/zh-TW.json index 490ba0f24..80d27909c 100644 --- a/locales/common/zh-TW.json +++ b/locales/common/zh-TW.json @@ -5,6 +5,7 @@ "confirm": "確認", "ok": "確定", "quantifier.piece": "", + "space": " ", "time.last_night": "昨晚", "time.the_night_before_last": "前晚", "time.today": "今天", @@ -24,6 +25,5 @@ "words.result": "結果", "words.result_one": "結果", "words.result_other": "多筆結果", - "words.space": " ", "words.which.all": "全部" -} +} \ No newline at end of file