mirror of
https://github.com/blakeblackshear/frigate.git
synced 2024-11-21 19:07:46 +01:00
Improve timeline auto scrolling (#13556)
* Improve timeline auto scrolling * touch events
This commit is contained in:
parent
055f0dfc22
commit
fe2fec81ac
@ -1,4 +1,11 @@
|
|||||||
import { ReactNode, useCallback, useEffect, useMemo, useState } from "react";
|
import {
|
||||||
|
ReactNode,
|
||||||
|
useCallback,
|
||||||
|
useEffect,
|
||||||
|
useMemo,
|
||||||
|
useRef,
|
||||||
|
useState,
|
||||||
|
} from "react";
|
||||||
import scrollIntoView from "scroll-into-view-if-needed";
|
import scrollIntoView from "scroll-into-view-if-needed";
|
||||||
import { useTimelineUtils } from "./use-timeline-utils";
|
import { useTimelineUtils } from "./use-timeline-utils";
|
||||||
import { FrigateConfig } from "@/types/frigateConfig";
|
import { FrigateConfig } from "@/types/frigateConfig";
|
||||||
@ -66,6 +73,12 @@ function useDraggableElement({
|
|||||||
timelineRef,
|
timelineRef,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// track user interaction and adjust scrolling behavior
|
||||||
|
|
||||||
|
const [userInteracting, setUserInteracting] = useState(false);
|
||||||
|
const interactionTimeout = useRef<NodeJS.Timeout>();
|
||||||
|
const isProgrammaticScroll = useRef(false);
|
||||||
|
|
||||||
const draggingAtTopEdge = useMemo(() => {
|
const draggingAtTopEdge = useMemo(() => {
|
||||||
if (clientYPosition && timelineRef.current && scrollEdgeSize) {
|
if (clientYPosition && timelineRef.current && scrollEdgeSize) {
|
||||||
const timelineRect = timelineRef.current.getBoundingClientRect();
|
const timelineRect = timelineRef.current.getBoundingClientRect();
|
||||||
@ -179,7 +192,7 @@ function useDraggableElement({
|
|||||||
minute: "2-digit",
|
minute: "2-digit",
|
||||||
...(segmentDuration < 60 && !dense && { second: "2-digit" }),
|
...(segmentDuration < 60 && !dense && { second: "2-digit" }),
|
||||||
});
|
});
|
||||||
if (scrollTimeline) {
|
if (scrollTimeline && !userInteracting) {
|
||||||
scrollIntoView(thumb, {
|
scrollIntoView(thumb, {
|
||||||
block: "center",
|
block: "center",
|
||||||
behavior: "smooth",
|
behavior: "smooth",
|
||||||
@ -202,6 +215,7 @@ function useDraggableElement({
|
|||||||
setDraggableElementPosition,
|
setDraggableElementPosition,
|
||||||
dense,
|
dense,
|
||||||
config,
|
config,
|
||||||
|
userInteracting,
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -510,6 +524,47 @@ function useDraggableElement({
|
|||||||
}
|
}
|
||||||
}, [timelineRef, segmentsRef, segments]);
|
}, [timelineRef, segmentsRef, segments]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const handleUserInteraction = () => {
|
||||||
|
if (!isProgrammaticScroll.current) {
|
||||||
|
setUserInteracting(true);
|
||||||
|
|
||||||
|
if (interactionTimeout.current) {
|
||||||
|
clearTimeout(interactionTimeout.current);
|
||||||
|
}
|
||||||
|
|
||||||
|
interactionTimeout.current = setTimeout(() => {
|
||||||
|
setUserInteracting(false);
|
||||||
|
}, 3000);
|
||||||
|
} else {
|
||||||
|
isProgrammaticScroll.current = false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const timelineElement = timelineRef.current;
|
||||||
|
|
||||||
|
if (timelineElement) {
|
||||||
|
timelineElement.addEventListener("scroll", handleUserInteraction);
|
||||||
|
timelineElement.addEventListener("mousedown", handleUserInteraction);
|
||||||
|
timelineElement.addEventListener("mouseup", handleUserInteraction);
|
||||||
|
timelineElement.addEventListener("touchstart", handleUserInteraction);
|
||||||
|
timelineElement.addEventListener("touchmove", handleUserInteraction);
|
||||||
|
timelineElement.addEventListener("touchend", handleUserInteraction);
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
timelineElement.removeEventListener("scroll", handleUserInteraction);
|
||||||
|
timelineElement.removeEventListener("mousedown", handleUserInteraction);
|
||||||
|
timelineElement.removeEventListener("mouseup", handleUserInteraction);
|
||||||
|
timelineElement.removeEventListener(
|
||||||
|
"touchstart",
|
||||||
|
handleUserInteraction,
|
||||||
|
);
|
||||||
|
timelineElement.removeEventListener("touchmove", handleUserInteraction);
|
||||||
|
timelineElement.removeEventListener("touchend", handleUserInteraction);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}, [timelineRef]);
|
||||||
|
|
||||||
return { handleMouseDown, handleMouseUp, handleMouseMove };
|
return { handleMouseDown, handleMouseUp, handleMouseMove };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -702,7 +702,6 @@ function Timeline({
|
|||||||
setExportEndTime={setExportEndTime}
|
setExportEndTime={setExportEndTime}
|
||||||
handlebarTime={currentTime}
|
handlebarTime={currentTime}
|
||||||
setHandlebarTime={setCurrentTime}
|
setHandlebarTime={setCurrentTime}
|
||||||
onlyInitialHandlebarScroll={true}
|
|
||||||
events={mainCameraReviewItems}
|
events={mainCameraReviewItems}
|
||||||
motion_events={motionData ?? []}
|
motion_events={motionData ?? []}
|
||||||
severityType="significant_motion"
|
severityType="significant_motion"
|
||||||
|
Loading…
Reference in New Issue
Block a user