hoist useprefs

This commit is contained in:
Samuel Newman
2026-03-23 19:17:39 +02:00
parent 21d8b07bfe
commit 226f7f4fd2
50 changed files with 283 additions and 414 deletions
+52 -49
View File
@@ -41,6 +41,7 @@ import {Provider as PrefsStateProvider} from '#/state/preferences'
import {Provider as LabelDefsProvider} from '#/state/preferences/label-defs' import {Provider as LabelDefsProvider} from '#/state/preferences/label-defs'
import {Provider as ModerationOptsProvider} from '#/state/preferences/moderation-opts' import {Provider as ModerationOptsProvider} from '#/state/preferences/moderation-opts'
import {Provider as UnreadNotifsProvider} from '#/state/queries/notifications/unread' import {Provider as UnreadNotifsProvider} from '#/state/queries/notifications/unread'
import {Provider as PreferencesProvider} from '#/state/queries/preferences'
import {Provider as ServiceAccountManager} from '#/state/service-config' import {Provider as ServiceAccountManager} from '#/state/service-config'
import { import {
Provider as SessionProvider, Provider as SessionProvider,
@@ -156,55 +157,57 @@ function InnerApp() {
key={currentAccount?.did}> key={currentAccount?.did}>
<AnalyticsFeaturesContext> <AnalyticsFeaturesContext>
<QueryProvider currentDid={currentAccount?.did}> <QueryProvider currentDid={currentAccount?.did}>
<PolicyUpdateOverlayProvider> <PreferencesProvider>
<LiveEventsProvider> <PolicyUpdateOverlayProvider>
<AgeAssuranceV2Provider> <LiveEventsProvider>
<ComposerProvider> <AgeAssuranceV2Provider>
<MessagesProvider> <ComposerProvider>
{/* LabelDefsProvider MUST come before ModerationOptsProvider */} <MessagesProvider>
<LabelDefsProvider> {/* LabelDefsProvider MUST come before ModerationOptsProvider */}
<ModerationOptsProvider> <LabelDefsProvider>
<LoggedOutViewProvider> <ModerationOptsProvider>
<SelectedFeedProvider> <LoggedOutViewProvider>
<HiddenRepliesProvider> <SelectedFeedProvider>
<HomeBadgeProvider> <HiddenRepliesProvider>
<UnreadNotifsProvider> <HomeBadgeProvider>
<BackgroundNotificationPreferencesProvider> <UnreadNotifsProvider>
<MutedThreadsProvider> <BackgroundNotificationPreferencesProvider>
<ProgressGuideProvider> <MutedThreadsProvider>
<ServiceAccountManager> <ProgressGuideProvider>
<EmailVerificationProvider> <ServiceAccountManager>
<HideBottomBarBorderProvider> <EmailVerificationProvider>
<GestureHandlerRootView <HideBottomBarBorderProvider>
style={s.h100pct}> <GestureHandlerRootView
<GlobalGestureEventsProvider> style={s.h100pct}>
<IntentDialogProvider> <GlobalGestureEventsProvider>
<TranslateOnDeviceProvider> <IntentDialogProvider>
<TestCtrls /> <TranslateOnDeviceProvider>
<Shell /> <TestCtrls />
<ToastOutlet /> <Shell />
</TranslateOnDeviceProvider> <ToastOutlet />
</IntentDialogProvider> </TranslateOnDeviceProvider>
</GlobalGestureEventsProvider> </IntentDialogProvider>
</GestureHandlerRootView> </GlobalGestureEventsProvider>
</HideBottomBarBorderProvider> </GestureHandlerRootView>
</EmailVerificationProvider> </HideBottomBarBorderProvider>
</ServiceAccountManager> </EmailVerificationProvider>
</ProgressGuideProvider> </ServiceAccountManager>
</MutedThreadsProvider> </ProgressGuideProvider>
</BackgroundNotificationPreferencesProvider> </MutedThreadsProvider>
</UnreadNotifsProvider> </BackgroundNotificationPreferencesProvider>
</HomeBadgeProvider> </UnreadNotifsProvider>
</HiddenRepliesProvider> </HomeBadgeProvider>
</SelectedFeedProvider> </HiddenRepliesProvider>
</LoggedOutViewProvider> </SelectedFeedProvider>
</ModerationOptsProvider> </LoggedOutViewProvider>
</LabelDefsProvider> </ModerationOptsProvider>
</MessagesProvider> </LabelDefsProvider>
</ComposerProvider> </MessagesProvider>
</AgeAssuranceV2Provider> </ComposerProvider>
</LiveEventsProvider> </AgeAssuranceV2Provider>
</PolicyUpdateOverlayProvider> </LiveEventsProvider>
</PolicyUpdateOverlayProvider>
</PreferencesProvider>
</QueryProvider> </QueryProvider>
</AnalyticsFeaturesContext> </AnalyticsFeaturesContext>
</Fragment> </Fragment>
+48 -45
View File
@@ -32,6 +32,7 @@ import {Provider as PrefsStateProvider} from '#/state/preferences'
import {Provider as LabelDefsProvider} from '#/state/preferences/label-defs' import {Provider as LabelDefsProvider} from '#/state/preferences/label-defs'
import {Provider as ModerationOptsProvider} from '#/state/preferences/moderation-opts' import {Provider as ModerationOptsProvider} from '#/state/preferences/moderation-opts'
import {Provider as UnreadNotifsProvider} from '#/state/queries/notifications/unread' import {Provider as UnreadNotifsProvider} from '#/state/queries/notifications/unread'
import {Provider as PreferencesProvider} from '#/state/queries/preferences'
import {Provider as ServiceConfigProvider} from '#/state/service-config' import {Provider as ServiceConfigProvider} from '#/state/service-config'
import { import {
Provider as SessionProvider, Provider as SessionProvider,
@@ -134,51 +135,53 @@ function InnerApp() {
key={currentAccount?.did}> key={currentAccount?.did}>
<AnalyticsFeaturesContext> <AnalyticsFeaturesContext>
<QueryProvider currentDid={currentAccount?.did}> <QueryProvider currentDid={currentAccount?.did}>
<PolicyUpdateOverlayProvider> <PreferencesProvider>
<LiveEventsProvider> <PolicyUpdateOverlayProvider>
<AgeAssuranceV2Provider> <LiveEventsProvider>
<ComposerProvider> <AgeAssuranceV2Provider>
<MessagesProvider> <ComposerProvider>
{/* LabelDefsProvider MUST come before ModerationOptsProvider */} <MessagesProvider>
<LabelDefsProvider> {/* LabelDefsProvider MUST come before ModerationOptsProvider */}
<ModerationOptsProvider> <LabelDefsProvider>
<LoggedOutViewProvider> <ModerationOptsProvider>
<SelectedFeedProvider> <LoggedOutViewProvider>
<HiddenRepliesProvider> <SelectedFeedProvider>
<HomeBadgeProvider> <HiddenRepliesProvider>
<UnreadNotifsProvider> <HomeBadgeProvider>
<BackgroundNotificationPreferencesProvider> <UnreadNotifsProvider>
<MutedThreadsProvider> <BackgroundNotificationPreferencesProvider>
<SafeAreaProvider> <MutedThreadsProvider>
<ProgressGuideProvider> <SafeAreaProvider>
<ServiceConfigProvider> <ProgressGuideProvider>
<EmailVerificationProvider> <ServiceConfigProvider>
<HideBottomBarBorderProvider> <EmailVerificationProvider>
<IntentDialogProvider> <HideBottomBarBorderProvider>
<TranslateOnDeviceProvider> <IntentDialogProvider>
<Shell /> <TranslateOnDeviceProvider>
<ToastOutlet /> <Shell />
</TranslateOnDeviceProvider> <ToastOutlet />
</IntentDialogProvider> </TranslateOnDeviceProvider>
</HideBottomBarBorderProvider> </IntentDialogProvider>
</EmailVerificationProvider> </HideBottomBarBorderProvider>
</ServiceConfigProvider> </EmailVerificationProvider>
</ProgressGuideProvider> </ServiceConfigProvider>
</SafeAreaProvider> </ProgressGuideProvider>
</MutedThreadsProvider> </SafeAreaProvider>
</BackgroundNotificationPreferencesProvider> </MutedThreadsProvider>
</UnreadNotifsProvider> </BackgroundNotificationPreferencesProvider>
</HomeBadgeProvider> </UnreadNotifsProvider>
</HiddenRepliesProvider> </HomeBadgeProvider>
</SelectedFeedProvider> </HiddenRepliesProvider>
</LoggedOutViewProvider> </SelectedFeedProvider>
</ModerationOptsProvider> </LoggedOutViewProvider>
</LabelDefsProvider> </ModerationOptsProvider>
</MessagesProvider> </LabelDefsProvider>
</ComposerProvider> </MessagesProvider>
</AgeAssuranceV2Provider> </ComposerProvider>
</LiveEventsProvider> </AgeAssuranceV2Provider>
</PolicyUpdateOverlayProvider> </LiveEventsProvider>
</PolicyUpdateOverlayProvider>
</PreferencesProvider>
</QueryProvider> </QueryProvider>
</AnalyticsFeaturesContext> </AnalyticsFeaturesContext>
</Fragment> </Fragment>
+2 -2
View File
@@ -14,7 +14,7 @@ import {logger} from '#/logger'
import {precacheFeedFromGeneratorView} from '#/state/queries/feed' import {precacheFeedFromGeneratorView} from '#/state/queries/feed'
import { import {
useAddSavedFeedsMutation, useAddSavedFeedsMutation,
usePreferencesQuery, usePreferences,
useRemoveFeedMutation, useRemoveFeedMutation,
} from '#/state/queries/preferences' } from '#/state/queries/preferences'
import {useSession} from '#/state/session' import {useSession} from '#/state/session'
@@ -278,7 +278,7 @@ function SaveButtonInner({
text?: boolean text?: boolean
} & Partial<ButtonProps>) { } & Partial<ButtonProps>) {
const {t: l} = useLingui() const {t: l} = useLingui()
const {data: preferences} = usePreferencesQuery() const preferences = usePreferences()
const {isPending: isAddSavedFeedPending, mutateAsync: saveFeeds} = const {isPending: isAddSavedFeedPending, mutateAsync: saveFeeds} =
useAddSavedFeedsMutation() useAddSavedFeedsMutation()
const {isPending: isRemovePending, mutateAsync: removeFeed} = const {isPending: isRemovePending, mutateAsync: removeFeed} =
@@ -38,13 +38,11 @@ export function usePolicyUpdateState({
} }
} }
const nuxIsReady = nux.status === 'ready'
const nuxIsCompleted = nux.nux?.completed === true const nuxIsCompleted = nux.nux?.completed === true
const nuxIsOptimisticallyCompleted = !!variables?.completed const nuxIsOptimisticallyCompleted = !!variables?.completed
const [completedForDevice, setCompletedForDevice] = deviceStorage const [completedForDevice, setCompletedForDevice] = deviceStorage
const completed = computeCompletedState({ const completed = computeCompletedState({
nuxIsReady,
nuxIsCompleted, nuxIsCompleted,
nuxIsOptimisticallyCompleted, nuxIsOptimisticallyCompleted,
completedForDevice, completedForDevice,
@@ -58,7 +56,6 @@ export function usePolicyUpdateState({
if (!debugOverride) { if (!debugOverride) {
syncCompletedState({ syncCompletedState({
nuxIsReady,
nuxIsCompleted, nuxIsCompleted,
nuxIsOptimisticallyCompleted, nuxIsOptimisticallyCompleted,
completedForDevice, completedForDevice,
@@ -83,27 +80,18 @@ export function usePolicyUpdateState({
} }
export function computeCompletedState({ export function computeCompletedState({
nuxIsReady,
nuxIsCompleted, nuxIsCompleted,
nuxIsOptimisticallyCompleted, nuxIsOptimisticallyCompleted,
completedForDevice, completedForDevice,
}: { }: {
nuxIsReady: boolean
nuxIsCompleted: boolean nuxIsCompleted: boolean
nuxIsOptimisticallyCompleted: boolean nuxIsOptimisticallyCompleted: boolean
completedForDevice: boolean | undefined completedForDevice: boolean | undefined
}): boolean { }): boolean {
/**
* Assume completed to prevent flash
*/
let completed = true
/** /**
* Prefer server state, if available * Prefer server state, if available
*/ */
if (nuxIsReady) { let completed = nuxIsCompleted
completed = nuxIsCompleted
}
/** /**
* Override with optimistic state or device state * Override with optimistic state or device state
@@ -116,14 +104,12 @@ export function computeCompletedState({
} }
export function syncCompletedState({ export function syncCompletedState({
nuxIsReady,
nuxIsCompleted, nuxIsCompleted,
nuxIsOptimisticallyCompleted, nuxIsOptimisticallyCompleted,
completedForDevice, completedForDevice,
save, save,
setCompletedForDevice, setCompletedForDevice,
}: { }: {
nuxIsReady: boolean
nuxIsCompleted: boolean nuxIsCompleted: boolean
nuxIsOptimisticallyCompleted: boolean nuxIsOptimisticallyCompleted: boolean
completedForDevice: boolean | undefined completedForDevice: boolean | undefined
@@ -134,7 +120,6 @@ export function syncCompletedState({
* Sync device state to server state for this account * Sync device state to server state for this account
*/ */
if ( if (
nuxIsReady &&
!nuxIsCompleted && !nuxIsCompleted &&
!nuxIsOptimisticallyCompleted && !nuxIsOptimisticallyCompleted &&
!!completedForDevice !!completedForDevice
@@ -145,7 +130,7 @@ export function syncCompletedState({
completed: true, completed: true,
data: undefined, data: undefined,
}) })
} else if (nuxIsReady && nuxIsCompleted && !completedForDevice) { } else if (nuxIsCompleted && !completedForDevice) {
logger.debug(`syncing server state to device state`) logger.debug(`syncing server state to device state`)
/* /*
* Sync server state to device state * Sync server state to device state
@@ -9,7 +9,7 @@ import {useNonReactiveCallback} from '#/lib/hooks/useNonReactiveCallback'
import {popularInterests, useInterestsDisplayNames} from '#/lib/interests' import {popularInterests, useInterestsDisplayNames} from '#/lib/interests'
import {useModerationOpts} from '#/state/preferences/moderation-opts' import {useModerationOpts} from '#/state/preferences/moderation-opts'
import {useActorSearch} from '#/state/queries/actor-search' import {useActorSearch} from '#/state/queries/actor-search'
import {usePreferencesQuery} from '#/state/queries/preferences' import {usePreferences} from '#/state/queries/preferences'
import {useGetSuggestedUsersQuery} from '#/state/queries/trending/useGetSuggestedUsersQuery' import {useGetSuggestedUsersQuery} from '#/state/queries/trending/useGetSuggestedUsersQuery'
import {useSession} from '#/state/session' import {useSession} from '#/state/session'
import {type Follow10ProgressGuide} from '#/state/shell/progress-guide' import {type Follow10ProgressGuide} from '#/state/shell/progress-guide'
@@ -115,7 +115,7 @@ function DialogInner({guide}: {guide?: Follow10ProgressGuide}) {
const {_} = useLingui() const {_} = useLingui()
const ax = useAnalytics() const ax = useAnalytics()
const interestsDisplayNames = useInterestsDisplayNames() const interestsDisplayNames = useInterestsDisplayNames()
const {data: preferences} = usePreferencesQuery() const preferences = usePreferences()
const personalizedInterests = preferences?.interests?.tags const personalizedInterests = preferences?.interests?.tags
const interests = Object.keys(interestsDisplayNames) const interests = Object.keys(interestsDisplayNames)
.sort(boostInterests(popularInterests)) .sort(boostInterests(popularInterests))
+3 -5
View File
@@ -8,7 +8,7 @@ import {useNavigation} from '@react-navigation/native'
import {type NavigationProp} from '#/lib/routes/types' import {type NavigationProp} from '#/lib/routes/types'
import {isInvalidHandle} from '#/lib/strings/handles' import {isInvalidHandle} from '#/lib/strings/handles'
import { import {
usePreferencesQuery, usePreferences,
useRemoveMutedWordsMutation, useRemoveMutedWordsMutation,
useUpsertMutedWordsMutation, useUpsertMutedWordsMutation,
} from '#/state/queries/preferences' } from '#/state/queries/preferences'
@@ -20,7 +20,6 @@ import {
createStaticClickIfUnmodified, createStaticClickIfUnmodified,
InlineLinkText, InlineLinkText,
} from '#/components/Link' } from '#/components/Link'
import {Loader} from '#/components/Loader'
import * as Menu from '#/components/Menu' import * as Menu from '#/components/Menu'
import {IS_NATIVE, IS_WEB} from '#/env' import {IS_NATIVE, IS_WEB} from '#/env'
@@ -36,8 +35,7 @@ export function RichTextTag({
textStyle: StyleProp<TextStyle> textStyle: StyleProp<TextStyle>
}) { }) {
const {_} = useLingui() const {_} = useLingui()
const {isLoading: isPreferencesLoading, data: preferences} = const preferences = usePreferences()
usePreferencesQuery()
const { const {
mutateAsync: upsertMutedWord, mutateAsync: upsertMutedWord,
variables: optimisticUpsert, variables: optimisticUpsert,
@@ -169,7 +167,7 @@ export function RichTextTag({
? _(msg`Unmute ${isCashtag ? tag : `#${tag}`}`) ? _(msg`Unmute ${isCashtag ? tag : `#${tag}`}`)
: _(msg`Mute ${isCashtag ? tag : `#${tag}`}`)} : _(msg`Mute ${isCashtag ? tag : `#${tag}`}`)}
</Menu.ItemText> </Menu.ItemText>
<Menu.ItemIcon icon={isPreferencesLoading ? Loader : Mute} /> <Menu.ItemIcon icon={Mute} />
</Menu.Item> </Menu.Item>
</Menu.Outer> </Menu.Outer>
</Menu.Root> </Menu.Root>
+3 -19
View File
@@ -7,7 +7,7 @@ import {Trans} from '@lingui/react/macro'
import {logger} from '#/logger' import {logger} from '#/logger'
import { import {
usePreferencesQuery, usePreferences,
useRemoveMutedWordMutation, useRemoveMutedWordMutation,
useUpdateMutedWordMutation, useUpdateMutedWordMutation,
useUpsertMutedWordsMutation, useUpsertMutedWordsMutation,
@@ -52,11 +52,7 @@ function MutedWordsInner() {
const t = useTheme() const t = useTheme()
const {_} = useLingui() const {_} = useLingui()
const {gtMobile} = useBreakpoints() const {gtMobile} = useBreakpoints()
const { const preferences = usePreferences()
isLoading: isPreferencesLoading,
data: preferences,
error: preferencesError,
} = usePreferencesQuery()
const {isPending, mutateAsync: addMutedWord} = useUpsertMutedWordsMutation() const {isPending, mutateAsync: addMutedWord} = useUpsertMutedWordsMutation()
const [field, setField] = useState('') const [field, setField] = useState('')
const [targets, setTargets] = useState(['content']) const [targets, setTargets] = useState(['content'])
@@ -378,19 +374,7 @@ function MutedWordsInner() {
<Trans>Your muted words</Trans> <Trans>Your muted words</Trans>
</Text> </Text>
{isPreferencesLoading ? ( {preferences.moderationPrefs.mutedWords.length ? (
<Loader />
) : preferencesError || !preferences ? (
<View
style={[a.py_md, a.px_lg, a.rounded_md, t.atoms.bg_contrast_25]}>
<Text style={[a.italic, t.atoms.text_contrast_high]}>
<Trans>
We're sorry, but we weren't able to load your muted words at
this time. Please try again.
</Trans>
</Text>
</View>
) : preferences.moderationPrefs.mutedWords.length ? (
[...preferences.moderationPrefs.mutedWords] [...preferences.moderationPrefs.mutedWords]
.reverse() .reverse()
.map((word, i) => ( .map((word, i) => (
+2 -2
View File
@@ -12,7 +12,7 @@ import {logger} from '#/logger'
import {STALE} from '#/state/queries' import {STALE} from '#/state/queries'
import {Nux, useNuxs, useResetNuxs, useSaveNux} from '#/state/queries/nuxs' import {Nux, useNuxs, useResetNuxs, useSaveNux} from '#/state/queries/nuxs'
import { import {
usePreferencesQuery, usePreferences,
type UsePreferencesQueryResponse, type UsePreferencesQueryResponse,
} from '#/state/queries/preferences' } from '#/state/queries/preferences'
import {useProfileQuery} from '#/state/queries/profile' import {useProfileQuery} from '#/state/queries/profile'
@@ -54,7 +54,7 @@ export function useNuxDialogContext() {
export function NuxDialogs() { export function NuxDialogs() {
const {currentAccount} = useSession() const {currentAccount} = useSession()
const {data: preferences} = usePreferencesQuery() const preferences = usePreferences()
const {data: profile} = useProfileQuery({ const {data: profile} = useProfileQuery({
did: currentAccount?.did, did: currentAccount?.did,
staleTime: STALE.INFINITY, // createdAt isn't gonna change staleTime: STALE.INFINITY, // createdAt isn't gonna change
@@ -11,7 +11,7 @@ import {useGlobalLabelStrings} from '#/lib/moderation/useGlobalLabelStrings'
import {useLabelBehaviorDescription} from '#/lib/moderation/useLabelBehaviorDescription' import {useLabelBehaviorDescription} from '#/lib/moderation/useLabelBehaviorDescription'
import {getLabelStrings} from '#/lib/moderation/useLabelInfo' import {getLabelStrings} from '#/lib/moderation/useLabelInfo'
import { import {
usePreferencesQuery, usePreferences,
usePreferencesSetContentLabelMutation, usePreferencesSetContentLabelMutation,
} from '#/state/queries/preferences' } from '#/state/queries/preferences'
import {atoms as a, useBreakpoints, useTheme} from '#/alf' import {atoms as a, useBreakpoints, useTheme} from '#/alf'
@@ -123,7 +123,7 @@ export function GlobalLabelPreference({
const {_} = useLingui() const {_} = useLingui()
const {identifier} = labelDefinition const {identifier} = labelDefinition
const {data: preferences} = usePreferencesQuery() const preferences = usePreferences()
const {mutate, variables} = usePreferencesSetContentLabelMutation() const {mutate, variables} = usePreferencesSetContentLabelMutation()
const savedPref = preferences?.moderationPrefs.labels[identifier] const savedPref = preferences?.moderationPrefs.labels[identifier]
const pref = variables?.visibility ?? savedPref ?? 'warn' const pref = variables?.visibility ?? savedPref ?? 'warn'
@@ -186,7 +186,7 @@ export function LabelerLabelPreference({
const isGlobalLabel = !labelDefinition.definedBy const isGlobalLabel = !labelDefinition.definedBy
const {identifier} = labelDefinition const {identifier} = labelDefinition
const {data: preferences} = usePreferencesQuery() const preferences = usePreferences()
const {mutate, variables} = usePreferencesSetContentLabelMutation() const {mutate, variables} = usePreferencesSetContentLabelMutation()
const savedPref = const savedPref =
labelerDid && !isGlobalLabel labelerDid && !isGlobalLabel
+2 -2
View File
@@ -1,6 +1,6 @@
import {useMemo} from 'react' import {useMemo} from 'react'
import {usePreferencesQuery} from '#/state/queries/preferences' import {usePreferences} from '#/state/queries/preferences'
import {useCurrentAccountProfile} from '#/state/queries/useCurrentAccountProfile' import {useCurrentAccountProfile} from '#/state/queries/useCurrentAccountProfile'
import {useSession} from '#/state/session' import {useSession} from '#/state/session'
import type * as bsky from '#/types/bsky' import type * as bsky from '#/types/bsky'
@@ -83,7 +83,7 @@ export function useSimpleVerificationState({
}: { }: {
profile?: bsky.profile.AnyProfileView profile?: bsky.profile.AnyProfileView
}): SimpleVerificationState { }): SimpleVerificationState {
const preferences = usePreferencesQuery() const preferences = usePreferences()
const prefs = useMemo( const prefs = useMemo(
() => preferences.data?.verificationPrefs || {hideBadges: false}, () => preferences.data?.verificationPrefs || {hideBadges: false},
[preferences.data?.verificationPrefs], [preferences.data?.verificationPrefs],
+2 -2
View File
@@ -9,7 +9,7 @@ import {
isBskyCustomFeedUrl, isBskyCustomFeedUrl,
makeRecordUri, makeRecordUri,
} from '#/lib/strings/url-helpers' } from '#/lib/strings/url-helpers'
import {usePreferencesQuery} from '#/state/queries/preferences' import {usePreferences} from '#/state/queries/preferences'
import {IS_DEV, LIVE_EVENTS_URL} from '#/env' import {IS_DEV, LIVE_EVENTS_URL} from '#/env'
import {useLiveEventPreferences} from '#/features/liveEvents/preferences' import {useLiveEventPreferences} from '#/features/liveEvents/preferences'
import {type LiveEventsWorkerResponse} from '#/features/liveEvents/types' import {type LiveEventsWorkerResponse} from '#/features/liveEvents/types'
@@ -38,7 +38,7 @@ const Context = createContext<LiveEventsWorkerResponse>(DEFAULT_LIVE_EVENTS)
export function Provider({children}: React.PropsWithChildren<{}>) { export function Provider({children}: React.PropsWithChildren<{}>) {
const [isDevMode] = useDevMode() const [isDevMode] = useDevMode()
const isBskyTeam = useIsBskyTeam() const isBskyTeam = useIsBskyTeam()
const {data: preferences} = usePreferencesQuery() const preferences = usePreferences()
const mutedWords = useMemo( const mutedWords = useMemo(
() => preferences?.moderationPrefs?.mutedWords ?? [], () => preferences?.moderationPrefs?.mutedWords ?? [],
[preferences?.moderationPrefs?.mutedWords], [preferences?.moderationPrefs?.mutedWords],
@@ -5,7 +5,7 @@ import {Trans} from '@lingui/react/macro'
import {urls} from '#/lib/constants' import {urls} from '#/lib/constants'
import { import {
usePreferencesQuery, usePreferences,
type UsePreferencesQueryResponse, type UsePreferencesQueryResponse,
} from '#/state/queries/preferences' } from '#/state/queries/preferences'
import {useSetVerificationPrefsMutation} from '#/state/queries/preferences' import {useSetVerificationPrefsMutation} from '#/state/queries/preferences'
@@ -23,7 +23,7 @@ export function Screen() {
const {_} = useLingui() const {_} = useLingui()
const ax = useAnalytics() const ax = useAnalytics()
const gutters = useGutters(['base']) const gutters = useGutters(['base'])
const {data: preferences} = usePreferencesQuery() const preferences = usePreferences()
return ( return (
<Layout.Screen testID="ModerationVerificationSettingsScreen"> <Layout.Screen testID="ModerationVerificationSettingsScreen">
+4 -61
View File
@@ -16,8 +16,7 @@ import {useIsBirthdateUpdateAllowed} from '#/state/birthdate'
import {useRemoveLabelersMutation} from '#/state/queries/labeler' import {useRemoveLabelersMutation} from '#/state/queries/labeler'
import { import {
useMyLabelersQuery, useMyLabelersQuery,
usePreferencesQuery, usePreferences,
type UsePreferencesQueryResponse,
usePreferencesSetAdultContentMutation, usePreferencesSetAdultContentMutation,
} from '#/state/queries/preferences' } from '#/state/queries/preferences'
import {isNonConfigurableModerationAuthority} from '#/state/session/additional-moderation-authorities' import {isNonConfigurableModerationAuthority} from '#/state/session/additional-moderation-authorities'
@@ -41,7 +40,6 @@ import {Person_Stroke2_Corner0_Rounded as Person} from '#/components/icons/Perso
import * as LabelingService from '#/components/LabelingServiceCard' import * as LabelingService from '#/components/LabelingServiceCard'
import * as Layout from '#/components/Layout' import * as Layout from '#/components/Layout'
import {InlineLinkText, Link} from '#/components/Link' import {InlineLinkText, Link} from '#/components/Link'
import {ListMaybePlaceholder} from '#/components/Lists'
import {Loader} from '#/components/Loader' import {Loader} from '#/components/Loader'
import {GlobalLabelPreference} from '#/components/moderation/LabelPreference' import {GlobalLabelPreference} from '#/components/moderation/LabelPreference'
import * as Toast from '#/components/Toast' import * as Toast from '#/components/Toast'
@@ -49,50 +47,9 @@ import {Text} from '#/components/Typography'
import {useAgeAssurance} from '#/ageAssurance' import {useAgeAssurance} from '#/ageAssurance'
import {IS_IOS} from '#/env' import {IS_IOS} from '#/env'
function ErrorState({error}: {error: string}) {
const t = useTheme()
return (
<View style={[a.p_xl]}>
<Text
style={[
a.text_md,
a.leading_normal,
a.pb_md,
t.atoms.text_contrast_medium,
]}>
<Trans>
Hmmmm, it seems we're having trouble loading this data. See below for
more details. If this issue persists, please contact us.
</Trans>
</Text>
<View
style={[
a.relative,
a.py_md,
a.px_lg,
a.rounded_md,
a.mb_2xl,
t.atoms.bg_contrast_25,
]}>
<Text style={[a.text_md, a.leading_normal]}>{error}</Text>
</View>
</View>
)
}
export function ModerationScreen( export function ModerationScreen(
_props: NativeStackScreenProps<CommonNavigatorParams, 'Moderation'>, _props: NativeStackScreenProps<CommonNavigatorParams, 'Moderation'>,
) { ) {
const {_} = useLingui()
const {
isLoading: isPreferencesLoading,
error: preferencesError,
data: preferences,
} = usePreferencesQuery()
const isLoading = isPreferencesLoading
const error = preferencesError
return ( return (
<Layout.Screen testID="moderationScreen"> <Layout.Screen testID="moderationScreen">
<Layout.Header.Outer> <Layout.Header.Outer>
@@ -105,18 +62,7 @@ export function ModerationScreen(
<Layout.Header.Slot /> <Layout.Header.Slot />
</Layout.Header.Outer> </Layout.Header.Outer>
<Layout.Content> <Layout.Content>
{isLoading ? ( <ModerationScreenInner />
<ListMaybePlaceholder isLoading={true} sideBorders={false} />
) : error || !preferences ? (
<ErrorState
error={
preferencesError?.toString() ||
_(msg`Something went wrong, please try again.`)
}
/>
) : (
<ModerationScreenInner preferences={preferences} />
)}
</Layout.Content> </Layout.Content>
</Layout.Screen> </Layout.Screen>
) )
@@ -154,11 +100,8 @@ function SubItem({
) )
} }
export function ModerationScreenInner({ export function ModerationScreenInner() {
preferences, const preferences = usePreferences()
}: {
preferences: UsePreferencesQueryResponse
}) {
const {_} = useLingui() const {_} = useLingui()
const t = useTheme() const t = useTheme()
const setMinimalShellMode = useSetMinimalShellMode() const setMinimalShellMode = useSetMinimalShellMode()
@@ -8,10 +8,7 @@ import deepEqual from 'fast-deep-equal'
import {logger} from '#/logger' import {logger} from '#/logger'
import {usePostInteractionSettingsMutation} from '#/state/queries/post-interaction-settings' import {usePostInteractionSettingsMutation} from '#/state/queries/post-interaction-settings'
import {createPostgateRecord} from '#/state/queries/postgate/util' import {createPostgateRecord} from '#/state/queries/postgate/util'
import { import {usePreferences} from '#/state/queries/preferences'
usePreferencesQuery,
type UsePreferencesQueryResponse,
} from '#/state/queries/preferences'
import { import {
threadgateAllowUISettingToAllowRecordValue, threadgateAllowUISettingToAllowRecordValue,
threadgateRecordToAllowUISetting, threadgateRecordToAllowUISetting,
@@ -20,12 +17,10 @@ import {atoms as a, useGutters} from '#/alf'
import {Admonition} from '#/components/Admonition' import {Admonition} from '#/components/Admonition'
import {PostInteractionSettingsForm} from '#/components/dialogs/PostInteractionSettingsDialog' import {PostInteractionSettingsForm} from '#/components/dialogs/PostInteractionSettingsDialog'
import * as Layout from '#/components/Layout' import * as Layout from '#/components/Layout'
import {Loader} from '#/components/Loader'
import * as Toast from '#/components/Toast' import * as Toast from '#/components/Toast'
export function Screen() { export function Screen() {
const gutters = useGutters(['base']) const gutters = useGutters(['base'])
const {data: preferences} = usePreferencesQuery()
return ( return (
<Layout.Screen testID="ModerationInteractionSettingsScreen"> <Layout.Screen testID="ModerationInteractionSettingsScreen">
<Layout.Header.Outer> <Layout.Header.Outer>
@@ -46,20 +41,15 @@ export function Screen() {
composer. composer.
</Trans> </Trans>
</Admonition> </Admonition>
{preferences ? ( <Inner />
<Inner preferences={preferences} />
) : (
<View style={[gutters, a.justify_center, a.align_center]}>
<Loader size="xl" />
</View>
)}
</View> </View>
</Layout.Content> </Layout.Content>
</Layout.Screen> </Layout.Screen>
) )
} }
function Inner({preferences}: {preferences: UsePreferencesQueryResponse}) { function Inner() {
const preferences = usePreferences()
const {_} = useLingui() const {_} = useLingui()
const {mutateAsync: setPostInteractionSettings, isPending} = const {mutateAsync: setPostInteractionSettings, isPending} =
usePostInteractionSettingsMutation() usePostInteractionSettingsMutation()
@@ -19,7 +19,7 @@ import {useProfileShadow} from '#/state/cache/profile-shadow'
import {type Shadow} from '#/state/cache/types' import {type Shadow} from '#/state/cache/types'
import {useLabelerSubscriptionMutation} from '#/state/queries/labeler' import {useLabelerSubscriptionMutation} from '#/state/queries/labeler'
import {useLikeMutation, useUnlikeMutation} from '#/state/queries/like' import {useLikeMutation, useUnlikeMutation} from '#/state/queries/like'
import {usePreferencesQuery} from '#/state/queries/preferences' import {usePreferences} from '#/state/queries/preferences'
import {useRequireAuth, useSession} from '#/state/session' import {useRequireAuth, useSession} from '#/state/session'
import {ProfileMenu} from '#/view/com/profile/ProfileMenu' import {ProfileMenu} from '#/view/com/profile/ProfileMenu'
import {atoms as a, tokens, useTheme} from '#/alf' import {atoms as a, tokens, useTheme} from '#/alf'
@@ -244,7 +244,7 @@ export function HeaderLabelerButtons({
const requireAuth = useRequireAuth() const requireAuth = useRequireAuth()
const playHaptic = useHaptics() const playHaptic = useHaptics()
const editProfileControl = useDialogControl() const editProfileControl = useDialogControl()
const {data: preferences} = usePreferencesQuery() const preferences = usePreferences()
const { const {
mutateAsync: toggleSubscription, mutateAsync: toggleSubscription,
variables, variables,
@@ -252,7 +252,7 @@ export function HeaderLabelerButtons({
} = useLabelerSubscriptionMutation() } = useLabelerSubscriptionMutation()
const isSubscribed = const isSubscribed =
variables?.subscribe ?? variables?.subscribe ??
preferences?.moderationPrefs.labelers.find(l => l.did === profile.did) preferences.moderationPrefs.labelers.find(l => l.did === profile.did)
const cantSubscribePrompt = Prompt.usePromptControl() const cantSubscribePrompt = Prompt.usePromptControl()
+2 -2
View File
@@ -23,7 +23,7 @@ import {
import {type FeedDescriptor, type FeedParams} from '#/state/queries/post-feed' import {type FeedDescriptor, type FeedParams} from '#/state/queries/post-feed'
import {RQKEY as FEED_RQKEY} from '#/state/queries/post-feed' import {RQKEY as FEED_RQKEY} from '#/state/queries/post-feed'
import { import {
usePreferencesQuery, usePreferences,
type UsePreferencesQueryResponse, type UsePreferencesQueryResponse,
} from '#/state/queries/preferences' } from '#/state/queries/preferences'
import {useResolveUriQuery} from '#/state/queries/resolve-uri' import {useResolveUriQuery} from '#/state/queries/resolve-uri'
@@ -101,7 +101,7 @@ function ProfileFeedScreenIntermediate({
feedUri: string feedUri: string
feedParams: FeedParams | undefined feedParams: FeedParams | undefined
}) { }) {
const {data: preferences} = usePreferencesQuery() const preferences = usePreferences()
const {data: info} = useFeedSourceInfoQuery({uri: feedUri}) const {data: info} = useFeedSourceInfoQuery({uri: feedUri})
if (!preferences || !info) { if (!preferences || !info) {
@@ -15,7 +15,7 @@ import {type FeedSourceFeedInfo} from '#/state/queries/feed'
import {useLikeMutation, useUnlikeMutation} from '#/state/queries/like' import {useLikeMutation, useUnlikeMutation} from '#/state/queries/like'
import { import {
useAddSavedFeedsMutation, useAddSavedFeedsMutation,
usePreferencesQuery, usePreferences,
useRemoveFeedMutation, useRemoveFeedMutation,
useUpdateSavedFeedsMutation, useUpdateSavedFeedsMutation,
} from '#/state/queries/preferences' } from '#/state/queries/preferences'
@@ -93,7 +93,7 @@ export function ProfileFeedHeader({info}: {info: FeedSourceFeedInfo}) {
const infoControl = Dialog.useDialogControl() const infoControl = Dialog.useDialogControl()
const playHaptic = useHaptics() const playHaptic = useHaptics()
const {data: preferences} = usePreferencesQuery() const preferences = usePreferences()
const [likeUri, setLikeUri] = useState(info.likeUri || '') const [likeUri, setLikeUri] = useState(info.likeUri || '')
const likeCount = const likeCount =
+2 -2
View File
@@ -25,7 +25,7 @@ import {useModerationOpts} from '#/state/preferences/moderation-opts'
import {useListQuery} from '#/state/queries/list' import {useListQuery} from '#/state/queries/list'
import {RQKEY as FEED_RQKEY} from '#/state/queries/post-feed' import {RQKEY as FEED_RQKEY} from '#/state/queries/post-feed'
import { import {
usePreferencesQuery, usePreferences,
type UsePreferencesQueryResponse, type UsePreferencesQueryResponse,
} from '#/state/queries/preferences' } from '#/state/queries/preferences'
import {useResolveUriQuery} from '#/state/queries/resolve-uri' import {useResolveUriQuery} from '#/state/queries/resolve-uri'
@@ -67,7 +67,7 @@ function ProfileListScreenInner(props: Props) {
const {data: resolvedUri, error: resolveError} = useResolveUriQuery( const {data: resolvedUri, error: resolveError} = useResolveUriQuery(
AtUri.make(handleOrDid, 'app.bsky.graph.list', rkey).toString(), AtUri.make(handleOrDid, 'app.bsky.graph.list', rkey).toString(),
) )
const {data: preferences} = usePreferencesQuery() const preferences = usePreferences()
const {data: list, error: listError} = useListQuery(resolvedUri?.uri) const {data: list, error: listError} = useListQuery(resolvedUri?.uri)
const moderationOpts = useModerationOpts() const moderationOpts = useModerationOpts()
+2 -2
View File
@@ -20,7 +20,7 @@ import {logger} from '#/logger'
import {useA11y} from '#/state/a11y' import {useA11y} from '#/state/a11y'
import { import {
useOverwriteSavedFeedsMutation, useOverwriteSavedFeedsMutation,
usePreferencesQuery, usePreferences,
} from '#/state/queries/preferences' } from '#/state/queries/preferences'
import {type UsePreferencesQueryResponse} from '#/state/queries/preferences/types' import {type UsePreferencesQueryResponse} from '#/state/queries/preferences/types'
import {useSetMinimalShellMode} from '#/state/shell' import {useSetMinimalShellMode} from '#/state/shell'
@@ -47,7 +47,7 @@ import {Text} from '#/components/Typography'
type Props = NativeStackScreenProps<CommonNavigatorParams, 'SavedFeeds'> type Props = NativeStackScreenProps<CommonNavigatorParams, 'SavedFeeds'>
export function SavedFeeds({}: Props) { export function SavedFeeds({}: Props) {
const {data: preferences} = usePreferencesQuery() const preferences = usePreferences()
const {screenReaderEnabled} = useA11y() const {screenReaderEnabled} = useA11y()
if (!preferences) { if (!preferences) {
return <View /> return <View />
+1 -2
View File
@@ -257,8 +257,7 @@ export function Explore({
fetchNextPage: fetchNextFeedsPage, fetchNextPage: fetchNextFeedsPage,
} = useGetPopularFeedsQuery({limit: 10, enabled: useFullExperience}) } = useGetPopularFeedsQuery({limit: 10, enabled: useFullExperience})
const interestsNux = useNux(Nux.ExploreInterestsCard) const interestsNux = useNux(Nux.ExploreInterestsCard)
const showInterestsNux = const showInterestsNux = !interestsNux.nux?.completed
interestsNux.status === 'ready' && !interestsNux.nux?.completed
const { const {
data: suggestedSPs, data: suggestedSPs,
@@ -6,7 +6,7 @@ import {Trans} from '@lingui/react/macro'
import {useInterestsDisplayNames} from '#/lib/interests' import {useInterestsDisplayNames} from '#/lib/interests'
import {Nux, useSaveNux} from '#/state/queries/nuxs' import {Nux, useSaveNux} from '#/state/queries/nuxs'
import {usePreferencesQuery} from '#/state/queries/preferences' import {usePreferences} from '#/state/queries/preferences'
import {atoms as a, useTheme} from '#/alf' import {atoms as a, useTheme} from '#/alf'
import {Button, ButtonIcon, ButtonText} from '#/components/Button' import {Button, ButtonIcon, ButtonText} from '#/components/Button'
import {Shapes_Stroke2_Corner0_Rounded as Shapes} from '#/components/icons/Shapes' import {Shapes_Stroke2_Corner0_Rounded as Shapes} from '#/components/icons/Shapes'
@@ -18,7 +18,7 @@ import {Text} from '#/components/Typography'
export function ExploreInterestsCard() { export function ExploreInterestsCard() {
const t = useTheme() const t = useTheme()
const {_} = useLingui() const {_} = useLingui()
const {data: preferences} = usePreferencesQuery() const preferences = usePreferences()
const interestsDisplayNames = useInterestsDisplayNames() const interestsDisplayNames = useInterestsDisplayNames()
const {mutateAsync: saveNux} = useSaveNux() const {mutateAsync: saveNux} = useSaveNux()
const trendingPrompt = Prompt.usePromptControl() const trendingPrompt = Prompt.usePromptControl()
@@ -7,7 +7,7 @@ import {type InfiniteData} from '@tanstack/react-query'
import {popularInterests, useInterestsDisplayNames} from '#/lib/interests' import {popularInterests, useInterestsDisplayNames} from '#/lib/interests'
import {logger} from '#/logger' import {logger} from '#/logger'
import {usePreferencesQuery} from '#/state/queries/preferences' import {usePreferences} from '#/state/queries/preferences'
import {BlockDrawerGesture} from '#/view/shell/BlockDrawerGesture' import {BlockDrawerGesture} from '#/view/shell/BlockDrawerGesture'
import {atoms as a, useTheme} from '#/alf' import {atoms as a, useTheme} from '#/alf'
import {boostInterests, InterestTabs} from '#/components/InterestTabs' import {boostInterests, InterestTabs} from '#/components/InterestTabs'
@@ -64,7 +64,7 @@ export function SuggestedAccountsTabBar({
const {_} = useLingui() const {_} = useLingui()
const ax = useAnalytics() const ax = useAnalytics()
const interestsDisplayNames = useInterestsDisplayNames() const interestsDisplayNames = useInterestsDisplayNames()
const {data: preferences} = usePreferencesQuery() const preferences = usePreferences()
const personalizedInterests = preferences?.interests?.tags const personalizedInterests = preferences?.interests?.tags
const interests = Object.keys(interestsDisplayNames) const interests = Object.keys(interestsDisplayNames)
.sort(boostInterests(popularInterests)) .sort(boostInterests(popularInterests))
@@ -7,7 +7,7 @@ import {
type NativeStackScreenProps, type NativeStackScreenProps,
} from '#/lib/routes/types' } from '#/lib/routes/types'
import { import {
usePreferencesQuery, usePreferences,
useSetFeedViewPreferencesMutation, useSetFeedViewPreferencesMutation,
} from '#/state/queries/preferences' } from '#/state/queries/preferences'
import {atoms as a} from '#/alf' import {atoms as a} from '#/alf'
@@ -27,7 +27,7 @@ type Props = NativeStackScreenProps<
export function FollowingFeedPreferencesScreen({}: Props) { export function FollowingFeedPreferencesScreen({}: Props) {
const {_} = useLingui() const {_} = useLingui()
const {data: preferences} = usePreferencesQuery() const preferences = usePreferences()
const {mutate: setFeedViewPref, variables} = const {mutate: setFeedViewPref, variables} =
useSetFeedViewPreferencesMutation() useSetFeedViewPreferencesMutation()
+4 -19
View File
@@ -13,10 +13,7 @@ import {
useInterestsDisplayNames, useInterestsDisplayNames,
} from '#/lib/interests' } from '#/lib/interests'
import {type CommonNavigatorParams} from '#/lib/routes/types' import {type CommonNavigatorParams} from '#/lib/routes/types'
import { import {preferencesQueryKey, usePreferences} from '#/state/queries/preferences'
preferencesQueryKey,
usePreferencesQuery,
} from '#/state/queries/preferences'
import {type UsePreferencesQueryResponse} from '#/state/queries/preferences/types' import {type UsePreferencesQueryResponse} from '#/state/queries/preferences/types'
import {createGetSuggestedFeedsQueryKey} from '#/state/queries/trending/useGetSuggestedFeedsQuery' import {createGetSuggestedFeedsQueryKey} from '#/state/queries/trending/useGetSuggestedFeedsQuery'
import {createGetSuggestedUsersQueryKey} from '#/state/queries/trending/useGetSuggestedUsersQuery' import {createGetSuggestedUsersQueryKey} from '#/state/queries/trending/useGetSuggestedUsersQuery'
@@ -35,7 +32,6 @@ type Props = NativeStackScreenProps<CommonNavigatorParams, 'InterestsSettings'>
export function InterestsSettingsScreen({}: Props) { export function InterestsSettingsScreen({}: Props) {
const t = useTheme() const t = useTheme()
const gutters = useGutters(['base']) const gutters = useGutters(['base'])
const {data: preferences} = usePreferencesQuery()
const [isSaving, setIsSaving] = useState(false) const [isSaving, setIsSaving] = useState(false)
return ( return (
@@ -65,26 +61,15 @@ export function InterestsSettingsScreen({}: Props) {
<Divider /> <Divider />
{preferences ? ( <Inner setIsSaving={setIsSaving} />
<Inner preferences={preferences} setIsSaving={setIsSaving} />
) : (
<View style={[a.flex_row, a.justify_center, a.p_lg]}>
<Loader size="xl" />
</View>
)}
</View> </View>
</Layout.Content> </Layout.Content>
</Layout.Screen> </Layout.Screen>
) )
} }
function Inner({ function Inner({setIsSaving}: {setIsSaving: (isSaving: boolean) => void}) {
preferences, const preferences = usePreferences()
setIsSaving,
}: {
preferences: UsePreferencesQueryResponse
setIsSaving: (isSaving: boolean) => void
}) {
const {_} = useLingui() const {_} = useLingui()
const agent = useAgent() const agent = useAgent()
const qc = useQueryClient() const qc = useQueryClient()
+4 -4
View File
@@ -1,14 +1,14 @@
import {useMemo} from 'react' import {useMemo} from 'react'
import {FeedTuner} from '#/lib/api/feed-manip' import {FeedTuner} from '#/lib/api/feed-manip'
import {type FeedDescriptor} from '../queries/post-feed' import {type FeedDescriptor} from '#/state/queries/post-feed'
import {usePreferencesQuery} from '../queries/preferences' import {usePreferences} from '#/state/queries/preferences'
import {useSession} from '../session' import {useSession} from '#/state/session'
import {useLanguagePrefs} from './languages' import {useLanguagePrefs} from './languages'
export function useFeedTuners(feedDesc: FeedDescriptor) { export function useFeedTuners(feedDesc: FeedDescriptor) {
const langPrefs = useLanguagePrefs() const langPrefs = useLanguagePrefs()
const {data: preferences} = usePreferencesQuery() const preferences = usePreferences()
const {currentAccount} = useSession() const {currentAccount} = useSession()
return useMemo(() => { return useMemo(() => {
+3 -3
View File
@@ -2,9 +2,9 @@ import {createContext, useContext, useMemo} from 'react'
import {BskyAgent, type ModerationOpts} from '@atproto/api' import {BskyAgent, type ModerationOpts} from '@atproto/api'
import {useHiddenPosts, useLabelDefinitions} from '#/state/preferences' import {useHiddenPosts, useLabelDefinitions} from '#/state/preferences'
import {usePreferences} from '#/state/queries/preferences'
import {DEFAULT_LOGGED_OUT_LABEL_PREFERENCES} from '#/state/queries/preferences/moderation' import {DEFAULT_LOGGED_OUT_LABEL_PREFERENCES} from '#/state/queries/preferences/moderation'
import {useSession} from '#/state/session' import {useSession} from '#/state/session'
import {usePreferencesQuery} from '../queries/preferences'
export const moderationOptsContext = createContext<ModerationOpts | undefined>( export const moderationOptsContext = createContext<ModerationOpts | undefined>(
undefined, undefined,
@@ -24,12 +24,12 @@ export function useModerationOpts() {
export function Provider({children}: React.PropsWithChildren<{}>) { export function Provider({children}: React.PropsWithChildren<{}>) {
const override = useContext(moderationOptsOverrideContext) const override = useContext(moderationOptsOverrideContext)
const {currentAccount} = useSession() const {currentAccount} = useSession()
const prefs = usePreferencesQuery() const preferences = usePreferences()
const {labelDefs} = useLabelDefinitions() const {labelDefs} = useLabelDefinitions()
const hiddenPosts = useHiddenPosts() // TODO move this into pds-stored prefs const hiddenPosts = useHiddenPosts() // TODO move this into pds-stored prefs
const userDid = currentAccount?.did const userDid = currentAccount?.did
const moderationPrefs = prefs.data?.moderationPrefs const moderationPrefs = preferences?.moderationPrefs
const value = useMemo<ModerationOpts | undefined>(() => { const value = useMemo<ModerationOpts | undefined>(() => {
if (override) { if (override) {
return override return override
+2 -2
View File
@@ -22,7 +22,7 @@ import {
type FeedPostSlice, type FeedPostSlice,
type FeedPostSliceItem, type FeedPostSliceItem,
} from '#/state/queries/post-feed' } from '#/state/queries/post-feed'
import {usePreferencesQuery} from '#/state/queries/preferences' import {usePreferences} from '#/state/queries/preferences'
import { import {
didOrHandleUriMatches, didOrHandleUriMatches,
embedViewRecordToPostView, embedViewRecordToPostView,
@@ -122,7 +122,7 @@ export function useFeedPreviews(
const uris = feeds.map(feed => feed.uri) const uris = feeds.map(feed => feed.uri)
const {_} = useLingui() const {_} = useLingui()
const agent = useAgent() const agent = useAgent()
const {data: preferences} = usePreferencesQuery() const preferences = usePreferences()
const userInterests = aggregateUserInterests(preferences) const userInterests = aggregateUserInterests(preferences)
const moderationOpts = useModerationOpts() const moderationOpts = useModerationOpts()
const enabled = feeds.length > 0 && isEnabled const enabled = feeds.length > 0 && isEnabled
+5 -7
View File
@@ -22,16 +22,16 @@ import {
import {DISCOVER_FEED_URI, DISCOVER_SAVED_FEED} from '#/lib/constants' import {DISCOVER_FEED_URI, DISCOVER_SAVED_FEED} from '#/lib/constants'
import {sanitizeDisplayName} from '#/lib/strings/display-names' import {sanitizeDisplayName} from '#/lib/strings/display-names'
import {sanitizeHandle} from '#/lib/strings/handles' import {sanitizeHandle} from '#/lib/strings/handles'
import {useModerationOpts} from '#/state/preferences/moderation-opts'
import { import {
PERSISTED_QUERY_GCTIME, PERSISTED_QUERY_GCTIME,
PERSISTED_QUERY_ROOT, PERSISTED_QUERY_ROOT,
STALE, STALE,
} from '#/state/queries' } from '#/state/queries'
import {RQKEY as listQueryKey} from '#/state/queries/list' import {RQKEY as listQueryKey} from '#/state/queries/list'
import {usePreferencesQuery} from '#/state/queries/preferences' import {usePreferences} from '#/state/queries/preferences'
import {useAgent, useSession} from '#/state/session' import {useAgent, useSession} from '#/state/session'
import {router} from '#/routes' import {router} from '#/routes'
import {useModerationOpts} from '../preferences/moderation-opts'
import {type FeedDescriptor} from './post-feed' import {type FeedDescriptor} from './post-feed'
import {precacheResolvedUri} from './resolve-uri' import {precacheResolvedUri} from './resolve-uri'
@@ -227,7 +227,7 @@ export function useGetPopularFeedsQuery(options?: GetPopularFeedsOptions) {
const {hasSession} = useSession() const {hasSession} = useSession()
const agent = useAgent() const agent = useAgent()
const limit = options?.limit || 10 const limit = options?.limit || 10
const {data: preferences} = usePreferencesQuery() const preferences = usePreferences()
const queryClient = useQueryClient() const queryClient = useQueryClient()
const moderationOpts = useModerationOpts() const moderationOpts = useModerationOpts()
@@ -424,7 +424,7 @@ const createPinnedFeedInfosQueryKeyRoot = (
export function usePinnedFeedsInfos() { export function usePinnedFeedsInfos() {
const {hasSession} = useSession() const {hasSession} = useSession()
const agent = useAgent() const agent = useAgent()
const {data: preferences, isLoading: isLoadingPrefs} = usePreferencesQuery() const preferences = usePreferences()
const pinnedItems = preferences?.savedFeeds.filter(feed => feed.pinned) ?? [] const pinnedItems = preferences?.savedFeeds.filter(feed => feed.pinned) ?? []
return useQuery({ return useQuery({
@@ -434,7 +434,6 @@ export function usePinnedFeedsInfos() {
), ),
gcTime: PERSISTED_QUERY_GCTIME, gcTime: PERSISTED_QUERY_GCTIME,
staleTime: STALE.INFINITY, staleTime: STALE.INFINITY,
enabled: !isLoadingPrefs,
queryFn: async () => { queryFn: async () => {
if (!hasSession) { if (!hasSession) {
return [PWI_DISCOVER_FEED_STUB] return [PWI_DISCOVER_FEED_STUB]
@@ -531,7 +530,7 @@ export type SavedFeedItem =
export function useSavedFeeds() { export function useSavedFeeds() {
const agent = useAgent() const agent = useAgent()
const {data: preferences, isLoading: isLoadingPrefs} = usePreferencesQuery() const preferences = usePreferences()
const savedItems = preferences?.savedFeeds ?? [] const savedItems = preferences?.savedFeeds ?? []
const queryClient = useQueryClient() const queryClient = useQueryClient()
@@ -542,7 +541,6 @@ export function useSavedFeeds() {
), ),
gcTime: PERSISTED_QUERY_GCTIME, gcTime: PERSISTED_QUERY_GCTIME,
staleTime: STALE.INFINITY, staleTime: STALE.INFINITY,
enabled: !isLoadingPrefs,
placeholderData: previousData => { placeholderData: previousData => {
return ( return (
previousData || { previousData || {
+2 -5
View File
@@ -8,10 +8,7 @@ import {
PERSISTED_QUERY_ROOT, PERSISTED_QUERY_ROOT,
STALE, STALE,
} from '#/state/queries' } from '#/state/queries'
import { import {preferencesQueryKey, usePreferences} from '#/state/queries/preferences'
preferencesQueryKey,
usePreferencesQuery,
} from '#/state/queries/preferences'
import {useAgent} from '#/state/session' import {useAgent} from '#/state/session'
const labelerInfoQueryKeyRoot = 'labeler-info' const labelerInfoQueryKeyRoot = 'labeler-info'
@@ -101,7 +98,7 @@ export function useRemoveLabelersMutation() {
export function useLabelerSubscriptionMutation() { export function useLabelerSubscriptionMutation() {
const queryClient = useQueryClient() const queryClient = useQueryClient()
const agent = useAgent() const agent = useAgent()
const preferences = usePreferencesQuery() const preferences = usePreferences()
return useMutation({ return useMutation({
async mutationFn({did, subscribe}: {did: string; subscribe: boolean}) { async mutationFn({did, subscribe}: {did: string; subscribe: boolean}) {
+29 -64
View File
@@ -2,44 +2,29 @@ import {useMutation, useQueryClient} from '@tanstack/react-query'
import {type AppNux, type Nux} from '#/state/queries/nuxs/definitions' import {type AppNux, type Nux} from '#/state/queries/nuxs/definitions'
import {parseAppNux, serializeAppNux} from '#/state/queries/nuxs/util' import {parseAppNux, serializeAppNux} from '#/state/queries/nuxs/util'
import { import {preferencesQueryKey, usePreferences} from '#/state/queries/preferences'
preferencesQueryKey,
usePreferencesQuery,
} from '#/state/queries/preferences'
import {useAgent} from '#/state/session' import {useAgent} from '#/state/session'
export {Nux} from '#/state/queries/nuxs/definitions' export {Nux} from '#/state/queries/nuxs/definitions'
export function useNuxs(): export function useNuxs(): {
| { nuxs: AppNux[]
nuxs: AppNux[] } {
status: 'ready' const preferences = usePreferences()
const nuxs = preferences?.bskyAppState?.nuxs
?.map(parseAppNux)
?.filter(Boolean) as AppNux[]
if (nuxs) {
return {
nuxs,
} }
| { } else {
nuxs: undefined return {
status: 'loading' | 'error' nuxs: [],
} {
const {data, isSuccess, isError} = usePreferencesQuery()
const status = isSuccess ? 'ready' : isError ? 'error' : 'loading'
if (status === 'ready') {
const nuxs = data?.bskyAppState?.nuxs
?.map(parseAppNux)
?.filter(Boolean) as AppNux[]
if (nuxs) {
return {
nuxs,
status,
}
} else {
return {
nuxs: [],
status,
}
} }
} }
// if (__DEV__) { // if (__DEV__) {
// const queryClient = useQueryClient() // const queryClient = useQueryClient()
// const agent = useAgent() // const agent = useAgent()
@@ -53,46 +38,26 @@ export function useNuxs():
// }) // })
// } // }
// } // }
return {
nuxs: undefined,
status,
}
} }
export function useNux<T extends Nux>( export function useNux<T extends Nux>(
id: T, id: T,
): ): {
| { nux: Extract<AppNux, {id: T}> | undefined
nux: Extract<AppNux, {id: T}> | undefined } {
status: 'ready' const {nuxs} = useNuxs()
const nux = nuxs.find(nux => nux.id === id)
if (nux) {
return {
nux: nux as Extract<AppNux, {id: T}>,
} }
| { } else {
nux: undefined return {
status: 'loading' | 'error' nux: undefined,
} {
const {nuxs, status} = useNuxs()
if (status === 'ready') {
const nux = nuxs.find(nux => nux.id === id)
if (nux) {
return {
nux: nux as Extract<AppNux, {id: T}>,
status,
}
} else {
return {
nux: undefined,
status,
}
} }
} }
return {
nux: undefined,
status,
}
} }
export function useSaveNux() { export function useSaveNux() {
+4 -4
View File
@@ -31,14 +31,14 @@ import {aggregateUserInterests} from '#/lib/api/feed/utils'
import {FeedTuner, type FeedTunerFn} from '#/lib/api/feed-manip' import {FeedTuner, type FeedTunerFn} from '#/lib/api/feed-manip'
import {DISCOVER_FEED_URI} from '#/lib/constants' import {DISCOVER_FEED_URI} from '#/lib/constants'
import {logger} from '#/logger' import {logger} from '#/logger'
import {useFeedTuners} from '#/state/preferences/feed-tuners'
import {useModerationOpts} from '#/state/preferences/moderation-opts'
import {STALE} from '#/state/queries' import {STALE} from '#/state/queries'
import {usePreferences} from '#/state/queries/preferences'
import {DEFAULT_LOGGED_OUT_PREFERENCES} from '#/state/queries/preferences/const' import {DEFAULT_LOGGED_OUT_PREFERENCES} from '#/state/queries/preferences/const'
import {useAgent} from '#/state/session' import {useAgent} from '#/state/session'
import * as userActionHistory from '#/state/userActionHistory' import * as userActionHistory from '#/state/userActionHistory'
import {KnownError} from '#/view/com/posts/PostFeedErrorMessage' import {KnownError} from '#/view/com/posts/PostFeedErrorMessage'
import {useFeedTuners} from '../preferences/feed-tuners'
import {useModerationOpts} from '../preferences/moderation-opts'
import {usePreferencesQuery} from './preferences'
import { import {
didOrHandleUriMatches, didOrHandleUriMatches,
embedViewRecordToPostView, embedViewRecordToPostView,
@@ -133,7 +133,7 @@ export function usePostFeedQuery(
) { ) {
const feedTuners = useFeedTuners(feedDesc) const feedTuners = useFeedTuners(feedDesc)
const moderationOpts = useModerationOpts() const moderationOpts = useModerationOpts()
const {data: preferences} = usePreferencesQuery() const preferences = usePreferences()
/** /**
* Load bearing: we need to await AA state or risk FOUC. This marginally * Load bearing: we need to await AA state or risk FOUC. This marginally
* delays feeds, but AA state is fetched immediately on load and is then * delays feeds, but AA state is fetched immediately on load and is then
+31
View File
@@ -0,0 +1,31 @@
import {createContext, useContext} from 'react'
import {ActivityIndicator, View} from 'react-native'
import {
usePreferencesQuery,
type UsePreferencesQueryResponse,
} from '#/state/queries/preferences'
import {atoms as a} from '#/alf'
const PreferencesContext = createContext<UsePreferencesQueryResponse | null>(
null,
)
PreferencesContext.displayName = 'PreferencesContext'
export function Provider({children}: {children: React.ReactNode}) {
const {data} = usePreferencesQuery()
if (!data) {
return null
}
return <PreferencesContext value={data}>{children}</PreferencesContext>
}
export function usePreferences() {
const context = useContext(PreferencesContext)
if (!context) {
throw new Error('usePreferences must be used within a PreferencesProvider')
}
return context
}
+13 -11
View File
@@ -30,6 +30,7 @@ import {makeAgeRestrictedModerationPrefs} from '#/ageAssurance/util'
import {useAnalytics} from '#/analytics' import {useAnalytics} from '#/analytics'
export * from '#/state/queries/preferences/const' export * from '#/state/queries/preferences/const'
export * from '#/state/queries/preferences/context'
export * from '#/state/queries/preferences/moderation' export * from '#/state/queries/preferences/moderation'
export * from '#/state/queries/preferences/types' export * from '#/state/queries/preferences/types'
@@ -39,7 +40,7 @@ export function usePreferencesQuery() {
const agent = useAgent() const agent = useAgent()
const aa = useAgeAssurance() const aa = useAgeAssurance()
const query = useQuery({ return useQuery({
staleTime: STALE.SECONDS.FIFTEEN, staleTime: STALE.SECONDS.FIFTEEN,
structuralSharing: replaceEqualDeep, structuralSharing: replaceEqualDeep,
refetchOnWindowFocus: true, refetchOnWindowFocus: true,
@@ -52,7 +53,7 @@ export function usePreferencesQuery() {
const res = await agent.getPreferences() const res = await agent.getPreferences()
// save to local storage to ensure there are labels on initial requests // save to local storage to ensure there are labels on initial requests
saveLabelers( void saveLabelers(
agent.did, agent.did,
res.moderationPrefs.labelers.map(l => l.did), res.moderationPrefs.labelers.map(l => l.did),
) )
@@ -91,20 +92,21 @@ export function usePreferencesQuery() {
), ),
} }
} }
/**
* The persisted query cache stores dates as strings, but our code expects a `Date`.
*/
if (data.birthDate) {
return {
...data,
birthDate: new Date(data.birthDate),
}
}
return data return data
}, },
[aa], [aa],
), ),
}) })
if (query.data?.birthDate) {
/**
* The persisted query cache stores dates as strings, but our code expects a `Date`.
*/
query.data.birthDate = new Date(query.data.birthDate)
}
return query
} }
export function useClearPreferencesMutation() { export function useClearPreferencesMutation() {
+4 -14
View File
@@ -7,7 +7,7 @@ import {
import {isNonConfigurableModerationAuthority} from '#/state/session/additional-moderation-authorities' import {isNonConfigurableModerationAuthority} from '#/state/session/additional-moderation-authorities'
import {useLabelersDetailedInfoQuery} from '../labeler' import {useLabelersDetailedInfoQuery} from '../labeler'
import {usePreferencesQuery} from './index' import {usePreferences} from './index'
/** /**
* More strict than our default settings for logged in users. * More strict than our default settings for logged in users.
@@ -22,28 +22,18 @@ export function useMyLabelersQuery({
}: { }: {
excludeNonConfigurableLabelers?: boolean excludeNonConfigurableLabelers?: boolean
} = {}) { } = {}) {
const prefs = usePreferencesQuery() const preferences = usePreferences()
let dids = Array.from( let dids = Array.from(
new Set( new Set(
BskyAgent.appLabelers.concat( BskyAgent.appLabelers.concat(
prefs.data?.moderationPrefs.labelers.map(l => l.did) || [], preferences?.moderationPrefs.labelers.map(l => l.did) || [],
), ),
), ),
) )
if (excludeNonConfigurableLabelers) { if (excludeNonConfigurableLabelers) {
dids = dids.filter(did => !isNonConfigurableModerationAuthority(did)) dids = dids.filter(did => !isNonConfigurableModerationAuthority(did))
} }
const labelers = useLabelersDetailedInfoQuery({dids}) return useLabelersDetailedInfoQuery({dids})
const isLoading = prefs.isLoading || labelers.isLoading
const error = prefs.error || labelers.error
return useMemo(() => {
return {
isLoading,
error,
data: labelers.data,
refetch: labelers.refetch,
}
}, [labelers, isLoading, error])
} }
export function useLabelDefinitionsQuery() { export function useLabelDefinitionsQuery() {
@@ -5,7 +5,7 @@ import debounce from 'lodash.debounce'
import {useCallOnce} from '#/lib/once' import {useCallOnce} from '#/lib/once'
import { import {
usePreferencesQuery, usePreferences,
useSetThreadViewPreferencesMutation, useSetThreadViewPreferencesMutation,
} from '#/state/queries/preferences' } from '#/state/queries/preferences'
import {type ThreadViewPreferences} from '#/state/queries/preferences/types' import {type ThreadViewPreferences} from '#/state/queries/preferences/types'
@@ -30,7 +30,7 @@ export function useThreadPreferences({
save, save,
}: {save?: boolean} = {}): ThreadPreferences { }: {save?: boolean} = {}): ThreadPreferences {
const ax = useAnalytics() const ax = useAnalytics()
const {data: preferences} = usePreferencesQuery() const preferences = usePreferences()
const serverPrefs = preferences?.threadViewPrefs const serverPrefs = preferences?.threadViewPrefs
const once = useCallOnce() const once = useCallOnce()
@@ -6,7 +6,7 @@ import {
} from '#/lib/api/feed/utils' } from '#/lib/api/feed/utils'
import {getContentLanguages} from '#/state/preferences/languages' import {getContentLanguages} from '#/state/preferences/languages'
import {STALE} from '#/state/queries' import {STALE} from '#/state/queries'
import {usePreferencesQuery} from '#/state/queries/preferences' import {usePreferences} from '#/state/queries/preferences'
import {useAgent} from '#/state/session' import {useAgent} from '#/state/session'
export const DEFAULT_LIMIT = 15 export const DEFAULT_LIMIT = 15
@@ -15,7 +15,7 @@ export const createGetSuggestedFeedsQueryKey = () => ['suggested-feeds']
export function useGetSuggestedFeedsQuery({enabled}: {enabled?: boolean}) { export function useGetSuggestedFeedsQuery({enabled}: {enabled?: boolean}) {
const agent = useAgent() const agent = useAgent()
const {data: preferences} = usePreferencesQuery() const preferences = usePreferences()
const savedFeeds = preferences?.savedFeeds const savedFeeds = preferences?.savedFeeds
return useQuery({ return useQuery({
@@ -8,7 +8,7 @@ import {createBskyTopicsHeader} from '#/lib/api/feed/utils'
import {logger} from '#/logger' import {logger} from '#/logger'
import {getContentLanguages} from '#/state/preferences/languages' import {getContentLanguages} from '#/state/preferences/languages'
import {STALE} from '#/state/queries' import {STALE} from '#/state/queries'
import {usePreferencesQuery} from '#/state/queries/preferences' import {usePreferences} from '#/state/queries/preferences'
import {useAgent} from '#/state/session' import {useAgent} from '#/state/session'
export type QueryProps = { export type QueryProps = {
@@ -31,7 +31,7 @@ export const createGetSuggestedOnboardingUsersQueryKey = (
export function useGetSuggestedOnboardingUsersQuery(props: QueryProps) { export function useGetSuggestedOnboardingUsersQuery(props: QueryProps) {
const agent = useAgent() const agent = useAgent()
const {data: preferences} = usePreferencesQuery() const preferences = usePreferences()
return useQuery({ return useQuery({
enabled: !!preferences && props.enabled !== false, enabled: !!preferences && props.enabled !== false,
@@ -11,7 +11,7 @@ import {
import {logger} from '#/logger' import {logger} from '#/logger'
import {getContentLanguages} from '#/state/preferences/languages' import {getContentLanguages} from '#/state/preferences/languages'
import {STALE} from '#/state/queries' import {STALE} from '#/state/queries'
import {usePreferencesQuery} from '#/state/queries/preferences' import {usePreferences} from '#/state/queries/preferences'
import {useAgent} from '#/state/session' import {useAgent} from '#/state/session'
export type QueryProps = { export type QueryProps = {
@@ -29,7 +29,7 @@ export const createGetSuggestedUsersQueryKey = (props: QueryProps) => [
export function useGetSuggestedUsersQuery(props: QueryProps) { export function useGetSuggestedUsersQuery(props: QueryProps) {
const agent = useAgent() const agent = useAgent()
const {data: preferences} = usePreferencesQuery() const preferences = usePreferences()
return useQuery({ return useQuery({
enabled: !!preferences && props.enabled !== false, enabled: !!preferences && props.enabled !== false,
@@ -8,7 +8,7 @@ import {
} from '#/lib/api/feed/utils' } from '#/lib/api/feed/utils'
import {getContentLanguages} from '#/state/preferences/languages' import {getContentLanguages} from '#/state/preferences/languages'
import {STALE} from '#/state/queries' import {STALE} from '#/state/queries'
import {usePreferencesQuery} from '#/state/queries/preferences' import {usePreferences} from '#/state/queries/preferences'
import {useAgent} from '#/state/session' import {useAgent} from '#/state/session'
export const DEFAULT_LIMIT = 5 export const DEFAULT_LIMIT = 5
@@ -17,7 +17,7 @@ export const createGetTrendsQueryKey = () => ['trends']
export function useGetTrendsQuery() { export function useGetTrendsQuery() {
const agent = useAgent() const agent = useAgent()
const {data: preferences} = usePreferencesQuery() const preferences = usePreferences()
const mutedWords = useMemo(() => { const mutedWords = useMemo(() => {
return preferences?.moderationPrefs?.mutedWords || [] return preferences?.moderationPrefs?.mutedWords || []
}, [preferences?.moderationPrefs]) }, [preferences?.moderationPrefs])
@@ -3,7 +3,7 @@ import {type AppBskyUnspeccedDefs, hasMutedWord} from '@atproto/api'
import {useQuery} from '@tanstack/react-query' import {useQuery} from '@tanstack/react-query'
import {STALE} from '#/state/queries' import {STALE} from '#/state/queries'
import {usePreferencesQuery} from '#/state/queries/preferences' import {usePreferences} from '#/state/queries/preferences'
import {useAgent} from '#/state/session' import {useAgent} from '#/state/session'
export type TrendingTopic = AppBskyUnspeccedDefs.TrendingTopic export type TrendingTopic = AppBskyUnspeccedDefs.TrendingTopic
@@ -28,7 +28,7 @@ export const trendingTopicsQueryKey = ['trending-topics']
export function useTrendingTopics() { export function useTrendingTopics() {
const agent = useAgent() const agent = useAgent()
const {data: preferences} = usePreferencesQuery() const preferences = usePreferences()
const mutedWords = useMemo( const mutedWords = useMemo(
() => preferences?.moderationPrefs?.mutedWords ?? [], () => preferences?.moderationPrefs?.mutedWords ?? [],
[preferences?.moderationPrefs?.mutedWords], [preferences?.moderationPrefs?.mutedWords],
@@ -6,7 +6,7 @@ import {
} from '#/lib/api/feed/utils' } from '#/lib/api/feed/utils'
import {getContentLanguages} from '#/state/preferences/languages' import {getContentLanguages} from '#/state/preferences/languages'
import {STALE} from '#/state/queries' import {STALE} from '#/state/queries'
import {usePreferencesQuery} from '#/state/queries/preferences' import {usePreferences} from '#/state/queries/preferences'
import {useAgent} from '#/state/session' import {useAgent} from '#/state/session'
export const createOnboardingSuggestedStarterPacksQueryKey = ( export const createOnboardingSuggestedStarterPacksQueryKey = (
@@ -21,7 +21,7 @@ export function useOnboardingSuggestedStarterPacksQuery({
overrideInterests?: string[] overrideInterests?: string[]
}) { }) {
const agent = useAgent() const agent = useAgent()
const {data: preferences} = usePreferencesQuery() const preferences = usePreferences()
const contentLangs = getContentLanguages().join(',') const contentLangs = getContentLanguages().join(',')
return useQuery({ return useQuery({
@@ -6,7 +6,7 @@ import {
} from '#/lib/api/feed/utils' } from '#/lib/api/feed/utils'
import {getContentLanguages} from '#/state/preferences/languages' import {getContentLanguages} from '#/state/preferences/languages'
import {STALE} from '#/state/queries' import {STALE} from '#/state/queries'
import {usePreferencesQuery} from '#/state/queries/preferences' import {usePreferences} from '#/state/queries/preferences'
import {useAgent} from '#/state/session' import {useAgent} from '#/state/session'
export const createSuggestedStarterPacksQueryKey = (interests?: string[]) => [ export const createSuggestedStarterPacksQueryKey = (interests?: string[]) => [
@@ -22,7 +22,7 @@ export function useSuggestedStarterPacksQuery({
overrideInterests?: string[] overrideInterests?: string[]
}) { }) {
const agent = useAgent() const agent = useAgent()
const {data: preferences} = usePreferencesQuery() const preferences = usePreferences()
const contentLangs = getContentLanguages().join(',') const contentLangs = getContentLanguages().join(',')
return useQuery({ return useQuery({
+2 -2
View File
@@ -8,7 +8,7 @@ import {
} from '#/components/ProgressGuide/Toast' } from '#/components/ProgressGuide/Toast'
import {useAnalytics} from '#/analytics' import {useAnalytics} from '#/analytics'
import { import {
usePreferencesQuery, usePreferences,
useSetActiveProgressGuideMutation, useSetActiveProgressGuideMutation,
} from '../queries/preferences' } from '../queries/preferences'
@@ -73,7 +73,7 @@ export function useProgressGuideControls() {
export function Provider({children}: React.PropsWithChildren<{}>) { export function Provider({children}: React.PropsWithChildren<{}>) {
const ax = useAnalytics() const ax = useAnalytics()
const {_} = useLingui() const {_} = useLingui()
const {data: preferences} = usePreferencesQuery() const preferences = usePreferences()
const {mutateAsync, variables, isPending} = const {mutateAsync, variables, isPending} =
useSetActiveProgressGuideMutation() useSetActiveProgressGuideMutation()
+2 -2
View File
@@ -95,7 +95,7 @@ import {
useLanguagePrefs, useLanguagePrefs,
useLanguagePrefsApi, useLanguagePrefsApi,
} from '#/state/preferences/languages' } from '#/state/preferences/languages'
import {usePreferencesQuery} from '#/state/queries/preferences' import {usePreferences} from '#/state/queries/preferences'
import {useProfileQuery} from '#/state/queries/profile' import {useProfileQuery} from '#/state/queries/profile'
import {type Gif} from '#/state/queries/tenor' import {type Gif} from '#/state/queries/tenor'
import {useAgent, useSession} from '#/state/session' import {useAgent, useSession} from '#/state/session'
@@ -213,7 +213,7 @@ export const ComposePost = ({
const {mutate: cleanupPublishedDraft} = useCleanupPublishedDraftMutation() const {mutate: cleanupPublishedDraft} = useCleanupPublishedDraftMutation()
const {closeAllDialogs} = useDialogStateControlContext() const {closeAllDialogs} = useDialogStateControlContext()
const {closeAllModals} = useModalControls() const {closeAllModals} = useModalControls()
const {data: preferences} = usePreferencesQuery() const preferences = usePreferences()
const navigation = useNavigation<NavigationProp>() const navigation = useNavigation<NavigationProp>()
const [isKeyboardVisible] = useIsKeyboardVisible({iosUseWillEvents: true}) const [isKeyboardVisible] = useIsKeyboardVisible({iosUseWillEvents: true})
@@ -11,7 +11,7 @@ import {isNetworkError} from '#/lib/strings/errors'
import {logger} from '#/logger' import {logger} from '#/logger'
import {usePostInteractionSettingsMutation} from '#/state/queries/post-interaction-settings' import {usePostInteractionSettingsMutation} from '#/state/queries/post-interaction-settings'
import {createPostgateRecord} from '#/state/queries/postgate/util' import {createPostgateRecord} from '#/state/queries/postgate/util'
import {usePreferencesQuery} from '#/state/queries/preferences' import {usePreferences} from '#/state/queries/preferences'
import { import {
type ThreadgateAllowUISetting, type ThreadgateAllowUISetting,
threadgateAllowUISettingToAllowRecordValue, threadgateAllowUISettingToAllowRecordValue,
@@ -65,7 +65,7 @@ export function ThreadgateBtn({
setShowTooltip(false) setShowTooltip(false)
} }
const {data: preferences} = usePreferencesQuery() const preferences = usePreferences()
const [persist, setPersist] = useState(false) const [persist, setPersist] = useState(false)
const onPress = () => { const onPress = () => {
+3 -3
View File
@@ -20,8 +20,8 @@ import {useQueryClient} from '@tanstack/react-query'
import {cleanError} from '#/lib/strings/errors' import {cleanError} from '#/lib/strings/errors'
import {logger} from '#/logger' import {logger} from '#/logger'
import {usePreferencesQuery} from '#/state/queries/preferences' import {usePreferences} from '#/state/queries/preferences'
import {RQKEY, useProfileFeedgensQuery} from '#/state/queries/profile-feedgens' import {RQKEY, useProfileFeedgens} from '#/state/queries/profile-feedgens'
import {useSession} from '#/state/session' import {useSession} from '#/state/session'
import {EmptyState} from '#/view/com/util/EmptyState' import {EmptyState} from '#/view/com/util/EmptyState'
import {ErrorMessage} from '#/view/com/util/error/ErrorMessage' import {ErrorMessage} from '#/view/com/util/error/ErrorMessage'
@@ -80,7 +80,7 @@ export function ProfileFeedgens({
refetch, refetch,
} = useProfileFeedgensQuery(did, opts) } = useProfileFeedgensQuery(did, opts)
const isEmpty = !isPending && !data?.pages[0]?.feeds.length const isEmpty = !isPending && !data?.pages[0]?.feeds.length
const {data: preferences} = usePreferencesQuery() const preferences = usePreferences()
const navigation = useNavigation() const navigation = useNavigation()
const {currentAccount} = useSession() const {currentAccount} = useSession()
const isSelf = currentAccount?.did === did const isSelf = currentAccount?.did === did
+3 -3
View File
@@ -20,8 +20,8 @@ import {useQueryClient} from '@tanstack/react-query'
import {cleanError} from '#/lib/strings/errors' import {cleanError} from '#/lib/strings/errors'
import {logger} from '#/logger' import {logger} from '#/logger'
import {usePreferencesQuery} from '#/state/queries/preferences' import {usePreferences} from '#/state/queries/preferences'
import {RQKEY, useProfileListsQuery} from '#/state/queries/profile-lists' import {RQKEY, useProfileListsQuerry} from '#/state/queries/profile-lists'
import {useSession} from '#/state/session' import {useSession} from '#/state/session'
import {EmptyState} from '#/view/com/util/EmptyState' import {EmptyState} from '#/view/com/util/EmptyState'
import {ErrorMessage} from '#/view/com/util/error/ErrorMessage' import {ErrorMessage} from '#/view/com/util/error/ErrorMessage'
@@ -80,7 +80,7 @@ export function ProfileLists({
refetch, refetch,
} = useProfileListsQuery(did, opts) } = useProfileListsQuery(did, opts)
const isEmpty = !isPending && !data?.pages[0]?.lists.length const isEmpty = !isPending && !data?.pages[0]?.lists.length
const {data: preferences} = usePreferencesQuery() const preferences = usePreferences()
const navigation = useNavigation() const navigation = useNavigation()
const {currentAccount} = useSession() const {currentAccount} = useSession()
const isSelf = currentAccount?.did === did const isSelf = currentAccount?.did === did
+2 -2
View File
@@ -7,7 +7,7 @@ import {Trans} from '@lingui/react/macro'
import {PROD_DEFAULT_FEED} from '#/lib/constants' import {PROD_DEFAULT_FEED} from '#/lib/constants'
import {logger} from '#/logger' import {logger} from '#/logger'
import { import {
usePreferencesQuery, usePreferences,
useRemoveFeedMutation, useRemoveFeedMutation,
useReplaceForYouWithDiscoverFeedMutation, useReplaceForYouWithDiscoverFeedMutation,
} from '#/state/queries/preferences' } from '#/state/queries/preferences'
@@ -23,7 +23,7 @@ export function FeedShutdownMsg({feedUri}: {feedUri: string}) {
const t = useTheme() const t = useTheme()
const {_} = useLingui() const {_} = useLingui()
const setSelectedFeed = useSetSelectedFeed() const setSelectedFeed = useSetSelectedFeed()
const {data: preferences} = usePreferencesQuery() const preferences = usePreferences()
const {mutateAsync: removeFeed, isPending: isRemovePending} = const {mutateAsync: removeFeed, isPending: isRemovePending} =
useRemoveFeedMutation() useRemoveFeedMutation()
const {mutateAsync: replaceFeedWithDiscover, isPending: isReplacePending} = const {mutateAsync: replaceFeedWithDiscover, isPending: isReplacePending} =
+1 -5
View File
@@ -88,11 +88,7 @@ let ProfileMenu = ({
const {canGoLive} = useLiveNowConfig() const {canGoLive} = useLiveNowConfig()
const status = useActorStatus(profile) const status = useActorStatus(profile)
const statusNudge = useNux(Nux.LiveNowBetaNudge) const statusNudge = useNux(Nux.LiveNowBetaNudge)
const statusNudgeActive = const statusNudgeActive = isSelf && canGoLive && !statusNudge.nux?.completed
isSelf &&
canGoLive &&
statusNudge.status === 'ready' &&
!statusNudge.nux?.completed
const {mutate: saveNux} = useSaveNux() const {mutate: saveNux} = useSaveNux()
const [queueMute, queueUnmute] = useProfileMuteMutationQueue(profile) const [queueMute, queueUnmute] = useProfileMuteMutationQueue(profile)
+2 -2
View File
@@ -17,7 +17,7 @@ import {
usePinnedFeedsInfos, usePinnedFeedsInfos,
} from '#/state/queries/feed' } from '#/state/queries/feed'
import {type FeedDescriptor, type FeedParams} from '#/state/queries/post-feed' import {type FeedDescriptor, type FeedParams} from '#/state/queries/post-feed'
import {usePreferencesQuery} from '#/state/queries/preferences' import {usePreferences} from '#/state/queries/preferences'
import {type UsePreferencesQueryResponse} from '#/state/queries/preferences/types' import {type UsePreferencesQueryResponse} from '#/state/queries/preferences/types'
import {useSession} from '#/state/session' import {useSession} from '#/state/session'
import {useSetMinimalShellMode} from '#/state/shell' import {useSetMinimalShellMode} from '#/state/shell'
@@ -42,7 +42,7 @@ import {useDemoMode} from '#/storage/hooks/demo-mode'
type Props = NativeStackScreenProps<HomeTabNavigatorParams, 'Home' | 'Start'> type Props = NativeStackScreenProps<HomeTabNavigatorParams, 'Home' | 'Start'>
export function HomeScreen(props: Props) { export function HomeScreen(props: Props) {
const {setShowLoggedOut} = useLoggedOutViewControls() const {setShowLoggedOut} = useLoggedOutViewControls()
const {data: preferences} = usePreferencesQuery() const preferences = usePreferences()
const {currentAccount} = useSession() const {currentAccount} = useSession()
const {data: pinnedFeedInfos, isLoading: isPinnedFeedsLoading} = const {data: pinnedFeedInfos, isLoading: isPinnedFeedsLoading} =
usePinnedFeedsInfos() usePinnedFeedsInfos()