diff --git a/apps/desktop/layer/renderer/src/lib/defineQuery.ts b/apps/desktop/layer/renderer/src/lib/defineQuery.ts index 86df2f5dc..c17dd6e4e 100644 --- a/apps/desktop/layer/renderer/src/lib/defineQuery.ts +++ b/apps/desktop/layer/renderer/src/lib/defineQuery.ts @@ -12,7 +12,10 @@ export type DefinedQuery = Readonly<{ cancel: (key?: (key: TQueryKey) => QueryKey) => Promise remove: (key?: (key: TQueryKey) => QueryKey) => Promise - invalidate: (key?: (key: TQueryKey) => QueryKey) => Promise + invalidate: (options?: { + keyExtractor?: (key: TQueryKey) => QueryKey + exact?: boolean + }) => Promise invalidateRoot: () => void refetch: () => Promise @@ -107,12 +110,14 @@ export function defineQuery< const queryKey = typeof keyExtactor === "function" ? keyExtactor(key) : key queryClient.removeQueries({ queryKey }) }, - invalidate: async (keyExtactor) => { - const queryKey = typeof keyExtactor === "function" ? keyExtactor(key) : key + invalidate: async (args) => { + const { keyExtractor, exact } = args || {} + const queryKey = typeof keyExtractor === "function" ? keyExtractor(key) : key await queryClient.invalidateQueries({ queryKey, refetchType: "all", + exact, }) options?.onInvalidate?.() }, diff --git a/apps/desktop/layer/renderer/src/modules/discover/FeedForm.tsx b/apps/desktop/layer/renderer/src/modules/discover/FeedForm.tsx index c9c78cfea..8147100d1 100644 --- a/apps/desktop/layer/renderer/src/modules/discover/FeedForm.tsx +++ b/apps/desktop/layer/renderer/src/modules/discover/FeedForm.tsx @@ -25,6 +25,7 @@ import { useTranslation } from "react-i18next" import { toast } from "sonner" import { z } from "zod" +import { getGeneralSettings } from "~/atoms/settings/general" import { Autocomplete } from "~/components/ui/auto-completion" import { useCurrentModal, useIsInModal } from "~/components/ui/modal/stacked/hooks" import { getRouteParams } from "~/hooks/biz/useRouteParams" @@ -32,6 +33,7 @@ import { useAuthQuery, useI18n } from "~/hooks/common" import { apiClient } from "~/lib/api-fetch" import { tipcClient } from "~/lib/client" import { toastFetchError } from "~/lib/error-parser" +import { entries as entriesQuery } from "~/queries/entries" import { feed as feedQuery, useFeedQuery } from "~/queries/feed" import { subscription as subscriptionQuery } from "~/queries/subscriptions" import { useFeedByIdOrUrl } from "~/store/feed" @@ -245,6 +247,16 @@ const FeedInnerForm = ({ }) }, onSuccess: (_, variables) => { + if (getGeneralSettings().hidePrivateSubscriptionsInTimeline) { + entriesQuery + .entries({ + feedId: "all", + view: Number(variables.view), + excludePrivate: true, + }) + .invalidate({ exact: true }) + } + if (isSubscribed && variables.view !== `${subscription?.view}`) { feedUnreadActions.fetchUnreadByView(subscription?.view) } else { diff --git a/apps/desktop/layer/renderer/src/modules/discover/ListForm.tsx b/apps/desktop/layer/renderer/src/modules/discover/ListForm.tsx index 322373e97..be001b0a2 100644 --- a/apps/desktop/layer/renderer/src/modules/discover/ListForm.tsx +++ b/apps/desktop/layer/renderer/src/modules/discover/ListForm.tsx @@ -24,6 +24,7 @@ import { useTranslation } from "react-i18next" import { toast } from "sonner" import { z } from "zod" +import { getGeneralSettings } from "~/atoms/settings/general" import { useCurrentModal } from "~/components/ui/modal/stacked/hooks" import { useI18n } from "~/hooks/common" import { apiClient } from "~/lib/api-fetch" @@ -31,6 +32,7 @@ import { tipcClient } from "~/lib/client" import { getFetchErrorMessage, toastFetchError } from "~/lib/error-parser" import { getNewIssueUrl } from "~/lib/issues" import { FollowSummary } from "~/modules/feed/feed-summary" +import { entries as entriesQuery } from "~/queries/entries" import { lists as listsQuery, useList } from "~/queries/lists" import { subscription as subscriptionQuery } from "~/queries/subscriptions" import { useListById } from "~/store/list" @@ -219,6 +221,16 @@ const ListInnerForm = ({ }) }, onSuccess: (_, variables) => { + if (getGeneralSettings().hidePrivateSubscriptionsInTimeline) { + entriesQuery + .entries({ + feedId: "all", + view: Number(variables.view), + excludePrivate: true, + }) + .invalidate({ exact: true }) + } + if (isSubscribed && variables.view !== `${subscription?.view}`) { feedUnreadActions.fetchUnreadByView(subscription?.view) } else { diff --git a/apps/desktop/layer/renderer/src/modules/entry-column/hooks/useEntriesByView.ts b/apps/desktop/layer/renderer/src/modules/entry-column/hooks/useEntriesByView.ts index b18a2a545..26929744d 100644 --- a/apps/desktop/layer/renderer/src/modules/entry-column/hooks/useEntriesByView.ts +++ b/apps/desktop/layer/renderer/src/modules/entry-column/hooks/useEntriesByView.ts @@ -51,6 +51,9 @@ const useRemoteEntries = (): UseEntriesReturn => { const isPreview = useIsPreviewFeed() const unreadOnly = useGeneralSettingKey("unreadOnly") + const hidePrivateSubscriptionsInTimeline = useGeneralSettingKey( + "hidePrivateSubscriptionsInTimeline", + ) const folderIds = useFolderFeedsByFeedId({ feedId, @@ -64,6 +67,7 @@ const useRemoteEntries = (): UseEntriesReturn => { listId, view, ...(unreadOnly === true && !isPreview && { read: false }), + ...(hidePrivateSubscriptionsInTimeline === true && { excludePrivate: true }), } if (feedId && listId && isBizId(feedId)) { @@ -71,7 +75,16 @@ const useRemoteEntries = (): UseEntriesReturn => { } return params - }, [feedId, folderIds, inboxId, listId, unreadOnly, view, isPreview]) + }, [ + feedId, + folderIds, + inboxId, + listId, + unreadOnly, + isPreview, + view, + hidePrivateSubscriptionsInTimeline, + ]) const query = useEntries(entriesOptions) const [fetchedTime, setFetchedTime] = useState() @@ -134,6 +147,9 @@ const useLocalEntries = (): UseEntriesReturn => { const { feedId, view, inboxId, listId, isAllFeeds } = useRouteParams() const unreadOnly = useGeneralSettingKey("unreadOnly") + const hidePrivateSubscriptionsInTimeline = useGeneralSettingKey( + "hidePrivateSubscriptionsInTimeline", + ) const folderIds = useFolderFeedsByFeedId({ feedId, @@ -145,6 +161,7 @@ const useLocalEntries = (): UseEntriesReturn => { { unread: unreadOnly, view, + excludePrivate: hidePrivateSubscriptionsInTimeline, }, ) diff --git a/apps/desktop/layer/renderer/src/modules/entry-column/hooks/useMarkAll.ts b/apps/desktop/layer/renderer/src/modules/entry-column/hooks/useMarkAll.ts index 65f1ac011..8b3ee3269 100644 --- a/apps/desktop/layer/renderer/src/modules/entry-column/hooks/useMarkAll.ts +++ b/apps/desktop/layer/renderer/src/modules/entry-column/hooks/useMarkAll.ts @@ -1,3 +1,4 @@ +import { getGeneralSettings } from "~/atoms/settings/general" import { getRouteParams } from "~/hooks/biz/useRouteParams" import { getFolderFeedsByFeedId, subscriptionActions } from "~/store/subscription" @@ -17,7 +18,12 @@ export const markAllByRoute = async (filter?: MarkAllFilter) => { if (!routerParams) return if (typeof routerParams.feedId === "number" || routerParams.isAllFeeds) { - subscriptionActions.markReadByView(view, filter) + const { hidePrivateSubscriptionsInTimeline } = getGeneralSettings() + subscriptionActions.markReadByView({ + view, + filter, + excludePrivate: hidePrivateSubscriptionsInTimeline, + }) } else if (inboxId) { subscriptionActions.markReadByFeedIds({ inboxId, diff --git a/apps/desktop/layer/renderer/src/modules/settings/tabs/general.tsx b/apps/desktop/layer/renderer/src/modules/settings/tabs/general.tsx index 611e84a2f..146692bc8 100644 --- a/apps/desktop/layer/renderer/src/modules/settings/tabs/general.tsx +++ b/apps/desktop/layer/renderer/src/modules/settings/tabs/general.tsx @@ -103,11 +103,14 @@ export const SettingGeneral = () => { label: t("general.auto_group.label"), description: t("general.auto_group.description"), }), - defineSettingItem("hideAllReadSubscriptions", { label: t("general.hide_all_read_subscriptions.label"), description: t("general.hide_all_read_subscriptions.description"), }), + defineSettingItem("hidePrivateSubscriptionsInTimeline", { + label: t("general.hide_private_subscriptions_in_timeline.label"), + description: t("general.hide_private_subscriptions_in_timeline.description"), + }), { type: "title", diff --git a/apps/desktop/layer/renderer/src/queries/entries.ts b/apps/desktop/layer/renderer/src/queries/entries.ts index 8c0a3be2c..baa01fd79 100644 --- a/apps/desktop/layer/renderer/src/queries/entries.ts +++ b/apps/desktop/layer/renderer/src/queries/entries.ts @@ -13,6 +13,7 @@ export const entries = { listId, view, read, + excludePrivate, limit, }: { feedId?: number | string @@ -20,10 +21,11 @@ export const entries = { listId?: number | string view?: number read?: boolean + excludePrivate?: boolean limit?: number }) => defineQuery( - ["entries", inboxId || listId || feedId, view, read, limit], + ["entries", inboxId || listId || feedId, view, read, excludePrivate, limit], async ({ pageParam }) => entryActions.fetchEntries({ feedId, @@ -31,6 +33,7 @@ export const entries = { listId, view, read, + excludePrivate, limit, pageParam: pageParam as string, }), @@ -130,30 +133,35 @@ export const useEntries = ({ listId, view, read, + excludePrivate, }: { feedId?: number | string inboxId?: number | string listId?: number | string view?: number read?: boolean + excludePrivate?: boolean }) => { const fetchUnread = read === false const feedUnreadDirty = useFeedUnreadIsDirty((feedId as string) || "") - return useAuthInfiniteQuery(entries.entries({ feedId, inboxId, listId, view, read }), { - enabled: feedId !== undefined || inboxId !== undefined || listId !== undefined, - getNextPageParam: (lastPage) => lastPage.data?.at(-1)?.entries.publishedAt, - initialPageParam: undefined, - refetchOnWindowFocus: false, - refetchOnReconnect: false, - // DON'T refetch when the router is pop to previous page - refetchOnMount: fetchUnread && feedUnreadDirty && !history.isPop ? "always" : false, + return useAuthInfiniteQuery( + entries.entries({ feedId, inboxId, listId, view, read, excludePrivate }), + { + enabled: feedId !== undefined || inboxId !== undefined || listId !== undefined, + getNextPageParam: (lastPage) => lastPage.data?.at(-1)?.entries.publishedAt, + initialPageParam: undefined, + refetchOnWindowFocus: false, + refetchOnReconnect: false, + // DON'T refetch when the router is pop to previous page + refetchOnMount: fetchUnread && feedUnreadDirty && !history.isPop ? "always" : false, - staleTime: - // Force refetch unread entries when feed is dirty - // HACK: disable refetch when the router is pop to previous page - history.isPop ? Infinity : fetchUnread && feedUnreadDirty ? 0 : defaultStaleTime, - }) + staleTime: + // Force refetch unread entries when feed is dirty + // HACK: disable refetch when the router is pop to previous page + history.isPop ? Infinity : fetchUnread && feedUnreadDirty ? 0 : defaultStaleTime, + }, + ) } export const useEntriesPreview = ({ id }: { id?: string }) => diff --git a/apps/desktop/layer/renderer/src/store/entry/hooks.ts b/apps/desktop/layer/renderer/src/store/entry/hooks.ts index 45ed4023c..da22cbfe2 100644 --- a/apps/desktop/layer/renderer/src/store/entry/hooks.ts +++ b/apps/desktop/layer/renderer/src/store/entry/hooks.ts @@ -5,7 +5,7 @@ import { useCallback } from "react" import { FEED_COLLECTION_LIST, ROUTE_FEED_IN_FOLDER } from "~/constants" import { useListsFeedIds } from "../list" -import { useFeedIdByView } from "../subscription" +import { useFeedIdByView, useNonPrivateSubscriptionIds } from "../subscription" import { getEntryIsInView, getFilteredFeedIds } from "./helper" import { useEntryStore } from "./store" import type { EntryFilter, FlatEntryModel } from "./types" @@ -82,12 +82,15 @@ export const useEntryIdsByFeedId = (feedId: string, filter?: EntryFilter) => export const useEntryIdsByView = (view: FeedViewType, filter?: EntryFilter) => { const feedIds = useFeedIdByView(view) - const listFeedIds = useListsFeedIds(feedIds) + const nonPrivateFeedIds = useNonPrivateSubscriptionIds(feedIds) + const finalFeedIds = filter?.excludePrivate ? nonPrivateFeedIds : feedIds + const listFeedIds = useListsFeedIds(finalFeedIds) return useEntryStore( useCallback( - () => getFilteredFeedIds(Array.from(new Set([...feedIds, ...listFeedIds])), filter) || [], - [feedIds, listFeedIds, filter], + () => + getFilteredFeedIds(Array.from(new Set([...finalFeedIds, ...listFeedIds])), filter) || [], + [finalFeedIds, listFeedIds, filter], ), ) } diff --git a/apps/desktop/layer/renderer/src/store/entry/store.ts b/apps/desktop/layer/renderer/src/store/entry/store.ts index 0f6712385..a9232ebeb 100644 --- a/apps/desktop/layer/renderer/src/store/entry/store.ts +++ b/apps/desktop/layer/renderer/src/store/entry/store.ts @@ -113,6 +113,7 @@ class EntryActions { listId, view, read, + excludePrivate, limit, pageParam, }: { @@ -121,6 +122,7 @@ class EntryActions { listId?: number | string view?: number read?: boolean + excludePrivate?: boolean limit?: number pageParam?: string }) { @@ -163,6 +165,7 @@ class EntryActions { publishedAfter: pageParam, read, limit, + excludePrivate, ...params, }, }) diff --git a/apps/desktop/layer/renderer/src/store/entry/types.ts b/apps/desktop/layer/renderer/src/store/entry/types.ts index d603dde3b..689d61855 100644 --- a/apps/desktop/layer/renderer/src/store/entry/types.ts +++ b/apps/desktop/layer/renderer/src/store/entry/types.ts @@ -31,4 +31,5 @@ export interface EntryState { export interface EntryFilter { unread?: boolean view?: FeedViewType + excludePrivate?: boolean } diff --git a/apps/desktop/layer/renderer/src/store/subscription/hooks.ts b/apps/desktop/layer/renderer/src/store/subscription/hooks.ts index cd731521e..9db7d079c 100644 --- a/apps/desktop/layer/renderer/src/store/subscription/hooks.ts +++ b/apps/desktop/layer/renderer/src/store/subscription/hooks.ts @@ -211,3 +211,9 @@ export const useInboxesGroupedData = (view: FeedViewType) => { export const useIsSubscribed = (feedId: string) => useSubscriptionStore(useCallback((state) => isSubscribedSelector(feedId)(state), [feedId])) + +export const useNonPrivateSubscriptionIds = (ids: string[]) => { + const subscriptions = useSubscriptionsByFeedIds(ids) + const nonPrivateSubscriptions = subscriptions.filter((s) => !!s).filter((s) => !s?.isPrivate) + return nonPrivateSubscriptions.map((s) => s.listId || s.feedId) +} diff --git a/apps/desktop/layer/renderer/src/store/subscription/store.ts b/apps/desktop/layer/renderer/src/store/subscription/store.ts index fa9431eb7..9ce2020a4 100644 --- a/apps/desktop/layer/renderer/src/store/subscription/store.ts +++ b/apps/desktop/layer/renderer/src/store/subscription/store.ts @@ -238,13 +238,22 @@ class SubscriptionActions { }) } - async markReadByView(view: FeedViewType, filter?: MarkReadFilter) { + async markReadByView({ + view, + excludePrivate, + filter, + }: { + view: FeedViewType + excludePrivate?: boolean + filter?: MarkReadFilter + }) { const tx = createTransaction() tx.execute(async () => { await apiClient.reads.all.$post({ json: { view, + excludePrivate, ...filter, }, }) @@ -257,6 +266,9 @@ class SubscriptionActions { tx.optimistic(async () => { const state = get() for (const feedId in state.data) { + if (excludePrivate && state.data[feedId]?.isPrivate) { + return + } if (state.data[feedId]!.view === view) { if (state.data[feedId]?.listId) { const listFeedIds = getListById(state.data[feedId].listId)?.feedIds diff --git a/apps/mobile/src/modules/settings/routes/General.tsx b/apps/mobile/src/modules/settings/routes/General.tsx index 7dd9dec9b..d311b07f5 100644 --- a/apps/mobile/src/modules/settings/routes/General.tsx +++ b/apps/mobile/src/modules/settings/routes/General.tsx @@ -111,6 +111,9 @@ export const GeneralScreen: NavigationControllerView = () => { const summary = useGeneralSettingKey("summary") const autoGroup = useGeneralSettingKey("autoGroup") const hideAllReadSubscriptions = useGeneralSettingKey("hideAllReadSubscriptions") + const hidePrivateSubscriptionsInTimeline = useGeneralSettingKey( + "hidePrivateSubscriptionsInTimeline", + ) const showUnreadOnLaunch = useGeneralSettingKey("unreadOnly") // const groupByDate = useGeneralSettingKey("groupByDate") const expandLongSocialMedia = useGeneralSettingKey("autoExpandLongSocialMedia") @@ -184,6 +187,19 @@ export const GeneralScreen: NavigationControllerView = () => { }} /> + + + { + setGeneralSetting("hidePrivateSubscriptionsInTimeline", value) + }} + /> + {/* Timeline */} diff --git a/apps/mobile/src/store/entry/hooks.ts b/apps/mobile/src/store/entry/hooks.ts index 6b0c256b4..8b3e5617b 100644 --- a/apps/mobile/src/store/entry/hooks.ts +++ b/apps/mobile/src/store/entry/hooks.ts @@ -11,10 +11,28 @@ import type { EntryModel, FetchEntriesProps } from "./types" export const usePrefetchEntries = (props: Omit | null) => { const { feedId, inboxId, listId, view, limit, feedIdList } = props || {} const unreadOnly = useGeneralSettingKey("unreadOnly") + const hidePrivateSubscriptionsInTimeline = useGeneralSettingKey( + "hidePrivateSubscriptionsInTimeline", + ) return useInfiniteQuery({ - queryKey: ["entries", feedId, inboxId, listId, view, unreadOnly, limit, feedIdList], + queryKey: [ + "entries", + feedId, + inboxId, + listId, + view, + unreadOnly, + limit, + feedIdList, + hidePrivateSubscriptionsInTimeline, + ], queryFn: ({ pageParam }) => - entrySyncServices.fetchEntries({ ...props, pageParam, read: unreadOnly ? false : undefined }), + entrySyncServices.fetchEntries({ + ...props, + pageParam, + read: unreadOnly ? false : undefined, + excludePrivate: hidePrivateSubscriptionsInTimeline, + }), getNextPageParam: (lastPage) => lastPage.data?.at(-1)?.entries.publishedAt, initialPageParam: undefined as undefined | string, refetchOnWindowFocus: false, diff --git a/apps/mobile/src/store/entry/store.ts b/apps/mobile/src/store/entry/store.ts index 45353ee53..c06613ac8 100644 --- a/apps/mobile/src/store/entry/store.ts +++ b/apps/mobile/src/store/entry/store.ts @@ -2,6 +2,7 @@ import { FeedViewType } from "@follow/constants" import { debounce } from "es-toolkit/compat" import { fetch as expoFetch } from "expo/fetch" +import { getGeneralSettings } from "@/src/atoms/settings/general" import { apiClient } from "@/src/lib/api-fetch" import { getCookie } from "@/src/lib/auth" import { honoMorph } from "@/src/morph/hono" @@ -68,16 +69,21 @@ class EntryActions { sources?: string[] | null }) { if (!feedId) return + const subscription = getSubscription(feedId) - if (typeof subscription?.view === "number") { + const { hidePrivateSubscriptionsInTimeline } = getGeneralSettings() + const ignore = hidePrivateSubscriptionsInTimeline && subscription?.isPrivate + + if (typeof subscription?.view === "number" && !ignore) { draft.entryIdByView[subscription.view].add(entryId) } // lists for (const s of sources ?? []) { const subscription = getSubscription(s) + const ignore = hidePrivateSubscriptionsInTimeline && subscription?.isPrivate - if (typeof subscription?.view === "number") { + if (typeof subscription?.view === "number" && !ignore) { draft.entryIdByView[subscription.view].add(entryId) } } @@ -363,8 +369,18 @@ class EntryActions { class EntrySyncServices { async fetchEntries(props: FetchEntriesProps) { - const { feedId, inboxId, listId, view, read, limit, pageParam, isCollection, feedIdList } = - props + const { + feedId, + inboxId, + listId, + view, + read, + limit, + pageParam, + isCollection, + feedIdList, + excludePrivate, + } = props const params = getEntriesParams({ feedId, inboxId, @@ -389,6 +405,7 @@ class EntrySyncServices { read, limit, isCollection, + excludePrivate, ...params, }, }) diff --git a/apps/mobile/src/store/entry/types.ts b/apps/mobile/src/store/entry/types.ts index 053085e7d..45b32e6ec 100644 --- a/apps/mobile/src/store/entry/types.ts +++ b/apps/mobile/src/store/entry/types.ts @@ -14,4 +14,5 @@ export type FetchEntriesProps = { limit?: number pageParam?: string isCollection?: boolean + excludePrivate?: boolean } diff --git a/apps/mobile/src/store/unread/store.ts b/apps/mobile/src/store/unread/store.ts index fdf37f88a..b9936da5b 100644 --- a/apps/mobile/src/store/unread/store.ts +++ b/apps/mobile/src/store/unread/store.ts @@ -1,5 +1,6 @@ import type { FeedViewType } from "@follow/constants" +import { getGeneralSettings } from "@/src/atoms/settings/general" import type { UnreadSchema } from "@/src/database/schemas/types" import { apiClient } from "@/src/lib/api-fetch" import { setBadgeCountAsyncWithPermission } from "@/src/lib/permission" @@ -68,9 +69,11 @@ class UnreadSyncService { } | null time?: PublishAtTimeRangeFilter }) { + const { hidePrivateSubscriptionsInTimeline } = getGeneralSettings() await apiClient.reads.all.$post({ json: { view, + excludePrivate: hidePrivateSubscriptionsInTimeline, ...filter, ...time, }, diff --git a/locales/settings/en.json b/locales/settings/en.json index 6904e85c6..3191a30b3 100644 --- a/locales/settings/en.json +++ b/locales/settings/en.json @@ -186,6 +186,8 @@ "general.group_by_date.label": "Group by date", "general.hide_all_read_subscriptions.description": "Hide subscriptions without unread entries in the subscription list.", "general.hide_all_read_subscriptions.label": "Hide read", + "general.hide_private_subscriptions_in_timeline.description": "Hide private subscriptions in the View Timeline.", + "general.hide_private_subscriptions_in_timeline.label": "Hide private", "general.language": "Language", "general.launch_at_login": "Launch at login", "general.log_file.button": "Reveal", diff --git a/locales/settings/zh-CN.json b/locales/settings/zh-CN.json index 59378c8f6..dc5e904e3 100644 --- a/locales/settings/zh-CN.json +++ b/locales/settings/zh-CN.json @@ -185,6 +185,8 @@ "general.group_by_date.label": "按日期分组", "general.hide_all_read_subscriptions.description": "在订阅列表中隐藏没有未读条目的订阅。", "general.hide_all_read_subscriptions.label": "隐藏已读", + "general.hide_private_subscriptions_in_timeline.description": "在视图时间线中隐藏私密订阅。", + "general.hide_private_subscriptions_in_timeline.label": "隐藏私密", "general.language": "语言", "general.launch_at_login": "开机时启动", "general.log_file.button": "显示", diff --git a/packages/internal/shared/src/settings/defaults.ts b/packages/internal/shared/src/settings/defaults.ts index 2dddbbec6..9a9903484 100644 --- a/packages/internal/shared/src/settings/defaults.ts +++ b/packages/internal/shared/src/settings/defaults.ts @@ -19,6 +19,7 @@ export const defaultGeneralSettings: GeneralSettings = { // subscription autoGroup: true, hideAllReadSubscriptions: false, + hidePrivateSubscriptionsInTimeline: false, // view unreadOnly: true, diff --git a/packages/internal/shared/src/settings/interface.ts b/packages/internal/shared/src/settings/interface.ts index aaf0b07bd..80529a279 100644 --- a/packages/internal/shared/src/settings/interface.ts +++ b/packages/internal/shared/src/settings/interface.ts @@ -20,6 +20,8 @@ export interface GeneralSettings { // subscription autoGroup: boolean hideAllReadSubscriptions: boolean + hidePrivateSubscriptionsInTimeline: boolean + /** * Top timeline for mobile */