Improve NUX geo gating from #9549

This commit is contained in:
Eric Bailey
2025-12-15 10:26:55 -06:00
parent fc1e8c71c6
commit 9c46e97561
4 changed files with 67 additions and 41 deletions
+10 -8
View File
@@ -18,7 +18,16 @@ const FIND_CONTACTS_FEATURE_COUNTRY_ALLOWLIST = [
'IT',
] satisfies CountryCode[] as string[]
export function isFindContactsFeatureEnabled(countryCode: string): boolean {
export function isFindContactsFeatureEnabled(countryCode?: string): boolean {
if (IS_DEV) return true
/*
* This should never happen unless geolocation fails entirely. In that
* case, let the user try, since it should work as long as they have a
* phone number from one of the allow-listed countries.
*/
if (!countryCode) return true
return FIND_CONTACTS_FEATURE_COUNTRY_ALLOWLIST.includes(
countryCode.toUpperCase(),
)
@@ -26,12 +35,5 @@ export function isFindContactsFeatureEnabled(countryCode: string): boolean {
export function useIsFindContactsFeatureEnabledBasedOnGeolocation() {
const location = useGeolocation()
if (IS_DEV) return true
// they can try, by they'll need a phone number
// from one of the allowlisted countries
if (!location.countryCode) return true
return isFindContactsFeatureEnabled(location.countryCode)
}
@@ -6,26 +6,33 @@ import {msg, Trans} from '@lingui/macro'
import {useLingui} from '@lingui/react'
import {logger} from '#/logger'
import {isWeb} from '#/platform/detection'
import {isNative, isWeb} from '#/platform/detection'
import {atoms as a, useTheme, web} from '#/alf'
import {Button, ButtonText} from '#/components/Button'
import {useIsFindContactsFeatureEnabledBasedOnGeolocation} from '#/components/contacts/country-allowlist'
import {isFindContactsFeatureEnabled} from '#/components/contacts/country-allowlist'
import * as Dialog from '#/components/Dialog'
import {useNuxDialogContext} from '#/components/dialogs/nuxs'
import {
createIsEnabledCheck,
isExistingUserAsOf,
} from '#/components/dialogs/nuxs/utils'
import {Text} from '#/components/Typography'
import {IS_E2E} from '#/env'
import {navigate} from '#/Navigation'
export const enabled = createIsEnabledCheck(props => {
return (
!IS_E2E &&
isNative &&
isExistingUserAsOf(
'2025-12-16T00:00:00.000Z',
props.currentProfile.createdAt,
) &&
isFindContactsFeatureEnabled(props.geolocation.countryCode)
)
})
export function FindContactsAnnouncement() {
const isFeatureEnabled = useIsFindContactsFeatureEnabledBasedOnGeolocation()
if (!isFeatureEnabled) {
return null
}
return <Inner />
}
function Inner() {
const t = useTheme()
const {_} = useLingui()
const nuxDialogs = useNuxDialogContext()
+17 -21
View File
@@ -10,7 +10,6 @@ import {type AppBskyActorDefs} from '@atproto/api'
import {useGate} from '#/lib/statsig/statsig'
import {logger} from '#/logger'
import {isNative} from '#/platform/detection'
import {STALE} from '#/state/queries'
import {Nux, useNuxs, useResetNuxs, useSaveNux} from '#/state/queries/nuxs'
import {
@@ -20,13 +19,13 @@ import {
import {useProfileQuery} from '#/state/queries/profile'
import {type SessionAccount, useSession} from '#/state/session'
import {useOnboardingState} from '#/state/shell'
import {
enabled as isFindContactsAnnouncementEnabled,
FindContactsAnnouncement,
} from '#/components/dialogs/nuxs/FindContactsAnnouncement'
import {isSnoozed, snooze, unsnooze} from '#/components/dialogs/nuxs/snoozing'
import {ENV} from '#/env'
/*
* NUXs
*/
import {FindContactsAnnouncement} from './FindContactsAnnouncement'
import {isExistingUserAsOf} from './utils'
import {type EnabledCheckProps} from '#/components/dialogs/nuxs/utils'
import {useGeolocation} from '#/geolocation'
type Context = {
activeNux: Nux | undefined
@@ -35,22 +34,11 @@ type Context = {
const queuedNuxs: {
id: Nux
enabled?: (props: {
gate: ReturnType<typeof useGate>
currentAccount: SessionAccount
currentProfile: AppBskyActorDefs.ProfileViewDetailed
preferences: UsePreferencesQueryResponse
}) => boolean
enabled?: (props: EnabledCheckProps) => boolean
}[] = [
{
id: Nux.FindContactsAnnouncement,
enabled: ({currentProfile}) => {
return (
isNative &&
ENV !== 'e2e' &&
isExistingUserAsOf('2025-12-16T00:00:00.000Z', currentProfile.createdAt)
)
},
enabled: isFindContactsAnnouncementEnabled,
},
]
@@ -101,6 +89,7 @@ function Inner({
preferences: UsePreferencesQueryResponse
}) {
const gate = useGate()
const geolocation = useGeolocation()
const {nuxs} = useNuxs()
const [snoozed, setSnoozed] = useState(() => {
return isSnoozed()
@@ -143,7 +132,13 @@ function Inner({
// then check gate (track exposure)
if (
enabled &&
!enabled({gate, currentAccount, currentProfile, preferences})
!enabled({
gate,
currentAccount,
currentProfile,
preferences,
geolocation,
})
) {
continue
}
@@ -178,6 +173,7 @@ function Inner({
currentAccount,
currentProfile,
preferences,
geolocation,
])
const ctx = useMemo(() => {
+21
View File
@@ -1,3 +1,24 @@
import {type AppBskyActorDefs} from '@atproto/api'
import {type useGate} from '#/lib/statsig/statsig'
import {type UsePreferencesQueryResponse} from '#/state/queries/preferences'
import {type SessionAccount} from '#/state/session'
import {type Geolocation} from '#/geolocation'
export type EnabledCheckProps = {
gate: ReturnType<typeof useGate>
currentAccount: SessionAccount
currentProfile: AppBskyActorDefs.ProfileViewDetailed
preferences: UsePreferencesQueryResponse
geolocation: Geolocation
}
export function createIsEnabledCheck(
cb: (props: EnabledCheckProps) => boolean,
) {
return cb
}
const ONE_DAY = 1000 * 60 * 60 * 24
export function isDaysOld(days: number, createdAt?: string) {