Move provider inside query provider

This commit is contained in:
Eric Bailey
2025-06-26 18:24:32 -05:00
parent 9144f61208
commit 13daf12c0c
4 changed files with 181 additions and 171 deletions
+69 -74
View File
@@ -26,10 +26,7 @@ import I18nProvider from '#/locale/i18nProvider'
import {logger} from '#/logger'
import {isAndroid, isIOS} from '#/platform/detection'
import {Provider as A11yProvider} from '#/state/a11y'
import {
Provider as AgeAssuranceProvider,
useAgeAssuranceAPIContext,
} from '#/state/ageAssurance'
import {Provider as AgeAssuranceProvider} from '#/state/ageAssurance'
import {Provider as MutedThreadsProvider} from '#/state/cache/thread-mutes'
import {Provider as DialogStateProvider} from '#/state/dialogs'
import {listenSessionDropped} from '#/state/events'
@@ -100,7 +97,6 @@ function InnerApp() {
const theme = useColorModeTheme()
const {_} = useLingui()
const hasCheckedReferrer = useStarterPackEntry()
const {refresh: refreshAgeAssurance} = useAgeAssuranceAPIContext()
// init
useEffect(() => {
@@ -108,7 +104,6 @@ function InnerApp() {
try {
if (account) {
await resumeSession(account)
await refreshAgeAssurance()
} else {
await tryFetchGates(undefined, 'prefer-fresh-gates')
}
@@ -120,7 +115,7 @@ function InnerApp() {
}
const account = readLastActiveAccount()
onLaunch(account)
}, [resumeSession, refreshAgeAssurance])
}, [resumeSession])
useEffect(() => {
return listenSessionDropped(() => {
@@ -142,47 +137,49 @@ function InnerApp() {
// Resets the entire tree below when it changes:
key={currentAccount?.did}>
<QueryProvider currentDid={currentAccount?.did}>
<ComposerProvider>
<StatsigProvider>
<MessagesProvider>
{/* LabelDefsProvider MUST come before ModerationOptsProvider */}
<LabelDefsProvider>
<ModerationOptsProvider>
<LoggedOutViewProvider>
<SelectedFeedProvider>
<HiddenRepliesProvider>
<HomeBadgeProvider>
<UnreadNotifsProvider>
<BackgroundNotificationPreferencesProvider>
<MutedThreadsProvider>
<ProgressGuideProvider>
<ServiceAccountManager>
<HideBottomBarBorderProvider>
<GestureHandlerRootView
style={s.h100pct}>
<GlobalGestureEventsProvider>
<IntentDialogProvider>
<TestCtrls />
<Shell />
<NuxDialogs />
</IntentDialogProvider>
</GlobalGestureEventsProvider>
</GestureHandlerRootView>
</HideBottomBarBorderProvider>
</ServiceAccountManager>
</ProgressGuideProvider>
</MutedThreadsProvider>
</BackgroundNotificationPreferencesProvider>
</UnreadNotifsProvider>
</HomeBadgeProvider>
</HiddenRepliesProvider>
</SelectedFeedProvider>
</LoggedOutViewProvider>
</ModerationOptsProvider>
</LabelDefsProvider>
</MessagesProvider>
</StatsigProvider>
</ComposerProvider>
<AgeAssuranceProvider>
<ComposerProvider>
<StatsigProvider>
<MessagesProvider>
{/* LabelDefsProvider MUST come before ModerationOptsProvider */}
<LabelDefsProvider>
<ModerationOptsProvider>
<LoggedOutViewProvider>
<SelectedFeedProvider>
<HiddenRepliesProvider>
<HomeBadgeProvider>
<UnreadNotifsProvider>
<BackgroundNotificationPreferencesProvider>
<MutedThreadsProvider>
<ProgressGuideProvider>
<ServiceAccountManager>
<HideBottomBarBorderProvider>
<GestureHandlerRootView
style={s.h100pct}>
<GlobalGestureEventsProvider>
<IntentDialogProvider>
<TestCtrls />
<Shell />
<NuxDialogs />
</IntentDialogProvider>
</GlobalGestureEventsProvider>
</GestureHandlerRootView>
</HideBottomBarBorderProvider>
</ServiceAccountManager>
</ProgressGuideProvider>
</MutedThreadsProvider>
</BackgroundNotificationPreferencesProvider>
</UnreadNotifsProvider>
</HomeBadgeProvider>
</HiddenRepliesProvider>
</SelectedFeedProvider>
</LoggedOutViewProvider>
</ModerationOptsProvider>
</LabelDefsProvider>
</MessagesProvider>
</StatsigProvider>
</ComposerProvider>
</AgeAssuranceProvider>
</QueryProvider>
</React.Fragment>
</VideoVolumeProvider>
@@ -216,32 +213,30 @@ function App() {
<A11yProvider>
<KeyboardControllerProvider>
<SessionProvider>
<AgeAssuranceProvider>
<PrefsStateProvider>
<I18nProvider>
<ShellStateProvider>
<InvitesStateProvider>
<ModalStateProvider>
<DialogStateProvider>
<LightboxStateProvider>
<PortalProvider>
<BottomSheetProvider>
<StarterPackProvider>
<SafeAreaProvider
initialMetrics={initialWindowMetrics}>
<InnerApp />
</SafeAreaProvider>
</StarterPackProvider>
</BottomSheetProvider>
</PortalProvider>
</LightboxStateProvider>
</DialogStateProvider>
</ModalStateProvider>
</InvitesStateProvider>
</ShellStateProvider>
</I18nProvider>
</PrefsStateProvider>
</AgeAssuranceProvider>
<PrefsStateProvider>
<I18nProvider>
<ShellStateProvider>
<InvitesStateProvider>
<ModalStateProvider>
<DialogStateProvider>
<LightboxStateProvider>
<PortalProvider>
<BottomSheetProvider>
<StarterPackProvider>
<SafeAreaProvider
initialMetrics={initialWindowMetrics}>
<InnerApp />
</SafeAreaProvider>
</StarterPackProvider>
</BottomSheetProvider>
</PortalProvider>
</LightboxStateProvider>
</DialogStateProvider>
</ModalStateProvider>
</InvitesStateProvider>
</ShellStateProvider>
</I18nProvider>
</PrefsStateProvider>
</SessionProvider>
</KeyboardControllerProvider>
</A11yProvider>
+59 -62
View File
@@ -17,7 +17,6 @@ import {logger} from '#/logger'
import {Provider as A11yProvider} from '#/state/a11y'
import {
Provider as AgeAssuranceProvider,
useAgeAssuranceAPIContext,
} from '#/state/ageAssurance'
import {Provider as MutedThreadsProvider} from '#/state/cache/thread-mutes'
import {Provider as DialogStateProvider} from '#/state/dialogs'
@@ -79,7 +78,6 @@ function InnerApp() {
const theme = useColorModeTheme()
const {_} = useLingui()
const hasCheckedReferrer = useStarterPackEntry()
const {refresh: refreshAgeAssurance} = useAgeAssuranceAPIContext()
// init
useEffect(() => {
@@ -87,7 +85,6 @@ function InnerApp() {
try {
if (account) {
await resumeSession(account)
await refreshAgeAssurance()
}
} catch (e) {
logger.error(`session: resumeSession failed`, {message: e})
@@ -97,7 +94,7 @@ function InnerApp() {
}
const account = readLastActiveAccount()
onLaunch(account)
}, [resumeSession, refreshAgeAssurance])
}, [resumeSession])
useEffect(() => {
return listenSessionDropped(() => {
@@ -122,43 +119,45 @@ function InnerApp() {
// Resets the entire tree below when it changes:
key={currentAccount?.did}>
<QueryProvider currentDid={currentAccount?.did}>
<ComposerProvider>
<StatsigProvider>
<MessagesProvider>
{/* LabelDefsProvider MUST come before ModerationOptsProvider */}
<LabelDefsProvider>
<ModerationOptsProvider>
<LoggedOutViewProvider>
<SelectedFeedProvider>
<HiddenRepliesProvider>
<HomeBadgeProvider>
<UnreadNotifsProvider>
<BackgroundNotificationPreferencesProvider>
<MutedThreadsProvider>
<SafeAreaProvider>
<ProgressGuideProvider>
<ServiceConfigProvider>
<HideBottomBarBorderProvider>
<IntentDialogProvider>
<Shell />
<NuxDialogs />
</IntentDialogProvider>
</HideBottomBarBorderProvider>
</ServiceConfigProvider>
</ProgressGuideProvider>
</SafeAreaProvider>
</MutedThreadsProvider>
</BackgroundNotificationPreferencesProvider>
</UnreadNotifsProvider>
</HomeBadgeProvider>
</HiddenRepliesProvider>
</SelectedFeedProvider>
</LoggedOutViewProvider>
</ModerationOptsProvider>
</LabelDefsProvider>
</MessagesProvider>
</StatsigProvider>
</ComposerProvider>
<AgeAssuranceProvider>
<ComposerProvider>
<StatsigProvider>
<MessagesProvider>
{/* LabelDefsProvider MUST come before ModerationOptsProvider */}
<LabelDefsProvider>
<ModerationOptsProvider>
<LoggedOutViewProvider>
<SelectedFeedProvider>
<HiddenRepliesProvider>
<HomeBadgeProvider>
<UnreadNotifsProvider>
<BackgroundNotificationPreferencesProvider>
<MutedThreadsProvider>
<SafeAreaProvider>
<ProgressGuideProvider>
<ServiceConfigProvider>
<HideBottomBarBorderProvider>
<IntentDialogProvider>
<Shell />
<NuxDialogs />
</IntentDialogProvider>
</HideBottomBarBorderProvider>
</ServiceConfigProvider>
</ProgressGuideProvider>
</SafeAreaProvider>
</MutedThreadsProvider>
</BackgroundNotificationPreferencesProvider>
</UnreadNotifsProvider>
</HomeBadgeProvider>
</HiddenRepliesProvider>
</SelectedFeedProvider>
</LoggedOutViewProvider>
</ModerationOptsProvider>
</LabelDefsProvider>
</MessagesProvider>
</StatsigProvider>
</ComposerProvider>
</AgeAssuranceProvider>
</QueryProvider>
<ToastContainer />
</React.Fragment>
@@ -192,27 +191,25 @@ function App() {
<GeolocationProvider>
<A11yProvider>
<SessionProvider>
<AgeAssuranceProvider>
<PrefsStateProvider>
<I18nProvider>
<ShellStateProvider>
<InvitesStateProvider>
<ModalStateProvider>
<DialogStateProvider>
<LightboxStateProvider>
<PortalProvider>
<StarterPackProvider>
<InnerApp />
</StarterPackProvider>
</PortalProvider>
</LightboxStateProvider>
</DialogStateProvider>
</ModalStateProvider>
</InvitesStateProvider>
</ShellStateProvider>
</I18nProvider>
</PrefsStateProvider>
</AgeAssuranceProvider>
<PrefsStateProvider>
<I18nProvider>
<ShellStateProvider>
<InvitesStateProvider>
<ModalStateProvider>
<DialogStateProvider>
<LightboxStateProvider>
<PortalProvider>
<StarterPackProvider>
<InnerApp />
</StarterPackProvider>
</PortalProvider>
</LightboxStateProvider>
</DialogStateProvider>
</ModalStateProvider>
</InvitesStateProvider>
</ShellStateProvider>
</I18nProvider>
</PrefsStateProvider>
</SessionProvider>
</A11yProvider>
</GeolocationProvider>
@@ -1,13 +1,13 @@
import {useAgeAssuranceContext} from '#/state/ageAssurance'
export function True({children}: {children: React.ReactNode}) {
const {isAgeRestricted} = useAgeAssuranceContext()
return isAgeRestricted ? children : null
const {isLoaded, isAgeRestricted} = useAgeAssuranceContext()
return isLoaded && isAgeRestricted ? children : null
}
export function False({children}: {children: React.ReactNode}) {
const {isAgeRestricted} = useAgeAssuranceContext()
return !isAgeRestricted ? children : null
const {isLoaded, isAgeRestricted} = useAgeAssuranceContext()
return isLoaded && !isAgeRestricted ? children : null
}
export const IsAgeRestricted = {
+49 -31
View File
@@ -1,12 +1,21 @@
import {createContext, useCallback, useContext, useMemo, useState} from 'react'
import {createContext, useContext, useMemo} from 'react'
import {
// useQueryClient,
type QueryObserverBaseResult,
useQuery,
} from '@tanstack/react-query'
import {wait} from '#/lib/async/wait'
import {isNetworkError} from '#/lib/strings/errors'
import {Logger} from '#/logger'
// import {useAgent} from '#/state/session'
import {useGeolocation} from '#/state/geolocation'
import {useAgent} from '#/state/session'
const logger = Logger.create(Logger.Context.AgeAssurance)
const ageAssuranceQueryKey = ['ageAssurance'] as const
const DEFAULT_AGE_ASSURANCE_STATE: TempAgeAssuranceState = {
status: 'unknown',
}
type TempAgeAssuranceState = {
lastInitiatedAt?: string
@@ -14,6 +23,7 @@ type TempAgeAssuranceState = {
}
export type AgeAssuranceContextType = {
isLoaded: boolean
/**
* Whether the current user is age-restricted based on their geolocation and
* age assurance state retrieved from the server.
@@ -37,10 +47,11 @@ export type AgeAssuranceAPIContextType = {
/**
* Refreshes the age assurance state by fetching it from the server.
*/
refresh: () => Promise<void>
refetch: QueryObserverBaseResult['refetch']
}
const AgeAssuranceContext = createContext<AgeAssuranceContextType>({
isLoaded: false,
isAgeRestricted: false,
status: 'unknown',
lastInitiatedAt: undefined,
@@ -48,42 +59,49 @@ const AgeAssuranceContext = createContext<AgeAssuranceContextType>({
})
const AgeAssuranceAPIContext = createContext<AgeAssuranceAPIContextType>({
refresh: () => Promise.resolve(),
// @ts-ignore
refetch: () => Promise.resolve(),
})
export function Provider({children}: {children: React.ReactNode}) {
// const agent = useAgent()
// const qc = useQueryClient()
const agent = useAgent()
const {geolocation} = useGeolocation()
const [ageAssuranceState, setAgeAssuranceState] =
useState<TempAgeAssuranceState>({
status: 'unknown',
})
const refresh = useCallback(async () => {
try {
const {data} = await wait(
200,
(() => ({
data: {
lastInitiatedAt: undefined,
status: 'unknown',
} as TempAgeAssuranceState,
}))(),
)
const {data, refetch} = useQuery({
queryKey: ageAssuranceQueryKey,
async queryFn() {
try {
const {data} = await wait(
1e3,
(() => ({
data: {
lastInitiatedAt: new Date().toISOString(),
status: 'assured',
} as TempAgeAssuranceState,
}))(),
)
logger.debug(`refresh`, {data})
logger.debug(`fetch`, {
data,
account: agent.session?.did,
})
setAgeAssuranceState(data)
} catch (e) {
if (!isNetworkError(e)) {
logger.error(`ageAssurance: failed to refresh`, {safeMessage: e})
return data
} catch (e) {
if (!isNetworkError(e)) {
logger.error(`ageAssurance: failed to fetch`, {safeMessage: e})
}
return DEFAULT_AGE_ASSURANCE_STATE
}
}
}, [setAgeAssuranceState])
},
})
const ageAssuranceContext = useMemo<AgeAssuranceContextType>(() => {
const {status, lastInitiatedAt} = ageAssuranceState
const {status, lastInitiatedAt} = data || DEFAULT_AGE_ASSURANCE_STATE
const ctx: AgeAssuranceContextType = {
isLoaded: !!data,
status,
lastInitiatedAt,
hasInitiated: !!lastInitiatedAt,
@@ -95,13 +113,13 @@ export function Provider({children}: {children: React.ReactNode}) {
logger.debug(`context`, ctx)
return ctx
}, [geolocation, ageAssuranceState])
}, [geolocation, data])
const ageAssuranceAPIContext = useMemo<AgeAssuranceAPIContextType>(
() => ({
refresh,
refetch,
}),
[refresh],
[refetch],
)
return (