Pipe through deviceSignals for logical handling

This commit is contained in:
Eric Bailey
2026-07-02 11:07:18 -05:00
parent c3182f9ef7
commit 0456562abf
7 changed files with 44 additions and 40 deletions
+11 -12
View File
@@ -384,13 +384,8 @@ function AccessSection() {
const diff = lastInitiatedAt
? dateDiff(lastInitiatedAt, new Date(), 'down')
: null
const {
onPressVerify,
openKwsDialog,
isVerifyingDevice,
allowsDeviceVerification,
verifyCta,
} = useAgeAssuranceVerificationFlow({initDialogControl: control})
const {onPressVerify, openInitDialog, isVerifying, verifyCta} =
useAgeAssuranceVerificationFlow({initDialogControl: control})
return (
<>
@@ -420,14 +415,18 @@ function AccessSection() {
<Button
label={verifyCta}
size="large"
color={hasInitiated ? 'secondary' : 'primary'}
disabled={isVerifyingDevice}
color={
hasInitiated || aa.flags.hasSharedDeviceSignals
? 'secondary'
: 'primary'
}
disabled={isVerifying}
onPress={() => void onPressVerify()}>
<ButtonIcon icon={isVerifyingDevice ? Loader : ShieldIcon} />
<ButtonIcon icon={isVerifying ? Loader : ShieldIcon} />
<ButtonText>{verifyCta}</ButtonText>
</Button>
{allowsDeviceVerification ? (
{aa.flags.allowsDeviceVerification ? (
<Text
style={[a.text_sm, a.italic, t.atoms.text_contrast_medium]}>
<Trans>
@@ -437,7 +436,7 @@ function AccessSection() {
<SimpleInlineLinkText
label={_(msg`Verify now using KWS`)}
{...createStaticClick(() => {
openKwsDialog()
openInitDialog()
})}>
you can use our trusted partner, KWS
</SimpleInlineLinkText>
+6 -3
View File
@@ -56,6 +56,7 @@ const AgeAssuranceStateContext = createContext<{
isOverRegionMinAccessAge: false,
isOverAppMinAccessAge: false,
allowsDeviceVerification: false,
hasSharedDeviceSignals: false,
},
})
@@ -81,7 +82,7 @@ export function Provider({children}: {children: React.ReactNode}) {
function InnerProvider({children}: {children: React.ReactNode}) {
const agent = useAgent()
const state = useAgeAssuranceState()
const {metadata} = useAgeAssuranceServerDataContext()
const {metadata, deviceSignals} = useAgeAssuranceServerDataContext()
const regionConfig = useAgeAssuranceRegionConfigWithFallback()
const getAndRegisterPushToken = useGetAndRegisterPushToken()
@@ -91,6 +92,7 @@ function InnerProvider({children}: {children: React.ReactNode}) {
state: s,
regionConfig,
metadata,
deviceSignals,
})
if (flags.isAgeRestricted) {
void getAndRegisterPushToken({
@@ -105,7 +107,7 @@ function InnerProvider({children}: {children: React.ReactNode}) {
})
}
},
[agent, getAndRegisterPushToken, regionConfig, metadata],
[agent, getAndRegisterPushToken, regionConfig, metadata, deviceSignals],
)
useOnAgeAssuranceAccessUpdate(handleAccessUpdate)
@@ -120,11 +122,12 @@ function InnerProvider({children}: {children: React.ReactNode}) {
state,
regionConfig,
metadata,
deviceSignals,
}),
}
logger.debug(`useAgeAssurance`, res)
return res
}, [state, metadata, regionConfig])}>
}, [state, metadata, regionConfig, deviceSignals])}>
{children}
</AgeAssuranceStateContext.Provider>
)
+1
View File
@@ -188,6 +188,7 @@ export function unsafeGetAndComputeAgeAssurance({did}: {did: string}) {
state: computed,
regionConfig: region,
metadata,
deviceSignals,
}),
}
}
+1
View File
@@ -56,6 +56,7 @@ export type AgeAssuranceFlags = {
isOverRegionMinAccessAge: boolean
isOverAppMinAccessAge: boolean
allowsDeviceVerification: boolean
hasSharedDeviceSignals: boolean
}
export function parseStatusFromString(raw: string) {
+10 -13
View File
@@ -28,12 +28,10 @@ import {useAnalytics} from '#/analytics'
* prompts the OS age API, persists a sufficient result (region-bound), and
* toasts the outcome; otherwise (or on any missing/failed device response) it
* opens the KWS dialog.
* - `openKwsDialog`: opens the KWS dialog directly (for the inline "use KWS"
* - `openInitDialog`: opens the KWS dialog directly (for the inline "use KWS"
* link), emitting the same metric as the fallback path.
* - `isVerifyingDevice`: true while the OS age prompt is up, for a button
* - `isVerifying`: true while the OS age prompt is up, for a button
* loading state.
* - `allowsDeviceVerification`: whether this region + device supports the
* on-device flow, for CTA/copy branching.
* - `verifyCta`: the localized button label for the current mode.
*/
export function useAgeAssuranceVerificationFlow({
@@ -54,9 +52,9 @@ export function useAgeAssuranceVerificationFlow({
? l`Verify again`
: l`Verify now`
const [isVerifyingDevice, setIsVerifyingDevice] = useState(false)
const [isVerifying, setIsVerifying] = useState(false)
const openKwsDialog = useCallback(() => {
const openInitDialog = useCallback(() => {
initDialogControl.open()
ax.metric('ageAssurance:initDialogOpen', {
hasInitiatedPreviously: hasInitiated,
@@ -84,12 +82,12 @@ export function useAgeAssuranceVerificationFlow({
*/
if (allowsDeviceVerification) {
// Show a loading state while the OS age prompt is up.
setIsVerifyingDevice(true)
setIsVerifying(true)
let signals: AgeRange.AgeRangeResponse | undefined
try {
signals = await getDeviceSignals()
} finally {
setIsVerifyingDevice(false)
setIsVerifying(false)
}
if (signals) {
const {assuredAge} = getAgeAssuranceDataFromDeviceSignals(
@@ -140,11 +138,11 @@ export function useAgeAssuranceVerificationFlow({
)
}
openKwsDialog()
openInitDialog()
}, [
region,
currentAccount?.did,
openKwsDialog,
openInitDialog,
allowsDeviceVerification,
aa,
l,
@@ -152,9 +150,8 @@ export function useAgeAssuranceVerificationFlow({
return {
onPressVerify,
openKwsDialog,
isVerifyingDevice,
allowsDeviceVerification,
openInitDialog,
isVerifying,
verifyCta,
}
}
+4
View File
@@ -266,10 +266,12 @@ export function computeAgeAssuranceFlags({
state,
regionConfig,
metadata,
deviceSignals,
}: {
state: AgeAssuranceState
regionConfig: AppBskyAgeassuranceDefs.ConfigRegion
metadata?: AgeAssuranceMetadata
deviceSignals?: AgeRange.AgeRangeResponse
}): AgeAssuranceFlags {
const isAgeRestricted = state.access !== AgeAssuranceAccess.Full
const chatDisabled = isAgeRestricted
@@ -287,6 +289,7 @@ export function computeAgeAssuranceFlags({
state.access !== AgeAssuranceAccess.Full || isDeclaredUnderAdultAge
const allowsDeviceVerification =
DEVICE_SIGNALS_SUPPORTED && regionAllowsDeviceVerification(regionConfig)
const hasSharedDeviceSignals = deviceSignals?.lowerBound !== undefined
return {
isAgeRestricted,
@@ -298,6 +301,7 @@ export function computeAgeAssuranceFlags({
isOverRegionMinAccessAge,
isOverAppMinAccessAge,
allowsDeviceVerification,
hasSharedDeviceSignals,
}
}
@@ -63,13 +63,8 @@ function Inner({style}: ViewStyleProp & {}) {
const diff = lastInitiatedAt
? dateDiff(lastInitiatedAt, new Date(), 'down')
: null
const {
onPressVerify,
openKwsDialog,
isVerifyingDevice,
allowsDeviceVerification,
verifyCta,
} = useAgeAssuranceVerificationFlow({initDialogControl: control})
const {onPressVerify, openInitDialog, isVerifying, verifyCta} =
useAgeAssuranceVerificationFlow({initDialogControl: control})
return (
<>
@@ -150,14 +145,18 @@ function Inner({style}: ViewStyleProp & {}) {
<Button
label={verifyCta}
size="small"
color={hasInitiated ? 'secondary' : 'primary'}
disabled={isVerifyingDevice}
color={
hasInitiated || aa.flags.hasSharedDeviceSignals
? 'secondary'
: 'primary'
}
disabled={isVerifying}
onPress={() => void onPressVerify()}>
<ButtonIcon icon={isVerifyingDevice ? Loader : ShieldIcon} />
<ButtonIcon icon={isVerifying ? Loader : ShieldIcon} />
<ButtonText>{verifyCta}</ButtonText>
</Button>
{allowsDeviceVerification ? (
{aa.flags.allowsDeviceVerification ? (
<Text
style={[a.text_sm, a.italic, t.atoms.text_contrast_medium]}>
<Trans>
@@ -167,7 +166,7 @@ function Inner({style}: ViewStyleProp & {}) {
<InlineLinkText
label={l`Verify now using KWS`}
{...createStaticClick(() => {
openKwsDialog()
openInitDialog()
})}>
you can use our trusted partner, KWS
</InlineLinkText>