This commit is contained in:
Eric Bailey
2025-06-26 21:54:04 -05:00
parent 7d4923fff4
commit e28af3259c
8 changed files with 57 additions and 59 deletions
+1 -1
View File
@@ -26,7 +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} from '#/state/ageAssurance'
import {Provider as AgeAssuranceProvider} from '#/state/age-assurance'
import {Provider as MutedThreadsProvider} from '#/state/cache/thread-mutes'
import {Provider as DialogStateProvider} from '#/state/dialogs'
import {listenSessionDropped} from '#/state/events'
+1 -3
View File
@@ -15,9 +15,7 @@ import {ThemeProvider} from '#/lib/ThemeContext'
import I18nProvider from '#/locale/i18nProvider'
import {logger} from '#/logger'
import {Provider as A11yProvider} from '#/state/a11y'
import {
Provider as AgeAssuranceProvider,
} from '#/state/ageAssurance'
import {Provider as AgeAssuranceProvider} from '#/state/age-assurance'
import {Provider as MutedThreadsProvider} from '#/state/cache/thread-mutes'
import {Provider as DialogStateProvider} from '#/state/dialogs'
import {listenSessionDropped} from '#/state/events'
@@ -2,7 +2,7 @@ import {View} from 'react-native'
import {msg, Trans} from '@lingui/macro'
import {useLingui} from '@lingui/react'
import {useAgeAssuranceContext} from '#/state/ageAssurance'
import {useAgeAssuranceContext} from '#/state/age-assurance'
import {atoms as a, select, useTheme, type ViewStyleProp} from '#/alf'
import {AgeAssuranceBadge} from '#/components/ageAssurance/AgeAssuranceBadge'
import {
@@ -1,4 +1,4 @@
import {useAgeAssuranceContext} from '#/state/ageAssurance'
import {useAgeAssuranceContext} from '#/state/age-assurance'
export function True({
children,
+1 -1
View File
@@ -8,7 +8,7 @@ import debounce from 'lodash.debounce'
import {PUBLIC_APPVIEW_DID, PUBLIC_STAGING_APPVIEW_DID} from '#/lib/constants'
import {logger as notyLogger} from '#/lib/notifications/util'
import {isNative} from '#/platform/detection'
import {useAgeAssuranceContext} from '#/state/ageAssurance'
import {useAgeAssuranceContext} from '#/state/age-assurance'
import {type SessionAccount, useAgent, useSession} from '#/state/session'
import BackgroundNotificationHandler from '#/../modules/expo-background-notification-handler'
+1 -1
View File
@@ -12,7 +12,7 @@ import {
} from '#/lib/routes/types'
import {logger} from '#/logger'
import {isIOS} from '#/platform/detection'
import {useAgeAssuranceContext} from '#/state/ageAssurance'
import {useAgeAssuranceContext} from '#/state/age-assurance'
import {
useMyLabelersQuery,
usePreferencesQuery,
@@ -1,54 +1,27 @@
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 {
type AgeAssuranceAPIContextType,
type AgeAssuranceContextType,
type AppBskyUnspeccedDefs,
} from '#/state/age-assurance/types'
import {useGeolocation} from '#/state/geolocation'
import {useAgent} from '#/state/session'
const logger = Logger.create(Logger.Context.AgeAssurance)
export const ageAssuranceQueryKeyRoot = 'ageAssurance' as const
export const createAgeAssuranceQueryKey = (did: string) =>
[ageAssuranceQueryKeyRoot, did] as const
const DEFAULT_AGE_ASSURANCE_STATE: TempAgeAssuranceState = {
const createAgeAssuranceQueryKey = (did: string) =>
['ageAssurance', did] as const
const DEFAULT_AGE_ASSURANCE_STATE: AppBskyUnspeccedDefs.AgeAssuranceState = {
lastInitiatedAt: undefined,
status: 'unknown',
}
type TempAgeAssuranceState = {
lastInitiatedAt?: string
status: 'unknown' | 'pending' | 'assured'
}
export type AgeAssuranceContextType = {
isLoaded: boolean
/**
* Whether the current user is age-restricted based on their geolocation and
* age assurance state retrieved from the server.
*/
isAgeRestricted: boolean
isExempt: boolean
/**
* The last time the age assurance state was attempted by the user.
*/
lastInitiatedAt: string | undefined
/**
* Whether the user has initiated an age assurance check.
*/
hasInitiated: boolean
}
export type AgeAssuranceAPIContextType = {
/**
* Refreshes the age assurance state by fetching it from the server.
*/
refetch: QueryObserverBaseResult['refetch']
}
const AgeAssuranceContext = createContext<AgeAssuranceContextType>({
isLoaded: false,
isAgeRestricted: false,
@@ -56,7 +29,6 @@ const AgeAssuranceContext = createContext<AgeAssuranceContextType>({
lastInitiatedAt: undefined,
hasInitiated: false,
})
const AgeAssuranceAPIContext = createContext<AgeAssuranceAPIContextType>({
// @ts-ignore
refetch: () => Promise.resolve(),
@@ -67,7 +39,7 @@ export function Provider({children}: {children: React.ReactNode}) {
const agent = useAgent()
const {geolocation} = useGeolocation()
const {data, refetch} = useQuery({
const {data, isFetched, refetch} = useQuery({
enabled: !!agent.session,
queryKey: createAgeAssuranceQueryKey(agent.session?.did ?? 'never'),
async queryFn() {
@@ -76,9 +48,9 @@ export function Provider({children}: {children: React.ReactNode}) {
1e3,
(() => ({
data: {
lastInitiatedAt: new Date().toISOString(),
lastInitiatedAt: undefined,
status: 'unknown',
} as TempAgeAssuranceState,
} as AppBskyUnspeccedDefs.AgeAssuranceState,
}))(),
)
@@ -92,18 +64,15 @@ export function Provider({children}: {children: React.ReactNode}) {
if (!isNetworkError(e)) {
logger.error(`ageAssurance: failed to fetch`, {safeMessage: e})
}
return DEFAULT_AGE_ASSURANCE_STATE
}
},
})
const ageAssuranceContext = useMemo<AgeAssuranceContextType>(() => {
const isLoaded = Boolean(data)
const isAgeRestrictedGeo = !!geolocation?.isAgeRestrictedGeo
const {status, lastInitiatedAt} = data || DEFAULT_AGE_ASSURANCE_STATE
const ctx: AgeAssuranceContextType = {
isLoaded,
isLoaded: isFetched,
lastInitiatedAt,
hasInitiated: !!lastInitiatedAt,
isExempt: !isAgeRestrictedGeo,
@@ -113,7 +82,7 @@ export function Provider({children}: {children: React.ReactNode}) {
logger.debug(`context`, ctx)
return ctx
}, [geolocation, data])
}, [geolocation, isFetched, data])
const ageAssuranceAPIContext = useMemo<AgeAssuranceAPIContextType>(
() => ({
@@ -131,12 +100,6 @@ export function Provider({children}: {children: React.ReactNode}) {
)
}
/**
* Returns the current age assurance state from context. This data is awaited
* prior to rendering the app, and therefore the data here should be up to date
* and trustworth by the time we're rendering anything inside the `Splash`
* wrapper in the root component files.
*/
export function useAgeAssuranceContext() {
return useContext(AgeAssuranceContext)
}
+37
View File
@@ -0,0 +1,37 @@
import {type QueryObserverBaseResult} from '@tanstack/react-query'
export namespace AppBskyUnspeccedDefs {
export type AgeAssuranceState = {
lastInitiatedAt?: string
status: 'unknown' | 'pending' | 'assured'
}
}
export type AgeAssuranceContextType = {
isLoaded: boolean
/**
* Whether the current user is age-restricted based on their geolocation and
* age assurance state retrieved from the server.
*/
isAgeRestricted: boolean
/**
* Whether the user is exempt from age assurance checks, e.g., due to
* them not being in a region that requires age assurance.
*/
isExempt: boolean
/**
* The last time the age assurance state was attempted by the user.
*/
lastInitiatedAt: string | undefined
/**
* Whether the user has initiated an age assurance check.
*/
hasInitiated: boolean
}
export type AgeAssuranceAPIContextType = {
/**
* Refreshes the age assurance state by fetching it from the server.
*/
refetch: QueryObserverBaseResult['refetch']
}