diff --git a/src/components/contacts/country-allowlist.ts b/src/components/contacts/country-allowlist.ts index 97d3d44587..35ba43c8fa 100644 --- a/src/components/contacts/country-allowlist.ts +++ b/src/components/contacts/country-allowlist.ts @@ -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) } diff --git a/src/components/dialogs/nuxs/FindContactsAnnouncement.tsx b/src/components/dialogs/nuxs/FindContactsAnnouncement.tsx index dd3aed013c..b92ece98a7 100644 --- a/src/components/dialogs/nuxs/FindContactsAnnouncement.tsx +++ b/src/components/dialogs/nuxs/FindContactsAnnouncement.tsx @@ -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 -} - -function Inner() { const t = useTheme() const {_} = useLingui() const nuxDialogs = useNuxDialogContext() diff --git a/src/components/dialogs/nuxs/index.tsx b/src/components/dialogs/nuxs/index.tsx index c0b1410e21..2ab319fafd 100644 --- a/src/components/dialogs/nuxs/index.tsx +++ b/src/components/dialogs/nuxs/index.tsx @@ -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 - 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(() => { diff --git a/src/components/dialogs/nuxs/utils.ts b/src/components/dialogs/nuxs/utils.ts index ba8f0169d6..68ea38ebf2 100644 --- a/src/components/dialogs/nuxs/utils.ts +++ b/src/components/dialogs/nuxs/utils.ts @@ -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 + 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) {