File size: 1,176 Bytes
867b17d |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
import useSWR from 'swr';
import { useRef, useEffect, useCallback } from 'react';
type ScrollFlag = ScrollBehavior | false;
export function useScrollToBottom() {
const containerRef = useRef<HTMLDivElement>(null);
const endRef = useRef<HTMLDivElement>(null);
const { data: isAtBottom = false, mutate: setIsAtBottom } = useSWR(
'messages:is-at-bottom',
null,
{ fallbackData: false },
);
const { data: scrollBehavior = false, mutate: setScrollBehavior } =
useSWR<ScrollFlag>('messages:should-scroll', null, { fallbackData: false });
useEffect(() => {
if (scrollBehavior) {
endRef.current?.scrollIntoView({ behavior: scrollBehavior });
setScrollBehavior(false);
}
}, [setScrollBehavior, scrollBehavior]);
const scrollToBottom = useCallback(
(scrollBehavior: ScrollBehavior = 'smooth') => {
setScrollBehavior(scrollBehavior);
},
[setScrollBehavior],
);
function onViewportEnter() {
setIsAtBottom(true);
}
function onViewportLeave() {
setIsAtBottom(false);
}
return {
containerRef,
endRef,
isAtBottom,
scrollToBottom,
onViewportEnter,
onViewportLeave,
};
}
|