fix: distinguish user initiated scroll (#596)

This commit is contained in:
Carlos Valente
2023-11-17 13:01:28 +01:00
committed by GitHub
parent c59e070076
commit 58239af8bb
2 changed files with 13 additions and 12 deletions
@@ -21,7 +21,7 @@ interface UseFollowComponentProps {
scrollRef: MutableRefObject<HTMLElement | null>; scrollRef: MutableRefObject<HTMLElement | null>;
doFollow: boolean; doFollow: boolean;
topOffset?: number; topOffset?: number;
setScrollFlag?: () => void; setScrollFlag?: (newValue: boolean) => void;
} }
export default function useFollowComponent(props: UseFollowComponentProps) { export default function useFollowComponent(props: UseFollowComponentProps) {
@@ -34,14 +34,15 @@ export default function useFollowComponent(props: UseFollowComponentProps) {
} }
if (followRef.current && scrollRef.current) { if (followRef.current && scrollRef.current) {
setScrollFlag?.(true);
// Use requestAnimationFrame to ensure the component is fully loaded // Use requestAnimationFrame to ensure the component is fully loaded
window.requestAnimationFrame(() => { window.requestAnimationFrame(() => {
setScrollFlag?.();
scrollToComponent( scrollToComponent(
followRef as MutableRefObject<HTMLElement>, followRef as MutableRefObject<HTMLElement>,
scrollRef as MutableRefObject<HTMLElement>, scrollRef as MutableRefObject<HTMLElement>,
topOffset, topOffset,
); );
setScrollFlag?.(false);
}); });
} }
+10 -10
View File
@@ -12,6 +12,7 @@ import { useOperator } from '../../common/hooks/useSocket';
import useProjectData from '../../common/hooks-query/useProjectData'; import useProjectData from '../../common/hooks-query/useProjectData';
import useRundown from '../../common/hooks-query/useRundown'; import useRundown from '../../common/hooks-query/useRundown';
import useUserFields from '../../common/hooks-query/useUserFields'; import useUserFields from '../../common/hooks-query/useUserFields';
import { debounce } from '../../common/utils/debounce';
import { isStringBoolean } from '../../common/utils/viewUtils'; import { isStringBoolean } from '../../common/utils/viewUtils';
import FollowButton from './follow-button/FollowButton'; import FollowButton from './follow-button/FollowButton';
@@ -32,7 +33,6 @@ export default function Operator() {
const featureData = useOperator(); const featureData = useOperator();
const [searchParams] = useSearchParams(); const [searchParams] = useSearchParams();
const isAutomatedScroll = useRef(false);
const [lockAutoScroll, setLockAutoScroll] = useState(false); const [lockAutoScroll, setLockAutoScroll] = useState(false);
const selectedRef = useRef<HTMLDivElement | null>(null); const selectedRef = useRef<HTMLDivElement | null>(null);
const scrollRef = useRef<HTMLDivElement | null>(null); const scrollRef = useRef<HTMLDivElement | null>(null);
@@ -41,7 +41,6 @@ export default function Operator() {
scrollRef: scrollRef, scrollRef: scrollRef,
doFollow: !lockAutoScroll, doFollow: !lockAutoScroll,
topOffset: selectedOffset, topOffset: selectedOffset,
setScrollFlag: () => (isAutomatedScroll.current = true),
}); });
// Set window title // Set window title
@@ -65,13 +64,8 @@ export default function Operator() {
setLockAutoScroll(false); setLockAutoScroll(false);
}; };
const handleScroll = () => { // prevent considering automated scrolls as user scrolls
// prevent considering automated scrolls as user scrolls const handleUserScroll = () => {
if (isAutomatedScroll.current) {
isAutomatedScroll.current = false;
return;
}
if (selectedRef?.current && scrollRef?.current) { if (selectedRef?.current && scrollRef?.current) {
const selectedRect = selectedRef.current.getBoundingClientRect(); const selectedRect = selectedRef.current.getBoundingClientRect();
const scrollerRect = scrollRef.current.getBoundingClientRect(); const scrollerRect = scrollRef.current.getBoundingClientRect();
@@ -82,6 +76,7 @@ export default function Operator() {
} }
} }
}; };
const debouncedHandleScroll = debounce(handleUserScroll, 1000);
const missingData = !data || !userFields || !projectData; const missingData = !data || !userFields || !projectData;
const isLoading = status === 'loading' || userFieldsStatus === 'loading' || projectDataStatus === 'loading'; const isLoading = status === 'loading' || userFieldsStatus === 'loading' || projectDataStatus === 'loading';
@@ -119,7 +114,12 @@ export default function Operator() {
lastId={lastEvent?.id} lastId={lastEvent?.id}
/> />
<div className={style.operatorEvents} onScroll={handleScroll} ref={scrollRef}> <div
className={style.operatorEvents}
onWheel={debouncedHandleScroll}
onTouchMove={debouncedHandleScroll}
ref={scrollRef}
>
{data.map((entry) => { {data.map((entry) => {
if (isOntimeEvent(entry)) { if (isOntimeEvent(entry)) {
const isSelected = featureData.selectedEventId === entry.id; const isSelected = featureData.selectedEventId === entry.id;