about summary refs log tree commit diff
diff options
context:
space:
mode:
authorAnsh <anshnanda10@gmail.com>2023-12-06 11:45:01 -0600
committerGitHub <noreply@github.com>2023-12-06 09:45:01 -0800
commit8e541d753a0718b85e0a754452c8ffbafb181a81 (patch)
treef9afd09859646cc71e948f391b688d2215107498
parent7229cda5a52192266d8e0ee202ae3d3fee7c66a3 (diff)
downloadvoidsky-8e541d753a0718b85e0a754452c8ffbafb181a81.tar.zst
Check Analytics (#2106)
* fix sign in event tracking

* add missing analytics events

* add more missing analytics

* fix like and unrepost event tracking

* reset onEndReachedThreshold
-rw-r--r--src/lib/analytics/types.ts10
-rw-r--r--src/state/muted-threads.tsx3
-rw-r--r--src/state/queries/post.ts6
-rw-r--r--src/state/queries/profile.ts3
-rw-r--r--src/state/session/index.tsx3
-rw-r--r--src/view/com/auth/login/LoginForm.tsx2
-rw-r--r--src/view/com/auth/onboarding/RecommendedFeedsItem.tsx3
-rw-r--r--src/view/com/posts/Feed.tsx2
-rw-r--r--src/view/com/posts/FeedItem.tsx5
-rw-r--r--src/view/screens/ProfileFeed.tsx6
-rw-r--r--src/view/screens/ProfileList.tsx20
11 files changed, 41 insertions, 22 deletions
diff --git a/src/lib/analytics/types.ts b/src/lib/analytics/types.ts
index b2c6f15d6..d677f3217 100644
--- a/src/lib/analytics/types.ts
+++ b/src/lib/analytics/types.ts
@@ -41,12 +41,6 @@ interface TrackPropertiesMap {
   'Post:ThreadMute': {} // CAN BE SERVER
   'Post:ThreadUnmute': {} // CAN BE SERVER
   'Post:Reply': {} // CAN BE SERVER
-  // FEED ITEM events
-  'FeedItem:PostReply': {} // CAN BE SERVER
-  'FeedItem:PostRepost': {} // CAN BE SERVER
-  'FeedItem:PostLike': {} // CAN BE SERVER
-  'FeedItem:PostDelete': {} // CAN BE SERVER
-  'FeedItem:ThreadMute': {} // CAN BE SERVER
   // PROFILE events
   'Profile:Follow': {
     username: string
@@ -79,7 +73,6 @@ interface TrackPropertiesMap {
   'Settings:AddAccountButtonClicked': {}
   'Settings:ChangeHandleButtonClicked': {}
   'Settings:InvitecodesButtonClicked': {}
-  'Settings:ContentfilteringButtonClicked': {}
   'Settings:SignOutButtonClicked': {}
   'Settings:ContentlanguagesButtonClicked': {}
   // MENU events
@@ -104,6 +97,8 @@ interface TrackPropertiesMap {
   'Lists:Unmute': {} // CAN BE SERVER
   'Lists:Block': {} // CAN BE SERVER
   'Lists:Unblock': {} // CAN BE SERVER
+  'Lists:Delete': {} // CAN BE SERVER
+  'Lists:Share': {} // CAN BE SERVER
   // CUSTOM FEED events
   'CustomFeed:Save': {}
   'CustomFeed:Unsave': {}
@@ -134,6 +129,7 @@ interface TrackPropertiesMap {
   'Onboarding:Skipped': {}
   'Onboarding:Reset': {}
   'Onboarding:SuggestedFollowFollowed': {}
+  'Onboarding:CustomFeedAdded': {}
 }
 
 interface ScreenPropertiesMap {
diff --git a/src/state/muted-threads.tsx b/src/state/muted-threads.tsx
index 2b3a7de6a..84a717eb7 100644
--- a/src/state/muted-threads.tsx
+++ b/src/state/muted-threads.tsx
@@ -1,5 +1,6 @@
 import React from 'react'
 import * as persisted from '#/state/persisted'
+import {track} from '#/lib/analytics/analytics'
 
 type StateContext = persisted.Schema['mutedThreads']
 type ToggleContext = (uri: string) => boolean
@@ -19,9 +20,11 @@ export function Provider({children}: React.PropsWithChildren<{}>) {
         if (arr.includes(uri)) {
           arr = arr.filter(v => v !== uri)
           muted = false
+          track('Post:ThreadUnmute')
         } else {
           arr = arr.concat([uri])
           muted = true
+          track('Post:ThreadMute')
         }
         persisted.write('mutedThreads', arr)
         return arr
diff --git a/src/state/queries/post.ts b/src/state/queries/post.ts
index b31696446..5570f022b 100644
--- a/src/state/queries/post.ts
+++ b/src/state/queries/post.ts
@@ -4,6 +4,7 @@ import {useQuery, useMutation, useQueryClient} from '@tanstack/react-query'
 
 import {getAgent} from '#/state/session'
 import {updatePostShadow} from '#/state/cache/post-shadow'
+import {track} from '#/lib/analytics/analytics'
 
 export const RQKEY = (postUri: string) => ['post', postUri]
 
@@ -73,6 +74,7 @@ export function usePostLikeMutation() {
       updatePostShadow(variables.uri, {
         likeUri: data.uri,
       })
+      track('Post:Like')
     },
     onError(error, variables) {
       // revert the optimistic update
@@ -92,6 +94,7 @@ export function usePostUnlikeMutation() {
   >({
     mutationFn: async ({likeUri}) => {
       await getAgent().deleteLike(likeUri)
+      track('Post:Unlike')
     },
     onMutate(variables) {
       // optimistically update the post-shadow
@@ -129,6 +132,7 @@ export function usePostRepostMutation() {
       updatePostShadow(variables.uri, {
         repostUri: data.uri,
       })
+      track('Post:Repost')
     },
     onError(error, variables) {
       // revert the optimistic update
@@ -148,6 +152,7 @@ export function usePostUnrepostMutation() {
   >({
     mutationFn: async ({repostUri}) => {
       await getAgent().deleteRepost(repostUri)
+      track('Post:Unrepost')
     },
     onMutate(variables) {
       // optimistically update the post-shadow
@@ -173,6 +178,7 @@ export function usePostDeleteMutation() {
     },
     onSuccess(data, variables) {
       updatePostShadow(variables.uri, {isDeleted: true})
+      track('Post:Delete')
     },
   })
 }
diff --git a/src/state/queries/profile.ts b/src/state/queries/profile.ts
index 9435d7ad5..267cf2c5b 100644
--- a/src/state/queries/profile.ts
+++ b/src/state/queries/profile.ts
@@ -21,6 +21,7 @@ import {useToggleMutationQueue} from '#/lib/hooks/useToggleMutationQueue'
 import {RQKEY as RQKEY_MY_MUTED} from './my-muted-accounts'
 import {RQKEY as RQKEY_MY_BLOCKED} from './my-blocked-accounts'
 import {STALE} from '#/state/queries'
+import {track} from '#/lib/analytics/analytics'
 
 export const RQKEY = (did: string) => ['profile', did]
 
@@ -188,6 +189,7 @@ function useProfileFollowMutation() {
         updateProfileShadow(variables.did, {
           followingUri: data.uri,
         })
+        track('Profile:Follow', {username: variables.did})
       }
     },
     onError(error, variables) {
@@ -208,6 +210,7 @@ function useProfileUnfollowMutation() {
     {did: string; followUri: string; skipOptimistic?: boolean}
   >({
     mutationFn: async ({followUri}) => {
+      track('Profile:Unfollow', {username: followUri})
       return await getAgent().deleteFollow(followUri)
     },
     onMutate(variables) {
diff --git a/src/state/session/index.tsx b/src/state/session/index.tsx
index 37454187a..0d52d2521 100644
--- a/src/state/session/index.tsx
+++ b/src/state/session/index.tsx
@@ -10,6 +10,7 @@ import {IS_PROD} from '#/lib/constants'
 import {emitSessionLoaded, emitSessionDropped} from '../events'
 import {useLoggedOutViewControls} from '#/state/shell/logged-out'
 import {useCloseAllActiveElements} from '#/state/util'
+import {track} from '#/lib/analytics/analytics'
 
 let __globalAgent: BskyAgent = PUBLIC_BSKY_AGENT
 
@@ -270,6 +271,8 @@ export function Provider({children}: React.PropsWithChildren<{}>) {
         },
         logger.DebugContext.session,
       )
+
+      track('Sign In', {resumedSession: false})
     },
     [upsertAccount, queryClient],
   )
diff --git a/src/view/com/auth/login/LoginForm.tsx b/src/view/com/auth/login/LoginForm.tsx
index 365f2e253..a39d0d9bf 100644
--- a/src/view/com/auth/login/LoginForm.tsx
+++ b/src/view/com/auth/login/LoginForm.tsx
@@ -120,8 +120,6 @@ export const LoginForm = ({
       } else {
         setError(cleanError(errMsg))
       }
-    } finally {
-      track('Sign In', {resumedSession: false})
     }
   }
 
diff --git a/src/view/com/auth/onboarding/RecommendedFeedsItem.tsx b/src/view/com/auth/onboarding/RecommendedFeedsItem.tsx
index 7417e5b06..fcc4572af 100644
--- a/src/view/com/auth/onboarding/RecommendedFeedsItem.tsx
+++ b/src/view/com/auth/onboarding/RecommendedFeedsItem.tsx
@@ -17,6 +17,7 @@ import {
   useRemoveFeedMutation,
 } from '#/state/queries/preferences'
 import {logger} from '#/logger'
+import {useAnalytics} from '#/lib/analytics/analytics'
 
 export function RecommendedFeedsItem({
   item,
@@ -36,6 +37,7 @@ export function RecommendedFeedsItem({
     variables: removedFeed,
     reset: resetRemoveFeed,
   } = useRemoveFeedMutation()
+  const {track} = useAnalytics()
 
   if (!item || !preferences) return null
 
@@ -56,6 +58,7 @@ export function RecommendedFeedsItem({
       try {
         await pinFeed({uri: item.uri})
         resetPinFeed()
+        track('Onboarding:CustomFeedAdded')
       } catch (e) {
         Toast.show('There was an issue contacting your server')
         logger.error('Failed to pin feed', {error: e})
diff --git a/src/view/com/posts/Feed.tsx b/src/view/com/posts/Feed.tsx
index 113436e73..371f73b87 100644
--- a/src/view/com/posts/Feed.tsx
+++ b/src/view/com/posts/Feed.tsx
@@ -294,7 +294,7 @@ let Feed = ({
         scrollEventThrottle={scrollEventThrottle}
         indicatorStyle={theme.colorScheme === 'dark' ? 'white' : 'black'}
         onEndReached={onEndReached}
-        onEndReachedThreshold={2}
+        onEndReachedThreshold={2} // number of posts left to trigger load more
         removeClippedSubviews={true}
         contentOffset={{x: 0, y: headerOffset * -1}}
         extraData={extraData}
diff --git a/src/view/com/posts/FeedItem.tsx b/src/view/com/posts/FeedItem.tsx
index b6c509e92..df4728a54 100644
--- a/src/view/com/posts/FeedItem.tsx
+++ b/src/view/com/posts/FeedItem.tsx
@@ -25,7 +25,6 @@ import {PostSandboxWarning} from '../util/PostSandboxWarning'
 import {PreviewableUserAvatar} from '../util/UserAvatar'
 import {s} from 'lib/styles'
 import {usePalette} from 'lib/hooks/usePalette'
-import {useAnalytics} from 'lib/analytics/analytics'
 import {sanitizeDisplayName} from 'lib/strings/display-names'
 import {sanitizeHandle} from 'lib/strings/handles'
 import {makeProfileLink} from 'lib/routes/links'
@@ -102,7 +101,6 @@ let FeedItemInner = ({
 }): React.ReactNode => {
   const {openComposer} = useComposerControls()
   const pal = usePalette('default')
-  const {track} = useAnalytics()
   const [limitLines, setLimitLines] = useState(
     () => countLines(richText.text) >= MAX_POST_LINES,
   )
@@ -121,7 +119,6 @@ let FeedItemInner = ({
   }, [record?.reply])
 
   const onPressReply = React.useCallback(() => {
-    track('FeedItem:PostReply')
     openComposer({
       replyTo: {
         uri: post.uri,
@@ -134,7 +131,7 @@ let FeedItemInner = ({
         },
       },
     })
-  }, [post, record, track, openComposer])
+  }, [post, record, openComposer])
 
   const onPressShowMore = React.useCallback(() => {
     setLimitLines(false)
diff --git a/src/view/screens/ProfileFeed.tsx b/src/view/screens/ProfileFeed.tsx
index 155df6480..f803930d1 100644
--- a/src/view/screens/ProfileFeed.tsx
+++ b/src/view/screens/ProfileFeed.tsx
@@ -571,7 +571,7 @@ function AboutSection({
   const scrollHandler = useAnimatedScrollHandler(onScroll)
   const [likeUri, setLikeUri] = React.useState(feedInfo.likeUri)
   const {hasSession} = useSession()
-
+  const {track} = useAnalytics()
   const {mutateAsync: likeFeed, isPending: isLikePending} = useLikeMutation()
   const {mutateAsync: unlikeFeed, isPending: isUnlikePending} =
     useUnlikeMutation()
@@ -586,9 +586,11 @@ function AboutSection({
 
       if (isLiked && likeUri) {
         await unlikeFeed({uri: likeUri})
+        track('CustomFeed:Unlike')
         setLikeUri('')
       } else {
         const res = await likeFeed({uri: feedInfo.uri, cid: feedInfo.cid})
+        track('CustomFeed:Like')
         setLikeUri(res.uri)
       }
     } catch (err) {
@@ -597,7 +599,7 @@ function AboutSection({
       )
       logger.error('Failed up toggle like', {error: err})
     }
-  }, [likeUri, isLiked, feedInfo, likeFeed, unlikeFeed])
+  }, [likeUri, isLiked, feedInfo, likeFeed, unlikeFeed, track])
 
   return (
     <ScrollView
diff --git a/src/view/screens/ProfileList.tsx b/src/view/screens/ProfileList.tsx
index 3e568c8cc..f50c6afb3 100644
--- a/src/view/screens/ProfileList.tsx
+++ b/src/view/screens/ProfileList.tsx
@@ -62,6 +62,7 @@ import {
   useUnpinFeedMutation,
 } from '#/state/queries/preferences'
 import {logger} from '#/logger'
+import {useAnalytics} from '#/lib/analytics/analytics'
 
 const SECTION_TITLES_CURATE = ['Posts', 'About']
 const SECTION_TITLES_MOD = ['About']
@@ -267,6 +268,7 @@ function Header({rkey, list}: {rkey: string; list: AppBskyGraphDefs.ListView}) {
     useUnpinFeedMutation()
   const isPending = isPinPending || isUnpinPending
   const {data: preferences} = usePreferencesQuery()
+  const {track} = useAnalytics()
 
   const isPinned = preferences?.feeds?.pinned?.includes(list.uri)
 
@@ -297,6 +299,7 @@ function Header({rkey, list}: {rkey: string; list: AppBskyGraphDefs.ListView}) {
         try {
           await listMuteMutation.mutateAsync({uri: list.uri, mute: true})
           Toast.show('List muted')
+          track('Lists:Mute')
         } catch {
           Toast.show(
             'There was an issue. Please check your internet connection and try again.',
@@ -307,18 +310,19 @@ function Header({rkey, list}: {rkey: string; list: AppBskyGraphDefs.ListView}) {
         closeModal()
       },
     })
-  }, [openModal, closeModal, list, listMuteMutation, _])
+  }, [openModal, closeModal, list, listMuteMutation, track, _])
 
   const onUnsubscribeMute = useCallback(async () => {
     try {
       await listMuteMutation.mutateAsync({uri: list.uri, mute: false})
       Toast.show('List unmuted')
+      track('Lists:Unmute')
     } catch {
       Toast.show(
         'There was an issue. Please check your internet connection and try again.',
       )
     }
-  }, [list, listMuteMutation])
+  }, [list, listMuteMutation, track])
 
   const onSubscribeBlock = useCallback(() => {
     openModal({
@@ -332,6 +336,7 @@ function Header({rkey, list}: {rkey: string; list: AppBskyGraphDefs.ListView}) {
         try {
           await listBlockMutation.mutateAsync({uri: list.uri, block: true})
           Toast.show('List blocked')
+          track('Lists:Block')
         } catch {
           Toast.show(
             'There was an issue. Please check your internet connection and try again.',
@@ -342,18 +347,19 @@ function Header({rkey, list}: {rkey: string; list: AppBskyGraphDefs.ListView}) {
         closeModal()
       },
     })
-  }, [openModal, closeModal, list, listBlockMutation, _])
+  }, [openModal, closeModal, list, listBlockMutation, track, _])
 
   const onUnsubscribeBlock = useCallback(async () => {
     try {
       await listBlockMutation.mutateAsync({uri: list.uri, block: false})
       Toast.show('List unblocked')
+      track('Lists:Unblock')
     } catch {
       Toast.show(
         'There was an issue. Please check your internet connection and try again.',
       )
     }
-  }, [list, listBlockMutation])
+  }, [list, listBlockMutation, track])
 
   const onPressEdit = useCallback(() => {
     openModal({
@@ -370,6 +376,7 @@ function Header({rkey, list}: {rkey: string; list: AppBskyGraphDefs.ListView}) {
       async onPressConfirm() {
         await listDeleteMutation.mutateAsync({uri: list.uri})
         Toast.show('List deleted')
+        track('Lists:Delete')
         if (navigation.canGoBack()) {
           navigation.goBack()
         } else {
@@ -377,7 +384,7 @@ function Header({rkey, list}: {rkey: string; list: AppBskyGraphDefs.ListView}) {
         }
       },
     })
-  }, [openModal, list, listDeleteMutation, navigation, _])
+  }, [openModal, list, listDeleteMutation, navigation, track, _])
 
   const onPressReport = useCallback(() => {
     openModal({
@@ -390,7 +397,8 @@ function Header({rkey, list}: {rkey: string; list: AppBskyGraphDefs.ListView}) {
   const onPressShare = useCallback(() => {
     const url = toShareUrl(`/profile/${list.creator.did}/lists/${rkey}`)
     shareUrl(url)
-  }, [list, rkey])
+    track('Lists:Share')
+  }, [list, rkey, track])
 
   const dropdownItems: DropdownItem[] = useMemo(() => {
     let items: DropdownItem[] = [