diff --git a/src/App.native.tsx b/src/App.native.tsx
index 49fd13529e..29e359c48c 100644
--- a/src/App.native.tsx
+++ b/src/App.native.tsx
@@ -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}>
-
-
-
- {/* LabelDefsProvider MUST come before ModerationOptsProvider */}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+ {/* LabelDefsProvider MUST come before ModerationOptsProvider */}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -216,32 +213,30 @@ function App() {
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/App.web.tsx b/src/App.web.tsx
index 487721dd40..ef60cb8a08 100644
--- a/src/App.web.tsx
+++ b/src/App.web.tsx
@@ -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}>
-
-
-
- {/* LabelDefsProvider MUST come before ModerationOptsProvider */}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+ {/* LabelDefsProvider MUST come before ModerationOptsProvider */}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -192,27 +191,25 @@ function App() {
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/components/ageAssurance/IsAgeRestricted.tsx b/src/components/ageAssurance/IsAgeRestricted.tsx
index 90e0340127..4d0638df86 100644
--- a/src/components/ageAssurance/IsAgeRestricted.tsx
+++ b/src/components/ageAssurance/IsAgeRestricted.tsx
@@ -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 = {
diff --git a/src/state/ageAssurance.tsx b/src/state/ageAssurance.tsx
index 7724438b57..e9fadb0e2d 100644
--- a/src/state/ageAssurance.tsx
+++ b/src/state/ageAssurance.tsx
@@ -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
+ refetch: QueryObserverBaseResult['refetch']
}
const AgeAssuranceContext = createContext({
+ isLoaded: false,
isAgeRestricted: false,
status: 'unknown',
lastInitiatedAt: undefined,
@@ -48,42 +59,49 @@ const AgeAssuranceContext = createContext({
})
const AgeAssuranceAPIContext = createContext({
- 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({
- 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(() => {
- 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(
() => ({
- refresh,
+ refetch,
}),
- [refresh],
+ [refetch],
)
return (