From 0f503e0560082780ead2dec1f9ee7b70902eba1c Mon Sep 17 00:00:00 2001 From: Yakir Zana <91827012+yakirza17@users.noreply.github.com> Date: Thu, 17 Aug 2023 18:03:29 +0300 Subject: [PATCH] fix(infiniteAgendaList): fixes (#2311) * Fix _onMomentumScrollEnd not called after first scroll, prevent scrollToIndex if same date as current * Fix _onMomentumScrollEnd not called after first scroll, prevent scrollToIndex if same date as current * Fix _onMomentumScrollEnd not called after first scroll, prevent scrollToIndex if same date as current * Revert "Allow passing listStyle to the infiniteAgendaList to allow control the RecyclerListView style (#2286)" This reverts commit c4bd90f7fafe4edcab7ac1ce802aabebc62c2a6e. * Prevent jump on onEndReach --- src/expandableCalendar/agendaList.tsx | 4 +-- src/expandableCalendar/infiniteAgendaList.tsx | 25 ++++++++++++------- src/infinite-list/index.tsx | 9 +++---- 3 files changed, 21 insertions(+), 17 deletions(-) diff --git a/src/expandableCalendar/agendaList.tsx b/src/expandableCalendar/agendaList.tsx index d4b433a97..2d0c59c89 100644 --- a/src/expandableCalendar/agendaList.tsx +++ b/src/expandableCalendar/agendaList.tsx @@ -21,8 +21,7 @@ import { NativeScrollEvent, LayoutChangeEvent, ViewToken, - TextProps, - StyleProp + TextProps } from 'react-native'; import {useDidUpdate} from '../hooks'; @@ -70,7 +69,6 @@ export interface AgendaListProps extends SectionListProps titleHeight?: number; visibleIndicesChangedDebounce?: number; renderFooter?: () => React.ReactElement | null; - style?: StyleProp; }; } diff --git a/src/expandableCalendar/infiniteAgendaList.tsx b/src/expandableCalendar/infiniteAgendaList.tsx index 5b53a2fc9..4431316e8 100644 --- a/src/expandableCalendar/infiniteAgendaList.tsx +++ b/src/expandableCalendar/infiniteAgendaList.tsx @@ -2,7 +2,7 @@ import PropTypes from 'prop-types'; import isUndefined from 'lodash/isUndefined'; import debounce from 'lodash/debounce'; -import InfiniteList, {InfiniteListProps} from '../infinite-list'; +import InfiniteList from '../infinite-list'; import XDate from 'xdate'; @@ -58,12 +58,14 @@ const InfiniteAgendaList = (props: AgendaListProps) => { const didScroll = useRef(false); const sectionScroll = useRef(false); const [data, setData] = useState([] as any[]); + const dataRef = useRef(data); useEffect(() => { const items = sections.reduce((acc: any, cur: any) => { return [...acc, {title: cur.title, isTitle: true}, ...cur.data]; }, []); setData(items); + dataRef.current = items; if (date !== _topSection.current) { setTimeout(() => { @@ -128,29 +130,34 @@ const InfiniteAgendaList = (props: AgendaListProps) => { return sectionTitle; }, []); - const scrollToSection = useCallback(debounce((d) => { - const sectionIndex = scrollToNextEvent ? getNextSectionIndex(d) : getSectionIndex(d); + const scrollToSection = useCallback(debounce((requestedDate) => { + const sectionIndex = scrollToNextEvent ? getNextSectionIndex(requestedDate) : getSectionIndex(requestedDate); if (isUndefined(sectionIndex)) { return; } if (list?.current && sectionIndex !== undefined) { sectionScroll.current = true; // to avoid setDate() in _onVisibleIndicesChanged - _topSection.current = sections[findItemTitleIndex(sectionIndex)]?.title; + if (requestedDate !== _topSection.current) { + _topSection.current = sections[findItemTitleIndex(sectionIndex)]?.title; + list.current?.scrollToIndex(sectionIndex, true); + } - list.current?.scrollToIndex(sectionIndex, true); + setTimeout(() => { + _onMomentumScrollEnd(); // the RecyclerListView doesn't trigger onMomentumScrollEnd when calling scrollToSection + }, 500); } - }, 1000, {leading: false, trailing: true}), [ sections]); + }, 1000, {leading: false, trailing: true}), [sections]); const layoutProvider = useMemo( () => new LayoutProvider( - (index) => data[index]?.isTitle ? 'title': 'page', + (index) => dataRef.current[index]?.isTitle ? 'title': 'page', (type, dim) => { dim.width = constants.screenWidth; dim.height = type === 'title' ? infiniteListProps?.titleHeight ?? 60 : infiniteListProps?.itemHeight ?? 80; } ), - [data] + [] ); const _onScroll = useCallback((rawEvent: any) => { @@ -233,7 +240,7 @@ const InfiniteAgendaList = (props: AgendaListProps) => { ref={list} renderItem={_renderItem} data={data} - style={infiniteListProps?.style as InfiniteListProps['style']} + style={style.current.container} layoutProvider={layoutProvider} onScroll={_onScroll} onVisibleIndicesChanged={_onVisibleIndicesChanged} diff --git a/src/infinite-list/index.tsx b/src/infinite-list/index.tsx index f147c25d2..1d87e72a1 100644 --- a/src/infinite-list/index.tsx +++ b/src/infinite-list/index.tsx @@ -53,7 +53,6 @@ const InfiniteList = (props: InfiniteListProps, ref: any) => { onScroll, onEndReached, renderFooter, - style, } = props; const dataProvider = useMemo(() => { @@ -161,9 +160,9 @@ const InfiniteList = (props: InfiniteListProps, ref: any) => { }; }, [onScrollBeginDrag, onMomentumScrollEnd, scrollViewProps, isHorizontal]); - const _style = useMemo(() => { - return [{height: pageHeight}, style]; - }, [pageHeight, style]); + const style = useMemo(() => { + return {height: pageHeight}; + }, [pageHeight]); return ( { initialRenderIndex={initialPageIndex} renderAheadOffset={5 * pageWidth} onScroll={_onScroll} - style={_style} + style={style} scrollViewProps={scrollViewPropsMemo} onEndReached={onEndReached} onEndReachedThreshold={onEndReachedThreshold}