[Statsig] Remove client downsampling (#6153)
This commit is contained in:
+1
-1
@@ -696,7 +696,7 @@ function RoutesContainer({children}: React.PropsWithChildren<{}>) {
|
|||||||
onStateChange={() => {
|
onStateChange={() => {
|
||||||
const routeName = getCurrentRouteName()
|
const routeName = getCurrentRouteName()
|
||||||
if (routeName === 'Notifications') {
|
if (routeName === 'Notifications') {
|
||||||
logEvent('router:navigate:notifications:sampled', {})
|
logEvent('router:navigate:notifications', {})
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
onReady={() => {
|
onReady={() => {
|
||||||
|
|||||||
@@ -283,8 +283,8 @@ export function DescriptionPlaceholder({
|
|||||||
export type FollowButtonProps = {
|
export type FollowButtonProps = {
|
||||||
profile: AppBskyActorDefs.ProfileViewBasic
|
profile: AppBskyActorDefs.ProfileViewBasic
|
||||||
moderationOpts: ModerationOpts
|
moderationOpts: ModerationOpts
|
||||||
logContext: LogEvents['profile:follow:sampled']['logContext'] &
|
logContext: LogEvents['profile:follow']['logContext'] &
|
||||||
LogEvents['profile:unfollow:sampled']['logContext']
|
LogEvents['profile:unfollow']['logContext']
|
||||||
} & Partial<ButtonProps>
|
} & Partial<ButtonProps>
|
||||||
|
|
||||||
export function FollowButton(props: FollowButtonProps) {
|
export function FollowButton(props: FollowButtonProps) {
|
||||||
|
|||||||
@@ -15,8 +15,8 @@ export function useFollowMethods({
|
|||||||
logContext,
|
logContext,
|
||||||
}: {
|
}: {
|
||||||
profile: Shadow<AppBskyActorDefs.ProfileViewBasic>
|
profile: Shadow<AppBskyActorDefs.ProfileViewBasic>
|
||||||
logContext: LogEvents['profile:follow:sampled']['logContext'] &
|
logContext: LogEvents['profile:follow']['logContext'] &
|
||||||
LogEvents['profile:unfollow:sampled']['logContext']
|
LogEvents['profile:unfollow']['logContext']
|
||||||
}) {
|
}) {
|
||||||
const {_} = useLingui()
|
const {_} = useLingui()
|
||||||
const requireAuth = useRequireAuth()
|
const requireAuth = useRequireAuth()
|
||||||
|
|||||||
+15
-15
@@ -21,11 +21,11 @@ export type LogEvents = {
|
|||||||
context: 'StartOnboarding' | 'AfterOnboarding' | 'Login' | 'Home'
|
context: 'StartOnboarding' | 'AfterOnboarding' | 'Login' | 'Home'
|
||||||
status: 'granted' | 'denied' | 'undetermined'
|
status: 'granted' | 'denied' | 'undetermined'
|
||||||
}
|
}
|
||||||
'state:background:sampled': {
|
'state:background': {
|
||||||
secondsActive: number
|
secondsActive: number
|
||||||
}
|
}
|
||||||
'state:foreground:sampled': {}
|
'state:foreground': {}
|
||||||
'router:navigate:notifications:sampled': {}
|
'router:navigate:notifications': {}
|
||||||
'deepLink:referrerReceived': {
|
'deepLink:referrerReceived': {
|
||||||
to: string
|
to: string
|
||||||
referrer: string
|
referrer: string
|
||||||
@@ -76,7 +76,7 @@ export type LogEvents = {
|
|||||||
'onboarding:finished:avatarResult': {
|
'onboarding:finished:avatarResult': {
|
||||||
avatarResult: 'default' | 'created' | 'uploaded'
|
avatarResult: 'default' | 'created' | 'uploaded'
|
||||||
}
|
}
|
||||||
'home:feedDisplayed:sampled': {
|
'home:feedDisplayed': {
|
||||||
feedUrl: string
|
feedUrl: string
|
||||||
feedType: string
|
feedType: string
|
||||||
index: number
|
index: number
|
||||||
@@ -87,12 +87,12 @@ export type LogEvents = {
|
|||||||
| 'desktop-sidebar-click'
|
| 'desktop-sidebar-click'
|
||||||
| 'starter-pack-initial-feed'
|
| 'starter-pack-initial-feed'
|
||||||
}
|
}
|
||||||
'feed:endReached:sampled': {
|
'feed:endReached': {
|
||||||
feedUrl: string
|
feedUrl: string
|
||||||
feedType: string
|
feedType: string
|
||||||
itemCount: number
|
itemCount: number
|
||||||
}
|
}
|
||||||
'feed:refresh:sampled': {
|
'feed:refresh': {
|
||||||
feedUrl: string
|
feedUrl: string
|
||||||
feedType: string
|
feedType: string
|
||||||
reason: 'pull-to-refresh' | 'soft-reset' | 'load-latest'
|
reason: 'pull-to-refresh' | 'soft-reset' | 'load-latest'
|
||||||
@@ -103,13 +103,13 @@ export type LogEvents = {
|
|||||||
'discover:showLess': {
|
'discover:showLess': {
|
||||||
feedContext: string
|
feedContext: string
|
||||||
}
|
}
|
||||||
'discover:clickthrough:sampled': {
|
'discover:clickthrough': {
|
||||||
count: number
|
count: number
|
||||||
}
|
}
|
||||||
'discover:engaged:sampled': {
|
'discover:engaged': {
|
||||||
count: number
|
count: number
|
||||||
}
|
}
|
||||||
'discover:seen:sampled': {
|
'discover:seen': {
|
||||||
count: number
|
count: number
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -132,27 +132,27 @@ export type LogEvents = {
|
|||||||
postCount: number
|
postCount: number
|
||||||
isReply: boolean
|
isReply: boolean
|
||||||
}
|
}
|
||||||
'post:like:sampled': {
|
'post:like': {
|
||||||
doesLikerFollowPoster: boolean | undefined
|
doesLikerFollowPoster: boolean | undefined
|
||||||
doesPosterFollowLiker: boolean | undefined
|
doesPosterFollowLiker: boolean | undefined
|
||||||
likerClout: number | undefined
|
likerClout: number | undefined
|
||||||
postClout: number | undefined
|
postClout: number | undefined
|
||||||
logContext: 'FeedItem' | 'PostThreadItem' | 'Post'
|
logContext: 'FeedItem' | 'PostThreadItem' | 'Post'
|
||||||
}
|
}
|
||||||
'post:repost:sampled': {
|
'post:repost': {
|
||||||
logContext: 'FeedItem' | 'PostThreadItem' | 'Post'
|
logContext: 'FeedItem' | 'PostThreadItem' | 'Post'
|
||||||
}
|
}
|
||||||
'post:unlike:sampled': {
|
'post:unlike': {
|
||||||
logContext: 'FeedItem' | 'PostThreadItem' | 'Post'
|
logContext: 'FeedItem' | 'PostThreadItem' | 'Post'
|
||||||
}
|
}
|
||||||
'post:unrepost:sampled': {
|
'post:unrepost': {
|
||||||
logContext: 'FeedItem' | 'PostThreadItem' | 'Post'
|
logContext: 'FeedItem' | 'PostThreadItem' | 'Post'
|
||||||
}
|
}
|
||||||
'post:mute': {}
|
'post:mute': {}
|
||||||
'post:unmute': {}
|
'post:unmute': {}
|
||||||
'post:pin': {}
|
'post:pin': {}
|
||||||
'post:unpin': {}
|
'post:unpin': {}
|
||||||
'profile:follow:sampled': {
|
'profile:follow': {
|
||||||
didBecomeMutual: boolean | undefined
|
didBecomeMutual: boolean | undefined
|
||||||
followeeClout: number | undefined
|
followeeClout: number | undefined
|
||||||
followerClout: number | undefined
|
followerClout: number | undefined
|
||||||
@@ -169,7 +169,7 @@ export type LogEvents = {
|
|||||||
| 'FeedInterstitial'
|
| 'FeedInterstitial'
|
||||||
| 'ProfileHeaderSuggestedFollows'
|
| 'ProfileHeaderSuggestedFollows'
|
||||||
}
|
}
|
||||||
'profile:unfollow:sampled': {
|
'profile:unfollow': {
|
||||||
logContext:
|
logContext:
|
||||||
| 'RecommendedFollowsItem'
|
| 'RecommendedFollowsItem'
|
||||||
| 'PostThreadItem'
|
| 'PostThreadItem'
|
||||||
|
|||||||
@@ -59,6 +59,7 @@ function createStatsigOptions(prefetchUsers: StatsigUser[]) {
|
|||||||
initTimeoutMs: 1,
|
initTimeoutMs: 1,
|
||||||
// Get fresh flags for other accounts as well, if any.
|
// Get fresh flags for other accounts as well, if any.
|
||||||
prefetchUsers,
|
prefetchUsers,
|
||||||
|
api: 'https://events.bsky.app/v2',
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -89,51 +90,14 @@ export function toClout(n: number | null | undefined): number | undefined {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const DOWNSAMPLE_RATE = 0.99 // 99% likely
|
|
||||||
const DOWNSAMPLED_EVENTS: Set<keyof LogEvents> = new Set([
|
|
||||||
'router:navigate:notifications:sampled',
|
|
||||||
'state:background:sampled',
|
|
||||||
'state:foreground:sampled',
|
|
||||||
'home:feedDisplayed:sampled',
|
|
||||||
'feed:endReached:sampled',
|
|
||||||
'feed:refresh:sampled',
|
|
||||||
'discover:clickthrough:sampled',
|
|
||||||
'discover:engaged:sampled',
|
|
||||||
'discover:seen:sampled',
|
|
||||||
'post:like:sampled',
|
|
||||||
'post:unlike:sampled',
|
|
||||||
'post:repost:sampled',
|
|
||||||
'post:unrepost:sampled',
|
|
||||||
'profile:follow:sampled',
|
|
||||||
'profile:unfollow:sampled',
|
|
||||||
])
|
|
||||||
const isDownsampledSession = Math.random() < DOWNSAMPLE_RATE
|
|
||||||
|
|
||||||
export function logEvent<E extends keyof LogEvents>(
|
export function logEvent<E extends keyof LogEvents>(
|
||||||
eventName: E & string,
|
eventName: E & string,
|
||||||
rawMetadata: LogEvents[E] & FlatJSONRecord,
|
rawMetadata: LogEvents[E] & FlatJSONRecord,
|
||||||
) {
|
) {
|
||||||
try {
|
try {
|
||||||
if (
|
|
||||||
process.env.NODE_ENV === 'development' &&
|
|
||||||
eventName.endsWith(':sampled') &&
|
|
||||||
!DOWNSAMPLED_EVENTS.has(eventName)
|
|
||||||
) {
|
|
||||||
logger.error(
|
|
||||||
'Did you forget to add ' + eventName + ' to DOWNSAMPLED_EVENTS?',
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
const isDownsampledEvent = DOWNSAMPLED_EVENTS.has(eventName)
|
|
||||||
if (isDownsampledSession && isDownsampledEvent) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
const fullMetadata = {
|
const fullMetadata = {
|
||||||
...rawMetadata,
|
...rawMetadata,
|
||||||
} as Record<string, string> // Statsig typings are unnecessarily strict here.
|
} as Record<string, string> // Statsig typings are unnecessarily strict here.
|
||||||
if (isDownsampledEvent) {
|
|
||||||
fullMetadata.downsampleRate = DOWNSAMPLE_RATE.toString()
|
|
||||||
}
|
|
||||||
fullMetadata.routeName = getCurrentRouteName() ?? '(Uninitialized)'
|
fullMetadata.routeName = getCurrentRouteName() ?? '(Uninitialized)'
|
||||||
if (Statsig.initializeCalled()) {
|
if (Statsig.initializeCalled()) {
|
||||||
Statsig.logEvent(eventName, null, fullMetadata)
|
Statsig.logEvent(eventName, null, fullMetadata)
|
||||||
@@ -232,13 +196,13 @@ AppState.addEventListener('change', (state: AppStateStatus) => {
|
|||||||
lastState = state
|
lastState = state
|
||||||
if (state === 'active') {
|
if (state === 'active') {
|
||||||
lastActive = performance.now()
|
lastActive = performance.now()
|
||||||
logEvent('state:foreground:sampled', {})
|
logEvent('state:foreground', {})
|
||||||
} else {
|
} else {
|
||||||
let secondsActive = 0
|
let secondsActive = 0
|
||||||
if (lastActive != null) {
|
if (lastActive != null) {
|
||||||
secondsActive = Math.round((performance.now() - lastActive) / 1e3)
|
secondsActive = Math.round((performance.now() - lastActive) / 1e3)
|
||||||
lastActive = null
|
lastActive = null
|
||||||
logEvent('state:background:sampled', {
|
logEvent('state:background', {
|
||||||
secondsActive,
|
secondsActive,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -234,21 +234,21 @@ function flushToStatsig(stats: AggregatedStats | null) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (stats.clickthroughCount > 0) {
|
if (stats.clickthroughCount > 0) {
|
||||||
logEvent('discover:clickthrough:sampled', {
|
logEvent('discover:clickthrough', {
|
||||||
count: stats.clickthroughCount,
|
count: stats.clickthroughCount,
|
||||||
})
|
})
|
||||||
stats.clickthroughCount = 0
|
stats.clickthroughCount = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
if (stats.engagedCount > 0) {
|
if (stats.engagedCount > 0) {
|
||||||
logEvent('discover:engaged:sampled', {
|
logEvent('discover:engaged', {
|
||||||
count: stats.engagedCount,
|
count: stats.engagedCount,
|
||||||
})
|
})
|
||||||
stats.engagedCount = 0
|
stats.engagedCount = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
if (stats.seenCount > 0) {
|
if (stats.seenCount > 0) {
|
||||||
logEvent('discover:seen:sampled', {
|
logEvent('discover:seen', {
|
||||||
count: stats.seenCount,
|
count: stats.seenCount,
|
||||||
})
|
})
|
||||||
stats.seenCount = 0
|
stats.seenCount = 0
|
||||||
|
|||||||
+12
-12
@@ -98,8 +98,8 @@ export function useGetPosts() {
|
|||||||
|
|
||||||
export function usePostLikeMutationQueue(
|
export function usePostLikeMutationQueue(
|
||||||
post: Shadow<AppBskyFeedDefs.PostView>,
|
post: Shadow<AppBskyFeedDefs.PostView>,
|
||||||
logContext: LogEvents['post:like:sampled']['logContext'] &
|
logContext: LogEvents['post:like']['logContext'] &
|
||||||
LogEvents['post:unlike:sampled']['logContext'],
|
LogEvents['post:unlike']['logContext'],
|
||||||
) {
|
) {
|
||||||
const queryClient = useQueryClient()
|
const queryClient = useQueryClient()
|
||||||
const postUri = post.uri
|
const postUri = post.uri
|
||||||
@@ -157,7 +157,7 @@ export function usePostLikeMutationQueue(
|
|||||||
}
|
}
|
||||||
|
|
||||||
function usePostLikeMutation(
|
function usePostLikeMutation(
|
||||||
logContext: LogEvents['post:like:sampled']['logContext'],
|
logContext: LogEvents['post:like']['logContext'],
|
||||||
post: Shadow<AppBskyFeedDefs.PostView>,
|
post: Shadow<AppBskyFeedDefs.PostView>,
|
||||||
) {
|
) {
|
||||||
const {currentAccount} = useSession()
|
const {currentAccount} = useSession()
|
||||||
@@ -174,7 +174,7 @@ function usePostLikeMutation(
|
|||||||
if (currentAccount) {
|
if (currentAccount) {
|
||||||
ownProfile = findProfileQueryData(queryClient, currentAccount.did)
|
ownProfile = findProfileQueryData(queryClient, currentAccount.did)
|
||||||
}
|
}
|
||||||
logEvent('post:like:sampled', {
|
logEvent('post:like', {
|
||||||
logContext,
|
logContext,
|
||||||
doesPosterFollowLiker: postAuthor.viewer
|
doesPosterFollowLiker: postAuthor.viewer
|
||||||
? Boolean(postAuthor.viewer.followedBy)
|
? Boolean(postAuthor.viewer.followedBy)
|
||||||
@@ -196,12 +196,12 @@ function usePostLikeMutation(
|
|||||||
}
|
}
|
||||||
|
|
||||||
function usePostUnlikeMutation(
|
function usePostUnlikeMutation(
|
||||||
logContext: LogEvents['post:unlike:sampled']['logContext'],
|
logContext: LogEvents['post:unlike']['logContext'],
|
||||||
) {
|
) {
|
||||||
const agent = useAgent()
|
const agent = useAgent()
|
||||||
return useMutation<void, Error, {postUri: string; likeUri: string}>({
|
return useMutation<void, Error, {postUri: string; likeUri: string}>({
|
||||||
mutationFn: ({likeUri}) => {
|
mutationFn: ({likeUri}) => {
|
||||||
logEvent('post:unlike:sampled', {logContext})
|
logEvent('post:unlike', {logContext})
|
||||||
return agent.deleteLike(likeUri)
|
return agent.deleteLike(likeUri)
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
@@ -209,8 +209,8 @@ function usePostUnlikeMutation(
|
|||||||
|
|
||||||
export function usePostRepostMutationQueue(
|
export function usePostRepostMutationQueue(
|
||||||
post: Shadow<AppBskyFeedDefs.PostView>,
|
post: Shadow<AppBskyFeedDefs.PostView>,
|
||||||
logContext: LogEvents['post:repost:sampled']['logContext'] &
|
logContext: LogEvents['post:repost']['logContext'] &
|
||||||
LogEvents['post:unrepost:sampled']['logContext'],
|
LogEvents['post:unrepost']['logContext'],
|
||||||
) {
|
) {
|
||||||
const queryClient = useQueryClient()
|
const queryClient = useQueryClient()
|
||||||
const postUri = post.uri
|
const postUri = post.uri
|
||||||
@@ -266,7 +266,7 @@ export function usePostRepostMutationQueue(
|
|||||||
}
|
}
|
||||||
|
|
||||||
function usePostRepostMutation(
|
function usePostRepostMutation(
|
||||||
logContext: LogEvents['post:repost:sampled']['logContext'],
|
logContext: LogEvents['post:repost']['logContext'],
|
||||||
) {
|
) {
|
||||||
const agent = useAgent()
|
const agent = useAgent()
|
||||||
return useMutation<
|
return useMutation<
|
||||||
@@ -275,19 +275,19 @@ function usePostRepostMutation(
|
|||||||
{uri: string; cid: string} // the post's uri and cid
|
{uri: string; cid: string} // the post's uri and cid
|
||||||
>({
|
>({
|
||||||
mutationFn: post => {
|
mutationFn: post => {
|
||||||
logEvent('post:repost:sampled', {logContext})
|
logEvent('post:repost', {logContext})
|
||||||
return agent.repost(post.uri, post.cid)
|
return agent.repost(post.uri, post.cid)
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
function usePostUnrepostMutation(
|
function usePostUnrepostMutation(
|
||||||
logContext: LogEvents['post:unrepost:sampled']['logContext'],
|
logContext: LogEvents['post:unrepost']['logContext'],
|
||||||
) {
|
) {
|
||||||
const agent = useAgent()
|
const agent = useAgent()
|
||||||
return useMutation<void, Error, {postUri: string; repostUri: string}>({
|
return useMutation<void, Error, {postUri: string; repostUri: string}>({
|
||||||
mutationFn: ({repostUri}) => {
|
mutationFn: ({repostUri}) => {
|
||||||
logEvent('post:unrepost:sampled', {logContext})
|
logEvent('post:unrepost', {logContext})
|
||||||
return agent.deleteRepost(repostUri)
|
return agent.deleteRepost(repostUri)
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -221,8 +221,8 @@ export function useProfileUpdateMutation() {
|
|||||||
|
|
||||||
export function useProfileFollowMutationQueue(
|
export function useProfileFollowMutationQueue(
|
||||||
profile: Shadow<AppBskyActorDefs.ProfileViewDetailed>,
|
profile: Shadow<AppBskyActorDefs.ProfileViewDetailed>,
|
||||||
logContext: LogEvents['profile:follow:sampled']['logContext'] &
|
logContext: LogEvents['profile:follow']['logContext'] &
|
||||||
LogEvents['profile:follow:sampled']['logContext'],
|
LogEvents['profile:follow']['logContext'],
|
||||||
) {
|
) {
|
||||||
const agent = useAgent()
|
const agent = useAgent()
|
||||||
const queryClient = useQueryClient()
|
const queryClient = useQueryClient()
|
||||||
@@ -293,7 +293,7 @@ export function useProfileFollowMutationQueue(
|
|||||||
}
|
}
|
||||||
|
|
||||||
function useProfileFollowMutation(
|
function useProfileFollowMutation(
|
||||||
logContext: LogEvents['profile:follow:sampled']['logContext'],
|
logContext: LogEvents['profile:follow']['logContext'],
|
||||||
profile: Shadow<AppBskyActorDefs.ProfileViewDetailed>,
|
profile: Shadow<AppBskyActorDefs.ProfileViewDetailed>,
|
||||||
) {
|
) {
|
||||||
const {currentAccount} = useSession()
|
const {currentAccount} = useSession()
|
||||||
@@ -308,7 +308,7 @@ function useProfileFollowMutation(
|
|||||||
ownProfile = findProfileQueryData(queryClient, currentAccount.did)
|
ownProfile = findProfileQueryData(queryClient, currentAccount.did)
|
||||||
}
|
}
|
||||||
captureAction(ProgressGuideAction.Follow)
|
captureAction(ProgressGuideAction.Follow)
|
||||||
logEvent('profile:follow:sampled', {
|
logEvent('profile:follow', {
|
||||||
logContext,
|
logContext,
|
||||||
didBecomeMutual: profile.viewer
|
didBecomeMutual: profile.viewer
|
||||||
? Boolean(profile.viewer.followedBy)
|
? Boolean(profile.viewer.followedBy)
|
||||||
@@ -322,12 +322,12 @@ function useProfileFollowMutation(
|
|||||||
}
|
}
|
||||||
|
|
||||||
function useProfileUnfollowMutation(
|
function useProfileUnfollowMutation(
|
||||||
logContext: LogEvents['profile:unfollow:sampled']['logContext'],
|
logContext: LogEvents['profile:unfollow']['logContext'],
|
||||||
) {
|
) {
|
||||||
const agent = useAgent()
|
const agent = useAgent()
|
||||||
return useMutation<void, Error, {did: string; followUri: string}>({
|
return useMutation<void, Error, {did: string; followUri: string}>({
|
||||||
mutationFn: async ({followUri}) => {
|
mutationFn: async ({followUri}) => {
|
||||||
logEvent('profile:unfollow:sampled', {logContext})
|
logEvent('profile:unfollow', {logContext})
|
||||||
return await agent.deleteFollow(followUri)
|
return await agent.deleteFollow(followUri)
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -74,7 +74,7 @@ export function FeedPage({
|
|||||||
scrollToTop()
|
scrollToTop()
|
||||||
truncateAndInvalidate(queryClient, FEED_RQKEY(feed))
|
truncateAndInvalidate(queryClient, FEED_RQKEY(feed))
|
||||||
setHasNew(false)
|
setHasNew(false)
|
||||||
logEvent('feed:refresh:sampled', {
|
logEvent('feed:refresh', {
|
||||||
feedType: feed.split('|')[0],
|
feedType: feed.split('|')[0],
|
||||||
feedUrl: feed,
|
feedUrl: feed,
|
||||||
reason: 'soft-reset',
|
reason: 'soft-reset',
|
||||||
@@ -98,7 +98,7 @@ export function FeedPage({
|
|||||||
scrollToTop()
|
scrollToTop()
|
||||||
truncateAndInvalidate(queryClient, FEED_RQKEY(feed))
|
truncateAndInvalidate(queryClient, FEED_RQKEY(feed))
|
||||||
setHasNew(false)
|
setHasNew(false)
|
||||||
logEvent('feed:refresh:sampled', {
|
logEvent('feed:refresh', {
|
||||||
feedType: feed.split('|')[0],
|
feedType: feed.split('|')[0],
|
||||||
feedUrl: feed,
|
feedUrl: feed,
|
||||||
reason: 'load-latest',
|
reason: 'load-latest',
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ const AnimatedPagerView = Animated.createAnimatedComponent(PagerView)
|
|||||||
export interface PagerRef {
|
export interface PagerRef {
|
||||||
setPage: (
|
setPage: (
|
||||||
index: number,
|
index: number,
|
||||||
reason: LogEvents['home:feedDisplayed:sampled']['reason'],
|
reason: LogEvents['home:feedDisplayed']['reason'],
|
||||||
) => void
|
) => void
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -32,7 +32,7 @@ interface Props {
|
|||||||
onPageSelected?: (index: number) => void
|
onPageSelected?: (index: number) => void
|
||||||
onPageSelecting?: (
|
onPageSelecting?: (
|
||||||
index: number,
|
index: number,
|
||||||
reason: LogEvents['home:feedDisplayed:sampled']['reason'],
|
reason: LogEvents['home:feedDisplayed']['reason'],
|
||||||
) => void
|
) => void
|
||||||
onPageScrollStateChanged?: (
|
onPageScrollStateChanged?: (
|
||||||
scrollState: 'idle' | 'dragging' | 'settling',
|
scrollState: 'idle' | 'dragging' | 'settling',
|
||||||
@@ -61,7 +61,7 @@ export const Pager = forwardRef<PagerRef, React.PropsWithChildren<Props>>(
|
|||||||
React.useImperativeHandle(ref, () => ({
|
React.useImperativeHandle(ref, () => ({
|
||||||
setPage: (
|
setPage: (
|
||||||
index: number,
|
index: number,
|
||||||
reason: LogEvents['home:feedDisplayed:sampled']['reason'],
|
reason: LogEvents['home:feedDisplayed']['reason'],
|
||||||
) => {
|
) => {
|
||||||
pagerView.current?.setPage(index)
|
pagerView.current?.setPage(index)
|
||||||
onPageSelecting?.(index, reason)
|
onPageSelecting?.(index, reason)
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ interface Props {
|
|||||||
onPageSelected?: (index: number) => void
|
onPageSelected?: (index: number) => void
|
||||||
onPageSelecting?: (
|
onPageSelecting?: (
|
||||||
index: number,
|
index: number,
|
||||||
reason: LogEvents['home:feedDisplayed:sampled']['reason'],
|
reason: LogEvents['home:feedDisplayed']['reason'],
|
||||||
) => void
|
) => void
|
||||||
}
|
}
|
||||||
export const Pager = React.forwardRef(function PagerImpl(
|
export const Pager = React.forwardRef(function PagerImpl(
|
||||||
@@ -38,17 +38,14 @@ export const Pager = React.forwardRef(function PagerImpl(
|
|||||||
React.useImperativeHandle(ref, () => ({
|
React.useImperativeHandle(ref, () => ({
|
||||||
setPage: (
|
setPage: (
|
||||||
index: number,
|
index: number,
|
||||||
reason: LogEvents['home:feedDisplayed:sampled']['reason'],
|
reason: LogEvents['home:feedDisplayed']['reason'],
|
||||||
) => {
|
) => {
|
||||||
onTabBarSelect(index, reason)
|
onTabBarSelect(index, reason)
|
||||||
},
|
},
|
||||||
}))
|
}))
|
||||||
|
|
||||||
const onTabBarSelect = React.useCallback(
|
const onTabBarSelect = React.useCallback(
|
||||||
(
|
(index: number, reason: LogEvents['home:feedDisplayed']['reason']) => {
|
||||||
index: number,
|
|
||||||
reason: LogEvents['home:feedDisplayed:sampled']['reason'],
|
|
||||||
) => {
|
|
||||||
const scrollY = window.scrollY
|
const scrollY = window.scrollY
|
||||||
// We want to determine if the tabbar is already "sticking" at the top (in which
|
// We want to determine if the tabbar is already "sticking" at the top (in which
|
||||||
// case we should preserve and restore scroll), or if it is somewhere below in the
|
// case we should preserve and restore scroll), or if it is somewhere below in the
|
||||||
|
|||||||
@@ -403,7 +403,7 @@ let Feed = ({
|
|||||||
// =
|
// =
|
||||||
|
|
||||||
const onRefresh = React.useCallback(async () => {
|
const onRefresh = React.useCallback(async () => {
|
||||||
logEvent('feed:refresh:sampled', {
|
logEvent('feed:refresh', {
|
||||||
feedType: feedType,
|
feedType: feedType,
|
||||||
feedUrl: feed,
|
feedUrl: feed,
|
||||||
reason: 'pull-to-refresh',
|
reason: 'pull-to-refresh',
|
||||||
@@ -421,7 +421,7 @@ let Feed = ({
|
|||||||
const onEndReached = React.useCallback(async () => {
|
const onEndReached = React.useCallback(async () => {
|
||||||
if (isFetching || !hasNextPage || isError) return
|
if (isFetching || !hasNextPage || isError) return
|
||||||
|
|
||||||
logEvent('feed:endReached:sampled', {
|
logEvent('feed:endReached', {
|
||||||
feedType: feedType,
|
feedType: feedType,
|
||||||
feedUrl: feed,
|
feedUrl: feed,
|
||||||
itemCount: feedItems.length,
|
itemCount: feedItems.length,
|
||||||
|
|||||||
@@ -141,7 +141,7 @@ function HomeScreenReady({
|
|||||||
useFocusEffect(
|
useFocusEffect(
|
||||||
useNonReactiveCallback(() => {
|
useNonReactiveCallback(() => {
|
||||||
if (selectedFeed) {
|
if (selectedFeed) {
|
||||||
logEvent('home:feedDisplayed:sampled', {
|
logEvent('home:feedDisplayed', {
|
||||||
index: selectedIndex,
|
index: selectedIndex,
|
||||||
feedType: selectedFeed.split('|')[0],
|
feedType: selectedFeed.split('|')[0],
|
||||||
feedUrl: selectedFeed,
|
feedUrl: selectedFeed,
|
||||||
@@ -163,12 +163,9 @@ function HomeScreenReady({
|
|||||||
)
|
)
|
||||||
|
|
||||||
const onPageSelecting = React.useCallback(
|
const onPageSelecting = React.useCallback(
|
||||||
(
|
(index: number, reason: LogEvents['home:feedDisplayed']['reason']) => {
|
||||||
index: number,
|
|
||||||
reason: LogEvents['home:feedDisplayed:sampled']['reason'],
|
|
||||||
) => {
|
|
||||||
const feed = allFeeds[index]
|
const feed = allFeeds[index]
|
||||||
logEvent('home:feedDisplayed:sampled', {
|
logEvent('home:feedDisplayed', {
|
||||||
index,
|
index,
|
||||||
feedType: feed.split('|')[0],
|
feedType: feed.split('|')[0],
|
||||||
feedUrl: feed,
|
feedUrl: feed,
|
||||||
|
|||||||
Reference in New Issue
Block a user