diff --git a/src/screens/Settings/DeerSettings.tsx b/src/screens/Settings/DeerSettings.tsx
--- a/src/screens/Settings/DeerSettings.tsx
+++ b/src/screens/Settings/DeerSettings.tsx
@@ -27,6 +27,10 @@
useNoAppLabelers,
useSetNoAppLabelers,
} from '#/state/preferences/no-app-labelers'
+import {
+ useNoDiscoverFallback,
+ useSetNoDiscoverFallback,
+} from '#/state/preferences/no-discover-fallback'
import {TextInput} from '#/view/com/modals/util'
import * as SettingsList from '#/screens/Settings/components/SettingsList'
import {atoms as a} from '#/alf'
@@ -124,6 +128,9 @@
const noAppLabelers = useNoAppLabelers()
const setNoAppLabelers = useSetNoAppLabelers()
+
+ const noDiscoverFallback = useNoDiscoverFallback()
+ const setNoDiscoverFallback = useSetNoDiscoverFallback()
const location = useGeolocation()
const setLocationControl = Dialog.useDialogControl()
@@ -277,14 +284,13 @@
Tweaks
{}}
- disabled={true}
+ name="no_discover_fallback"
+ label={_(msg`Do not fall back to discover feed`)}
+ value={noDiscoverFallback}
+ onChange={value => setNoDiscoverFallback(value)}
style={[a.w_full]}>
- 🚧 under construction...
+ Do not fall back to discover feed
diff --git a/src/state/persisted/schema.ts b/src/state/persisted/schema.ts
--- a/src/state/persisted/schema.ts
+++ b/src/state/persisted/schema.ts
@@ -129,6 +129,7 @@
constellationEnabled: z.boolean().optional(),
directFetchRecords: z.boolean().optional(),
noAppLabelers: z.boolean().optional(),
+ noDiscoverFallback: z.boolean().optional(),
/** @deprecated */
mutedThreads: z.array(z.string()),
@@ -187,6 +188,7 @@
constellationEnabled: false,
directFetchRecords: false,
noAppLabelers: false,
+ noDiscoverFallback: false,
}
export function tryParse(rawData: string): Schema | undefined {
diff --git a/src/state/preferences/index.tsx b/src/state/preferences/index.tsx
--- a/src/state/preferences/index.tsx
+++ b/src/state/preferences/index.tsx
@@ -13,6 +13,7 @@
import {Provider as LanguagesProvider} from './languages'
import {Provider as LargeAltBadgeProvider} from './large-alt-badge'
import {Provider as NoAppLabelersProvider} from './no-app-labelers'
+import {Provider as NoDiscoverProvider} from './no-discover-fallback'
import {Provider as SubtitlesProvider} from './subtitles'
import {Provider as TrendingSettingsProvider} from './trending'
import {Provider as UsedStarterPacksProvider} from './used-starter-packs'
@@ -41,25 +42,27 @@
-
-
-
-
-
-
-
-
-
- {children}
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+ {children}
+
+
+
+
+
+
+
+
+
+
diff --git a/src/state/preferences/no-discover-fallback.tsx b/src/state/preferences/no-discover-fallback.tsx
new file mode 100644
--- /dev/null
+++ b/src/state/preferences/no-discover-fallback.tsx
@@ -0,0 +1,47 @@
+import React from 'react'
+
+import * as persisted from '#/state/persisted'
+
+type StateContext = persisted.Schema['noDiscoverFallback']
+type SetContext = (v: persisted.Schema['noDiscoverFallback']) => void
+
+const stateContext = React.createContext(
+ persisted.defaults.noDiscoverFallback,
+)
+const setContext = React.createContext(
+ (_: persisted.Schema['noDiscoverFallback']) => {},
+)
+
+export function Provider({children}: React.PropsWithChildren<{}>) {
+ const [state, setState] = React.useState(persisted.get('noDiscoverFallback'))
+
+ const setStateWrapped = React.useCallback(
+ (noDiscoverFallback: persisted.Schema['noDiscoverFallback']) => {
+ setState(noDiscoverFallback)
+ persisted.write('noDiscoverFallback', noDiscoverFallback)
+ },
+ [setState],
+ )
+
+ React.useEffect(() => {
+ return persisted.onUpdate('noDiscoverFallback', nextNoDiscoverFallback => {
+ setState(nextNoDiscoverFallback)
+ })
+ }, [setStateWrapped])
+
+ return (
+
+
+ {children}
+
+
+ )
+}
+
+export function useNoDiscoverFallback() {
+ return React.useContext(stateContext)
+}
+
+export function useSetNoDiscoverFallback() {
+ return React.useContext(setContext)
+}
diff --git a/src/state/queries/post-feed.ts b/src/state/queries/post-feed.ts
--- a/src/state/queries/post-feed.ts
+++ b/src/state/queries/post-feed.ts
@@ -1,18 +1,18 @@
import React, {useCallback, useEffect, useRef} from 'react'
import {AppState} from 'react-native'
import {
- AppBskyActorDefs,
+ type AppBskyActorDefs,
AppBskyFeedDefs,
- AppBskyFeedPost,
+ type AppBskyFeedPost,
AtUri,
- BskyAgent,
+ type BskyAgent,
moderatePost,
- ModerationDecision,
+ type ModerationDecision,
} from '@atproto/api'
import {
- InfiniteData,
- QueryClient,
- QueryKey,
+ type InfiniteData,
+ type QueryClient,
+ type QueryKey,
useInfiniteQuery,
} from '@tanstack/react-query'
@@ -23,9 +23,9 @@
import {LikesFeedAPI} from '#/lib/api/feed/likes'
import {ListFeedAPI} from '#/lib/api/feed/list'
import {MergeFeedAPI} from '#/lib/api/feed/merge'
-import {FeedAPI, ReasonFeedSource} from '#/lib/api/feed/types'
+import {type FeedAPI, type ReasonFeedSource} from '#/lib/api/feed/types'
import {aggregateUserInterests} from '#/lib/api/feed/utils'
-import {FeedTuner, FeedTunerFn} from '#/lib/api/feed-manip'
+import {FeedTuner, type FeedTunerFn} from '#/lib/api/feed-manip'
import {DISCOVER_FEED_URI} from '#/lib/constants'
import {BSKY_FEED_OWNER_DIDS} from '#/lib/constants'
import {logger} from '#/logger'
@@ -36,6 +36,7 @@
import {KnownError} from '#/view/com/posts/PostFeedErrorMessage'
import {useFeedTuners} from '../preferences/feed-tuners'
import {useModerationOpts} from '../preferences/moderation-opts'
+import {useNoDiscoverFallback} from '../preferences/no-discover-fallback'
import {usePreferencesQuery} from './preferences'
import {
didOrHandleUriMatches,
@@ -135,7 +136,9 @@
preferences?.savedFeeds?.findIndex(
f => f.pinned && f.value === 'following',
) ?? -1
- const enableFollowingToDiscoverFallback = followingPinnedIndex === 0
+ const noDiscoverFallback = useNoDiscoverFallback()
+ const enableFollowingToDiscoverFallback =
+ followingPinnedIndex === 0 && !noDiscoverFallback
const agent = useAgent()
const lastRun = useRef<{
data: InfiniteData