[APP-1787] Some analytics cleanup (#9736)
* Clean up flags * Move getMetadataForLogger * Nail down attributers * Polyfill features cache
This commit is contained in:
@@ -1,10 +1,26 @@
|
|||||||
|
import {MMKV} from '@bsky.app/react-native-mmkv'
|
||||||
|
import {setPolyfills} from '@growthbook/growthbook'
|
||||||
import {GrowthBook} from '@growthbook/growthbook-react'
|
import {GrowthBook} from '@growthbook/growthbook-react'
|
||||||
|
|
||||||
import {type Metadata} from '#/analytics/metadata'
|
import {getNavigationMetadata, type Metadata} from '#/analytics/metadata'
|
||||||
import * as env from '#/env'
|
import * as env from '#/env'
|
||||||
|
|
||||||
export {Features} from '#/analytics/features/types'
|
export {Features} from '#/analytics/features/types'
|
||||||
|
|
||||||
|
const CACHE = new MMKV({id: 'bsky_features_cache'})
|
||||||
|
|
||||||
|
setPolyfills({
|
||||||
|
localStorage: {
|
||||||
|
getItem: key => {
|
||||||
|
const value = CACHE.getString(key)
|
||||||
|
return value != null ? JSON.parse(value) : null
|
||||||
|
},
|
||||||
|
setItem: async (key, value) => {
|
||||||
|
CACHE.set(key, JSON.stringify(value))
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* We vary the amount of time we wait for GrowthBook to fetch feature
|
* We vary the amount of time we wait for GrowthBook to fetch feature
|
||||||
* gates based on the strategy specified.
|
* gates based on the strategy specified.
|
||||||
@@ -46,17 +62,28 @@ export async function refresh({strategy}: {strategy: FeatureFetchStrategy}) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Converts our metadata into GrowthBook attributes and sets them.
|
* Converts our metadata into GrowthBook attributes and sets them. GrowthBook
|
||||||
|
* attributes are manually configured in the GrowthBook dashboard. So these
|
||||||
|
* values need to match exactly. Therefore, let's add them here manually to and
|
||||||
|
* not spread them to avoid mistakes.
|
||||||
*/
|
*/
|
||||||
export function setAttributes({base, session, preferences}: Metadata) {
|
export function setAttributes({
|
||||||
const {deviceId, sessionId, ...br} = base
|
base,
|
||||||
|
geolocation,
|
||||||
|
session,
|
||||||
|
preferences,
|
||||||
|
}: Metadata) {
|
||||||
features.setAttributes({
|
features.setAttributes({
|
||||||
device_id: deviceId, // GrowthBook special field
|
deviceId: base.deviceId,
|
||||||
session_id: sessionId, // GrowthBook special field
|
sessionId: base.sessionId,
|
||||||
user_id: session?.did, // GrowthBook special field
|
platform: base.platform,
|
||||||
id: session?.did, // GrowthBook special field
|
appVersion: base.appVersion,
|
||||||
...br,
|
countryCode: geolocation.countryCode,
|
||||||
...(session || {}),
|
regionCode: geolocation.regionCode,
|
||||||
...(preferences || {}),
|
did: session?.did,
|
||||||
|
isBskyPds: session?.isBskyPds,
|
||||||
|
appLanguage: preferences?.appLanguage,
|
||||||
|
contentLanguages: preferences?.contentLanguages,
|
||||||
|
currentScreen: getNavigationMetadata()?.currentScreen,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,12 @@
|
|||||||
export enum Features {
|
export enum Features {
|
||||||
DebugFeedContext = 'debug_show_feedcontext',
|
// core flags
|
||||||
IsBskyTeam = 'is_bsky_team_member',
|
IsBskyTeam = 'is_bsky_team',
|
||||||
DisableOnboardingFindContacts = 'disable_onboarding_find_contacts',
|
|
||||||
DisableSettingsFindContacts = 'disable_settings_find_contacts',
|
// debug flags
|
||||||
DisableLiveNowBeta = 'disable_live_now_beta',
|
DebugFeedContext = 'debug_feed_context',
|
||||||
|
|
||||||
|
// feature flags
|
||||||
|
ImportContactsOnboardingDisable = 'import_contacts:onboarding:disable',
|
||||||
|
ImportContactsSettingsDisable = 'import_contacts:settings:disable',
|
||||||
|
LiveNowBetaDisable = 'live_now_beta:disable',
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,13 +16,13 @@ import {
|
|||||||
useSessionId,
|
useSessionId,
|
||||||
} from '#/analytics/identifiers'
|
} from '#/analytics/identifiers'
|
||||||
import {
|
import {
|
||||||
|
getMetadataForLogger,
|
||||||
getNavigationMetadata,
|
getNavigationMetadata,
|
||||||
type MergeableMetadata,
|
type MergeableMetadata,
|
||||||
type Metadata,
|
type Metadata,
|
||||||
} from '#/analytics/metadata'
|
} from '#/analytics/metadata'
|
||||||
import {type Metrics, metrics} from '#/analytics/metrics'
|
import {type Metrics, metrics} from '#/analytics/metrics'
|
||||||
import * as refParams from '#/analytics/misc/refParams'
|
import * as refParams from '#/analytics/misc/refParams'
|
||||||
import {getMetadataForLogger} from '#/analytics/utils'
|
|
||||||
import * as env from '#/env'
|
import * as env from '#/env'
|
||||||
import {useGeolocation} from '#/geolocation'
|
import {useGeolocation} from '#/geolocation'
|
||||||
import {device} from '#/storage'
|
import {device} from '#/storage'
|
||||||
|
|||||||
@@ -53,9 +53,27 @@ export type NavigationMetadata = {
|
|||||||
}
|
}
|
||||||
let navigationMetadata: NavigationMetadata | undefined
|
let navigationMetadata: NavigationMetadata | undefined
|
||||||
export function getNavigationMetadata() {
|
export function getNavigationMetadata() {
|
||||||
console.log('metadata', JSON.stringify(navigationMetadata, null, 2))
|
|
||||||
return navigationMetadata
|
return navigationMetadata
|
||||||
}
|
}
|
||||||
export function setNavigationMetadata(meta: NavigationMetadata | undefined) {
|
export function setNavigationMetadata(meta: NavigationMetadata | undefined) {
|
||||||
navigationMetadata = meta
|
navigationMetadata = meta
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* We don't want or need to send all data to the logger
|
||||||
|
*/
|
||||||
|
export function getMetadataForLogger({
|
||||||
|
base,
|
||||||
|
geolocation,
|
||||||
|
session,
|
||||||
|
}: Metadata): Record<string, any> {
|
||||||
|
return {
|
||||||
|
deviceId: base.deviceId,
|
||||||
|
sessionId: base.sessionId,
|
||||||
|
platform: base.platform,
|
||||||
|
appVersion: base.appVersion,
|
||||||
|
countryCode: geolocation.countryCode,
|
||||||
|
regionCode: geolocation.regionCode,
|
||||||
|
isBskyPds: session?.isBskyPds || 'anonymous',
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ import {BSKY_SERVICE} from '#/lib/constants'
|
|||||||
import {type SessionAccount} from '#/state/session'
|
import {type SessionAccount} from '#/state/session'
|
||||||
import {
|
import {
|
||||||
type MergeableMetadata,
|
type MergeableMetadata,
|
||||||
type Metadata,
|
|
||||||
type SessionMetadata,
|
type SessionMetadata,
|
||||||
} from '#/analytics/metadata'
|
} from '#/analytics/metadata'
|
||||||
|
|
||||||
@@ -32,19 +31,3 @@ export function accountToSessionMetadata(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getMetadataForLogger({
|
|
||||||
base,
|
|
||||||
geolocation,
|
|
||||||
session,
|
|
||||||
}: Metadata): Record<string, any> {
|
|
||||||
return {
|
|
||||||
deviceId: base.deviceId,
|
|
||||||
sessionId: base.sessionId,
|
|
||||||
platform: base.platform,
|
|
||||||
appVersion: base.appVersion,
|
|
||||||
countryCode: geolocation.countryCode,
|
|
||||||
regionCode: geolocation.regionCode,
|
|
||||||
isBskyPds: session?.isBskyPds || 'anonymous',
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -24,7 +24,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.features.enabled(props.features.DisableLiveNowBeta)
|
!props.features.enabled(props.features.LiveNowBetaDisable)
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ export function Onboarding() {
|
|||||||
ENV !== 'e2e' &&
|
ENV !== 'e2e' &&
|
||||||
IS_NATIVE &&
|
IS_NATIVE &&
|
||||||
findContactsEnabled &&
|
findContactsEnabled &&
|
||||||
!ax.features.enabled(ax.features.DisableOnboardingFindContacts)
|
!ax.features.enabled(ax.features.ImportContactsOnboardingDisable)
|
||||||
|
|
||||||
const [state, dispatch] = useReducer(
|
const [state, dispatch] = useReducer(
|
||||||
reducer,
|
reducer,
|
||||||
|
|||||||
@@ -213,7 +213,7 @@ export function SettingsScreen({}: Props) {
|
|||||||
</SettingsList.LinkItem>
|
</SettingsList.LinkItem>
|
||||||
{IS_NATIVE &&
|
{IS_NATIVE &&
|
||||||
findContactsEnabled &&
|
findContactsEnabled &&
|
||||||
!ax.features.enabled(ax.features.DisableSettingsFindContacts) && (
|
!ax.features.enabled(ax.features.ImportContactsSettingsDisable) && (
|
||||||
<SettingsList.LinkItem
|
<SettingsList.LinkItem
|
||||||
to="/settings/find-contacts"
|
to="/settings/find-contacts"
|
||||||
label={_(msg`Find friends from contacts`)}>
|
label={_(msg`Find friends from contacts`)}>
|
||||||
|
|||||||
@@ -106,7 +106,7 @@ export function useCanGoLive() {
|
|||||||
const ax = useAnalytics()
|
const ax = useAnalytics()
|
||||||
const {hasSession} = useSession()
|
const {hasSession} = useSession()
|
||||||
if (!hasSession) return false
|
if (!hasSession) return false
|
||||||
return IS_DEV ? true : !ax.features.enabled(ax.features.DisableLiveNowBeta)
|
return IS_DEV ? true : !ax.features.enabled(ax.features.LiveNowBetaDisable)
|
||||||
}
|
}
|
||||||
|
|
||||||
export function useCheckEmailConfirmed() {
|
export function useCheckEmailConfirmed() {
|
||||||
|
|||||||
Reference in New Issue
Block a user