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' ;
67
78import constants from '../commons/constants' ;
9+ import useCombinedRefs from '../commons/useCombinedRefs' ;
810
911const dataProviderMaker = ( items : string [ ] ) => new DataProvider ( ( item1 , item2 ) => item1 !== item2 ) . cloneWithRows ( items ) ;
1012
@@ -20,12 +22,14 @@ export interface InfiniteListProps
2022 onReachNearEdgeThreshold ?: number ;
2123 initialPageIndex ?: number ;
2224 scrollViewProps ?: ScrollViewProps ;
25+ reloadPages ?: ( pageIndex : number ) => void ;
2326}
2427
2528const InfiniteList = ( props : InfiniteListProps , ref : any ) => {
2629 const {
2730 renderItem,
2831 data,
32+ reloadPages,
2933 pageWidth = constants . screenWidth ,
3034 pageHeight = constants . screenHeight ,
3135 onPageChange,
@@ -50,13 +54,25 @@ const InfiniteList = (props: InfiniteListProps, ref: any) => {
5054 )
5155 ) ;
5256
57+ const listRef = useCombinedRefs ( ref ) ;
5358 const pageIndex = useRef < number > ( ) ;
5459 const isOnEdge = useRef ( false ) ;
5560 const isNearEdge = useRef ( false ) ;
5661 const scrolledByUser = useRef ( false ) ;
5762
63+ // @ts -expect-error lodash can't handle reloadPages signature
64+ const reloadPagesDebounce = useCallback ( debounce ( reloadPages , 500 , { leading : false , trailing : true } ) , [ reloadPages ] ) ;
65+
66+ useEffect ( ( ) => {
67+ setTimeout ( ( ) => {
68+ // @ts -expect-error
69+ listRef . current ?. scrollToOffset ?.( Math . floor ( data . length / 2 ) * pageWidth , 0 , false ) ;
70+ } , 0 ) ;
71+ } , [ data ] ) ;
72+
5873 const onScroll = useCallback (
5974 ( event , offsetX , offsetY ) => {
75+ reloadPagesDebounce ?. cancel ( ) ;
6076 const newPageIndex = Math . round ( event . nativeEvent . contentOffset . x / pageWidth ) ;
6177
6278 if ( pageIndex . current !== newPageIndex ) {
@@ -81,20 +97,22 @@ const InfiniteList = (props: InfiniteListProps, ref: any) => {
8197
8298 props . onScroll ?.( event , offsetX , offsetY ) ;
8399 } ,
84- [ props . onScroll , onPageChange , data . length ]
100+ [ props . onScroll , onPageChange , data . length , reloadPagesDebounce ]
85101 ) ;
86102
87103 const onMomentumScrollEnd = useCallback (
88104 event => {
89105 if ( isOnEdge . current ) {
90106 onReachEdge ?.( pageIndex . current ! ) ;
107+ reloadPagesDebounce ?.( pageIndex . current ) ;
91108 } else if ( isNearEdge . current ) {
109+ reloadPagesDebounce ?.( pageIndex . current ) ;
92110 onReachNearEdge ?.( pageIndex . current ! ) ;
93111 }
94112
95113 scrollViewProps ?. onMomentumScrollEnd ?.( event ) ;
96114 } ,
97- [ scrollViewProps ?. onMomentumScrollEnd , onReachEdge , onReachNearEdge ]
115+ [ scrollViewProps ?. onMomentumScrollEnd , onReachEdge , onReachNearEdge , reloadPagesDebounce ]
98116 ) ;
99117
100118 const onScrollBeginDrag = useCallback ( ( ) => {
@@ -107,7 +125,8 @@ const InfiniteList = (props: InfiniteListProps, ref: any) => {
107125
108126 return (
109127 < RecyclerListView
110- ref = { ref }
128+ // @ts -expect-error
129+ ref = { listRef }
111130 isHorizontal
112131 rowRenderer = { renderItem }
113132 dataProvider = { dataProvider }
0 commit comments