diff --git a/src/App.native.tsx b/src/App.native.tsx
index 569f342c2f..14daa3bd6f 100644
--- a/src/App.native.tsx
+++ b/src/App.native.tsx
@@ -18,6 +18,7 @@ import {useQueryClient} from '@tanstack/react-query'
import {Provider as StatsigProvider} from '#/lib/statsig/statsig'
import {init as initPersistedState} from '#/state/persisted'
import {Provider as LabelDefsProvider} from '#/state/preferences/label-defs'
+import {Provider as ModerationOptsProvider} from '#/state/preferences/moderation-opts'
import {readLastActiveAccount} from '#/state/session/util'
import {useIntentHandler} from 'lib/hooks/useIntentHandler'
import {useNotificationsListener} from 'lib/notifications/notifications'
@@ -79,23 +80,25 @@ function InnerApp() {
-
-
-
-
-
- {/* All components should be within this provider */}
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+ {/* All components should be within this provider */}
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/App.web.tsx b/src/App.web.tsx
index 226fb8d3f3..e04fd45f17 100644
--- a/src/App.web.tsx
+++ b/src/App.web.tsx
@@ -8,6 +8,7 @@ import {SafeAreaProvider} from 'react-native-safe-area-context'
import {Provider as StatsigProvider} from '#/lib/statsig/statsig'
import {init as initPersistedState} from '#/state/persisted'
import {Provider as LabelDefsProvider} from '#/state/preferences/label-defs'
+import {Provider as ModerationOptsProvider} from '#/state/preferences/moderation-opts'
import {readLastActiveAccount} from '#/state/session/util'
import {useIntentHandler} from 'lib/hooks/useIntentHandler'
import {QueryProvider} from 'lib/react-query'
@@ -56,23 +57,25 @@ function InnerApp() {
key={currentAccount?.did}>
-
-
-
-
-
- {/* All components should be within this provider */}
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+ {/* All components should be within this provider */}
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/components/ProfileHoverCard/index.web.tsx b/src/components/ProfileHoverCard/index.web.tsx
index d1b00d522f..a22436879b 100644
--- a/src/components/ProfileHoverCard/index.web.tsx
+++ b/src/components/ProfileHoverCard/index.web.tsx
@@ -9,7 +9,7 @@ import {makeProfileLink} from '#/lib/routes/links'
import {sanitizeDisplayName} from '#/lib/strings/display-names'
import {sanitizeHandle} from '#/lib/strings/handles'
import {pluralize} from '#/lib/strings/helpers'
-import {useModerationOpts} from '#/state/queries/preferences'
+import {useModerationOpts} from '#/state/preferences/moderation-opts'
import {usePrefetchProfileQuery, useProfileQuery} from '#/state/queries/profile'
import {useSession} from '#/state/session'
import {useProfileShadow} from 'state/cache/profile-shadow'
diff --git a/src/components/dms/NewChat.tsx b/src/components/dms/NewChat.tsx
index 86d421ebad..3ad1ce7ee3 100644
--- a/src/components/dms/NewChat.tsx
+++ b/src/components/dms/NewChat.tsx
@@ -8,7 +8,7 @@ import {useLingui} from '@lingui/react'
import {sanitizeDisplayName} from '#/lib/strings/display-names'
import {sanitizeHandle} from '#/lib/strings/handles'
import {isWeb} from '#/platform/detection'
-import {useModerationOpts} from '#/state/queries/preferences'
+import {useModerationOpts} from '#/state/preferences/moderation-opts'
import {useActorAutocompleteQuery} from 'state/queries/actor-autocomplete'
import {FAB} from '#/view/com/util/fab/FAB'
import * as Toast from '#/view/com/util/Toast'
diff --git a/src/lib/functions.ts b/src/lib/functions.ts
index b45c7fa6d1..e0d44ce2d7 100644
--- a/src/lib/functions.ts
+++ b/src/lib/functions.ts
@@ -9,3 +9,90 @@ export function dedupArray(arr: T[]): T[] {
const s = new Set(arr)
return [...s]
}
+
+/**
+ * Taken from @tanstack/query-core utils.ts
+ * Modified to support Date object comparisons
+ *
+ * This function returns `a` if `b` is deeply equal.
+ * If not, it will replace any deeply equal children of `b` with those of `a`.
+ * This can be used for structural sharing between JSON values for example.
+ */
+export function replaceEqualDeep(a: any, b: any): any {
+ if (a === b) {
+ return a
+ }
+
+ if (a instanceof Date && b instanceof Date) {
+ return a.getTime() === b.getTime() ? a : b
+ }
+
+ const array = isPlainArray(a) && isPlainArray(b)
+
+ if (array || (isPlainObject(a) && isPlainObject(b))) {
+ const aItems = array ? a : Object.keys(a)
+ const aSize = aItems.length
+ const bItems = array ? b : Object.keys(b)
+ const bSize = bItems.length
+ const copy: any = array ? [] : {}
+
+ let equalItems = 0
+
+ for (let i = 0; i < bSize; i++) {
+ const key = array ? i : bItems[i]
+ if (
+ !array &&
+ a[key] === undefined &&
+ b[key] === undefined &&
+ aItems.includes(key)
+ ) {
+ copy[key] = undefined
+ equalItems++
+ } else {
+ copy[key] = replaceEqualDeep(a[key], b[key])
+ if (copy[key] === a[key] && a[key] !== undefined) {
+ equalItems++
+ }
+ }
+ }
+
+ return aSize === bSize && equalItems === aSize ? a : copy
+ }
+
+ return b
+}
+
+export function isPlainArray(value: unknown) {
+ return Array.isArray(value) && value.length === Object.keys(value).length
+}
+
+// Copied from: https://github.com/jonschlinkert/is-plain-object
+export function isPlainObject(o: any): o is Object {
+ if (!hasObjectPrototype(o)) {
+ return false
+ }
+
+ // If has no constructor
+ const ctor = o.constructor
+ if (ctor === undefined) {
+ return true
+ }
+
+ // If has modified prototype
+ const prot = ctor.prototype
+ if (!hasObjectPrototype(prot)) {
+ return false
+ }
+
+ // If constructor does not have an Object-specific method
+ if (!prot.hasOwnProperty('isPrototypeOf')) {
+ return false
+ }
+
+ // Most likely a plain Object
+ return true
+}
+
+function hasObjectPrototype(o: any): boolean {
+ return Object.prototype.toString.call(o) === '[object Object]'
+}
diff --git a/src/screens/Onboarding/StepSuggestedAccounts/SuggestedAccountCard.tsx b/src/screens/Onboarding/StepSuggestedAccounts/SuggestedAccountCard.tsx
index 7e4ea1f8b8..f0ba36e39f 100644
--- a/src/screens/Onboarding/StepSuggestedAccounts/SuggestedAccountCard.tsx
+++ b/src/screens/Onboarding/StepSuggestedAccounts/SuggestedAccountCard.tsx
@@ -2,13 +2,13 @@ import React from 'react'
import {View, ViewStyle} from 'react-native'
import {AppBskyActorDefs, moderateProfile} from '@atproto/api'
-import {useTheme, atoms as a, flatten} from '#/alf'
-import {Text} from '#/components/Typography'
+import {useModerationOpts} from '#/state/preferences/moderation-opts'
+import {UserAvatar} from '#/view/com/util/UserAvatar'
+import {atoms as a, flatten, useTheme} from '#/alf'
import {useItemContext} from '#/components/forms/Toggle'
import {Check_Stroke2_Corner0_Rounded as Check} from '#/components/icons/Check'
-import {UserAvatar} from '#/view/com/util/UserAvatar'
-import {useModerationOpts} from '#/state/queries/preferences'
import {RichText} from '#/components/RichText'
+import {Text} from '#/components/Typography'
export function SuggestedAccountCard({
profile,
diff --git a/src/screens/Onboarding/StepSuggestedAccounts/index.tsx b/src/screens/Onboarding/StepSuggestedAccounts/index.tsx
index e9bc3f0fde..7b2ad2b999 100644
--- a/src/screens/Onboarding/StepSuggestedAccounts/index.tsx
+++ b/src/screens/Onboarding/StepSuggestedAccounts/index.tsx
@@ -7,7 +7,7 @@ import {useLingui} from '@lingui/react'
import {useAnalytics} from '#/lib/analytics/analytics'
import {logEvent} from '#/lib/statsig/statsig'
import {capitalize} from '#/lib/strings/capitalize'
-import {useModerationOpts} from '#/state/queries/preferences'
+import {useModerationOpts} from '#/state/preferences/moderation-opts'
import {useProfilesQuery} from '#/state/queries/profile'
import {
DescriptionText,
diff --git a/src/state/preferences/moderation-opts.tsx b/src/state/preferences/moderation-opts.tsx
new file mode 100644
index 0000000000..b0278d5e88
--- /dev/null
+++ b/src/state/preferences/moderation-opts.tsx
@@ -0,0 +1,61 @@
+import React, {createContext, useContext, useMemo} from 'react'
+import {BSKY_LABELER_DID, ModerationOpts} from '@atproto/api'
+
+import {useHiddenPosts, useLabelDefinitions} from '#/state/preferences'
+import {DEFAULT_LOGGED_OUT_LABEL_PREFERENCES} from '#/state/queries/preferences/moderation'
+import {useSession} from '#/state/session'
+import {usePreferencesQuery} from '../queries/preferences'
+
+export const moderationOptsContext = createContext(
+ undefined,
+)
+
+// used in the moderation state devtool
+export const moderationOptsOverrideContext = createContext<
+ ModerationOpts | undefined
+>(undefined)
+
+export function useModerationOpts() {
+ return useContext(moderationOptsContext)
+}
+
+export function Provider({children}: React.PropsWithChildren<{}>) {
+ const override = useContext(moderationOptsOverrideContext)
+ const {currentAccount} = useSession()
+ const prefs = usePreferencesQuery()
+ const {labelDefs} = useLabelDefinitions()
+ const hiddenPosts = useHiddenPosts() // TODO move this into pds-stored prefs
+
+ const userDid = currentAccount?.did
+ const moderationPrefs = prefs.data?.moderationPrefs
+ const value = useMemo(() => {
+ if (override) {
+ return override
+ }
+ if (!moderationPrefs) {
+ return undefined
+ }
+ return {
+ userDid,
+ prefs: {
+ ...moderationPrefs,
+ labelers: moderationPrefs.labelers.length
+ ? moderationPrefs.labelers
+ : [
+ {
+ did: BSKY_LABELER_DID,
+ labels: DEFAULT_LOGGED_OUT_LABEL_PREFERENCES,
+ },
+ ],
+ hiddenPosts: hiddenPosts || [],
+ },
+ labelDefs,
+ }
+ }, [override, userDid, labelDefs, moderationPrefs, hiddenPosts])
+
+ return (
+
+ {children}
+
+ )
+}
diff --git a/src/state/queries/actor-autocomplete.ts b/src/state/queries/actor-autocomplete.ts
index 98b5aa17e6..430f6978a6 100644
--- a/src/state/queries/actor-autocomplete.ts
+++ b/src/state/queries/actor-autocomplete.ts
@@ -6,7 +6,8 @@ import {isJustAMute} from '#/lib/moderation'
import {logger} from '#/logger'
import {STALE} from '#/state/queries'
import {useAgent} from '#/state/session'
-import {DEFAULT_LOGGED_OUT_PREFERENCES, useModerationOpts} from './preferences'
+import {useModerationOpts} from '../preferences/moderation-opts'
+import {DEFAULT_LOGGED_OUT_PREFERENCES} from './preferences'
const DEFAULT_MOD_OPTS = {
userDid: undefined,
diff --git a/src/state/queries/notifications/feed.ts b/src/state/queries/notifications/feed.ts
index 1f21999017..80e5a4c472 100644
--- a/src/state/queries/notifications/feed.ts
+++ b/src/state/queries/notifications/feed.ts
@@ -28,8 +28,8 @@ import {
import {useMutedThreads} from '#/state/muted-threads'
import {useAgent} from '#/state/session'
+import {useModerationOpts} from '../../preferences/moderation-opts'
import {STALE} from '..'
-import {useModerationOpts} from '../preferences'
import {embedViewRecordToPostView, getEmbeddedPost} from '../util'
import {FeedPage} from './types'
import {useUnreadNotificationsApi} from './unread'
diff --git a/src/state/queries/notifications/unread.tsx b/src/state/queries/notifications/unread.tsx
index 1c569e2a09..80333b524f 100644
--- a/src/state/queries/notifications/unread.tsx
+++ b/src/state/queries/notifications/unread.tsx
@@ -13,7 +13,7 @@ import {logger} from '#/logger'
import {isNative} from '#/platform/detection'
import {useMutedThreads} from '#/state/muted-threads'
import {useAgent, useSession} from '#/state/session'
-import {useModerationOpts} from '../preferences'
+import {useModerationOpts} from '../../preferences/moderation-opts'
import {truncateAndInvalidate} from '../util'
import {RQKEY as RQKEY_NOTIFS} from './feed'
import {CachedFeedPage, FeedPage} from './types'
diff --git a/src/state/queries/post-feed.ts b/src/state/queries/post-feed.ts
index c265cecd60..827f8a2a86 100644
--- a/src/state/queries/post-feed.ts
+++ b/src/state/queries/post-feed.ts
@@ -32,7 +32,8 @@ import {FeedTuner, FeedTunerFn, NoopFeedTuner} from 'lib/api/feed-manip'
import {BSKY_FEED_OWNER_DIDS} from 'lib/constants'
import {KnownError} from '#/view/com/posts/FeedErrorMessage'
import {useFeedTuners} from '../preferences/feed-tuners'
-import {useModerationOpts, usePreferencesQuery} from './preferences'
+import {useModerationOpts} from '../preferences/moderation-opts'
+import {usePreferencesQuery} from './preferences'
import {embedViewRecordToPostView, getEmbeddedPost} from './util'
type ActorDid = string
diff --git a/src/state/queries/preferences/index.ts b/src/state/queries/preferences/index.ts
index 06e47391f2..f51eaac2a4 100644
--- a/src/state/queries/preferences/index.ts
+++ b/src/state/queries/preferences/index.ts
@@ -1,28 +1,24 @@
-import {createContext, useContext, useMemo} from 'react'
import {
AppBskyActorDefs,
- BSKY_LABELER_DID,
BskyFeedViewPreference,
LabelPreference,
- ModerationOpts,
} from '@atproto/api'
import {useMutation, useQuery, useQueryClient} from '@tanstack/react-query'
import {track} from '#/lib/analytics/analytics'
+import {replaceEqualDeep} from '#/lib/functions'
import {getAge} from '#/lib/strings/time'
-import {useHiddenPosts, useLabelDefinitions} from '#/state/preferences'
import {STALE} from '#/state/queries'
import {
DEFAULT_HOME_FEED_PREFS,
DEFAULT_LOGGED_OUT_PREFERENCES,
DEFAULT_THREAD_VIEW_PREFS,
} from '#/state/queries/preferences/const'
-import {DEFAULT_LOGGED_OUT_LABEL_PREFERENCES} from '#/state/queries/preferences/moderation'
import {
ThreadViewPreferences,
UsePreferencesQueryResponse,
} from '#/state/queries/preferences/types'
-import {useAgent, useSession} from '#/state/session'
+import {useAgent} from '#/state/session'
import {saveLabelers} from '#/state/session/agent-config'
export * from '#/state/queries/preferences/const'
@@ -36,7 +32,7 @@ export function usePreferencesQuery() {
const {getAgent} = useAgent()
return useQuery({
staleTime: STALE.SECONDS.FIFTEEN,
- structuralSharing: true,
+ structuralSharing: replaceEqualDeep,
refetchOnWindowFocus: true,
queryKey: preferencesQueryKey,
queryFn: async () => {
@@ -79,44 +75,6 @@ export function usePreferencesQuery() {
})
}
-// used in the moderation state devtool
-export const moderationOptsOverrideContext = createContext<
- ModerationOpts | undefined
->(undefined)
-
-export function useModerationOpts() {
- const override = useContext(moderationOptsOverrideContext)
- const {currentAccount} = useSession()
- const prefs = usePreferencesQuery()
- const {labelDefs} = useLabelDefinitions()
- const hiddenPosts = useHiddenPosts() // TODO move this into pds-stored prefs
- const opts = useMemo(() => {
- if (override) {
- return override
- }
- if (!prefs.data) {
- return
- }
- return {
- userDid: currentAccount?.did,
- prefs: {
- ...prefs.data.moderationPrefs,
- labelers: prefs.data.moderationPrefs.labelers.length
- ? prefs.data.moderationPrefs.labelers
- : [
- {
- did: BSKY_LABELER_DID,
- labels: DEFAULT_LOGGED_OUT_LABEL_PREFERENCES,
- },
- ],
- hiddenPosts: hiddenPosts || [],
- },
- labelDefs,
- }
- }, [override, currentAccount, labelDefs, prefs.data, hiddenPosts])
- return opts
-}
-
export function useClearPreferencesMutation() {
const queryClient = useQueryClient()
const {getAgent} = useAgent()
diff --git a/src/state/queries/suggested-follows.ts b/src/state/queries/suggested-follows.ts
index 3338130f4a..7740b1977c 100644
--- a/src/state/queries/suggested-follows.ts
+++ b/src/state/queries/suggested-follows.ts
@@ -18,11 +18,9 @@ import {
} from '#/lib/api/feed/utils'
import {getContentLanguages} from '#/state/preferences/languages'
import {STALE} from '#/state/queries'
-import {
- useModerationOpts,
- usePreferencesQuery,
-} from '#/state/queries/preferences'
+import {usePreferencesQuery} from '#/state/queries/preferences'
import {useAgent, useSession} from '#/state/session'
+import {useModerationOpts} from '../preferences/moderation-opts'
const suggestedFollowsQueryKeyRoot = 'suggested-follows'
const suggestedFollowsQueryKey = [suggestedFollowsQueryKeyRoot]
diff --git a/src/view/com/notifications/Feed.tsx b/src/view/com/notifications/Feed.tsx
index dd439d4755..7d34596d98 100644
--- a/src/view/com/notifications/Feed.tsx
+++ b/src/view/com/notifications/Feed.tsx
@@ -1,21 +1,22 @@
import React from 'react'
-import {CenteredView} from '../util/Views'
import {ActivityIndicator, StyleSheet, View} from 'react-native'
-import {FeedItem} from './FeedItem'
-import {NotificationFeedLoadingPlaceholder} from '../util/LoadingPlaceholder'
-import {ErrorMessage} from '../util/error/ErrorMessage'
-import {LoadMoreRetryBtn} from '../util/LoadMoreRetryBtn'
-import {EmptyState} from '../util/EmptyState'
-import {s} from 'lib/styles'
+import {msg} from '@lingui/macro'
+import {useLingui} from '@lingui/react'
+
+import {usePalette} from '#/lib/hooks/usePalette'
+import {cleanError} from '#/lib/strings/errors'
+import {logger} from '#/logger'
+import {useModerationOpts} from '#/state/preferences/moderation-opts'
import {useNotificationFeedQuery} from '#/state/queries/notifications/feed'
import {useUnreadNotificationsApi} from '#/state/queries/notifications/unread'
-import {logger} from '#/logger'
-import {cleanError} from '#/lib/strings/errors'
-import {useModerationOpts} from '#/state/queries/preferences'
+import {s} from 'lib/styles'
+import {EmptyState} from '../util/EmptyState'
+import {ErrorMessage} from '../util/error/ErrorMessage'
import {List, ListRef} from '../util/List'
-import {useLingui} from '@lingui/react'
-import {msg} from '@lingui/macro'
-import {usePalette} from '#/lib/hooks/usePalette'
+import {NotificationFeedLoadingPlaceholder} from '../util/LoadingPlaceholder'
+import {LoadMoreRetryBtn} from '../util/LoadMoreRetryBtn'
+import {CenteredView} from '../util/Views'
+import {FeedItem} from './FeedItem'
const EMPTY_FEED_ITEM = {_reactKey: '__empty__'}
const LOAD_MORE_ERROR_ITEM = {_reactKey: '__load_more_error__'}
diff --git a/src/view/com/post-thread/PostThread.tsx b/src/view/com/post-thread/PostThread.tsx
index 6e356f994e..69b26ad448 100644
--- a/src/view/com/post-thread/PostThread.tsx
+++ b/src/view/com/post-thread/PostThread.tsx
@@ -8,6 +8,7 @@ import {useLingui} from '@lingui/react'
import {moderatePost_wrapped as moderatePost} from '#/lib/moderatePost_wrapped'
import {ScrollProvider} from '#/lib/ScrollContext'
import {isAndroid, isNative, isWeb} from '#/platform/detection'
+import {useModerationOpts} from '#/state/preferences/moderation-opts'
import {
sortThread,
ThreadBlocked,
@@ -16,10 +17,7 @@ import {
ThreadPost,
usePostThreadQuery,
} from '#/state/queries/post-thread'
-import {
- useModerationOpts,
- usePreferencesQuery,
-} from '#/state/queries/preferences'
+import {usePreferencesQuery} from '#/state/queries/preferences'
import {useSession} from '#/state/session'
import {useInitialNumToRender} from 'lib/hooks/useInitialNumToRender'
import {usePalette} from 'lib/hooks/usePalette'
diff --git a/src/view/com/post-thread/PostThreadItem.tsx b/src/view/com/post-thread/PostThreadItem.tsx
index 564e37e7a6..cfb8bd93f0 100644
--- a/src/view/com/post-thread/PostThreadItem.tsx
+++ b/src/view/com/post-thread/PostThreadItem.tsx
@@ -15,8 +15,8 @@ import {moderatePost_wrapped as moderatePost} from '#/lib/moderatePost_wrapped'
import {POST_TOMBSTONE, Shadow, usePostShadow} from '#/state/cache/post-shadow'
import {useLanguagePrefs} from '#/state/preferences'
import {useOpenLink} from '#/state/preferences/in-app-browser'
+import {useModerationOpts} from '#/state/preferences/moderation-opts'
import {ThreadPost} from '#/state/queries/post-thread'
-import {useModerationOpts} from '#/state/queries/preferences'
import {useComposerControls} from '#/state/shell/composer'
import {MAX_POST_LINES} from 'lib/constants'
import {usePalette} from 'lib/hooks/usePalette'
diff --git a/src/view/com/post/Post.tsx b/src/view/com/post/Post.tsx
index 546eb28210..1a7185cd92 100644
--- a/src/view/com/post/Post.tsx
+++ b/src/view/com/post/Post.tsx
@@ -14,7 +14,7 @@ import {useQueryClient} from '@tanstack/react-query'
import {moderatePost_wrapped as moderatePost} from '#/lib/moderatePost_wrapped'
import {POST_TOMBSTONE, Shadow, usePostShadow} from '#/state/cache/post-shadow'
-import {useModerationOpts} from '#/state/queries/preferences'
+import {useModerationOpts} from '#/state/preferences/moderation-opts'
import {useComposerControls} from '#/state/shell/composer'
import {MAX_POST_LINES} from 'lib/constants'
import {usePalette} from 'lib/hooks/usePalette'
diff --git a/src/view/com/profile/ProfileCard.tsx b/src/view/com/profile/ProfileCard.tsx
index 90ab9b7385..6c89789467 100644
--- a/src/view/com/profile/ProfileCard.tsx
+++ b/src/view/com/profile/ProfileCard.tsx
@@ -12,7 +12,7 @@ import {useQueryClient} from '@tanstack/react-query'
import {useModerationCauseDescription} from '#/lib/moderation/useModerationCauseDescription'
import {useProfileShadow} from '#/state/cache/profile-shadow'
import {Shadow} from '#/state/cache/types'
-import {useModerationOpts} from '#/state/queries/preferences'
+import {useModerationOpts} from '#/state/preferences/moderation-opts'
import {useSession} from '#/state/session'
import {usePalette} from 'lib/hooks/usePalette'
import {getModerationCauseKey, isJustAMute} from 'lib/moderation'
diff --git a/src/view/com/profile/ProfileHeaderSuggestedFollows.tsx b/src/view/com/profile/ProfileHeaderSuggestedFollows.tsx
index 4c9d164f75..bb5ad2a636 100644
--- a/src/view/com/profile/ProfileHeaderSuggestedFollows.tsx
+++ b/src/view/com/profile/ProfileHeaderSuggestedFollows.tsx
@@ -9,7 +9,7 @@ import {msg, Trans} from '@lingui/macro'
import {useLingui} from '@lingui/react'
import {useProfileShadow} from '#/state/cache/profile-shadow'
-import {useModerationOpts} from '#/state/queries/preferences'
+import {useModerationOpts} from '#/state/preferences/moderation-opts'
import {useProfileFollowMutationQueue} from '#/state/queries/profile'
import {useSuggestedFollowsByActorQuery} from '#/state/queries/suggested-follows'
import {useAnalytics} from 'lib/analytics/analytics'
diff --git a/src/view/com/util/post-embeds/QuoteEmbed.tsx b/src/view/com/util/post-embeds/QuoteEmbed.tsx
index e0178f34b4..0e19a6ccde 100644
--- a/src/view/com/util/post-embeds/QuoteEmbed.tsx
+++ b/src/view/com/util/post-embeds/QuoteEmbed.tsx
@@ -25,7 +25,7 @@ import {useQueryClient} from '@tanstack/react-query'
import {HITSLOP_20} from '#/lib/constants'
import {s} from '#/lib/styles'
-import {useModerationOpts} from '#/state/queries/preferences'
+import {useModerationOpts} from '#/state/preferences/moderation-opts'
import {usePalette} from 'lib/hooks/usePalette'
import {InfoCircleIcon} from 'lib/icons'
import {makeProfileLink} from 'lib/routes/links'
diff --git a/src/view/screens/DebugMod.tsx b/src/view/screens/DebugMod.tsx
index f88d500f97..442e33fd30 100644
--- a/src/view/screens/DebugMod.tsx
+++ b/src/view/screens/DebugMod.tsx
@@ -20,12 +20,12 @@ import {msg} from '@lingui/macro'
import {useLingui} from '@lingui/react'
import {useGlobalLabelStrings} from '#/lib/moderation/useGlobalLabelStrings'
+import {moderationOptsOverrideContext} from '#/state/preferences/moderation-opts'
import {FeedNotification} from '#/state/queries/notifications/types'
import {
groupNotifications,
shouldFilterNotif,
} from '#/state/queries/notifications/util'
-import {moderationOptsOverrideContext} from '#/state/queries/preferences'
import {useSession} from '#/state/session'
import {CommonNavigatorParams, NativeStackScreenProps} from 'lib/routes/types'
import {CenteredView, ScrollView} from '#/view/com/util/Views'
diff --git a/src/view/screens/Profile.tsx b/src/view/screens/Profile.tsx
index 02d7c90fb4..4fa46a4cf1 100644
--- a/src/view/screens/Profile.tsx
+++ b/src/view/screens/Profile.tsx
@@ -13,9 +13,9 @@ import {useQueryClient} from '@tanstack/react-query'
import {cleanError} from '#/lib/strings/errors'
import {useProfileShadow} from '#/state/cache/profile-shadow'
+import {useModerationOpts} from '#/state/preferences/moderation-opts'
import {useLabelerInfoQuery} from '#/state/queries/labeler'
import {resetProfilePostsQueries} from '#/state/queries/post-feed'
-import {useModerationOpts} from '#/state/queries/preferences'
import {useProfileQuery} from '#/state/queries/profile'
import {useResolveDidQuery} from '#/state/queries/resolve-uri'
import {useAgent, useSession} from '#/state/session'
diff --git a/src/view/screens/Search/Search.tsx b/src/view/screens/Search/Search.tsx
index 9e34067fb8..9dd1c397f3 100644
--- a/src/view/screens/Search/Search.tsx
+++ b/src/view/screens/Search/Search.tsx
@@ -27,9 +27,9 @@ import {s} from '#/lib/styles'
import {logger} from '#/logger'
import {isIOS, isNative, isWeb} from '#/platform/detection'
import {listenSoftReset} from '#/state/events'
+import {useModerationOpts} from '#/state/preferences/moderation-opts'
import {useActorAutocompleteQuery} from '#/state/queries/actor-autocomplete'
import {useActorSearch} from '#/state/queries/actor-search'
-import {useModerationOpts} from '#/state/queries/preferences'
import {useSearchPostsQuery} from '#/state/queries/search-posts'
import {useSuggestedFollowsQuery} from '#/state/queries/suggested-follows'
import {useSession} from '#/state/session'
diff --git a/src/view/shell/desktop/Search.tsx b/src/view/shell/desktop/Search.tsx
index 683d4421a7..3829a6c0b2 100644
--- a/src/view/shell/desktop/Search.tsx
+++ b/src/view/shell/desktop/Search.tsx
@@ -21,8 +21,8 @@ import {makeProfileLink} from '#/lib/routes/links'
import {sanitizeDisplayName} from '#/lib/strings/display-names'
import {sanitizeHandle} from '#/lib/strings/handles'
import {s} from '#/lib/styles'
+import {useModerationOpts} from '#/state/preferences/moderation-opts'
import {useActorAutocompleteQuery} from '#/state/queries/actor-autocomplete'
-import {useModerationOpts} from '#/state/queries/preferences'
import {usePalette} from 'lib/hooks/usePalette'
import {MagnifyingGlassIcon2} from 'lib/icons'
import {NavigationProp} from 'lib/routes/types'