Some comments and cleanup
This commit is contained in:
@@ -0,0 +1,32 @@
|
||||
import {useEffect, useRef} from 'react'
|
||||
|
||||
import {getCurrentState, onAppStateChange} from '#/lib/appState'
|
||||
import {useAnalytics} from '#/analytics'
|
||||
|
||||
/**
|
||||
* Tracks passive analytics like app foreground/background time.
|
||||
*/
|
||||
export function PassiveAnalytics() {
|
||||
const ax = useAnalytics()
|
||||
const lastActive = useRef(
|
||||
getCurrentState() === 'active' ? performance.now() : null,
|
||||
)
|
||||
|
||||
useEffect(() => {
|
||||
const sub = onAppStateChange(state => {
|
||||
if (state === 'active') {
|
||||
lastActive.current = performance.now()
|
||||
ax.metric('state:foreground', {})
|
||||
} else if (lastActive.current !== null) {
|
||||
ax.metric('state:background', {
|
||||
secondsActive: Math.round(
|
||||
(performance.now() - lastActive.current) / 1e3,
|
||||
),
|
||||
})
|
||||
}
|
||||
})
|
||||
return () => sub.remove()
|
||||
}, [ax])
|
||||
|
||||
return null
|
||||
}
|
||||
@@ -61,8 +61,17 @@ const Context = createContext<AnalyticsBaseContextType>({
|
||||
},
|
||||
})
|
||||
|
||||
/**
|
||||
* Ensures that deviceId is set and migrated from legacy storage. Handled on
|
||||
* startup in `App.<platform>.tsx`. This must be awaited prior to the app
|
||||
* booting up.
|
||||
*/
|
||||
export const setupDeviceId = getAndMigrateDeviceId()
|
||||
|
||||
/**
|
||||
* Analytics context provider. Decorates the parent analytics context with
|
||||
* additional metadata. Nesting should be done carefully and sparingly.
|
||||
*/
|
||||
export function AnalyticsContext({
|
||||
children,
|
||||
metadata,
|
||||
@@ -102,6 +111,11 @@ export function AnalyticsContext({
|
||||
return <Context.Provider value={childContext}>{children}</Context.Provider>
|
||||
}
|
||||
|
||||
/**
|
||||
* Feature gates provider. Decorates the parent analytics context with
|
||||
* feature gate capabilities. Should be mounted within `AnalyticsContext`,
|
||||
* and below the `<Fragment key={did} />` breaker in `App.<platform>.tsx`.
|
||||
*/
|
||||
export function AnalyticsFeaturesContext({
|
||||
children,
|
||||
}: {
|
||||
@@ -133,10 +147,18 @@ export function AnalyticsFeaturesContext({
|
||||
return <Context.Provider value={childContext}>{children}</Context.Provider>
|
||||
}
|
||||
|
||||
/**
|
||||
* Basic analytics context without feature gates. Should really only be used
|
||||
* above the `AnalyticsFeaturesContext` provider.
|
||||
*/
|
||||
export function useAnalyticsBase() {
|
||||
return useContext(Context)
|
||||
}
|
||||
|
||||
/**
|
||||
* The main analytics context, including feature gates. Use this everywhere you
|
||||
* need metrics, features, or logging within the React tree.
|
||||
*/
|
||||
export function useAnalytics() {
|
||||
const ctx = useContext(Context)
|
||||
if (!('feature' in ctx) || !('Features' in ctx)) {
|
||||
|
||||
@@ -3,7 +3,7 @@ import {isNetworkError} from '#/lib/strings/errors'
|
||||
import {Sentry} from '#/logger/sentry/lib'
|
||||
import * as env from '#/env'
|
||||
|
||||
// TODO just fucken use logger in here
|
||||
// TODO debug logging
|
||||
|
||||
type Event<M extends Record<string, any>> = {
|
||||
time: number
|
||||
|
||||
@@ -3,18 +3,3 @@ import {type Events} from '#/analytics/metrics/types'
|
||||
|
||||
export type {Events as Metrics} from '#/analytics/metrics/types'
|
||||
export const metrics = new MetricsClient<Events>()
|
||||
|
||||
/*
|
||||
* TODO
|
||||
let lastActive = getCurrentState() === 'active' ? performance.now() : null
|
||||
onAppStateChange(state => {
|
||||
if (state === 'active') {
|
||||
lastActive = performance.now()
|
||||
metrics.track('state:foreground', {})
|
||||
} else if (lastActive !== null) {
|
||||
metrics.track('state:background', {
|
||||
secondsActive: Math.round((performance.now() - lastActive) / 1e3),
|
||||
})
|
||||
}
|
||||
})
|
||||
*/
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
/*
|
||||
* Do not import runtime code into this file
|
||||
*/
|
||||
|
||||
import {type NotificationReason} from '#/lib/hooks/useNotificationHandler'
|
||||
import {type FeedDescriptor} from '#/state/queries/post-feed'
|
||||
import {type LiveEventFeedMetricContext} from '#/features/liveEvents/types'
|
||||
|
||||
@@ -4,6 +4,10 @@ import {BSKY_SERVICE} from '#/lib/constants'
|
||||
import {type SessionAccount} from '#/state/session'
|
||||
import {type MergeableMetadata, type SessionMetadata} from '#/analytics/types'
|
||||
|
||||
/**
|
||||
* Thin `useMemo` wrapper that marks the metadata as memoized and provides a
|
||||
* type guard.
|
||||
*/
|
||||
export function useMeta(metadata: MergeableMetadata) {
|
||||
const m = useMemo(() => metadata, [metadata])
|
||||
// @ts-ignore
|
||||
|
||||
@@ -42,6 +42,7 @@ import {Outlet as PortalOutlet} from '#/components/Portal'
|
||||
import {useAgeAssurance} from '#/ageAssurance'
|
||||
import {NoAccessScreen} from '#/ageAssurance/components/NoAccessScreen'
|
||||
import {RedirectOverlay} from '#/ageAssurance/components/RedirectOverlay'
|
||||
import {PassiveAnalytics} from '#/analytics/PassiveAnalytics'
|
||||
import {IS_ANDROID, IS_IOS} from '#/env'
|
||||
import {RoutesContainer, TabsNavigator} from '#/Navigation'
|
||||
import {BottomSheetOutlet} from '../../../modules/bottom-sheet'
|
||||
@@ -245,6 +246,8 @@ export function Shell() {
|
||||
<RedirectOverlay />
|
||||
</>
|
||||
)}
|
||||
|
||||
<PassiveAnalytics />
|
||||
</View>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -34,6 +34,7 @@ import {WelcomeModal} from '#/components/WelcomeModal'
|
||||
import {useAgeAssurance} from '#/ageAssurance'
|
||||
import {NoAccessScreen} from '#/ageAssurance/components/NoAccessScreen'
|
||||
import {RedirectOverlay} from '#/ageAssurance/components/RedirectOverlay'
|
||||
import {PassiveAnalytics} from '#/analytics/PassiveAnalytics'
|
||||
import {FlatNavigator, RoutesContainer} from '#/Navigation'
|
||||
import {Composer} from './Composer.web'
|
||||
import {DrawerContent} from './Drawer'
|
||||
@@ -181,6 +182,8 @@ export function Shell() {
|
||||
<RedirectOverlay />
|
||||
</>
|
||||
)}
|
||||
|
||||
<PassiveAnalytics />
|
||||
</View>
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user