Implement FeedFeedback API (#3498)
* Implement onViewableItemsChanged on List.web.tsx * Introduce onItemSeen to List API * Add FeedFeedback tracker * Add clickthrough interaction tracking * Add engagement interaction tracking * Reduce duplicate sends, introduce a flushAndReset to be triggered on refreshes, and modify the api design a bit * Wire up SDK types and feedContext * Avoid needless function allocations * Fix schema usage * Add show more / show less buttons * Fix minor rendering issue on mobile menu * Wire up sendInteractions() * Fix logic error * Fix: it's item not uri * Update 'seen' to mean 3 seconds on-screen with some significant portion visible * Fix non-reactive debounce * Move methods out * Use a WeakSet for deduping * Reset timeout * 3 -> 2 seconds * Oopsie * Throttle instead * Fix divider * Remove explicit flush calls * Rm unused --------- Co-authored-by: dan <dan.abramov@gmail.com>
This commit is contained in:
parent
e264dfbb87
commit
4fad18b2fa
22 changed files with 516 additions and 64 deletions
|
@ -1,5 +1,5 @@
|
|||
import React, {memo} from 'react'
|
||||
import {FlatListProps, RefreshControl} from 'react-native'
|
||||
import {FlatListProps, RefreshControl, ViewToken} from 'react-native'
|
||||
import {runOnJS, useSharedValue} from 'react-native-reanimated'
|
||||
|
||||
import {useAnimatedScrollHandler} from '#/lib/hooks/useAnimatedScrollHandler_FIXED'
|
||||
|
@ -23,6 +23,7 @@ export type ListProps<ItemT> = Omit<
|
|||
headerOffset?: number
|
||||
refreshing?: boolean
|
||||
onRefresh?: () => void
|
||||
onItemSeen?: (item: ItemT) => void
|
||||
containWeb?: boolean
|
||||
}
|
||||
export type ListRef = React.MutableRefObject<FlatList_INTERNAL | null>
|
||||
|
@ -34,6 +35,7 @@ function ListImpl<ItemT>(
|
|||
onScrolledDownChange,
|
||||
refreshing,
|
||||
onRefresh,
|
||||
onItemSeen,
|
||||
headerOffset,
|
||||
style,
|
||||
...props
|
||||
|
@ -73,6 +75,25 @@ function ListImpl<ItemT>(
|
|||
},
|
||||
})
|
||||
|
||||
const [onViewableItemsChanged, viewabilityConfig] = React.useMemo(() => {
|
||||
if (!onItemSeen) {
|
||||
return [undefined, undefined]
|
||||
}
|
||||
return [
|
||||
(info: {viewableItems: Array<ViewToken>; changed: Array<ViewToken>}) => {
|
||||
for (const item of info.changed) {
|
||||
if (item.isViewable) {
|
||||
onItemSeen(item.item)
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
itemVisiblePercentThreshold: 40,
|
||||
minimumViewTime: 2e3,
|
||||
},
|
||||
]
|
||||
}, [onItemSeen])
|
||||
|
||||
let refreshControl
|
||||
if (refreshing !== undefined || onRefresh !== undefined) {
|
||||
refreshControl = (
|
||||
|
@ -102,6 +123,8 @@ function ListImpl<ItemT>(
|
|||
refreshControl={refreshControl}
|
||||
onScroll={scrollHandler}
|
||||
scrollEventThrottle={1}
|
||||
onViewableItemsChanged={onViewableItemsChanged}
|
||||
viewabilityConfig={viewabilityConfig}
|
||||
style={style}
|
||||
ref={ref}
|
||||
/>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue