11// TODO: Make this a common component for all horizontal lists in this lib
2- import React , { forwardRef , useCallback , useMemo , useRef } from 'react' ;
2+ import React , { forwardRef , useCallback , useEffect , useMemo , useRef } from 'react' ;
33import { ScrollViewProps } from 'react-native' ;
44import { DataProvider , LayoutProvider , RecyclerListView , RecyclerListViewProps } from 'recyclerlistview' ;
55import inRange from 'lodash/inRange' ;
6+ import debounce from 'lodash/debounce' ;
7+ import noop from 'lodash/noop' ;
68
79import constants from '../commons/constants' ;
10+ import useCombinedRefs from '../commons/useCombinedRefs' ;
811
912const dataProviderMaker = ( items : string [ ] ) => new DataProvider ( ( item1 , item2 ) => item1 !== item2 ) . cloneWithRows ( items ) ;
1013
@@ -20,12 +23,14 @@ export interface InfiniteListProps
2023 onReachNearEdgeThreshold ?: number ;
2124 initialPageIndex ?: number ;
2225 scrollViewProps ?: ScrollViewProps ;
26+ reloadPages ?: ( pageIndex : number ) => void ;
2327}
2428
2529const InfiniteList = ( props : InfiniteListProps , ref : any ) => {
2630 const {
2731 renderItem,
2832 data,
33+ reloadPages = noop ,
2934 pageWidth = constants . screenWidth ,
3035 pageHeight = constants . screenHeight ,
3136 onPageChange,
@@ -50,13 +55,23 @@ const InfiniteList = (props: InfiniteListProps, ref: any) => {
5055 )
5156 ) ;
5257
58+ const listRef = useCombinedRefs ( ref ) ;
5359 const pageIndex = useRef < number > ( ) ;
5460 const isOnEdge = useRef ( false ) ;
5561 const isNearEdge = useRef ( false ) ;
5662 const scrolledByUser = useRef ( false ) ;
63+ const reloadPagesDebounce = useCallback ( debounce ( reloadPages , 500 , { leading : false , trailing : true } ) , [ reloadPages ] ) ;
64+
65+ useEffect ( ( ) => {
66+ setTimeout ( ( ) => {
67+ // @ts -expect-error
68+ listRef . current ?. scrollToOffset ?.( Math . floor ( data . length / 2 ) * pageWidth , 0 , false ) ;
69+ } , 0 ) ;
70+ } , [ data ] ) ;
5771
5872 const onScroll = useCallback (
5973 ( event , offsetX , offsetY ) => {
74+ reloadPagesDebounce ?. cancel ( ) ;
6075 const newPageIndex = Math . round ( event . nativeEvent . contentOffset . x / pageWidth ) ;
6176
6277 if ( pageIndex . current !== newPageIndex ) {
@@ -81,20 +96,22 @@ const InfiniteList = (props: InfiniteListProps, ref: any) => {
8196
8297 props . onScroll ?.( event , offsetX , offsetY ) ;
8398 } ,
84- [ props . onScroll , onPageChange , data . length ]
99+ [ props . onScroll , onPageChange , data . length , reloadPagesDebounce ]
85100 ) ;
86101
87102 const onMomentumScrollEnd = useCallback (
88103 event => {
89104 if ( isOnEdge . current ) {
90105 onReachEdge ?.( pageIndex . current ! ) ;
106+ reloadPagesDebounce ?.( pageIndex . current ) ;
91107 } else if ( isNearEdge . current ) {
108+ reloadPagesDebounce ?.( pageIndex . current ) ;
92109 onReachNearEdge ?.( pageIndex . current ! ) ;
93110 }
94111
95112 scrollViewProps ?. onMomentumScrollEnd ?.( event ) ;
96113 } ,
97- [ scrollViewProps ?. onMomentumScrollEnd , onReachEdge , onReachNearEdge ]
114+ [ scrollViewProps ?. onMomentumScrollEnd , onReachEdge , onReachNearEdge , reloadPagesDebounce ]
98115 ) ;
99116
100117 const onScrollBeginDrag = useCallback ( ( ) => {
@@ -107,7 +124,8 @@ const InfiniteList = (props: InfiniteListProps, ref: any) => {
107124
108125 return (
109126 < RecyclerListView
110- ref = { ref }
127+ // @ts -expect-error
128+ ref = { listRef }
111129 isHorizontal
112130 rowRenderer = { renderItem }
113131 dataProvider = { dataProvider }
0 commit comments