···7878import {msg} from '@lingui/macro'
7979import {i18n, MessageDescriptor} from '@lingui/core'
8080import HashtagScreen from '#/screens/Hashtag'
8181+import {logEvent} from './lib/statsig/statsig'
81828283const navigationRef = createNavigationContainerRef<AllNavigatorParams>()
8384···649650 return
650651 }
651652 didInit = true
653653+652654 const initMs = Math.round(
653655 // @ts-ignore Emitted by Metro in the bundle prelude
654656 performance.now() - global.__BUNDLE_START_TIME__,
655657 )
656658 console.log(`Time to first paint: ${initMs} ms`)
659659+ logEvent('init', initMs)
660660+657661 if (__DEV__) {
658662 // This log is noisy, so keep false committed
659663 const shouldLog = false
+57-5
src/lib/statsig/statsig.tsx
···11import React from 'react'
22+import {
33+ Statsig,
44+ StatsigProvider,
55+ useGate as useStatsigGate,
66+} from 'statsig-react-native-expo'
77+import {useSession} from '../../state/session'
88+import {sha256} from 'js-sha256'
2933-export function useGate(_gateName: string) {
44- // Not enabled for native yet.
55- return false
1010+const statsigOptions = {
1111+ environment: {
1212+ tier: process.env.NODE_ENV === 'development' ? 'development' : 'production',
1313+ },
1414+ // Don't block on waiting for network. The fetched config will kick in on next load.
1515+ // This ensures the UI is always consistent and doesn't update mid-session.
1616+ // Note this makes cold load (no local storage) and private mode return `false` for all gates.
1717+ initTimeoutMs: 1,
1818+}
1919+2020+export function logEvent(
2121+ eventName: string,
2222+ value?: string | number | null,
2323+ metadata?: Record<string, string> | null,
2424+) {
2525+ Statsig.logEvent(eventName, value, metadata)
2626+}
2727+2828+export function useGate(gateName: string) {
2929+ const {isLoading, value} = useStatsigGate(gateName)
3030+ if (isLoading) {
3131+ // This should not happen because of waitForInitialization={true}.
3232+ console.error('Did not expected isLoading to ever be true.')
3333+ }
3434+ return value
3535+}
3636+3737+function toStatsigUser(did: string | undefined) {
3838+ let userID: string | undefined
3939+ if (did) {
4040+ userID = sha256(did)
4141+ }
4242+ return {userID}
643}
744845export function Provider({children}: {children: React.ReactNode}) {
99- // Not enabled for native yet.
1010- return children
4646+ const {currentAccount} = useSession()
4747+ const currentStatsigUser = React.useMemo(
4848+ () => toStatsigUser(currentAccount?.did),
4949+ [currentAccount?.did],
5050+ )
5151+ return (
5252+ <StatsigProvider
5353+ sdkKey="client-SXJakO39w9vIhl3D44u8UupyzFl4oZ2qPIkjwcvuPsV"
5454+ mountKey={currentStatsigUser.userID}
5555+ user={currentStatsigUser}
5656+ // This isn't really blocking due to short initTimeoutMs above.
5757+ // However, it ensures `isLoading` is always `false`.
5858+ waitForInitialization={true}
5959+ options={statsigOptions}>
6060+ {children}
6161+ </StatsigProvider>
6262+ )
1163}
+13-1
src/lib/statsig/statsig.web.tsx
···11import React from 'react'
22-import {StatsigProvider, useGate as useStatsigGate} from 'statsig-react'
22+import {
33+ Statsig,
44+ StatsigProvider,
55+ useGate as useStatsigGate,
66+} from 'statsig-react'
37import {useSession} from '../../state/session'
48import {sha256} from 'js-sha256'
59···1115 // This ensures the UI is always consistent and doesn't update mid-session.
1216 // Note this makes cold load (no local storage) and private mode return `false` for all gates.
1317 initTimeoutMs: 1,
1818+}
1919+2020+export function logEvent(
2121+ eventName: string,
2222+ value?: string | number | null,
2323+ metadata?: Record<string, string> | null,
2424+) {
2525+ Statsig.logEvent(eventName, value, metadata)
1426}
15271628export function useGate(gateName: string) {