Skip to content

Commit

Permalink
add topViewabilityInset
Browse files Browse the repository at this point in the history
  • Loading branch information
yayvery committed Apr 5, 2024
1 parent 73de76d commit 70fab8b
Show file tree
Hide file tree
Showing 4 changed files with 21 additions and 8 deletions.
1 change: 1 addition & 0 deletions src/FlashListProps.ts
Original file line number Diff line number Diff line change
Expand Up @@ -344,4 +344,5 @@ export interface FlashListProps<TItem> extends ScrollViewProps {
* can consider the visible area of the bottom sheet in its calculations.
*/
bottomViewabilityInsetRef?: React.MutableRefObject<number>;
topViewabilityInsetRef?: React.MutableRefObject<number>;
}
3 changes: 3 additions & 0 deletions src/__tests__/ViewabilityHelper.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,7 @@ describe("ViewabilityHelper", () => {
horizontal,
scrollOffset,
bottomViewabilityInset,
topViewabilityInset,
listSize,
getLayout,
runAllTimers,
Expand All @@ -265,6 +266,7 @@ describe("ViewabilityHelper", () => {
horizontal?: boolean;
scrollOffset?: number;
bottomViewabilityInset?: number;
topViewabilityInset?: number;
listSize?: Dimension;
getLayout?: (index: number) => Layout | undefined;
runAllTimers?: boolean;
Expand All @@ -273,6 +275,7 @@ describe("ViewabilityHelper", () => {
horizontal ?? false,
scrollOffset ?? 0,
bottomViewabilityInset ?? 0,
topViewabilityInset ?? 0,
listSize ?? { height: 300, width: 300 },
getLayout ??
((index) => {
Expand Down
22 changes: 14 additions & 8 deletions src/viewability/ViewabilityHelper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ class ViewabilityHelper {
horizontal: boolean,
scrollOffset: number,
bottomViewabilityInset: number,
topViewabilityInset: number,
listSize: Dimension,
getLayout: (index: number) => Layout | undefined,
viewableIndices?: number[]
Expand Down Expand Up @@ -78,6 +79,7 @@ class ViewabilityHelper {
horizontal,
scrollOffset,
bottomViewabilityInset,
topViewabilityInset,
listSize,
this.viewabilityConfig?.viewAreaCoveragePercentThreshold,
this.viewabilityConfig?.itemVisiblePercentThreshold,
Expand Down Expand Up @@ -127,6 +129,7 @@ class ViewabilityHelper {
horizontal: boolean,
scrollOffset: number,
bottomViewabilityInset: number,
topViewabilityInset: number,
listSize: Dimension,
viewAreaCoveragePercentThreshold: number | null | undefined,
itemVisiblePercentThreshold: number | null | undefined,
Expand All @@ -137,27 +140,30 @@ class ViewabilityHelper {
return false;
}
const itemTop = (horizontal ? itemLayout.x : itemLayout.y) - scrollOffset;
const itemSize = horizontal ? itemLayout.width : itemLayout.height;
const listMainSize = horizontal
? listSize.width
: listSize.height - bottomViewabilityInset;
const pixelsVisible =
Math.min(itemTop + itemSize, listMainSize) - Math.max(itemTop, 0);
const itemEnd =
itemTop + (horizontal ? itemLayout.width : itemLayout.height);
const listStart = topViewabilityInset;
const listEnd =
(horizontal ? listSize.width : listSize.height) - bottomViewabilityInset;
const visibleStart = Math.max(itemTop, listStart);
const visibleEnd = Math.min(itemEnd, listEnd);
const pixelsVisible = Math.max(0, visibleEnd - visibleStart);

// Always consider item fully viewable if it is fully visible, regardless of the `viewAreaCoveragePercentThreshold`
// Account for floating point imprecision.
const itemSize = horizontal ? itemLayout.width : itemLayout.height;
if (Math.abs(pixelsVisible - itemSize) <= 0.001) {
return true;
}
// Skip checking item if it's not visible at all
if (pixelsVisible === 0) {
if (pixelsVisible <= 0) {
return false;
}
const viewAreaMode =
viewAreaCoveragePercentThreshold !== null &&
viewAreaCoveragePercentThreshold !== undefined;
const percent = viewAreaMode
? pixelsVisible / listMainSize
? pixelsVisible / (listEnd - listStart)
: pixelsVisible / itemSize;
const viewableAreaPercentThreshold = viewAreaMode
? viewAreaCoveragePercentThreshold * 0.01
Expand Down
3 changes: 3 additions & 0 deletions src/viewability/ViewabilityManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,12 +79,15 @@ export default class ViewabilityManager<T> {

const bottomViewabilityInset =
this.flashListRef.props.bottomViewabilityInsetRef?.current ?? 0;
const topViewabilityInset =
this.flashListRef.props.topViewabilityInsetRef?.current ?? 0;

this.viewabilityHelpers.forEach((viewabilityHelper) => {
viewabilityHelper.updateViewableItems(
this.flashListRef.props.horizontal ?? false,
scrollOffset,
bottomViewabilityInset,
topViewabilityInset,
listSize,
(index: number) =>
this.flashListRef.recyclerlistview_unsafe?.getLayout(index),
Expand Down

0 comments on commit 70fab8b

Please sign in to comment.