Age Assurance V2 (#9479)
* Age Assurance V2 * Tighten up test * Add todos for sdk migration * Align RQ versions * Use useEffect for side effect * Improve effects, memoize * Standarize on birthdate * Copy feedback * Copilot * Add support link * Reove double .. * Cleanup * Remove redirect dialog * Cleanup todos, add comments * Update splash in main template too * Mock some stuff * Exhaustive checks Co-authored-by: Samuel Newman <mozzius@protonmail.com> * Exhaustive checks Co-authored-by: Samuel Newman <mozzius@protonmail.com> * Small fix to bday handling * Add comment * onboarding style tweak sneaking this in sorry! * rm unreachable breaks * Put useIntentHandler back on web * Remove misleading success set * Align on birthdate --------- Co-authored-by: Samuel Newman <mozzius@protonmail.com>
This commit is contained in:
@@ -7,10 +7,13 @@ import {cleanError} from '#/lib/strings/errors'
|
||||
import {getAge, getDateAgo} from '#/lib/strings/time'
|
||||
import {logger} from '#/logger'
|
||||
import {isIOS, isWeb} from '#/platform/detection'
|
||||
import {
|
||||
useBirthdateMutation,
|
||||
useIsBirthdateUpdateAllowed,
|
||||
} from '#/state/birthdate'
|
||||
import {
|
||||
usePreferencesQuery,
|
||||
type UsePreferencesQueryResponse,
|
||||
usePreferencesSetBirthDateMutation,
|
||||
} from '#/state/queries/preferences'
|
||||
import {ErrorMessage} from '#/view/com/util/error/ErrorMessage'
|
||||
import {atoms as a, useTheme, web} from '#/alf'
|
||||
@@ -18,7 +21,7 @@ import {Admonition} from '#/components/Admonition'
|
||||
import {Button, ButtonIcon, ButtonText} from '#/components/Button'
|
||||
import * as Dialog from '#/components/Dialog'
|
||||
import {DateField} from '#/components/forms/DateField'
|
||||
import {InlineLinkText} from '#/components/Link'
|
||||
import {SimpleInlineLinkText} from '#/components/Link'
|
||||
import {Loader} from '#/components/Loader'
|
||||
import {Text} from '#/components/Typography'
|
||||
|
||||
@@ -30,42 +33,71 @@ export function BirthDateSettingsDialog({
|
||||
const t = useTheme()
|
||||
const {_} = useLingui()
|
||||
const {isLoading, error, data: preferences} = usePreferencesQuery()
|
||||
const isBirthdateUpdateAllowed = useIsBirthdateUpdateAllowed()
|
||||
|
||||
return (
|
||||
<Dialog.Outer control={control} nativeOptions={{preventExpansion: true}}>
|
||||
<Dialog.Handle />
|
||||
<Dialog.ScrollableInner
|
||||
label={_(msg`My Birthday`)}
|
||||
style={web({maxWidth: 400})}>
|
||||
<View style={[a.gap_sm]}>
|
||||
<Text style={[a.text_xl, a.font_semi_bold]}>
|
||||
<Trans>My Birthday</Trans>
|
||||
</Text>
|
||||
<Text style={[a.leading_snug, t.atoms.text_contrast_medium]}>
|
||||
<Trans>
|
||||
This information is private and not shared with other users.
|
||||
</Trans>
|
||||
</Text>
|
||||
{isBirthdateUpdateAllowed ? (
|
||||
<Dialog.ScrollableInner
|
||||
label={_(msg`My Birthdate`)}
|
||||
style={web({maxWidth: 400})}>
|
||||
<View style={[a.gap_md]}>
|
||||
<Text style={[a.text_xl, a.font_semi_bold]}>
|
||||
<Trans>My Birthdate</Trans>
|
||||
</Text>
|
||||
<Text
|
||||
style={[a.text_md, a.leading_snug, t.atoms.text_contrast_medium]}>
|
||||
<Trans>
|
||||
This information is private and not shared with other users.
|
||||
</Trans>
|
||||
</Text>
|
||||
|
||||
{isLoading ? (
|
||||
<Loader size="xl" />
|
||||
) : error || !preferences ? (
|
||||
<ErrorMessage
|
||||
message={
|
||||
error?.toString() ||
|
||||
_(
|
||||
msg`We were unable to load your birth date preferences. Please try again.`,
|
||||
)
|
||||
}
|
||||
style={[a.rounded_sm]}
|
||||
/>
|
||||
) : (
|
||||
<BirthdayInner control={control} preferences={preferences} />
|
||||
)}
|
||||
</View>
|
||||
{isLoading ? (
|
||||
<Loader size="xl" />
|
||||
) : error || !preferences ? (
|
||||
<ErrorMessage
|
||||
message={
|
||||
error?.toString() ||
|
||||
_(
|
||||
msg`We were unable to load your birthdate preferences. Please try again.`,
|
||||
)
|
||||
}
|
||||
style={[a.rounded_sm]}
|
||||
/>
|
||||
) : (
|
||||
<BirthdayInner control={control} preferences={preferences} />
|
||||
)}
|
||||
</View>
|
||||
|
||||
<Dialog.Close />
|
||||
</Dialog.ScrollableInner>
|
||||
<Dialog.Close />
|
||||
</Dialog.ScrollableInner>
|
||||
) : (
|
||||
<Dialog.ScrollableInner
|
||||
label={_(msg`You recently changed your birthdate`)}
|
||||
style={web({maxWidth: 400})}>
|
||||
<View style={[a.gap_sm]}>
|
||||
<Text
|
||||
style={[
|
||||
a.text_xl,
|
||||
a.font_semi_bold,
|
||||
a.leading_snug,
|
||||
{paddingRight: 32},
|
||||
]}>
|
||||
<Trans>You recently changed your birthdate</Trans>
|
||||
</Text>
|
||||
<Text
|
||||
style={[a.text_md, a.leading_snug, t.atoms.text_contrast_medium]}>
|
||||
<Trans>
|
||||
There is a limit to how often you can change your birthdate. You
|
||||
may need to wait a day or two before updating it again.
|
||||
</Trans>
|
||||
</Text>
|
||||
</View>
|
||||
|
||||
<Dialog.Close />
|
||||
</Dialog.ScrollableInner>
|
||||
)}
|
||||
</Dialog.Outer>
|
||||
)
|
||||
}
|
||||
@@ -86,7 +118,7 @@ function BirthdayInner({
|
||||
isError,
|
||||
error,
|
||||
mutateAsync: setBirthDate,
|
||||
} = usePreferencesSetBirthDateMutation()
|
||||
} = useBirthdateMutation()
|
||||
const hasChanged = date !== preferences.birthDate
|
||||
|
||||
const age = getAge(new Date(date))
|
||||
@@ -112,8 +144,8 @@ function BirthdayInner({
|
||||
testID="birthdayInput"
|
||||
value={date}
|
||||
onChangeDate={newDate => setDate(new Date(newDate))}
|
||||
label={_(msg`Birthday`)}
|
||||
accessibilityHint={_(msg`Enter your birth date`)}
|
||||
label={_(msg`Birthdate`)}
|
||||
accessibilityHint={_(msg`Enter your birthdate`)}
|
||||
/>
|
||||
</View>
|
||||
|
||||
@@ -130,11 +162,11 @@ function BirthdayInner({
|
||||
<Admonition type="error">
|
||||
<Trans>
|
||||
You must be at least 13 years old to use Bluesky. Read our{' '}
|
||||
<InlineLinkText
|
||||
<SimpleInlineLinkText
|
||||
to="https://bsky.social/about/support/tos"
|
||||
label={_(msg`Terms of Service`)}>
|
||||
Terms of Service
|
||||
</InlineLinkText>{' '}
|
||||
</SimpleInlineLinkText>{' '}
|
||||
for more information.
|
||||
</Trans>
|
||||
</Admonition>
|
||||
@@ -146,7 +178,7 @@ function BirthdayInner({
|
||||
|
||||
<View style={isWeb && [a.flex_row, a.justify_end]}>
|
||||
<Button
|
||||
label={hasChanged ? _(msg`Save birthday`) : _(msg`Done`)}
|
||||
label={hasChanged ? _(msg`Save birthdate`) : _(msg`Done`)}
|
||||
size="large"
|
||||
onPress={onSave}
|
||||
variant="solid"
|
||||
|
||||
@@ -7,12 +7,6 @@ import {wait} from '#/lib/async/wait'
|
||||
import {isNetworkError, useCleanError} from '#/lib/hooks/useCleanError'
|
||||
import {logger} from '#/logger'
|
||||
import {isWeb} from '#/platform/detection'
|
||||
import {
|
||||
computeGeolocationStatus,
|
||||
type GeolocationStatus,
|
||||
useGeolocationConfig,
|
||||
} from '#/state/geolocation'
|
||||
import {useRequestDeviceLocation} from '#/state/geolocation/useRequestDeviceLocation'
|
||||
import {atoms as a, useTheme, web} from '#/alf'
|
||||
import {Admonition} from '#/components/Admonition'
|
||||
import {Button, ButtonIcon, ButtonText} from '#/components/Button'
|
||||
@@ -20,10 +14,11 @@ import * as Dialog from '#/components/Dialog'
|
||||
import {PinLocation_Stroke2_Corner0_Rounded as LocationIcon} from '#/components/icons/PinLocation'
|
||||
import {Loader} from '#/components/Loader'
|
||||
import {Text} from '#/components/Typography'
|
||||
import {type Geolocation, useRequestDeviceGeolocation} from '#/geolocation'
|
||||
|
||||
export type Props = {
|
||||
onLocationAcquired?: (props: {
|
||||
geolocationStatus: GeolocationStatus
|
||||
geolocation: Geolocation
|
||||
setDialogError: (error: string) => void
|
||||
disableDialogAction: () => void
|
||||
closeDialog: (callback?: () => void) => void
|
||||
@@ -57,8 +52,7 @@ function DeviceLocationRequestDialogInner({onLocationAcquired}: Props) {
|
||||
const t = useTheme()
|
||||
const {_} = useLingui()
|
||||
const {close} = Dialog.useDialogContext()
|
||||
const requestDeviceLocation = useRequestDeviceLocation()
|
||||
const {config} = useGeolocationConfig()
|
||||
const requestDeviceLocation = useRequestDeviceGeolocation()
|
||||
const cleanError = useCleanError()
|
||||
|
||||
const [isRequesting, setIsRequesting] = useState(false)
|
||||
@@ -76,9 +70,8 @@ function DeviceLocationRequestDialogInner({onLocationAcquired}: Props) {
|
||||
const location = req.location
|
||||
|
||||
if (location && location.countryCode) {
|
||||
const geolocationStatus = computeGeolocationStatus(location, config)
|
||||
onLocationAcquired?.({
|
||||
geolocationStatus,
|
||||
geolocation: location,
|
||||
setDialogError: setError,
|
||||
disableDialogAction: () => setDialogDisabled(true),
|
||||
closeDialog: close,
|
||||
|
||||
Reference in New Issue
Block a user