Check Analytics (#2106)
* fix sign in event tracking * add missing analytics events * add more missing analytics * fix like and unrepost event tracking * reset onEndReachedThresholdzio/stable
parent
7229cda5a5
commit
8e541d753a
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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')
|
||||
},
|
||||
})
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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],
|
||||
)
|
||||
|
|
|
@ -120,8 +120,6 @@ export const LoginForm = ({
|
|||
} else {
|
||||
setError(cleanError(errMsg))
|
||||
}
|
||||
} finally {
|
||||
track('Sign In', {resumedSession: false})
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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})
|
||||
|
|
|
@ -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}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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[] = [
|
||||
|
|
Loading…
Reference in New Issue