From 0995e81b58925139dc2a16f98c613fcf2bba84d5 Mon Sep 17 00:00:00 2001 From: Eric Bailey Date: Fri, 18 Jul 2025 14:21:23 -0500 Subject: Age assurance tweaks (#8671) * Refetch state while in pending status * Add success state to redirect, just have user close, nicer experience * Stop refetching after pending --- .../ageAssurance/AgeAssuranceRedirectDialog.tsx | 63 +++++++++++++++++++--- src/state/ageAssurance/index.tsx | 22 +++++++- 2 files changed, 78 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/components/ageAssurance/AgeAssuranceRedirectDialog.tsx b/src/components/ageAssurance/AgeAssuranceRedirectDialog.tsx index ff2e0bfd0..b1c287e1b 100644 --- a/src/components/ageAssurance/AgeAssuranceRedirectDialog.tsx +++ b/src/components/ageAssurance/AgeAssuranceRedirectDialog.tsx @@ -14,6 +14,7 @@ import {AgeAssuranceBadge} from '#/components/ageAssurance/AgeAssuranceBadge' import {Button, ButtonText} from '#/components/Button' import * as Dialog from '#/components/Dialog' import {useGlobalDialogsControlContext} from '#/components/dialogs/Context' +import {CheckThick_Stroke2_Corner0_Rounded as SuccessIcon} from '#/components/icons/Check' import {CircleInfo_Stroke2_Corner0_Rounded as ErrorIcon} from '#/components/icons/CircleInfo' import {Loader} from '#/components/Loader' import {Text} from '#/components/Typography' @@ -66,7 +67,7 @@ export function AgeAssuranceRedirectDialog() { // Dialog.useAutoOpen(control.control, 3e3) return ( - + control.clear()}> { @@ -125,8 +127,7 @@ export function Inner({}: {optimisticState?: AgeAssuranceRedirectDialogState}) { // success! update state await refreshAgeAssuranceState() - control.clear() - control.control.close() + setSuccess(true) logger.metric('ageAssurance:redirectDialogSuccess', {}) }) @@ -143,6 +144,55 @@ export function Inner({}: {optimisticState?: AgeAssuranceRedirectDialogState}) { } }, [agent, control, refreshAgeAssuranceState]) + if (success) { + return ( + <> + + + + + + + Success + + + + + + We've confirmed your age assurance status. You can now close this + dialog. + + + + {isNative && ( + + + + )} + + + + + ) + } + return ( <> @@ -175,8 +225,8 @@ export function Inner({}: {optimisticState?: AgeAssuranceRedirectDialogState}) { ) : ( - We're confirming your status with our servers. This dialog should - close in a few seconds. + We're confirming your age assurance status with our servers. This + should only take a few seconds. )} @@ -187,7 +237,8 @@ export function Inner({}: {optimisticState?: AgeAssuranceRedirectDialogState}) { label={_(msg`Close`)} size="large" variant="solid" - color="secondary"> + color="secondary" + onPress={() => control.control.close()}> Close diff --git a/src/state/ageAssurance/index.tsx b/src/state/ageAssurance/index.tsx index eded74773..3451b1139 100644 --- a/src/state/ageAssurance/index.tsx +++ b/src/state/ageAssurance/index.tsx @@ -1,4 +1,4 @@ -import {createContext, useContext, useMemo} from 'react' +import {createContext, useContext, useMemo, useState} from 'react' import {type AppBskyUnspeccedDefs} from '@atproto/api' import {useQuery} from '@tanstack/react-query' @@ -46,6 +46,7 @@ export function Provider({children}: {children: React.ReactNode}) { const {geolocation} = useGeolocation() const isAgeAssuranceEnabled = useIsAgeAssuranceEnabled() const getAndRegisterPushToken = useGetAndRegisterPushToken() + const [refetchWhilePending, setRefetchWhilePending] = useState(false) const {data, isFetched, refetch} = useQuery({ /** @@ -56,6 +57,7 @@ export function Provider({children}: {children: React.ReactNode}) { * However, it only needs to run if AA is enabled. */ enabled: isAgeAssuranceEnabled, + refetchOnWindowFocus: refetchWhilePending, queryKey: createAgeAssuranceQueryKey(agent.session?.did ?? 'never'), async queryFn() { if (!agent.session) return null @@ -109,6 +111,24 @@ export function Provider({children}: {children: React.ReactNode}) { return ctx }, [isFetched, data, isAgeAssuranceEnabled]) + if ( + !!ageAssuranceContext.lastInitiatedAt && + ageAssuranceContext.status === 'pending' && + !refetchWhilePending + ) { + /* + * If we have a pending state, we want to refetch on window focus to ensure + * that we get the latest state when the user returns to the app. + */ + setRefetchWhilePending(true) + } else if ( + !!ageAssuranceContext.lastInitiatedAt && + ageAssuranceContext.status !== 'pending' && + refetchWhilePending + ) { + setRefetchWhilePending(false) + } + const ageAssuranceAPIContext = useMemo( () => ({ refetch, -- cgit 1.4.1