Bluesky app fork with some witchin' additions 💫
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

[Statsig] Instrument feed display (#3455)

* [Statsig] Instrument feed display

* Back out leftover change

authored by

dan and committed by
GitHub
c300d4ca c96bc920

+71 -15
+6
src/lib/statsig/events.ts
··· 44 44 } 45 45 'onboarding:moderation:nextPressed': {} 46 46 'onboarding:finished:nextPressed': {} 47 + 'home:feedDisplayed': { 48 + feedUrl: string 49 + feedType: string 50 + index: number 51 + reason: 'focus' | 'tabbar-click' | 'pager-swipe' | 'desktop-sidebar-click' 52 + } 47 53 'feed:endReached': { 48 54 feedUrl: string 49 55 feedType: string
+21 -7
src/view/com/pager/Pager.tsx
··· 1 1 import React, {forwardRef} from 'react' 2 2 import {Animated, View} from 'react-native' 3 3 import PagerView, { 4 - PagerViewOnPageSelectedEvent, 5 4 PagerViewOnPageScrollEvent, 5 + PagerViewOnPageSelectedEvent, 6 6 PageScrollStateChangedNativeEvent, 7 7 } from 'react-native-pager-view' 8 + 9 + import {LogEvents} from '#/lib/statsig/events' 8 10 import {s} from 'lib/styles' 9 11 10 12 export type PageSelectedEvent = PagerViewOnPageSelectedEvent 11 13 const AnimatedPagerView = Animated.createAnimatedComponent(PagerView) 12 14 13 15 export interface PagerRef { 14 - setPage: (index: number) => void 16 + setPage: ( 17 + index: number, 18 + reason: LogEvents['home:feedDisplayed']['reason'], 19 + ) => void 15 20 } 16 21 17 22 export interface RenderTabBarFnProps { ··· 25 30 initialPage?: number 26 31 renderTabBar: RenderTabBarFn 27 32 onPageSelected?: (index: number) => void 28 - onPageSelecting?: (index: number) => void 33 + onPageSelecting?: ( 34 + index: number, 35 + reason: LogEvents['home:feedDisplayed']['reason'], 36 + ) => void 29 37 onPageScrollStateChanged?: ( 30 38 scrollState: 'idle' | 'dragging' | 'settling', 31 39 ) => void ··· 51 59 const pagerView = React.useRef<PagerView>(null) 52 60 53 61 React.useImperativeHandle(ref, () => ({ 54 - setPage: (index: number) => pagerView.current?.setPage(index), 62 + setPage: ( 63 + index: number, 64 + reason: LogEvents['home:feedDisplayed']['reason'], 65 + ) => { 66 + pagerView.current?.setPage(index) 67 + onPageSelecting?.(index, reason) 68 + }, 55 69 })) 56 70 57 71 const onPageSelectedInner = React.useCallback( ··· 79 93 // -prf 80 94 if (scrollState.current === 'settling') { 81 95 if (lastDirection.current === -1 && offset < lastOffset.current) { 82 - onPageSelecting?.(position) 96 + onPageSelecting?.(position, 'pager-swipe') 83 97 setSelectedPage(position) 84 98 lastDirection.current = 0 85 99 } else if ( 86 100 lastDirection.current === 1 && 87 101 offset > lastOffset.current 88 102 ) { 89 - onPageSelecting?.(position + 1) 103 + onPageSelecting?.(position + 1, 'pager-swipe') 90 104 setSelectedPage(position + 1) 91 105 lastDirection.current = 0 92 106 } ··· 113 127 const onTabBarSelect = React.useCallback( 114 128 (index: number) => { 115 129 pagerView.current?.setPage(index) 116 - onPageSelecting?.(index) 130 + onPageSelecting?.(index, 'tabbar-click') 117 131 }, 118 132 [pagerView, onPageSelecting], 119 133 )
+16 -6
src/view/com/pager/Pager.web.tsx
··· 1 1 import React from 'react' 2 - import {flushSync} from 'react-dom' 3 2 import {View} from 'react-native' 3 + import {flushSync} from 'react-dom' 4 + 5 + import {LogEvents} from '#/lib/statsig/events' 4 6 import {s} from 'lib/styles' 5 7 6 8 export interface RenderTabBarFnProps { ··· 14 16 initialPage?: number 15 17 renderTabBar: RenderTabBarFn 16 18 onPageSelected?: (index: number) => void 17 - onPageSelecting?: (index: number) => void 19 + onPageSelecting?: ( 20 + index: number, 21 + reason: LogEvents['home:feedDisplayed']['reason'], 22 + ) => void 18 23 } 19 24 export const Pager = React.forwardRef(function PagerImpl( 20 25 { ··· 31 36 const anchorRef = React.useRef(null) 32 37 33 38 React.useImperativeHandle(ref, () => ({ 34 - setPage: (index: number) => onTabBarSelect(index), 39 + setPage: ( 40 + index: number, 41 + reason: LogEvents['home:feedDisplayed']['reason'], 42 + ) => { 43 + onTabBarSelect(index, reason) 44 + }, 35 45 })) 36 46 37 47 const onTabBarSelect = React.useCallback( 38 - (index: number) => { 48 + (index: number, reason: LogEvents['home:feedDisplayed']['reason']) => { 39 49 const scrollY = window.scrollY 40 50 // We want to determine if the tabbar is already "sticking" at the top (in which 41 51 // case we should preserve and restore scroll), or if it is somewhere below in the ··· 54 64 flushSync(() => { 55 65 setSelectedPage(index) 56 66 onPageSelected?.(index) 57 - onPageSelecting?.(index) 67 + onPageSelecting?.(index, reason) 58 68 }) 59 69 if (isSticking) { 60 70 const restoredScrollY = scrollYs.current[index] ··· 73 83 {renderTabBar({ 74 84 selectedPage, 75 85 tabBarAnchor: <View ref={anchorRef} />, 76 - onSelect: onTabBarSelect, 86 + onSelect: e => onTabBarSelect(e, 'tabbar-click'), 77 87 })} 78 88 {React.Children.map(children, (child, i) => ( 79 89 <View style={selectedPage === i ? s.flex1 : s.hidden} key={`page-${i}`}>
+28 -2
src/view/screens/Home.tsx
··· 2 2 import {ActivityIndicator, AppState, StyleSheet, View} from 'react-native' 3 3 import {useFocusEffect} from '@react-navigation/native' 4 4 5 + import {useNonReactiveCallback} from '#/lib/hooks/useNonReactiveCallback' 5 6 import {useSetTitle} from '#/lib/hooks/useSetTitle' 6 - import {useGate} from '#/lib/statsig/statsig' 7 + import {logEvent, LogEvents, useGate} from '#/lib/statsig/statsig' 7 8 import {emitSoftReset} from '#/state/events' 8 9 import {FeedSourceInfo, usePinnedFeedsInfos} from '#/state/queries/feed' 9 10 import {FeedDescriptor, FeedParams} from '#/state/queries/post-feed' ··· 79 80 // This is supposed to only happen on the web when you use the right nav. 80 81 if (selectedIndex !== lastPagerReportedIndexRef.current) { 81 82 lastPagerReportedIndexRef.current = selectedIndex 82 - pagerRef.current?.setPage(selectedIndex) 83 + pagerRef.current?.setPage(selectedIndex, 'desktop-sidebar-click') 83 84 } 84 85 }, [selectedIndex]) 85 86 ··· 96 97 }, [setDrawerSwipeDisabled, selectedIndex, setMinimalShellMode]), 97 98 ) 98 99 100 + useFocusEffect( 101 + useNonReactiveCallback(() => { 102 + logEvent('home:feedDisplayed', { 103 + index: selectedIndex, 104 + feedType: selectedFeed.split('|')[0], 105 + feedUrl: selectedFeed, 106 + reason: 'focus', 107 + }) 108 + }), 109 + ) 110 + 99 111 const disableMinShellOnForegrounding = useGate( 100 112 'disable_min_shell_on_foregrounding', 101 113 ) ··· 121 133 lastPagerReportedIndexRef.current = index 122 134 }, 123 135 [setDrawerSwipeDisabled, setSelectedFeed, setMinimalShellMode, allFeeds], 136 + ) 137 + 138 + const onPageSelecting = React.useCallback( 139 + (index: number, reason: LogEvents['home:feedDisplayed']['reason']) => { 140 + const feed = allFeeds[index] 141 + logEvent('home:feedDisplayed', { 142 + index, 143 + feedType: feed.split('|')[0], 144 + feedUrl: feed, 145 + reason, 146 + }) 147 + }, 148 + [allFeeds], 124 149 ) 125 150 126 151 const onPressSelected = React.useCallback(() => { ··· 175 200 ref={pagerRef} 176 201 testID="homeScreen" 177 202 initialPage={selectedIndex} 203 + onPageSelecting={onPageSelecting} 178 204 onPageSelected={onPageSelected} 179 205 onPageScrollStateChanged={onPageScrollStateChanged} 180 206 renderTabBar={renderTabBar}>