[Statsig] Slightly block the UI on gates (#3608)
parent
6101c32bd9
commit
bef7d8a325
|
@ -8,6 +8,7 @@ import {logger} from '#/logger'
|
|||
import {isWeb} from '#/platform/detection'
|
||||
import {IS_TESTFLIGHT} from 'lib/app-info'
|
||||
import {useSession} from '../../state/session'
|
||||
import {timeout} from '../async/timeout'
|
||||
import {useNonReactiveCallback} from '../hooks/useNonReactiveCallback'
|
||||
import {LogEvents} from './events'
|
||||
import {Gate} from './gates'
|
||||
|
@ -164,6 +165,31 @@ AppState.addEventListener('change', (state: AppStateStatus) => {
|
|||
}
|
||||
})
|
||||
|
||||
export async function tryFetchGates(
|
||||
did: string,
|
||||
strategy: 'prefer-low-latency' | 'prefer-fresh-gates',
|
||||
) {
|
||||
try {
|
||||
let timeoutMs = 250 // Don't block the UI if we can't do this fast.
|
||||
if (strategy === 'prefer-fresh-gates') {
|
||||
// Use this for less common operations where the user would be OK with a delay.
|
||||
timeoutMs = 1500
|
||||
}
|
||||
// Note: This condition is currently false the very first render because
|
||||
// Statsig has not initialized yet. In the future, we can fix this by
|
||||
// doing the initialization ourselves instead of relying on the provider.
|
||||
if (Statsig.initializeCalled()) {
|
||||
await Promise.race([
|
||||
timeout(timeoutMs),
|
||||
Statsig.prefetchUsers([toStatsigUser(did)]),
|
||||
])
|
||||
}
|
||||
} catch (e) {
|
||||
// Don't leak errors to the calling code, this is meant to be always safe.
|
||||
console.error(e)
|
||||
}
|
||||
}
|
||||
|
||||
export function Provider({children}: {children: React.ReactNode}) {
|
||||
const {currentAccount, accounts} = useSession()
|
||||
const did = currentAccount?.did
|
||||
|
|
|
@ -9,7 +9,7 @@ import {jwtDecode} from 'jwt-decode'
|
|||
import {track} from '#/lib/analytics/analytics'
|
||||
import {networkRetry} from '#/lib/async/retry'
|
||||
import {IS_TEST_USER} from '#/lib/constants'
|
||||
import {logEvent, LogEvents} from '#/lib/statsig/statsig'
|
||||
import {logEvent, LogEvents, tryFetchGates} from '#/lib/statsig/statsig'
|
||||
import {hasProp} from '#/lib/type-guards'
|
||||
import {logger} from '#/logger'
|
||||
import {isWeb} from '#/platform/detection'
|
||||
|
@ -243,6 +243,10 @@ export function Provider({children}: React.PropsWithChildren<{}>) {
|
|||
if (!agent.session) {
|
||||
throw new Error(`session: createAccount failed to establish a session`)
|
||||
}
|
||||
const fetchingGates = tryFetchGates(
|
||||
agent.session.did,
|
||||
'prefer-fresh-gates',
|
||||
)
|
||||
|
||||
const deactivated = isSessionDeactivated(agent.session.accessJwt)
|
||||
if (!deactivated) {
|
||||
|
@ -283,6 +287,7 @@ export function Provider({children}: React.PropsWithChildren<{}>) {
|
|||
)
|
||||
|
||||
__globalAgent = agent
|
||||
await fetchingGates
|
||||
upsertAccount(account)
|
||||
|
||||
logger.debug(`session: created account`, {}, logger.DebugContext.session)
|
||||
|
@ -303,6 +308,10 @@ export function Provider({children}: React.PropsWithChildren<{}>) {
|
|||
if (!agent.session) {
|
||||
throw new Error(`session: login failed to establish a session`)
|
||||
}
|
||||
const fetchingGates = tryFetchGates(
|
||||
agent.session.did,
|
||||
'prefer-fresh-gates',
|
||||
)
|
||||
|
||||
const account: SessionAccount = {
|
||||
service: agent.service.toString(),
|
||||
|
@ -330,6 +339,7 @@ export function Provider({children}: React.PropsWithChildren<{}>) {
|
|||
__globalAgent = agent
|
||||
// @ts-ignore
|
||||
if (IS_DEV && isWeb) window.agent = agent
|
||||
await fetchingGates
|
||||
upsertAccount(account)
|
||||
|
||||
logger.debug(`session: logged in`, {}, logger.DebugContext.session)
|
||||
|
@ -362,6 +372,7 @@ export function Provider({children}: React.PropsWithChildren<{}>) {
|
|||
const initSession = React.useCallback<ApiContext['initSession']>(
|
||||
async account => {
|
||||
logger.debug(`session: initSession`, {}, logger.DebugContext.session)
|
||||
const fetchingGates = tryFetchGates(account.did, 'prefer-low-latency')
|
||||
|
||||
const agent = new BskyAgent({
|
||||
service: account.service,
|
||||
|
@ -406,6 +417,7 @@ export function Provider({children}: React.PropsWithChildren<{}>) {
|
|||
|
||||
agent.session = prevSession
|
||||
__globalAgent = agent
|
||||
await fetchingGates
|
||||
upsertAccount(account)
|
||||
|
||||
if (prevSession.deactivated) {
|
||||
|
@ -442,6 +454,7 @@ export function Provider({children}: React.PropsWithChildren<{}>) {
|
|||
try {
|
||||
const freshAccount = await resumeSessionWithFreshAccount()
|
||||
__globalAgent = agent
|
||||
await fetchingGates
|
||||
upsertAccount(freshAccount)
|
||||
} catch (e) {
|
||||
/*
|
||||
|
|
Loading…
Reference in New Issue