Move analytics out of init (#2115)
* Remove listenSessionLoaded from analytics * Move analytics init call to navigation ready * Remove zod dependency from analytics * Mirror changes on the web * Delete listenSessionLoaded * Only set up listeners oncezio/stable
parent
748212e000
commit
6335be14e1
|
@ -16,7 +16,7 @@ import {ThemeProvider} from 'lib/ThemeContext'
|
|||
import {s} from 'lib/styles'
|
||||
import {Shell} from 'view/shell'
|
||||
import * as notifications from 'lib/notifications/notifications'
|
||||
import * as analytics from 'lib/analytics/analytics'
|
||||
import {Provider as AnalyticsProvider} from 'lib/analytics/analytics'
|
||||
import * as Toast from 'view/com/util/Toast'
|
||||
import {queryClient} from 'lib/react-query'
|
||||
import {TestCtrls} from 'view/com/testing/TestCtrls'
|
||||
|
@ -45,7 +45,6 @@ function InnerApp() {
|
|||
|
||||
// init
|
||||
useEffect(() => {
|
||||
analytics.init()
|
||||
notifications.init(queryClient)
|
||||
listenSessionDropped(() => {
|
||||
Toast.show('Sorry! Your session expired. Please log in again.')
|
||||
|
@ -72,7 +71,7 @@ function InnerApp() {
|
|||
<LoggedOutViewProvider>
|
||||
<UnreadNotifsProvider>
|
||||
<ThemeProvider theme={colorMode}>
|
||||
<analytics.Provider>
|
||||
<AnalyticsProvider>
|
||||
{/* All components should be within this provider */}
|
||||
<RootSiblingParent>
|
||||
<GestureHandlerRootView style={s.h100pct}>
|
||||
|
@ -80,7 +79,7 @@ function InnerApp() {
|
|||
<Shell />
|
||||
</GestureHandlerRootView>
|
||||
</RootSiblingParent>
|
||||
</analytics.Provider>
|
||||
</AnalyticsProvider>
|
||||
</ThemeProvider>
|
||||
</UnreadNotifsProvider>
|
||||
</LoggedOutViewProvider>
|
||||
|
|
|
@ -9,7 +9,7 @@ import 'view/icons'
|
|||
|
||||
import {init as initPersistedState} from '#/state/persisted'
|
||||
import {useColorMode} from 'state/shell'
|
||||
import * as analytics from 'lib/analytics/analytics'
|
||||
import {Provider as AnalyticsProvider} from 'lib/analytics/analytics'
|
||||
import {Shell} from 'view/shell/index'
|
||||
import {ToastContainer} from 'view/com/util/Toast.web'
|
||||
import {ThemeProvider} from 'lib/ThemeContext'
|
||||
|
@ -37,7 +37,6 @@ function InnerApp() {
|
|||
|
||||
// init
|
||||
useEffect(() => {
|
||||
analytics.init()
|
||||
const account = persisted.get('session').currentAccount
|
||||
resumeSession(account)
|
||||
}, [resumeSession])
|
||||
|
@ -59,7 +58,7 @@ function InnerApp() {
|
|||
<LoggedOutViewProvider>
|
||||
<UnreadNotifsProvider>
|
||||
<ThemeProvider theme={colorMode}>
|
||||
<analytics.Provider>
|
||||
<AnalyticsProvider>
|
||||
{/* All components should be within this provider */}
|
||||
<RootSiblingParent>
|
||||
<SafeAreaProvider>
|
||||
|
@ -67,7 +66,7 @@ function InnerApp() {
|
|||
</SafeAreaProvider>
|
||||
</RootSiblingParent>
|
||||
<ToastContainer />
|
||||
</analytics.Provider>
|
||||
</AnalyticsProvider>
|
||||
</ThemeProvider>
|
||||
</UnreadNotifsProvider>
|
||||
</LoggedOutViewProvider>
|
||||
|
|
|
@ -41,6 +41,7 @@ import {
|
|||
shouldRequestEmailConfirmation,
|
||||
setEmailConfirmationRequested,
|
||||
} from './state/shell/reminders'
|
||||
import {init as initAnalytics} from './lib/analytics/analytics'
|
||||
|
||||
import {HomeScreen} from './view/screens/Home'
|
||||
import {SearchScreen} from './view/screens/Search'
|
||||
|
@ -474,6 +475,8 @@ function RoutesContainer({children}: React.PropsWithChildren<{}>) {
|
|||
const {openModal} = useModalControls()
|
||||
|
||||
function onReady() {
|
||||
initAnalytics(currentAccount)
|
||||
|
||||
if (currentAccount && shouldRequestEmailConfirmation(currentAccount)) {
|
||||
openModal({name: 'verify-email', showReminder: true})
|
||||
setEmailConfirmationRequested()
|
||||
|
|
|
@ -7,20 +7,17 @@ import {
|
|||
useAnalytics as useAnalyticsOrig,
|
||||
ClientMethods,
|
||||
} from '@segment/analytics-react-native'
|
||||
import {z} from 'zod'
|
||||
import {useSession} from '#/state/session'
|
||||
import {useSession, SessionAccount} from '#/state/session'
|
||||
import {sha256} from 'js-sha256'
|
||||
import {ScreenEvent, TrackEvent} from './types'
|
||||
import {logger} from '#/logger'
|
||||
import {listenSessionLoaded} from '#/state/events'
|
||||
|
||||
export const appInfo = z.object({
|
||||
build: z.string().optional(),
|
||||
name: z.string().optional(),
|
||||
namespace: z.string().optional(),
|
||||
version: z.string().optional(),
|
||||
})
|
||||
export type AppInfo = z.infer<typeof appInfo>
|
||||
type AppInfo = {
|
||||
build?: string | undefined
|
||||
name?: string | undefined
|
||||
namespace?: string | undefined
|
||||
version?: string | undefined
|
||||
}
|
||||
|
||||
const segmentClient = createClient({
|
||||
writeKey: '8I6DsgfiSLuoONyaunGoiQM7A6y2ybdI',
|
||||
|
@ -58,8 +55,10 @@ export function useAnalytics() {
|
|||
}, [hasSession, methods])
|
||||
}
|
||||
|
||||
export function init() {
|
||||
listenSessionLoaded(account => {
|
||||
export function init(account: SessionAccount | undefined) {
|
||||
setupListenersOnce()
|
||||
|
||||
if (account) {
|
||||
if (account.did) {
|
||||
const did_hashed = sha256(account.did)
|
||||
segmentClient.identify(did_hashed, {did_hashed})
|
||||
|
@ -68,8 +67,15 @@ export function init() {
|
|||
logger.debug('Ping w/o hash')
|
||||
segmentClient.identify()
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
let didSetupListeners = false
|
||||
function setupListenersOnce() {
|
||||
if (didSetupListeners) {
|
||||
return
|
||||
}
|
||||
didSetupListeners = true
|
||||
// NOTE
|
||||
// this is a copy of segment's own lifecycle event tracking
|
||||
// we handle it manually to ensure that it never fires while the app is backgrounded
|
||||
|
|
|
@ -6,9 +6,8 @@ import {
|
|||
} from '@segment/analytics-react'
|
||||
import {sha256} from 'js-sha256'
|
||||
|
||||
import {useSession} from '#/state/session'
|
||||
import {useSession, SessionAccount} from '#/state/session'
|
||||
import {logger} from '#/logger'
|
||||
import {listenSessionLoaded} from '#/state/events'
|
||||
|
||||
const segmentClient = createClient(
|
||||
{
|
||||
|
@ -44,8 +43,8 @@ export function useAnalytics() {
|
|||
}, [hasSession, methods])
|
||||
}
|
||||
|
||||
export function init() {
|
||||
listenSessionLoaded(account => {
|
||||
export function init(account: SessionAccount | undefined) {
|
||||
if (account) {
|
||||
if (account.did) {
|
||||
if (account.did) {
|
||||
const did_hashed = sha256(account.did)
|
||||
|
@ -56,7 +55,7 @@ export function init() {
|
|||
segmentClient.identify()
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
export function Provider({children}: React.PropsWithChildren<{}>) {
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
import EventEmitter from 'eventemitter3'
|
||||
import {BskyAgent} from '@atproto/api'
|
||||
import {SessionAccount} from './session'
|
||||
|
||||
type UnlistenFn = () => void
|
||||
|
||||
|
@ -16,19 +14,6 @@ export function listenSoftReset(fn: () => void): UnlistenFn {
|
|||
return () => emitter.off('soft-reset', fn)
|
||||
}
|
||||
|
||||
export function emitSessionLoaded(
|
||||
sessionAccount: SessionAccount,
|
||||
agent: BskyAgent,
|
||||
) {
|
||||
emitter.emit('session-loaded', sessionAccount, agent)
|
||||
}
|
||||
export function listenSessionLoaded(
|
||||
fn: (sessionAccount: SessionAccount, agent: BskyAgent) => void,
|
||||
): UnlistenFn {
|
||||
emitter.on('session-loaded', fn)
|
||||
return () => emitter.off('session-loaded', fn)
|
||||
}
|
||||
|
||||
export function emitSessionDropped() {
|
||||
emitter.emit('session-dropped')
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@ import {logger} from '#/logger'
|
|||
import * as persisted from '#/state/persisted'
|
||||
import {PUBLIC_BSKY_AGENT} from '#/state/queries'
|
||||
import {IS_PROD} from '#/lib/constants'
|
||||
import {emitSessionLoaded, emitSessionDropped} from '../events'
|
||||
import {emitSessionDropped} from '../events'
|
||||
import {useLoggedOutViewControls} from '#/state/shell/logged-out'
|
||||
import {useCloseAllActiveElements} from '#/state/util'
|
||||
import {track} from '#/lib/analytics/analytics'
|
||||
|
@ -210,7 +210,6 @@ export function Provider({children}: React.PropsWithChildren<{}>) {
|
|||
__globalAgent = agent
|
||||
queryClient.clear()
|
||||
upsertAccount(account)
|
||||
emitSessionLoaded(account, agent)
|
||||
|
||||
logger.debug(
|
||||
`session: created account`,
|
||||
|
@ -262,7 +261,6 @@ export function Provider({children}: React.PropsWithChildren<{}>) {
|
|||
__globalAgent = agent
|
||||
queryClient.clear()
|
||||
upsertAccount(account)
|
||||
emitSessionLoaded(account, agent)
|
||||
|
||||
logger.debug(
|
||||
`session: logged in`,
|
||||
|
@ -355,12 +353,11 @@ export function Provider({children}: React.PropsWithChildren<{}>) {
|
|||
__globalAgent = agent
|
||||
queryClient.clear()
|
||||
upsertAccount(account)
|
||||
emitSessionLoaded(account, agent)
|
||||
|
||||
// Intentionally not awaited to unblock the UI:
|
||||
resumeSessionWithFreshAccount().then(async freshAccount => {
|
||||
resumeSessionWithFreshAccount().then(freshAccount => {
|
||||
if (JSON.stringify(account) !== JSON.stringify(freshAccount)) {
|
||||
upsertAccount(freshAccount)
|
||||
emitSessionLoaded(freshAccount, agent)
|
||||
}
|
||||
})
|
||||
} else {
|
||||
|
@ -368,7 +365,6 @@ export function Provider({children}: React.PropsWithChildren<{}>) {
|
|||
__globalAgent = agent
|
||||
queryClient.clear()
|
||||
upsertAccount(freshAccount)
|
||||
emitSessionLoaded(freshAccount, agent)
|
||||
}
|
||||
|
||||
async function resumeSessionWithFreshAccount(): Promise<SessionAccount> {
|
||||
|
|
Loading…
Reference in New Issue