refactor: distinguish automated scrolling

This commit is contained in:
cv
2023-09-01 21:46:17 +02:00
parent 5245da7ce7
commit c9976c7fe8
4 changed files with 28 additions and 2 deletions
@@ -21,10 +21,11 @@ interface UseFollowComponentProps {
scrollRef: MutableRefObject<HTMLElement | null>; scrollRef: MutableRefObject<HTMLElement | null>;
doFollow: boolean; doFollow: boolean;
topOffset?: number; topOffset?: number;
setScrollFlag?: () => void;
} }
export default function useFollowComponent(props: UseFollowComponentProps) { export default function useFollowComponent(props: UseFollowComponentProps) {
const { followRef, scrollRef, doFollow, topOffset = 100 } = props; const { followRef, scrollRef, doFollow, topOffset = 100, setScrollFlag } = props;
// when cursor moves, view should follow // when cursor moves, view should follow
useEffect(() => { useEffect(() => {
@@ -35,6 +36,7 @@ export default function useFollowComponent(props: UseFollowComponentProps) {
if (followRef.current && scrollRef.current) { if (followRef.current && scrollRef.current) {
// 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>,
@@ -31,6 +31,7 @@ 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);
@@ -39,6 +40,7 @@ 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
@@ -63,12 +65,21 @@ export default function Operator() {
}; };
const handleScroll = () => { const handleScroll = () => {
// prevent considering automated scrolls as user scrolls
console.log('handling', isAutomatedScroll);
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();
if (selectedRect && scrollerRect) { if (selectedRect && scrollerRect) {
const distanceFromTop = selectedRect.top - scrollerRect.top; const distanceFromTop = selectedRect.top - scrollerRect.top;
const hasScrolledOutOfThreshold = distanceFromTop < -8 || distanceFromTop > selectedOffset; const hasScrolledOutOfThreshold = distanceFromTop < -8 || distanceFromTop > selectedOffset;
console.log('distanceFromTop', distanceFromTop, hasScrolledOutOfThreshold);
setLockAutoScroll(hasScrolledOutOfThreshold); setLockAutoScroll(hasScrolledOutOfThreshold);
} }
} }
@@ -27,3 +27,16 @@
transition: bottom 1s; transition: bottom 1s;
bottom: -50px; bottom: -50px;
} }
// tablet
@media (min-width: $min-tablet) {
.followButton {
font-size: 1.5rem;
gap: 1rem;
padding: 0.25rem 1rem;
&:not(.hidden) {
bottom: 12.5rem;
}
}
}
@@ -50,7 +50,7 @@
.title { .title {
grid-area: title; grid-area: title;
font-size: 1rem; font-size: 1.25rem;
padding-left: 0.25rem; padding-left: 0.25rem;
display: none; display: none;
line-height: 1.25em; line-height: 1.25em;