diff --git a/packages/desktop-client/src/components/ScrollProvider.tsx b/packages/desktop-client/src/components/ScrollProvider.tsx index f9e58e4bf56e8400f59171609ab9f05d216a860a..21bb683b1560c7a8dc603e38592e5ffbf6c006df 100644 --- a/packages/desktop-client/src/components/ScrollProvider.tsx +++ b/packages/desktop-client/src/components/ScrollProvider.tsx @@ -5,13 +5,14 @@ import React, { useState, useContext, useEffect, + useCallback, } from 'react'; import debounce from 'debounce'; type IScrollContext = { scrollY: number | undefined; - isBottomReached: boolean; + hasScrolledToBottom: (tolerance?: number) => boolean; }; const ScrollContext = createContext<IScrollContext | undefined>(undefined); @@ -22,14 +23,20 @@ type ScrollProviderProps = { export function ScrollProvider({ children }: ScrollProviderProps) { const [scrollY, setScrollY] = useState(undefined); - const [isBottomReached, setIsBottomReached] = useState(false); + const [scrollHeight, setScrollHeight] = useState(undefined); + const [clientHeight, setClientHeight] = useState(undefined); + + const hasScrolledToBottom = useCallback( + (tolerance = 1) => scrollHeight - scrollY <= clientHeight + tolerance, + [clientHeight, scrollHeight, scrollY], + ); useEffect(() => { const listenToScroll = debounce(e => { - setScrollY(e.target?.scrollTop || 0); - setIsBottomReached( - e.target?.scrollHeight - e.target?.scrollTop <= e.target?.clientHeight, - ); + const target = e.target; + setScrollY(target?.scrollTop || 0); + setScrollHeight(target?.scrollHeight || 0); + setClientHeight(target?.clientHeight || 0); }, 10); window.addEventListener('scroll', listenToScroll, { @@ -43,7 +50,7 @@ export function ScrollProvider({ children }: ScrollProviderProps) { }, []); return ( - <ScrollContext.Provider value={{ scrollY, isBottomReached }}> + <ScrollContext.Provider value={{ scrollY, hasScrolledToBottom }}> {children} </ScrollContext.Provider> ); diff --git a/packages/desktop-client/src/components/mobile/transactions/ListBox.jsx b/packages/desktop-client/src/components/mobile/transactions/ListBox.jsx index 9c2e0e27484ccd12211f9974df388e148818a1b2..028c1787e3eaa251f43376ec13ad425eb345ab99 100644 --- a/packages/desktop-client/src/components/mobile/transactions/ListBox.jsx +++ b/packages/desktop-client/src/components/mobile/transactions/ListBox.jsx @@ -1,8 +1,11 @@ -import React, { useEffect, useRef } from 'react'; +import React, { useRef } from 'react'; import { useListBox } from '@react-aria/listbox'; import { useListState } from '@react-stately/list'; +import { usePrevious } from '../../../hooks/usePrevious'; +import { useScroll } from '../../ScrollProvider'; + import { ListBoxSection } from './ListBoxSection'; export function ListBox(props) { @@ -11,25 +14,13 @@ export function ListBox(props) { const { listBoxProps, labelProps } = useListBox(props, state, listBoxRef); const { loadMore } = props; - useEffect(() => { - function loadMoreTransactions() { - if ( - Math.abs( - listBoxRef.current.scrollHeight - - listBoxRef.current.clientHeight - - listBoxRef.current.scrollTop, - ) < listBoxRef.current.clientHeight // load more when we're one screen height from the end - ) { - loadMore?.(); - } - } - const currentListBoxRef = listBoxRef.current; - currentListBoxRef?.addEventListener('scroll', loadMoreTransactions); + const { hasScrolledToBottom } = useScroll(); + const scrolledToBottom = hasScrolledToBottom(); + const prevScrolledToBottom = usePrevious(scrolledToBottom); - return () => { - currentListBoxRef?.removeEventListener('scroll', loadMoreTransactions); - }; - }, [loadMore, state.collection]); + if (!prevScrolledToBottom && scrolledToBottom) { + loadMore?.(); + } return ( <> diff --git a/upcoming-release-notes/2504.md b/upcoming-release-notes/2504.md new file mode 100644 index 0000000000000000000000000000000000000000..7c89f25d4e59c07f5a244471ea6bd202175126d3 --- /dev/null +++ b/upcoming-release-notes/2504.md @@ -0,0 +1,6 @@ +--- +category: Bugfix +authors: [joel-jeremy] +--- + +Fix mobile account transactions page not loading more transactions when reaching end of page.