Add basic analytics (#89)

* Add basic analytics

* Fix: add mock for analytics
This commit is contained in:
Paul Frazee 2023-01-24 13:58:35 -06:00 committed by GitHub
parent f36c956536
commit 21f5f4de15
9 changed files with 190 additions and 14 deletions

View file

@ -6,6 +6,11 @@ import {GestureHandlerRootView} from 'react-native-gesture-handler'
import SplashScreen from 'react-native-splash-screen'
import {SafeAreaProvider} from 'react-native-safe-area-context'
import {observer} from 'mobx-react-lite'
import {
createClient,
SegmentClient,
AnalyticsProvider,
} from '@segment/analytics-react-native'
import {ThemeProvider} from './view/lib/ThemeContext'
import * as view from './view/index'
import {RootStoreModel, setupState, RootStoreProvider} from './state'
@ -16,10 +21,17 @@ const App = observer(() => {
const [rootStore, setRootStore] = useState<RootStoreModel | undefined>(
undefined,
)
const [segment, setSegment] = useState<SegmentClient | undefined>(undefined)
// init
useEffect(() => {
view.setup()
setSegment(
createClient({
writeKey: '8I6DsgfiSLuoONyaunGoiQM7A6y2ybdI',
trackAppLifecycleEvents: true,
}),
)
setupState().then(store => {
setRootStore(store)
SplashScreen.hide()
@ -42,13 +54,15 @@ const App = observer(() => {
return (
<GestureHandlerRootView style={s.h100pct}>
<RootSiblingParent>
<RootStoreProvider value={rootStore}>
<ThemeProvider theme={rootStore.shell.darkMode ? 'dark' : 'light'}>
<SafeAreaProvider>
<MobileShell />
</SafeAreaProvider>
</ThemeProvider>
</RootStoreProvider>
<AnalyticsProvider client={segment}>
<RootStoreProvider value={rootStore}>
<ThemeProvider theme={rootStore.shell.darkMode ? 'dark' : 'light'}>
<SafeAreaProvider>
<MobileShell />
</SafeAreaProvider>
</ThemeProvider>
</RootStoreProvider>
</AnalyticsProvider>
</RootSiblingParent>
</GestureHandlerRootView>
)

View file

@ -17,6 +17,7 @@ import PasteInput, {
} from '@mattermost/react-native-paste-input'
import LinearGradient from 'react-native-linear-gradient'
import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome'
import {useAnalytics} from '@segment/analytics-react-native'
import {UserAutocompleteViewModel} from '../../../state/models/user-autocomplete-view'
import {Autocomplete} from './Autocomplete'
import {ExternalEmbed} from './ExternalEmbed'
@ -59,6 +60,7 @@ export const ComposePost = observer(function ComposePost({
onPost?: ComposerOpts['onPost']
onClose: () => void
}) {
const {track} = useAnalytics()
const pal = usePalette('default')
const store = useStores()
const textInput = useRef<PasteInputRef>(null)
@ -252,6 +254,9 @@ export const ComposePost = observer(function ComposePost({
autocompleteView.knownHandles,
setProcessingState,
)
track('Create Post', {
imageCount: selectedPhotos.length,
})
} catch (e: any) {
setError(cleanError(e.message))
setIsProcessing(false)

View file

@ -12,6 +12,7 @@ import {
import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome'
import {ComAtprotoAccountCreate} from '@atproto/api'
import * as EmailValidator from 'email-validator'
import {useAnalytics} from '@segment/analytics-react-native'
import {LogoTextHero} from './Logo'
import {Picker} from '../util/Picker'
import {TextLink} from '../util/Link'
@ -28,6 +29,7 @@ import {ServerInputModal} from '../../../state/models/shell-ui'
import {usePalette} from '../../lib/hooks/usePalette'
export const CreateAccount = ({onPressBack}: {onPressBack: () => void}) => {
const {track} = useAnalytics()
const pal = usePalette('default')
const store = useStores()
const [isProcessing, setIsProcessing] = useState<boolean>(false)
@ -104,6 +106,7 @@ export const CreateAccount = ({onPressBack}: {onPressBack: () => void}) => {
password,
inviteCode,
})
track('Create Account')
} catch (e: any) {
let errMsg = e.toString()
if (e instanceof ComAtprotoAccountCreate.InvalidInviteCodeError) {

View file

@ -11,6 +11,7 @@ import {
import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome'
import * as EmailValidator from 'email-validator'
import {sessionClient as AtpApi, SessionServiceClient} from '@atproto/api'
import {useAnalytics} from '@segment/analytics-react-native'
import {LogoTextHero} from './Logo'
import {Text} from '../util/text/Text'
import {UserAvatar} from '../util/UserAvatar'
@ -149,6 +150,7 @@ const ChooseAccountForm = ({
onSelectAccount: (account?: AccountData) => void
onPressBack: () => void
}) => {
const {track} = useAnalytics()
const pal = usePalette('default')
const [isProcessing, setIsProcessing] = React.useState(false)
@ -156,6 +158,7 @@ const ChooseAccountForm = ({
if (account.accessJwt && account.refreshJwt) {
setIsProcessing(true)
if (await store.session.resumeSession(account)) {
track('Sign In', {resumedSession: true})
setIsProcessing(false)
return
}
@ -255,6 +258,7 @@ const LoginForm = ({
onPressBack: () => void
onPressForgotPassword: () => void
}) => {
const {track} = useAnalytics()
const pal = usePalette('default')
const [isProcessing, setIsProcessing] = useState<boolean>(false)
const [handle, setHandle] = useState<string>(initialHandle)
@ -295,6 +299,7 @@ const LoginForm = ({
handle: fullHandle,
password,
})
track('Sign In', {resumedSession: false})
} catch (e: any) {
const errMsg = e.toString()
store.log.warn('Failed to login', e)