Move everything out of React
This commit is contained in:
+52
-57
@@ -22,10 +22,7 @@ import {s} from '#/lib/styles'
|
||||
import {ThemeProvider} from '#/lib/ThemeContext'
|
||||
import I18nProvider from '#/locale/i18nProvider'
|
||||
import {logger} from '#/logger'
|
||||
import {
|
||||
initializer as growthbookInitializer,
|
||||
Provider as GrowthBookProvider,
|
||||
} from '#/logger/growthbook/context'
|
||||
import {initializer as growthbookInitializer} from '#/logger/growthbook'
|
||||
import {Provider as A11yProvider} from '#/state/a11y'
|
||||
import {Provider as MutedThreadsProvider} from '#/state/cache/thread-mutes'
|
||||
import {Provider as DialogStateProvider} from '#/state/dialogs'
|
||||
@@ -147,59 +144,57 @@ function InnerApp() {
|
||||
<React.Fragment
|
||||
// Resets the entire tree below when it changes:
|
||||
key={currentAccount?.did}>
|
||||
<GrowthBookProvider>
|
||||
<QueryProvider currentDid={currentAccount?.did}>
|
||||
<PolicyUpdateOverlayProvider>
|
||||
<StatsigProvider>
|
||||
<LiveEventsProvider>
|
||||
<AgeAssuranceV2Provider>
|
||||
<ComposerProvider>
|
||||
<MessagesProvider>
|
||||
{/* LabelDefsProvider MUST come before ModerationOptsProvider */}
|
||||
<LabelDefsProvider>
|
||||
<ModerationOptsProvider>
|
||||
<LoggedOutViewProvider>
|
||||
<SelectedFeedProvider>
|
||||
<HiddenRepliesProvider>
|
||||
<HomeBadgeProvider>
|
||||
<UnreadNotifsProvider>
|
||||
<BackgroundNotificationPreferencesProvider>
|
||||
<MutedThreadsProvider>
|
||||
<ProgressGuideProvider>
|
||||
<ServiceAccountManager>
|
||||
<EmailVerificationProvider>
|
||||
<HideBottomBarBorderProvider>
|
||||
<GestureHandlerRootView
|
||||
style={s.h100pct}>
|
||||
<GlobalGestureEventsProvider>
|
||||
<IntentDialogProvider>
|
||||
<TestCtrls />
|
||||
<Shell />
|
||||
<ToastOutlet />
|
||||
</IntentDialogProvider>
|
||||
</GlobalGestureEventsProvider>
|
||||
</GestureHandlerRootView>
|
||||
</HideBottomBarBorderProvider>
|
||||
</EmailVerificationProvider>
|
||||
</ServiceAccountManager>
|
||||
</ProgressGuideProvider>
|
||||
</MutedThreadsProvider>
|
||||
</BackgroundNotificationPreferencesProvider>
|
||||
</UnreadNotifsProvider>
|
||||
</HomeBadgeProvider>
|
||||
</HiddenRepliesProvider>
|
||||
</SelectedFeedProvider>
|
||||
</LoggedOutViewProvider>
|
||||
</ModerationOptsProvider>
|
||||
</LabelDefsProvider>
|
||||
</MessagesProvider>
|
||||
</ComposerProvider>
|
||||
</AgeAssuranceV2Provider>
|
||||
</LiveEventsProvider>
|
||||
</StatsigProvider>
|
||||
</PolicyUpdateOverlayProvider>
|
||||
</QueryProvider>
|
||||
</GrowthBookProvider>
|
||||
<QueryProvider currentDid={currentAccount?.did}>
|
||||
<PolicyUpdateOverlayProvider>
|
||||
<StatsigProvider>
|
||||
<LiveEventsProvider>
|
||||
<AgeAssuranceV2Provider>
|
||||
<ComposerProvider>
|
||||
<MessagesProvider>
|
||||
{/* LabelDefsProvider MUST come before ModerationOptsProvider */}
|
||||
<LabelDefsProvider>
|
||||
<ModerationOptsProvider>
|
||||
<LoggedOutViewProvider>
|
||||
<SelectedFeedProvider>
|
||||
<HiddenRepliesProvider>
|
||||
<HomeBadgeProvider>
|
||||
<UnreadNotifsProvider>
|
||||
<BackgroundNotificationPreferencesProvider>
|
||||
<MutedThreadsProvider>
|
||||
<ProgressGuideProvider>
|
||||
<ServiceAccountManager>
|
||||
<EmailVerificationProvider>
|
||||
<HideBottomBarBorderProvider>
|
||||
<GestureHandlerRootView
|
||||
style={s.h100pct}>
|
||||
<GlobalGestureEventsProvider>
|
||||
<IntentDialogProvider>
|
||||
<TestCtrls />
|
||||
<Shell />
|
||||
<ToastOutlet />
|
||||
</IntentDialogProvider>
|
||||
</GlobalGestureEventsProvider>
|
||||
</GestureHandlerRootView>
|
||||
</HideBottomBarBorderProvider>
|
||||
</EmailVerificationProvider>
|
||||
</ServiceAccountManager>
|
||||
</ProgressGuideProvider>
|
||||
</MutedThreadsProvider>
|
||||
</BackgroundNotificationPreferencesProvider>
|
||||
</UnreadNotifsProvider>
|
||||
</HomeBadgeProvider>
|
||||
</HiddenRepliesProvider>
|
||||
</SelectedFeedProvider>
|
||||
</LoggedOutViewProvider>
|
||||
</ModerationOptsProvider>
|
||||
</LabelDefsProvider>
|
||||
</MessagesProvider>
|
||||
</ComposerProvider>
|
||||
</AgeAssuranceV2Provider>
|
||||
</LiveEventsProvider>
|
||||
</StatsigProvider>
|
||||
</PolicyUpdateOverlayProvider>
|
||||
</QueryProvider>
|
||||
</React.Fragment>
|
||||
</VideoVolumeProvider>
|
||||
</Splash>
|
||||
|
||||
+48
-53
@@ -13,10 +13,7 @@ import {Provider as StatsigProvider} from '#/lib/statsig/statsig'
|
||||
import {ThemeProvider} from '#/lib/ThemeContext'
|
||||
import I18nProvider from '#/locale/i18nProvider'
|
||||
import {logger} from '#/logger'
|
||||
import {
|
||||
initializer as growthbookInitializer,
|
||||
Provider as GrowthBookProvider,
|
||||
} from '#/logger/growthbook/context'
|
||||
import {initializer as growthbookInitializer} from '#/logger/growthbook'
|
||||
import {Provider as A11yProvider} from '#/state/a11y'
|
||||
import {Provider as MutedThreadsProvider} from '#/state/cache/thread-mutes'
|
||||
import {Provider as DialogStateProvider} from '#/state/dialogs'
|
||||
@@ -126,55 +123,53 @@ function InnerApp() {
|
||||
<React.Fragment
|
||||
// Resets the entire tree below when it changes:
|
||||
key={currentAccount?.did}>
|
||||
<GrowthBookProvider>
|
||||
<QueryProvider currentDid={currentAccount?.did}>
|
||||
<PolicyUpdateOverlayProvider>
|
||||
<StatsigProvider>
|
||||
<LiveEventsProvider>
|
||||
<AgeAssuranceV2Provider>
|
||||
<ComposerProvider>
|
||||
<MessagesProvider>
|
||||
{/* LabelDefsProvider MUST come before ModerationOptsProvider */}
|
||||
<LabelDefsProvider>
|
||||
<ModerationOptsProvider>
|
||||
<LoggedOutViewProvider>
|
||||
<SelectedFeedProvider>
|
||||
<HiddenRepliesProvider>
|
||||
<HomeBadgeProvider>
|
||||
<UnreadNotifsProvider>
|
||||
<BackgroundNotificationPreferencesProvider>
|
||||
<MutedThreadsProvider>
|
||||
<SafeAreaProvider>
|
||||
<ProgressGuideProvider>
|
||||
<ServiceConfigProvider>
|
||||
<EmailVerificationProvider>
|
||||
<HideBottomBarBorderProvider>
|
||||
<IntentDialogProvider>
|
||||
<Shell />
|
||||
<ToastOutlet />
|
||||
</IntentDialogProvider>
|
||||
</HideBottomBarBorderProvider>
|
||||
</EmailVerificationProvider>
|
||||
</ServiceConfigProvider>
|
||||
</ProgressGuideProvider>
|
||||
</SafeAreaProvider>
|
||||
</MutedThreadsProvider>
|
||||
</BackgroundNotificationPreferencesProvider>
|
||||
</UnreadNotifsProvider>
|
||||
</HomeBadgeProvider>
|
||||
</HiddenRepliesProvider>
|
||||
</SelectedFeedProvider>
|
||||
</LoggedOutViewProvider>
|
||||
</ModerationOptsProvider>
|
||||
</LabelDefsProvider>
|
||||
</MessagesProvider>
|
||||
</ComposerProvider>
|
||||
</AgeAssuranceV2Provider>
|
||||
</LiveEventsProvider>
|
||||
</StatsigProvider>
|
||||
</PolicyUpdateOverlayProvider>
|
||||
</QueryProvider>
|
||||
</GrowthBookProvider>
|
||||
<QueryProvider currentDid={currentAccount?.did}>
|
||||
<PolicyUpdateOverlayProvider>
|
||||
<StatsigProvider>
|
||||
<LiveEventsProvider>
|
||||
<AgeAssuranceV2Provider>
|
||||
<ComposerProvider>
|
||||
<MessagesProvider>
|
||||
{/* LabelDefsProvider MUST come before ModerationOptsProvider */}
|
||||
<LabelDefsProvider>
|
||||
<ModerationOptsProvider>
|
||||
<LoggedOutViewProvider>
|
||||
<SelectedFeedProvider>
|
||||
<HiddenRepliesProvider>
|
||||
<HomeBadgeProvider>
|
||||
<UnreadNotifsProvider>
|
||||
<BackgroundNotificationPreferencesProvider>
|
||||
<MutedThreadsProvider>
|
||||
<SafeAreaProvider>
|
||||
<ProgressGuideProvider>
|
||||
<ServiceConfigProvider>
|
||||
<EmailVerificationProvider>
|
||||
<HideBottomBarBorderProvider>
|
||||
<IntentDialogProvider>
|
||||
<Shell />
|
||||
<ToastOutlet />
|
||||
</IntentDialogProvider>
|
||||
</HideBottomBarBorderProvider>
|
||||
</EmailVerificationProvider>
|
||||
</ServiceConfigProvider>
|
||||
</ProgressGuideProvider>
|
||||
</SafeAreaProvider>
|
||||
</MutedThreadsProvider>
|
||||
</BackgroundNotificationPreferencesProvider>
|
||||
</UnreadNotifsProvider>
|
||||
</HomeBadgeProvider>
|
||||
</HiddenRepliesProvider>
|
||||
</SelectedFeedProvider>
|
||||
</LoggedOutViewProvider>
|
||||
</ModerationOptsProvider>
|
||||
</LabelDefsProvider>
|
||||
</MessagesProvider>
|
||||
</ComposerProvider>
|
||||
</AgeAssuranceV2Provider>
|
||||
</LiveEventsProvider>
|
||||
</StatsigProvider>
|
||||
</PolicyUpdateOverlayProvider>
|
||||
</QueryProvider>
|
||||
</React.Fragment>
|
||||
</ActiveVideoProvider>
|
||||
</VideoVolumeProvider>
|
||||
|
||||
@@ -4,7 +4,7 @@ import {t} from '@lingui/macro'
|
||||
|
||||
import {DISCOVER_DEBUG_DIDS} from '#/lib/constants'
|
||||
import {useGate} from '#/lib/statsig/statsig'
|
||||
import {logEvent} from '#/logger/growthbook/context'
|
||||
import {logEvent} from '#/logger/growthbook'
|
||||
import {useSession} from '#/state/session'
|
||||
import {atoms as a, useTheme} from '#/alf'
|
||||
import * as Toast from '#/components/Toast'
|
||||
|
||||
@@ -1,20 +1,19 @@
|
||||
import {useCallback, useEffect} from 'react'
|
||||
import {useCallback} from 'react'
|
||||
import {Platform} from 'react-native'
|
||||
import {growthbookTrackingPlugin} from '@growthbook/growthbook/plugins'
|
||||
import {GrowthBook, GrowthBookProvider} from '@growthbook/growthbook-react'
|
||||
import {GrowthBook} from '@growthbook/growthbook-react'
|
||||
|
||||
import {BSKY_SERVICE} from '#/lib/constants'
|
||||
import {
|
||||
getAndMigrateStableId,
|
||||
getSessionId,
|
||||
getStableId,
|
||||
getStableIdOrThrow,
|
||||
} from '#/logger/growthbook/identifiers'
|
||||
import * as referrer from '#/logger/growthbook/util/referrer'
|
||||
import * as persisted from '#/state/persisted'
|
||||
import {type SessionAccount, useSession} from '#/state/session'
|
||||
import {type SessionAccount} from '#/state/session'
|
||||
import * as env from '#/env'
|
||||
import {type Geolocation, useGeolocation} from '#/geolocation'
|
||||
import {device} from '#/storage'
|
||||
|
||||
const TIMEOUT_INIT = 500 // TODO should base on p99 or something
|
||||
const TIMEOUT_PREFER_LOW_LATENCY = 250
|
||||
@@ -63,18 +62,12 @@ type UserAttributes = GrowthBookDefaultUserAttributes & {
|
||||
}
|
||||
type Attributes = DefaultAttributes & UserAttributes
|
||||
|
||||
/**
|
||||
* We cache the geolocation outside of React to use when setting
|
||||
* default attributes outside React, such as during `refresh()`.
|
||||
*/
|
||||
let unsafeGeolocation: Geolocation | null = null
|
||||
|
||||
const gb = new GrowthBook({
|
||||
apiHost: env.GROWTHBOOK_API_HOST,
|
||||
clientKey: env.GROWTHBOOK_CLIENT_KEY,
|
||||
plugins: [growthbookTrackingPlugin()],
|
||||
trackingCallback: (experiment, result) => {
|
||||
console.log('Experiment Viewed', {
|
||||
console.debug('Experiment Viewed', {
|
||||
experimentId: experiment.key,
|
||||
variationId: result.key,
|
||||
})
|
||||
@@ -83,10 +76,7 @@ const gb = new GrowthBook({
|
||||
variationId: result.key,
|
||||
})
|
||||
},
|
||||
attributes: {
|
||||
device_id: getStableId() || 'unset',
|
||||
session_id: getSessionId(),
|
||||
} satisfies GrowthBookDefaultAttributes,
|
||||
attributes: getDefaultAttributes(),
|
||||
})
|
||||
|
||||
/**
|
||||
@@ -147,47 +137,15 @@ export function useGate() {
|
||||
}, [])
|
||||
}
|
||||
|
||||
/**
|
||||
* Main provider for GrowthBook and feature flag context. Should be rendered
|
||||
* _after_ `initializer` is complete, and _after_ the Session provider.
|
||||
*/
|
||||
export function Provider({children}: {children: React.ReactNode}) {
|
||||
const geo = useGeolocation()
|
||||
const {currentAccount} = useSession()
|
||||
|
||||
/**
|
||||
* Decorate existing attributes with any new default attributes
|
||||
*/
|
||||
useEffect(() => {
|
||||
// cache outside react
|
||||
unsafeGeolocation = geo
|
||||
const attr = {
|
||||
...gb.getAttributes(),
|
||||
...getDefaultAttributes(),
|
||||
}
|
||||
gb.setAttributes(attr)
|
||||
console.debug(`update attributes`, {attributes: attr})
|
||||
}, [geo])
|
||||
|
||||
/**
|
||||
* Update user attributes on session change, and clear them on logout
|
||||
*/
|
||||
useEffect(() => {
|
||||
setAttributesForAccount(currentAccount)
|
||||
}, [currentAccount])
|
||||
|
||||
return <GrowthBookProvider growthbook={gb}>{children}</GrowthBookProvider>
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the default attributes that should always be set
|
||||
* on the GrowthBook instance
|
||||
*/
|
||||
function getDefaultAttributes() {
|
||||
return {
|
||||
device_id: getStableIdOrThrow(),
|
||||
device_id: getStableId() || 'unset',
|
||||
session_id: getSessionId(),
|
||||
country: unsafeGeolocation?.countryCode || 'unknown',
|
||||
country: device.get(['mergedGeolocation'])?.countryCode || 'unknown',
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import {nanoid} from 'nanoid/non-secure'
|
||||
|
||||
import {logEvent} from '#/lib/statsig/statsig'
|
||||
import {logEvent} from '#/logger/growthbook'
|
||||
import {add} from '#/logger/logDump'
|
||||
import {type MetricEvents} from '#/logger/metrics'
|
||||
import {consoleTransport} from '#/logger/transports/console'
|
||||
|
||||
@@ -15,6 +15,7 @@ export enum LogContext {
|
||||
AgeAssurance = 'age-assurance',
|
||||
PolicyUpdate = 'policy-update',
|
||||
Geolocation = 'geolocation',
|
||||
GrowthBook = 'growthbook',
|
||||
|
||||
/**
|
||||
* METRIC IS FOR INTERNAL USE ONLY, don't create any other loggers using this
|
||||
|
||||
@@ -24,7 +24,7 @@ import {
|
||||
} from '#/lib/constants'
|
||||
import {getAge} from '#/lib/strings/time'
|
||||
import {logger} from '#/logger'
|
||||
import {refresh as refreshGates} from '#/logger/growthbook/context'
|
||||
import {refresh as refreshGates} from '#/logger/growthbook'
|
||||
import {snoozeBirthdateUpdateAllowedForDid} from '#/state/birthdate'
|
||||
import {snoozeEmailConfirmationPrompt} from '#/state/shell/reminders'
|
||||
import {
|
||||
|
||||
Reference in New Issue
Block a user