Scroll Down Button: Add debounce (#6520)

This commit is contained in:
zubiden 2025-12-08 17:39:29 +01:00 committed by Alexander Zinchuk
parent a0bf570dd6
commit b75d506497

View File

@ -11,6 +11,7 @@ import { MESSAGE_LIST_SENSITIVE_AREA } from '../../../util/browser/windowEnviron
import { debounce } from '../../../util/schedulers';
import { useDebouncedSignal } from '../../../hooks/useAsyncResolvers';
import useDebouncedCallback from '../../../hooks/useDebouncedCallback';
import { useIntersectionObserver, useOnIntersect } from '../../../hooks/useIntersectionObserver';
import useLastCallback from '../../../hooks/useLastCallback';
import { useSignalEffect } from '../../../hooks/useSignalEffect';
@ -19,6 +20,7 @@ import useSyncEffect from '../../../hooks/useSyncEffect';
const FAB_THRESHOLD = 50;
const NOTCH_THRESHOLD = 1; // Notch has zero height so we at least need a 1px margin to intersect
const CONTAINER_HEIGHT_DEBOUNCE = 200;
const SCROLL_TOOLS_DEBOUNCE = 100;
const TOOLS_FREEZE_TIMEOUT = 350; // Approximate message sending animation duration
export default function useScrollHooks({
@ -57,19 +59,26 @@ export default function useScrollHooks({
const forwardsTriggerRef = useRef<HTMLDivElement>();
const fabTriggerRef = useRef<HTMLDivElement>();
const toggleScrollTools = useLastCallback(() => {
const toggleScrollTools = useLastCallback((scrollDown: boolean, notch: boolean) => {
onScrollDownToggle?.(scrollDown);
onNotchToggle?.(notch);
});
const toggleScrollToolsDebounced = useDebouncedCallback(
toggleScrollTools, [toggleScrollTools], SCROLL_TOOLS_DEBOUNCE, true, false,
);
const updateScrollTools = useLastCallback(() => {
if (!isReady) return;
if (!messageIds?.length) {
onScrollDownToggle?.(false);
onNotchToggle?.(false);
toggleScrollTools(false, false);
return;
}
if (!isViewportNewest) {
onScrollDownToggle?.(true);
onNotchToggle?.(true);
toggleScrollToolsDebounced(true, true);
return;
}
@ -86,8 +95,7 @@ export default function useScrollHooks({
if (scrollHeight === 0) return;
onScrollDownToggle?.(isUnread ? !isAtBottom : !isNearBottom);
onNotchToggle?.(!isAtBottom);
toggleScrollToolsDebounced(isUnread ? !isAtBottom : !isNearBottom, !isAtBottom);
});
const {
@ -126,7 +134,7 @@ export default function useScrollHooks({
rootRef: containerRef,
margin: FAB_THRESHOLD * 2,
throttleScheduler: requestMeasure,
}, toggleScrollTools);
}, updateScrollTools);
useOnIntersect(fabTriggerRef, observeIntersectionForFab);
@ -138,13 +146,13 @@ export default function useScrollHooks({
rootRef: containerRef,
margin: NOTCH_THRESHOLD,
throttleScheduler: requestMeasure,
}, toggleScrollTools);
}, updateScrollTools);
useOnIntersect(fabTriggerRef, observeIntersectionForNotch);
useEffect(() => {
if (isReady) {
toggleScrollTools();
updateScrollTools();
}
}, [isReady]);
@ -152,10 +160,10 @@ export default function useScrollHooks({
const container = containerRef.current;
if (!container) return;
container.addEventListener('scrollend', toggleScrollTools);
container.addEventListener('scrollend', updateScrollTools);
return () => {
container.removeEventListener('scrollend', toggleScrollTools);
container.removeEventListener('scrollend', updateScrollTools);
};
}, [containerRef]);