about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/Navigation.tsx2
-rw-r--r--src/components/ProfileCard.tsx4
-rw-r--r--src/components/hooks/useFollowMethods.ts4
-rw-r--r--src/lib/statsig/events.ts30
-rw-r--r--src/lib/statsig/statsig.tsx42
-rw-r--r--src/state/feed-feedback.tsx6
-rw-r--r--src/state/queries/post.ts24
-rw-r--r--src/state/queries/profile.ts12
-rw-r--r--src/view/com/feeds/FeedPage.tsx4
-rw-r--r--src/view/com/pager/Pager.tsx6
-rw-r--r--src/view/com/pager/Pager.web.tsx9
-rw-r--r--src/view/com/posts/Feed.tsx4
-rw-r--r--src/view/screens/Home.tsx9
13 files changed, 57 insertions, 99 deletions
diff --git a/src/Navigation.tsx b/src/Navigation.tsx
index 0ab4bb613..1806df92e 100644
--- a/src/Navigation.tsx
+++ b/src/Navigation.tsx
@@ -696,7 +696,7 @@ function RoutesContainer({children}: React.PropsWithChildren<{}>) {
       onStateChange={() => {
         const routeName = getCurrentRouteName()
         if (routeName === 'Notifications') {
-          logEvent('router:navigate:notifications:sampled', {})
+          logEvent('router:navigate:notifications', {})
         }
       }}
       onReady={() => {
diff --git a/src/components/ProfileCard.tsx b/src/components/ProfileCard.tsx
index 50b34ba99..668bd0f3c 100644
--- a/src/components/ProfileCard.tsx
+++ b/src/components/ProfileCard.tsx
@@ -283,8 +283,8 @@ export function DescriptionPlaceholder({
 export type FollowButtonProps = {
   profile: AppBskyActorDefs.ProfileViewBasic
   moderationOpts: ModerationOpts
-  logContext: LogEvents['profile:follow:sampled']['logContext'] &
-    LogEvents['profile:unfollow:sampled']['logContext']
+  logContext: LogEvents['profile:follow']['logContext'] &
+    LogEvents['profile:unfollow']['logContext']
 } & Partial<ButtonProps>
 
 export function FollowButton(props: FollowButtonProps) {
diff --git a/src/components/hooks/useFollowMethods.ts b/src/components/hooks/useFollowMethods.ts
index 31a1e43da..d67c3690f 100644
--- a/src/components/hooks/useFollowMethods.ts
+++ b/src/components/hooks/useFollowMethods.ts
@@ -15,8 +15,8 @@ export function useFollowMethods({
   logContext,
 }: {
   profile: Shadow<AppBskyActorDefs.ProfileViewBasic>
-  logContext: LogEvents['profile:follow:sampled']['logContext'] &
-    LogEvents['profile:unfollow:sampled']['logContext']
+  logContext: LogEvents['profile:follow']['logContext'] &
+    LogEvents['profile:unfollow']['logContext']
 }) {
   const {_} = useLingui()
   const requireAuth = useRequireAuth()
diff --git a/src/lib/statsig/events.ts b/src/lib/statsig/events.ts
index 8f8504021..f8c6d181c 100644
--- a/src/lib/statsig/events.ts
+++ b/src/lib/statsig/events.ts
@@ -21,11 +21,11 @@ export type LogEvents = {
     context: 'StartOnboarding' | 'AfterOnboarding' | 'Login' | 'Home'
     status: 'granted' | 'denied' | 'undetermined'
   }
-  'state:background:sampled': {
+  'state:background': {
     secondsActive: number
   }
-  'state:foreground:sampled': {}
-  'router:navigate:notifications:sampled': {}
+  'state:foreground': {}
+  'router:navigate:notifications': {}
   'deepLink:referrerReceived': {
     to: string
     referrer: string
@@ -76,7 +76,7 @@ export type LogEvents = {
   'onboarding:finished:avatarResult': {
     avatarResult: 'default' | 'created' | 'uploaded'
   }
-  'home:feedDisplayed:sampled': {
+  'home:feedDisplayed': {
     feedUrl: string
     feedType: string
     index: number
@@ -87,12 +87,12 @@ export type LogEvents = {
       | 'desktop-sidebar-click'
       | 'starter-pack-initial-feed'
   }
-  'feed:endReached:sampled': {
+  'feed:endReached': {
     feedUrl: string
     feedType: string
     itemCount: number
   }
-  'feed:refresh:sampled': {
+  'feed:refresh': {
     feedUrl: string
     feedType: string
     reason: 'pull-to-refresh' | 'soft-reset' | 'load-latest'
@@ -103,13 +103,13 @@ export type LogEvents = {
   'discover:showLess': {
     feedContext: string
   }
-  'discover:clickthrough:sampled': {
+  'discover:clickthrough': {
     count: number
   }
-  'discover:engaged:sampled': {
+  'discover:engaged': {
     count: number
   }
-  'discover:seen:sampled': {
+  'discover:seen': {
     count: number
   }
 
@@ -132,27 +132,27 @@ export type LogEvents = {
     postCount: number
     isReply: boolean
   }
-  'post:like:sampled': {
+  'post:like': {
     doesLikerFollowPoster: boolean | undefined
     doesPosterFollowLiker: boolean | undefined
     likerClout: number | undefined
     postClout: number | undefined
     logContext: 'FeedItem' | 'PostThreadItem' | 'Post'
   }
-  'post:repost:sampled': {
+  'post:repost': {
     logContext: 'FeedItem' | 'PostThreadItem' | 'Post'
   }
-  'post:unlike:sampled': {
+  'post:unlike': {
     logContext: 'FeedItem' | 'PostThreadItem' | 'Post'
   }
-  'post:unrepost:sampled': {
+  'post:unrepost': {
     logContext: 'FeedItem' | 'PostThreadItem' | 'Post'
   }
   'post:mute': {}
   'post:unmute': {}
   'post:pin': {}
   'post:unpin': {}
-  'profile:follow:sampled': {
+  'profile:follow': {
     didBecomeMutual: boolean | undefined
     followeeClout: number | undefined
     followerClout: number | undefined
@@ -169,7 +169,7 @@ export type LogEvents = {
       | 'FeedInterstitial'
       | 'ProfileHeaderSuggestedFollows'
   }
-  'profile:unfollow:sampled': {
+  'profile:unfollow': {
     logContext:
       | 'RecommendedFollowsItem'
       | 'PostThreadItem'
diff --git a/src/lib/statsig/statsig.tsx b/src/lib/statsig/statsig.tsx
index 36bd54e2a..51d7eb98e 100644
--- a/src/lib/statsig/statsig.tsx
+++ b/src/lib/statsig/statsig.tsx
@@ -59,6 +59,7 @@ function createStatsigOptions(prefetchUsers: StatsigUser[]) {
     initTimeoutMs: 1,
     // Get fresh flags for other accounts as well, if any.
     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>(
   eventName: E & string,
   rawMetadata: LogEvents[E] & FlatJSONRecord,
 ) {
   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 = {
       ...rawMetadata,
     } as Record<string, string> // Statsig typings are unnecessarily strict here.
-    if (isDownsampledEvent) {
-      fullMetadata.downsampleRate = DOWNSAMPLE_RATE.toString()
-    }
     fullMetadata.routeName = getCurrentRouteName() ?? '(Uninitialized)'
     if (Statsig.initializeCalled()) {
       Statsig.logEvent(eventName, null, fullMetadata)
@@ -232,13 +196,13 @@ AppState.addEventListener('change', (state: AppStateStatus) => {
   lastState = state
   if (state === 'active') {
     lastActive = performance.now()
-    logEvent('state:foreground:sampled', {})
+    logEvent('state:foreground', {})
   } else {
     let secondsActive = 0
     if (lastActive != null) {
       secondsActive = Math.round((performance.now() - lastActive) / 1e3)
       lastActive = null
-      logEvent('state:background:sampled', {
+      logEvent('state:background', {
         secondsActive,
       })
     }
diff --git a/src/state/feed-feedback.tsx b/src/state/feed-feedback.tsx
index 41579edc1..eaf6529f3 100644
--- a/src/state/feed-feedback.tsx
+++ b/src/state/feed-feedback.tsx
@@ -234,21 +234,21 @@ function flushToStatsig(stats: AggregatedStats | null) {
   }
 
   if (stats.clickthroughCount > 0) {
-    logEvent('discover:clickthrough:sampled', {
+    logEvent('discover:clickthrough', {
       count: stats.clickthroughCount,
     })
     stats.clickthroughCount = 0
   }
 
   if (stats.engagedCount > 0) {
-    logEvent('discover:engaged:sampled', {
+    logEvent('discover:engaged', {
       count: stats.engagedCount,
     })
     stats.engagedCount = 0
   }
 
   if (stats.seenCount > 0) {
-    logEvent('discover:seen:sampled', {
+    logEvent('discover:seen', {
       count: stats.seenCount,
     })
     stats.seenCount = 0
diff --git a/src/state/queries/post.ts b/src/state/queries/post.ts
index 7023580bb..7052590ca 100644
--- a/src/state/queries/post.ts
+++ b/src/state/queries/post.ts
@@ -98,8 +98,8 @@ export function useGetPosts() {
 
 export function usePostLikeMutationQueue(
   post: Shadow<AppBskyFeedDefs.PostView>,
-  logContext: LogEvents['post:like:sampled']['logContext'] &
-    LogEvents['post:unlike:sampled']['logContext'],
+  logContext: LogEvents['post:like']['logContext'] &
+    LogEvents['post:unlike']['logContext'],
 ) {
   const queryClient = useQueryClient()
   const postUri = post.uri
@@ -157,7 +157,7 @@ export function usePostLikeMutationQueue(
 }
 
 function usePostLikeMutation(
-  logContext: LogEvents['post:like:sampled']['logContext'],
+  logContext: LogEvents['post:like']['logContext'],
   post: Shadow<AppBskyFeedDefs.PostView>,
 ) {
   const {currentAccount} = useSession()
@@ -174,7 +174,7 @@ function usePostLikeMutation(
       if (currentAccount) {
         ownProfile = findProfileQueryData(queryClient, currentAccount.did)
       }
-      logEvent('post:like:sampled', {
+      logEvent('post:like', {
         logContext,
         doesPosterFollowLiker: postAuthor.viewer
           ? Boolean(postAuthor.viewer.followedBy)
@@ -196,12 +196,12 @@ function usePostLikeMutation(
 }
 
 function usePostUnlikeMutation(
-  logContext: LogEvents['post:unlike:sampled']['logContext'],
+  logContext: LogEvents['post:unlike']['logContext'],
 ) {
   const agent = useAgent()
   return useMutation<void, Error, {postUri: string; likeUri: string}>({
     mutationFn: ({likeUri}) => {
-      logEvent('post:unlike:sampled', {logContext})
+      logEvent('post:unlike', {logContext})
       return agent.deleteLike(likeUri)
     },
   })
@@ -209,8 +209,8 @@ function usePostUnlikeMutation(
 
 export function usePostRepostMutationQueue(
   post: Shadow<AppBskyFeedDefs.PostView>,
-  logContext: LogEvents['post:repost:sampled']['logContext'] &
-    LogEvents['post:unrepost:sampled']['logContext'],
+  logContext: LogEvents['post:repost']['logContext'] &
+    LogEvents['post:unrepost']['logContext'],
 ) {
   const queryClient = useQueryClient()
   const postUri = post.uri
@@ -266,7 +266,7 @@ export function usePostRepostMutationQueue(
 }
 
 function usePostRepostMutation(
-  logContext: LogEvents['post:repost:sampled']['logContext'],
+  logContext: LogEvents['post:repost']['logContext'],
 ) {
   const agent = useAgent()
   return useMutation<
@@ -275,19 +275,19 @@ function usePostRepostMutation(
     {uri: string; cid: string} // the post's uri and cid
   >({
     mutationFn: post => {
-      logEvent('post:repost:sampled', {logContext})
+      logEvent('post:repost', {logContext})
       return agent.repost(post.uri, post.cid)
     },
   })
 }
 
 function usePostUnrepostMutation(
-  logContext: LogEvents['post:unrepost:sampled']['logContext'],
+  logContext: LogEvents['post:unrepost']['logContext'],
 ) {
   const agent = useAgent()
   return useMutation<void, Error, {postUri: string; repostUri: string}>({
     mutationFn: ({repostUri}) => {
-      logEvent('post:unrepost:sampled', {logContext})
+      logEvent('post:unrepost', {logContext})
       return agent.deleteRepost(repostUri)
     },
   })
diff --git a/src/state/queries/profile.ts b/src/state/queries/profile.ts
index 3059d9efe..84f209d95 100644
--- a/src/state/queries/profile.ts
+++ b/src/state/queries/profile.ts
@@ -221,8 +221,8 @@ export function useProfileUpdateMutation() {
 
 export function useProfileFollowMutationQueue(
   profile: Shadow<AppBskyActorDefs.ProfileViewDetailed>,
-  logContext: LogEvents['profile:follow:sampled']['logContext'] &
-    LogEvents['profile:follow:sampled']['logContext'],
+  logContext: LogEvents['profile:follow']['logContext'] &
+    LogEvents['profile:follow']['logContext'],
 ) {
   const agent = useAgent()
   const queryClient = useQueryClient()
@@ -293,7 +293,7 @@ export function useProfileFollowMutationQueue(
 }
 
 function useProfileFollowMutation(
-  logContext: LogEvents['profile:follow:sampled']['logContext'],
+  logContext: LogEvents['profile:follow']['logContext'],
   profile: Shadow<AppBskyActorDefs.ProfileViewDetailed>,
 ) {
   const {currentAccount} = useSession()
@@ -308,7 +308,7 @@ function useProfileFollowMutation(
         ownProfile = findProfileQueryData(queryClient, currentAccount.did)
       }
       captureAction(ProgressGuideAction.Follow)
-      logEvent('profile:follow:sampled', {
+      logEvent('profile:follow', {
         logContext,
         didBecomeMutual: profile.viewer
           ? Boolean(profile.viewer.followedBy)
@@ -322,12 +322,12 @@ function useProfileFollowMutation(
 }
 
 function useProfileUnfollowMutation(
-  logContext: LogEvents['profile:unfollow:sampled']['logContext'],
+  logContext: LogEvents['profile:unfollow']['logContext'],
 ) {
   const agent = useAgent()
   return useMutation<void, Error, {did: string; followUri: string}>({
     mutationFn: async ({followUri}) => {
-      logEvent('profile:unfollow:sampled', {logContext})
+      logEvent('profile:unfollow', {logContext})
       return await agent.deleteFollow(followUri)
     },
   })
diff --git a/src/view/com/feeds/FeedPage.tsx b/src/view/com/feeds/FeedPage.tsx
index d61a81498..1028d7e64 100644
--- a/src/view/com/feeds/FeedPage.tsx
+++ b/src/view/com/feeds/FeedPage.tsx
@@ -74,7 +74,7 @@ export function FeedPage({
       scrollToTop()
       truncateAndInvalidate(queryClient, FEED_RQKEY(feed))
       setHasNew(false)
-      logEvent('feed:refresh:sampled', {
+      logEvent('feed:refresh', {
         feedType: feed.split('|')[0],
         feedUrl: feed,
         reason: 'soft-reset',
@@ -98,7 +98,7 @@ export function FeedPage({
     scrollToTop()
     truncateAndInvalidate(queryClient, FEED_RQKEY(feed))
     setHasNew(false)
-    logEvent('feed:refresh:sampled', {
+    logEvent('feed:refresh', {
       feedType: feed.split('|')[0],
       feedUrl: feed,
       reason: 'load-latest',
diff --git a/src/view/com/pager/Pager.tsx b/src/view/com/pager/Pager.tsx
index 4d5da960c..aca3245a7 100644
--- a/src/view/com/pager/Pager.tsx
+++ b/src/view/com/pager/Pager.tsx
@@ -15,7 +15,7 @@ const AnimatedPagerView = Animated.createAnimatedComponent(PagerView)
 export interface PagerRef {
   setPage: (
     index: number,
-    reason: LogEvents['home:feedDisplayed:sampled']['reason'],
+    reason: LogEvents['home:feedDisplayed']['reason'],
   ) => void
 }
 
@@ -32,7 +32,7 @@ interface Props {
   onPageSelected?: (index: number) => void
   onPageSelecting?: (
     index: number,
-    reason: LogEvents['home:feedDisplayed:sampled']['reason'],
+    reason: LogEvents['home:feedDisplayed']['reason'],
   ) => void
   onPageScrollStateChanged?: (
     scrollState: 'idle' | 'dragging' | 'settling',
@@ -61,7 +61,7 @@ export const Pager = forwardRef<PagerRef, React.PropsWithChildren<Props>>(
     React.useImperativeHandle(ref, () => ({
       setPage: (
         index: number,
-        reason: LogEvents['home:feedDisplayed:sampled']['reason'],
+        reason: LogEvents['home:feedDisplayed']['reason'],
       ) => {
         pagerView.current?.setPage(index)
         onPageSelecting?.(index, reason)
diff --git a/src/view/com/pager/Pager.web.tsx b/src/view/com/pager/Pager.web.tsx
index 2cce727c0..e6909fe10 100644
--- a/src/view/com/pager/Pager.web.tsx
+++ b/src/view/com/pager/Pager.web.tsx
@@ -18,7 +18,7 @@ interface Props {
   onPageSelected?: (index: number) => void
   onPageSelecting?: (
     index: number,
-    reason: LogEvents['home:feedDisplayed:sampled']['reason'],
+    reason: LogEvents['home:feedDisplayed']['reason'],
   ) => void
 }
 export const Pager = React.forwardRef(function PagerImpl(
@@ -38,17 +38,14 @@ export const Pager = React.forwardRef(function PagerImpl(
   React.useImperativeHandle(ref, () => ({
     setPage: (
       index: number,
-      reason: LogEvents['home:feedDisplayed:sampled']['reason'],
+      reason: LogEvents['home:feedDisplayed']['reason'],
     ) => {
       onTabBarSelect(index, reason)
     },
   }))
 
   const onTabBarSelect = React.useCallback(
-    (
-      index: number,
-      reason: LogEvents['home:feedDisplayed:sampled']['reason'],
-    ) => {
+    (index: number, reason: LogEvents['home:feedDisplayed']['reason']) => {
       const scrollY = window.scrollY
       // 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
diff --git a/src/view/com/posts/Feed.tsx b/src/view/com/posts/Feed.tsx
index 905c1e0e0..d6cf6dac5 100644
--- a/src/view/com/posts/Feed.tsx
+++ b/src/view/com/posts/Feed.tsx
@@ -403,7 +403,7 @@ let Feed = ({
   // =
 
   const onRefresh = React.useCallback(async () => {
-    logEvent('feed:refresh:sampled', {
+    logEvent('feed:refresh', {
       feedType: feedType,
       feedUrl: feed,
       reason: 'pull-to-refresh',
@@ -421,7 +421,7 @@ let Feed = ({
   const onEndReached = React.useCallback(async () => {
     if (isFetching || !hasNextPage || isError) return
 
-    logEvent('feed:endReached:sampled', {
+    logEvent('feed:endReached', {
       feedType: feedType,
       feedUrl: feed,
       itemCount: feedItems.length,
diff --git a/src/view/screens/Home.tsx b/src/view/screens/Home.tsx
index 237449383..cadfb4890 100644
--- a/src/view/screens/Home.tsx
+++ b/src/view/screens/Home.tsx
@@ -141,7 +141,7 @@ function HomeScreenReady({
   useFocusEffect(
     useNonReactiveCallback(() => {
       if (selectedFeed) {
-        logEvent('home:feedDisplayed:sampled', {
+        logEvent('home:feedDisplayed', {
           index: selectedIndex,
           feedType: selectedFeed.split('|')[0],
           feedUrl: selectedFeed,
@@ -163,12 +163,9 @@ function HomeScreenReady({
   )
 
   const onPageSelecting = React.useCallback(
-    (
-      index: number,
-      reason: LogEvents['home:feedDisplayed:sampled']['reason'],
-    ) => {
+    (index: number, reason: LogEvents['home:feedDisplayed']['reason']) => {
       const feed = allFeeds[index]
-      logEvent('home:feedDisplayed:sampled', {
+      logEvent('home:feedDisplayed', {
         index,
         feedType: feed.split('|')[0],
         feedUrl: feed,