Migrate useGate to useAnalytics

This commit is contained in:
Eric Bailey
2026-01-21 17:29:34 -06:00
parent 63514c6d68
commit d33e474f47
15 changed files with 112 additions and 139 deletions
-3
View File
@@ -17,7 +17,6 @@ import * as Sentry from '@sentry/react-native'
import {KeyboardControllerProvider} from '#/lib/hooks/useEnableKeyboardController' import {KeyboardControllerProvider} from '#/lib/hooks/useEnableKeyboardController'
import {Provider as HideBottomBarBorderProvider} from '#/lib/hooks/useHideBottomBarBorder' import {Provider as HideBottomBarBorderProvider} from '#/lib/hooks/useHideBottomBarBorder'
import {QueryProvider} from '#/lib/react-query' import {QueryProvider} from '#/lib/react-query'
import {Provider as StatsigProvider} from '#/lib/statsig/statsig'
import {s} from '#/lib/styles' import {s} from '#/lib/styles'
import {ThemeProvider} from '#/lib/ThemeContext' import {ThemeProvider} from '#/lib/ThemeContext'
import I18nProvider from '#/locale/i18nProvider' import I18nProvider from '#/locale/i18nProvider'
@@ -153,7 +152,6 @@ function InnerApp() {
<AnalyticsFeaturesContext> <AnalyticsFeaturesContext>
<QueryProvider currentDid={currentAccount?.did}> <QueryProvider currentDid={currentAccount?.did}>
<PolicyUpdateOverlayProvider> <PolicyUpdateOverlayProvider>
<StatsigProvider>
<LiveEventsProvider> <LiveEventsProvider>
<AgeAssuranceV2Provider> <AgeAssuranceV2Provider>
<ComposerProvider> <ComposerProvider>
@@ -199,7 +197,6 @@ function InnerApp() {
</ComposerProvider> </ComposerProvider>
</AgeAssuranceV2Provider> </AgeAssuranceV2Provider>
</LiveEventsProvider> </LiveEventsProvider>
</StatsigProvider>
</PolicyUpdateOverlayProvider> </PolicyUpdateOverlayProvider>
</QueryProvider> </QueryProvider>
</AnalyticsFeaturesContext> </AnalyticsFeaturesContext>
-3
View File
@@ -9,7 +9,6 @@ import {useLingui} from '@lingui/react'
import * as Sentry from '@sentry/react-native' import * as Sentry from '@sentry/react-native'
import {QueryProvider} from '#/lib/react-query' import {QueryProvider} from '#/lib/react-query'
import {Provider as StatsigProvider} from '#/lib/statsig/statsig'
import {ThemeProvider} from '#/lib/ThemeContext' import {ThemeProvider} from '#/lib/ThemeContext'
import I18nProvider from '#/locale/i18nProvider' import I18nProvider from '#/locale/i18nProvider'
import {logger} from '#/logger' import {logger} from '#/logger'
@@ -132,7 +131,6 @@ function InnerApp() {
<AnalyticsFeaturesContext> <AnalyticsFeaturesContext>
<QueryProvider currentDid={currentAccount?.did}> <QueryProvider currentDid={currentAccount?.did}>
<PolicyUpdateOverlayProvider> <PolicyUpdateOverlayProvider>
<StatsigProvider>
<LiveEventsProvider> <LiveEventsProvider>
<AgeAssuranceV2Provider> <AgeAssuranceV2Provider>
<ComposerProvider> <ComposerProvider>
@@ -174,7 +172,6 @@ function InnerApp() {
</ComposerProvider> </ComposerProvider>
</AgeAssuranceV2Provider> </AgeAssuranceV2Provider>
</LiveEventsProvider> </LiveEventsProvider>
</StatsigProvider>
</PolicyUpdateOverlayProvider> </PolicyUpdateOverlayProvider>
</QueryProvider> </QueryProvider>
</AnalyticsFeaturesContext> </AnalyticsFeaturesContext>
+1
View File
@@ -24,6 +24,7 @@ import {device} from '#/storage'
export * as utils from '#/analytics/utils' export * as utils from '#/analytics/utils'
export const features = {init, refresh} export const features = {init, refresh}
export {Features} from '#/analytics/features'
export {type Metrics} from '#/analytics/metrics' export {type Metrics} from '#/analytics/metrics'
type LoggerType = { type LoggerType = {
@@ -3,11 +3,11 @@ import * as Clipboard from 'expo-clipboard'
import {t} from '@lingui/macro' import {t} from '@lingui/macro'
import {DISCOVER_DEBUG_DIDS} from '#/lib/constants' import {DISCOVER_DEBUG_DIDS} from '#/lib/constants'
import {useGate} from '#/lib/statsig/statsig'
import {useSession} from '#/state/session' import {useSession} from '#/state/session'
import {atoms as a, useTheme} from '#/alf' import {atoms as a, useTheme} from '#/alf'
import * as Toast from '#/components/Toast' import * as Toast from '#/components/Toast'
import {Text} from '#/components/Typography' import {Text} from '#/components/Typography'
import {useAnalytics} from '#/analytics'
import {IS_INTERNAL} from '#/env' import {IS_INTERNAL} from '#/env'
export function DiscoverDebug({ export function DiscoverDebug({
@@ -15,12 +15,12 @@ export function DiscoverDebug({
}: { }: {
feedContext: string | undefined feedContext: string | undefined
}) { }) {
const ax = useAnalytics()
const {currentAccount} = useSession() const {currentAccount} = useSession()
const gate = useGate()
const isDiscoverDebugUser = const isDiscoverDebugUser =
IS_INTERNAL || IS_INTERNAL ||
DISCOVER_DEBUG_DIDS[currentAccount?.did || ''] || DISCOVER_DEBUG_DIDS[currentAccount?.did || ''] ||
gate('debug_show_feedcontext') ax.feature(ax.Features.DebugFeedContext)
const theme = useTheme() const theme = useTheme()
return ( return (
@@ -26,7 +26,6 @@ import {
type CommonNavigatorParams, type CommonNavigatorParams,
type NavigationProp, type NavigationProp,
} from '#/lib/routes/types' } from '#/lib/routes/types'
import {useGate} from '#/lib/statsig/statsig'
import {richTextToString} from '#/lib/strings/rich-text-helpers' import {richTextToString} from '#/lib/strings/rich-text-helpers'
import {toShareUrl} from '#/lib/strings/url-helpers' import {toShareUrl} from '#/lib/strings/url-helpers'
import {logger} from '#/logger' import {logger} from '#/logger'
@@ -463,11 +462,10 @@ let PostMenuItems = ({
const onSignIn = () => requireSignIn(() => {}) const onSignIn = () => requireSignIn(() => {})
const gate = useGate()
const isDiscoverDebugUser = const isDiscoverDebugUser =
IS_INTERNAL || IS_INTERNAL ||
DISCOVER_DEBUG_DIDS[currentAccount?.did || ''] || DISCOVER_DEBUG_DIDS[currentAccount?.did || ''] ||
gate('debug_show_feedcontext') ax.feature(ax.Features.DebugFeedContext)
return ( return (
<> <>
@@ -15,6 +15,7 @@ import {
} from '#/components/dialogs/nuxs/utils' } from '#/components/dialogs/nuxs/utils'
import {Beaker_Stroke2_Corner2_Rounded as BeakerIcon} from '#/components/icons/Beaker' import {Beaker_Stroke2_Corner2_Rounded as BeakerIcon} from '#/components/icons/Beaker'
import {Text} from '#/components/Typography' import {Text} from '#/components/Typography'
import {Features} from '#/analytics'
import {IS_E2E, IS_WEB} from '#/env' import {IS_E2E, IS_WEB} from '#/env'
export const enabled = createIsEnabledCheck(props => { export const enabled = createIsEnabledCheck(props => {
@@ -24,7 +25,7 @@ export const enabled = createIsEnabledCheck(props => {
'2026-01-16T00:00:00.000Z', '2026-01-16T00:00:00.000Z',
props.currentProfile.createdAt, props.currentProfile.createdAt,
) && ) &&
!props.gate('disable_live_now_beta') !props.feature(Features.DisableLiveNowBeta)
) )
}) })
+4 -4
View File
@@ -8,7 +8,6 @@ import {
} from 'react' } from 'react'
import {type AppBskyActorDefs} from '@atproto/api' import {type AppBskyActorDefs} from '@atproto/api'
import {useGate} from '#/lib/statsig/statsig'
import {logger} from '#/logger' import {logger} from '#/logger'
import {STALE} from '#/state/queries' import {STALE} from '#/state/queries'
import {Nux, useNuxs, useResetNuxs, useSaveNux} from '#/state/queries/nuxs' import {Nux, useNuxs, useResetNuxs, useSaveNux} from '#/state/queries/nuxs'
@@ -25,6 +24,7 @@ import {
} from '#/components/dialogs/nuxs/LiveNowBetaDialog' } from '#/components/dialogs/nuxs/LiveNowBetaDialog'
import {isSnoozed, snooze, unsnooze} from '#/components/dialogs/nuxs/snoozing' import {isSnoozed, snooze, unsnooze} from '#/components/dialogs/nuxs/snoozing'
import {type EnabledCheckProps} from '#/components/dialogs/nuxs/utils' import {type EnabledCheckProps} from '#/components/dialogs/nuxs/utils'
import {useAnalytics} from '#/analytics'
import {useGeolocation} from '#/geolocation' import {useGeolocation} from '#/geolocation'
type Context = { type Context = {
@@ -88,7 +88,7 @@ function Inner({
currentProfile: AppBskyActorDefs.ProfileViewDetailed currentProfile: AppBskyActorDefs.ProfileViewDetailed
preferences: UsePreferencesQueryResponse preferences: UsePreferencesQueryResponse
}) { }) {
const gate = useGate() const ax = useAnalytics()
const geolocation = useGeolocation() const geolocation = useGeolocation()
const {nuxs} = useNuxs() const {nuxs} = useNuxs()
const [snoozed, setSnoozed] = useState(() => { const [snoozed, setSnoozed] = useState(() => {
@@ -133,7 +133,7 @@ function Inner({
if ( if (
enabled && enabled &&
!enabled({ !enabled({
gate, feature: ax.feature,
currentAccount, currentAccount,
currentProfile, currentProfile,
preferences, preferences,
@@ -165,11 +165,11 @@ function Inner({
break break
} }
}, [ }, [
ax.feature,
nuxs, nuxs,
snoozed, snoozed,
snoozeNuxDialog, snoozeNuxDialog,
saveNux, saveNux,
gate,
currentAccount, currentAccount,
currentProfile, currentProfile,
preferences, preferences,
+2 -2
View File
@@ -1,12 +1,12 @@
import {type AppBskyActorDefs} from '@atproto/api' import {type AppBskyActorDefs} from '@atproto/api'
import {type useGate} from '#/lib/statsig/statsig'
import {type UsePreferencesQueryResponse} from '#/state/queries/preferences' import {type UsePreferencesQueryResponse} from '#/state/queries/preferences'
import {type SessionAccount} from '#/state/session' import {type SessionAccount} from '#/state/session'
import {type AnalyticsContextType} from '#/analytics'
import {type Geolocation} from '#/geolocation' import {type Geolocation} from '#/geolocation'
export type EnabledCheckProps = { export type EnabledCheckProps = {
gate: ReturnType<typeof useGate> feature: AnalyticsContextType['feature']
currentAccount: SessionAccount currentAccount: SessionAccount
currentProfile: AppBskyActorDefs.ProfileViewDetailed currentProfile: AppBskyActorDefs.ProfileViewDetailed
preferences: UsePreferencesQueryResponse preferences: UsePreferencesQueryResponse
+3 -3
View File
@@ -1,8 +1,8 @@
import {useMemo} from 'react' import {useMemo} from 'react'
import {useGate} from '#/lib/statsig/statsig' import {useAnalytics} from '#/analytics'
export function useIsBskyTeam() { export function useIsBskyTeam() {
const gate = useGate() const ax = useAnalytics()
return useMemo(() => gate('is_bsky_team_member'), [gate]) return useMemo(() => ax.feature(ax.Features.IsBskyTeam), [ax])
} }
-7
View File
@@ -1,7 +0,0 @@
export type Gate =
// Keep this alphabetic please.
| 'debug_show_feedcontext'
| 'is_bsky_team_member' // special, do not remove
| 'disable_onboarding_find_contacts'
| 'disable_settings_find_contacts'
| 'disable_live_now_beta'
-12
View File
@@ -1,12 +0,0 @@
import type React from 'react'
import {type Gate} from './gates'
const fn = () => false
export function useGate(): (_gateName: Gate, _options?: any) => boolean {
return fn
}
export function Provider({children}: {children: React.ReactNode}) {
return children
}
+1 -3
View File
@@ -14,7 +14,6 @@ import {compressIfNeeded} from '#/lib/media/manip'
import {openCropper} from '#/lib/media/picker' import {openCropper} from '#/lib/media/picker'
import {getDataUriSize} from '#/lib/media/util' import {getDataUriSize} from '#/lib/media/util'
import {useRequestNotificationsPermission} from '#/lib/notifications/notifications' import {useRequestNotificationsPermission} from '#/lib/notifications/notifications'
import {useGate} from '#/lib/statsig/statsig'
import {isCancelledError} from '#/lib/strings/errors' import {isCancelledError} from '#/lib/strings/errors'
import {logger} from '#/logger' import {logger} from '#/logger'
import { import {
@@ -72,7 +71,6 @@ export function StepProfile() {
const t = useTheme() const t = useTheme()
const {gtMobile} = useBreakpoints() const {gtMobile} = useBreakpoints()
const {requestPhotoAccessIfNeeded} = usePhotoLibraryPermission() const {requestPhotoAccessIfNeeded} = usePhotoLibraryPermission()
const gate = useGate()
const requestNotificationsPermission = useRequestNotificationsPermission() const requestNotificationsPermission = useRequestNotificationsPermission()
const creatorControl = Dialog.useDialogControl() const creatorControl = Dialog.useDialogControl()
@@ -91,7 +89,7 @@ export function StepProfile() {
React.useEffect(() => { React.useEffect(() => {
requestNotificationsPermission('StartOnboarding') requestNotificationsPermission('StartOnboarding')
}, [gate, requestNotificationsPermission]) }, [requestNotificationsPermission])
const sheetWrapper = useSheetWrapper() const sheetWrapper = useSheetWrapper()
const openPicker = React.useCallback( const openPicker = React.useCallback(
+3 -3
View File
@@ -3,7 +3,6 @@ import {View} from 'react-native'
import * as bcp47Match from 'bcp-47-match' import * as bcp47Match from 'bcp-47-match'
import {useEnableKeyboardControllerScreen} from '#/lib/hooks/useEnableKeyboardController' import {useEnableKeyboardControllerScreen} from '#/lib/hooks/useEnableKeyboardController'
import {useGate} from '#/lib/statsig/statsig'
import {useLanguagePrefs} from '#/state/preferences' import {useLanguagePrefs} from '#/state/preferences'
import { import {
Layout, Layout,
@@ -23,6 +22,7 @@ import {useIsFindContactsFeatureEnabledBasedOnGeolocation} from '#/components/co
import {useFindContactsFlowState} from '#/components/contacts/state' import {useFindContactsFlowState} from '#/components/contacts/state'
import {Portal} from '#/components/Portal' import {Portal} from '#/components/Portal'
import {ScreenTransition} from '#/components/ScreenTransition' import {ScreenTransition} from '#/components/ScreenTransition'
import {useAnalytics} from '#/analytics'
import {ENV, IS_NATIVE} from '#/env' import {ENV, IS_NATIVE} from '#/env'
import {StepFindContacts} from './StepFindContacts' import {StepFindContacts} from './StepFindContacts'
import {StepFindContactsIntro} from './StepFindContactsIntro' import {StepFindContactsIntro} from './StepFindContactsIntro'
@@ -31,7 +31,7 @@ import {StepSuggestedStarterpacks} from './StepSuggestedStarterpacks'
export function Onboarding() { export function Onboarding() {
const t = useTheme() const t = useTheme()
const gate = useGate() const ax = useAnalytics()
const {contentLanguages} = useLanguagePrefs() const {contentLanguages} = useLanguagePrefs()
const probablySpeaksEnglish = useMemo(() => { const probablySpeaksEnglish = useMemo(() => {
@@ -48,7 +48,7 @@ export function Onboarding() {
ENV !== 'e2e' && ENV !== 'e2e' &&
IS_NATIVE && IS_NATIVE &&
findContactsEnabled && findContactsEnabled &&
!gate('disable_onboarding_find_contacts') !ax.feature(ax.Features.DisableOnboardingFindContacts)
const [state, dispatch] = useReducer( const [state, dispatch] = useReducer(
reducer, reducer,
+3 -3
View File
@@ -15,7 +15,6 @@ import {
type CommonNavigatorParams, type CommonNavigatorParams,
type NavigationProp, type NavigationProp,
} from '#/lib/routes/types' } from '#/lib/routes/types'
import {useGate} from '#/lib/statsig/statsig'
import {sanitizeDisplayName} from '#/lib/strings/display-names' import {sanitizeDisplayName} from '#/lib/strings/display-names'
import {sanitizeHandle} from '#/lib/strings/handles' import {sanitizeHandle} from '#/lib/strings/handles'
import {useProfileShadow} from '#/state/cache/profile-shadow' import {useProfileShadow} from '#/state/cache/profile-shadow'
@@ -69,12 +68,14 @@ import {
shouldShowVerificationCheckButton, shouldShowVerificationCheckButton,
VerificationCheckButton, VerificationCheckButton,
} from '#/components/verification/VerificationCheckButton' } from '#/components/verification/VerificationCheckButton'
import {useAnalytics} from '#/analytics'
import {IS_INTERNAL, IS_IOS, IS_NATIVE} from '#/env' import {IS_INTERNAL, IS_IOS, IS_NATIVE} from '#/env'
import {device, useStorage} from '#/storage' import {device, useStorage} from '#/storage'
import {useActivitySubscriptionsNudged} from '#/storage/hooks/activity-subscriptions-nudged' import {useActivitySubscriptionsNudged} from '#/storage/hooks/activity-subscriptions-nudged'
type Props = NativeStackScreenProps<CommonNavigatorParams, 'Settings'> type Props = NativeStackScreenProps<CommonNavigatorParams, 'Settings'>
export function SettingsScreen({}: Props) { export function SettingsScreen({}: Props) {
const ax = useAnalytics()
const {_} = useLingui() const {_} = useLingui()
const reducedMotion = useReducedMotion() const reducedMotion = useReducedMotion()
const {logoutEveryAccount} = useSessionApi() const {logoutEveryAccount} = useSessionApi()
@@ -92,7 +93,6 @@ export function SettingsScreen({}: Props) {
const [showDevOptions, setShowDevOptions] = useState(false) const [showDevOptions, setShowDevOptions] = useState(false)
const findContactsEnabled = const findContactsEnabled =
useIsFindContactsFeatureEnabledBasedOnGeolocation() useIsFindContactsFeatureEnabledBasedOnGeolocation()
const gate = useGate()
return ( return (
<Layout.Screen> <Layout.Screen>
@@ -213,7 +213,7 @@ export function SettingsScreen({}: Props) {
</SettingsList.LinkItem> </SettingsList.LinkItem>
{IS_NATIVE && {IS_NATIVE &&
findContactsEnabled && findContactsEnabled &&
!gate('disable_settings_find_contacts') && ( !ax.feature(ax.Features.DisableSettingsFindContacts) && (
<SettingsList.LinkItem <SettingsList.LinkItem
to="/settings/find-contacts" to="/settings/find-contacts"
label={_(msg`Find friends from contacts`)}> label={_(msg`Find friends from contacts`)}>
+3 -3
View File
@@ -1,9 +1,9 @@
import {createContext, useContext, useMemo} from 'react' import {createContext, useContext, useMemo} from 'react'
import {useGate} from '#/lib/statsig/statsig'
import {useLanguagePrefs} from '#/state/preferences/languages' import {useLanguagePrefs} from '#/state/preferences/languages'
import {useServiceConfigQuery} from '#/state/queries/service-config' import {useServiceConfigQuery} from '#/state/queries/service-config'
import {useSession} from '#/state/session' import {useSession} from '#/state/session'
import {useAnalytics} from '#/analytics'
import {IS_DEV} from '#/env' import {IS_DEV} from '#/env'
import {device} from '#/storage' import {device} from '#/storage'
@@ -107,10 +107,10 @@ export function useLiveNowConfig(): LiveNowConfig {
} }
export function useCanGoLive() { export function useCanGoLive() {
const gate = useGate() const ax = useAnalytics()
const {hasSession} = useSession() const {hasSession} = useSession()
if (!hasSession) return false if (!hasSession) return false
return IS_DEV ? true : !gate('disable_live_now_beta') return IS_DEV ? true : !ax.feature(ax.Features.DisableLiveNowBeta)
} }
export function useCheckEmailConfirmed() { export function useCheckEmailConfirmed() {