Add region notice to age assurance card (#10439)

This commit is contained in:
Spence Pope
2026-05-11 08:27:24 -04:00
committed by GitHub
parent 28428a5750
commit 9b5be84c5a
@@ -1,9 +1,8 @@
import {View} from 'react-native'
import {msg} from '@lingui/core/macro'
import {useLingui} from '@lingui/react'
import {Trans} from '@lingui/react/macro'
import {Trans, useLingui} from '@lingui/react/macro'
import {dateDiff, useGetTimeAgo} from '#/lib/hooks/useTimeAgo'
import {regionName} from '#/locale/helpers'
import {atoms as a, useBreakpoints, useTheme, type ViewStyleProp} from '#/alf'
import {Admonition} from '#/components/Admonition'
import {AgeAssuranceAppealDialog} from '#/components/ageAssurance/AgeAssuranceAppealDialog'
@@ -25,7 +24,38 @@ import {useAgeAssurance} from '#/ageAssurance'
import {useComputeAgeAssuranceRegionAccess} from '#/ageAssurance/useComputeAgeAssuranceRegionAccess'
import {useAnalytics} from '#/analytics'
import {IS_NATIVE} from '#/env'
import {useDeviceGeolocationApi} from '#/geolocation'
import {
type Geolocation,
useDeviceGeolocationApi,
useGeolocation,
} from '#/geolocation'
import {USRegionNameToRegionCode} from '#/geolocation/util'
import {device, useStorage} from '#/storage'
const USRegionCodeToRegionName: {[regionCode: string]: string} =
Object.fromEntries(
Object.entries(USRegionNameToRegionCode).map(([name, code]) => [
code,
name,
]),
)
function formatRegion(
geolocation: Geolocation,
appLang: string,
): string | undefined {
const {countryCode, regionCode} = geolocation
if (!countryCode) return undefined
const country = regionName(countryCode, appLang)
// If `regionName` couldn't resolve a real name and fell through to the raw
// code, we'd rather show nothing than a bare ISO code in the prose.
if (country === countryCode) return undefined
if (regionCode && countryCode === 'US') {
const state = USRegionCodeToRegionName[regionCode]
if (state) return `${state}, ${country}`
}
return country
}
export function AgeAssuranceAccountCard({style}: ViewStyleProp & {}) {
const aa = useAgeAssurance()
@@ -42,15 +72,12 @@ export function AgeAssuranceAccountCard({style}: ViewStyleProp & {}) {
function Inner({style}: ViewStyleProp & {}) {
const t = useTheme()
const {_, i18n} = useLingui()
const {t: l, i18n} = useLingui()
const ax = useAnalytics()
const control = useDialogControl()
const appealControl = Dialog.useDialogControl()
const locationControl = Dialog.useDialogControl()
const getTimeAgo = useGetTimeAgo()
const {gtPhone} = useBreakpoints()
const {setDeviceGeolocation} = useDeviceGeolocationApi()
const computeAgeAssuranceRegionAccess = useComputeAgeAssuranceRegionAccess()
const copy = useAgeAssuranceCopy()
const aa = useAgeAssurance()
@@ -97,7 +124,7 @@ function Inner({style}: ViewStyleProp & {}) {
if one is available in your region. If you have questions or
concerns,{' '}
<InlineLinkText
label={_(msg`Contact our support team`)}
label={l`Contact our support team`}
{...createStaticClick(() => {
appealControl.open()
})}>
@@ -107,47 +134,7 @@ function Inner({style}: ViewStyleProp & {}) {
</Text>
)}
{IS_NATIVE && (
<>
<Text style={[a.text_sm, a.leading_snug]}>
<Trans>
Is your location not accurate?{' '}
<InlineLinkText
label={_(msg`Confirm your location`)}
{...createStaticClick(() => {
locationControl.open()
})}>
Tap here to confirm your location.
</InlineLinkText>{' '}
</Trans>
</Text>
<DeviceLocationRequestDialog
control={locationControl}
onLocationAcquired={props => {
const access = computeAgeAssuranceRegionAccess(
props.geolocation,
)
if (access !== aa.Access.Full) {
props.disableDialogAction()
props.setDialogError(
_(
msg`We're sorry, but based on your device's location, you are currently located in a region that requires age assurance.`,
),
)
} else {
props.closeDialog(() => {
// set this after close!
setDeviceGeolocation(props.geolocation)
Toast.show(_(msg`Thanks! You're all set.`), {
type: 'success',
})
})
}
}}
/>
</>
)}
<RegionNotice />
</View>
{isBlocked ? (
@@ -156,7 +143,7 @@ function Inner({style}: ViewStyleProp & {}) {
You are currently unable to access Bluesky's Age Assurance flow.
Please{' '}
<InlineLinkText
label={_(msg`Contact our moderation team`)}
label={l`Contact our moderation team`}
{...createStaticClick(() => {
appealControl.open()
ax.metric('ageAssurance:appealDialogOpen', {})
@@ -182,7 +169,7 @@ function Inner({style}: ViewStyleProp & {}) {
: [a.gap_md],
]}>
<Button
label={_(msg`Verify now`)}
label={l`Verify now`}
size="small"
variant="solid"
color={hasInitiated ? 'secondary' : 'primary'}
@@ -228,3 +215,75 @@ function Inner({style}: ViewStyleProp & {}) {
</>
)
}
function RegionNotice() {
const {t: l, i18n} = useLingui()
const aa = useAgeAssurance()
const geolocation = useGeolocation()
const [deviceGeolocation] = useStorage(device, ['deviceGeolocation'])
const {setDeviceGeolocation} = useDeviceGeolocationApi()
const computeAgeAssuranceRegionAccess = useComputeAgeAssuranceRegionAccess()
const locationControl = Dialog.useDialogControl()
const region = formatRegion(geolocation, i18n.locale)
const isGPS = !!deviceGeolocation?.countryCode && IS_NATIVE
return (
<>
{IS_NATIVE && (
<DeviceLocationRequestDialog
control={locationControl}
onLocationAcquired={props => {
const access = computeAgeAssuranceRegionAccess(props.geolocation)
if (access !== aa.Access.Full) {
props.disableDialogAction()
props.setDialogError(
l`We're sorry, but based on your device's location, you are currently located in a region that requires age assurance.`,
)
} else {
props.closeDialog(() => {
// set this after close!
setDeviceGeolocation(props.geolocation)
Toast.show(l`Thanks! You're all set.`, {
type: 'success',
})
})
}
}}
/>
)}
{region && (
<Text style={[a.text_sm, a.leading_snug]}>
{isGPS ? (
<Trans>
Based on your device's location, we think you're in{' '}
<Text style={[a.text_sm, a.font_bold]}>{region}</Text>. This
estimate may be inaccurate if you're using a VPN.
</Trans>
) : (
<Trans>
Based on your network, we think you're in{' '}
<Text style={[a.text_sm, a.font_bold]}>{region}</Text>. This
estimate may be inaccurate if you're using a VPN.
</Trans>
)}
</Text>
)}
{IS_NATIVE && (
<Text style={[a.text_sm, a.leading_snug]}>
<Trans>
<InlineLinkText
label={l`Confirm your location`}
{...createStaticClick(() => {
locationControl.open()
})}>
Tap here to confirm your location.
</InlineLinkText>
</Trans>
</Text>
)}
</>
)
}