From 425505b5ec54e3199a9079682236b76cd5d3eec9 Mon Sep 17 00:00:00 2001 From: Eric Bailey Date: Tue, 23 Jun 2026 15:58:04 -0500 Subject: [PATCH] Show loading state on Verify button during device age prompt While the native OS age prompt is up, swap the Verify button icon for a Loader and disable it to prevent double-taps. Scoped to the device path; the KWS fallback opens a dialog synchronously. Co-Authored-By: Claude Opus 4.8 --- src/ageAssurance/components/NoAccessScreen.tsx | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/src/ageAssurance/components/NoAccessScreen.tsx b/src/ageAssurance/components/NoAccessScreen.tsx index de06986cfe..1f0bbb051a 100644 --- a/src/ageAssurance/components/NoAccessScreen.tsx +++ b/src/ageAssurance/components/NoAccessScreen.tsx @@ -1,6 +1,7 @@ -import {useCallback, useEffect} from 'react' +import {useCallback, useEffect, useState} from 'react' import {ScrollView, View} from 'react-native' import {useSafeAreaInsets} from 'react-native-safe-area-context' +import type * as AgeRange from 'expo-age-range' import {msg} from '@lingui/core/macro' import {useLingui} from '@lingui/react' import {Trans} from '@lingui/react/macro' @@ -27,6 +28,7 @@ import {DeviceLocationRequestDialog} from '#/components/dialogs/DeviceLocationRe import {Full as Logo} from '#/components/icons/Logo' import {ShieldCheck_Stroke2_Corner0_Rounded as ShieldIcon} from '#/components/icons/Shield' import {createStaticClick, SimpleInlineLinkText} from '#/components/Link' +import {Loader} from '#/components/Loader' import {Outlet as PortalOutlet} from '#/components/Portal' import * as Toast from '#/components/Toast' import {Text} from '#/components/Typography' @@ -328,6 +330,8 @@ function AccessSection() { ? dateDiff(lastInitiatedAt, new Date(), 'down') : null + const [isVerifyingDevice, setIsVerifyingDevice] = useState(false) + const openKwsDialog = useCallback(() => { control.open() ax.metric('ageAssurance:initDialogOpen', { @@ -347,7 +351,14 @@ function AccessSection() { */ if (region && regionAllowsDeviceVerification(region)) { const did = currentAccount?.did - const signals = await getDeviceSignals() + // Show a loading state while the OS age prompt is up. + setIsVerifyingDevice(true) + let signals: AgeRange.AgeRangeResponse | undefined + try { + signals = await getDeviceSignals() + } finally { + setIsVerifyingDevice(false) + } if (signals && did) { const assuredAge = getAssuredAgeFromDeviceSignals(region, signals) if (assuredAge !== undefined) { @@ -395,8 +406,9 @@ function AccessSection() { label={_(msg`Verify now`)} size="large" color={hasInitiated ? 'secondary' : 'primary'} + disabled={isVerifyingDevice} onPress={() => void onPressVerify()}> - + {hasInitiated ? ( Verify again