11// TODO: Make this a common component for all horizontal lists in this lib
22import React , { forwardRef , useCallback , useMemo , useRef } from 'react' ;
3+ import { ScrollViewProps } from 'react-native' ;
34import { DataProvider , LayoutProvider , RecyclerListView , RecyclerListViewProps } from 'recyclerlistview' ;
45import inRange from 'lodash/inRange' ;
56
@@ -18,6 +19,7 @@ export interface InfiniteListProps
1819 onReachNearEdge ?: ( pageIndex : number ) => void ;
1920 nearEdgeThreshold ?: number ;
2021 initialPageIndex ?: number ;
22+ scrollViewProps ?: ScrollViewProps ;
2123}
2224
2325const InfiniteList = ( props : InfiniteListProps , ref : any ) => {
@@ -49,27 +51,45 @@ const InfiniteList = (props: InfiniteListProps, ref: any) => {
4951 ) ;
5052
5153 const pageIndex = useRef < number > ( ) ;
54+ const isOnEdge = useRef ( false ) ;
55+ const isNearEdge = useRef ( false ) ;
5256
5357 const onScroll = useCallback (
5458 ( event , offsetX , offsetY ) => {
55- const currPageIndex = Math . round ( event . nativeEvent . contentOffset . x / pageWidth ) ;
59+ const newPageIndex = Math . round ( event . nativeEvent . contentOffset . x / pageWidth ) ;
5660
57- if ( pageIndex . current !== currPageIndex ) {
61+ if ( pageIndex . current !== newPageIndex ) {
5862 if ( pageIndex . current !== undefined ) {
59- onPageChange ?.( currPageIndex , pageIndex . current ) ;
63+ onPageChange ?.( newPageIndex , pageIndex . current ) ;
6064
61- if ( currPageIndex === 0 || currPageIndex === data . length - 1 ) {
62- onReachEdge ?.( currPageIndex ) ;
63- } else if ( nearEdgeThreshold && ! inRange ( currPageIndex , nearEdgeThreshold , data . length - nearEdgeThreshold ) ) {
64- onReachNearEdge ?.( currPageIndex ) ;
65+ isOnEdge . current = false ;
66+ isNearEdge . current = false ;
67+
68+ if ( newPageIndex === 0 || newPageIndex === data . length - 1 ) {
69+ isOnEdge . current = true ;
70+ } else if ( nearEdgeThreshold && ! inRange ( newPageIndex , nearEdgeThreshold , data . length - nearEdgeThreshold ) ) {
71+ isNearEdge . current = true ;
6572 }
6673 }
67- pageIndex . current = currPageIndex ;
74+ pageIndex . current = newPageIndex ;
6875 }
6976
7077 props . onScroll ?.( event , offsetX , offsetY ) ;
7178 } ,
72- [ props . onScroll , data . length ]
79+ [ props . onScroll , onPageChange , data . length ]
80+ ) ;
81+
82+ const onMomentumScrollEnd = useCallback (
83+ event => {
84+ if ( isOnEdge . current ) {
85+ onReachEdge ?.( pageIndex . current ! ) ;
86+ } else if ( isNearEdge . current ) {
87+ onReachNearEdge ?.( pageIndex . current ! ) ;
88+ }
89+
90+ scrollViewProps ?. onMomentumScrollEnd ?.( event ) ;
91+ } ,
92+ [ scrollViewProps ?. onMomentumScrollEnd , onReachEdge , onReachNearEdge ]
7393 ) ;
7494
7595 const style = useMemo ( ( ) => {
@@ -91,7 +111,8 @@ const InfiniteList = (props: InfiniteListProps, ref: any) => {
91111 scrollViewProps = { {
92112 pagingEnabled : true ,
93113 bounces : false ,
94- ...scrollViewProps
114+ ...scrollViewProps ,
115+ onMomentumScrollEnd
95116 } }
96117 />
97118 ) ;
0 commit comments