Implement scroll lock for previews (#10180)

* Implement scroll lock

* Fix seekbar not working
This commit is contained in:
Nicolas Mowen 2024-03-01 17:34:41 -07:00 committed by GitHub
parent ebf34ce378
commit a67e970fca
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 53 additions and 6 deletions

View File

@ -23,6 +23,7 @@ import { useSwipeable } from "react-swipeable";
type PreviewPlayerProps = {
review: ReviewSegment;
allPreviews?: Preview[];
scrollLock?: boolean;
onTimeUpdate?: React.Dispatch<React.SetStateAction<number | undefined>>;
setReviewed: (reviewId: string) => void;
onClick: (reviewId: string, ctrl: boolean) => void;
@ -39,6 +40,7 @@ type Preview = {
export default function PreviewThumbnailPlayer({
review,
allPreviews,
scrollLock = false,
setReviewed,
onClick,
onTimeUpdate,
@ -116,12 +118,16 @@ export default function PreviewThumbnailPlayer({
return undefined;
}
}, [allPreviews]);
}, [allPreviews, review]);
const playingBack = useMemo(() => playback, [playback]);
const onPlayback = useCallback(
(isHovered: boolean) => {
if (isHovered && scrollLock) {
return;
}
if (isHovered) {
setHoverTimeout(
setTimeout(() => {
@ -144,7 +150,7 @@ export default function PreviewThumbnailPlayer({
// we know that these deps are correct
// eslint-disable-next-line react-hooks/exhaustive-deps
[hoverTimeout, review],
[hoverTimeout, scrollLock, review],
);
// date
@ -462,7 +468,7 @@ function VideoPreview({
<source src={relevantPreview.src} type={relevantPreview.type} />
</video>
<Slider
className="absolute inset-x-0 bottom-0"
className="absolute inset-x-0 bottom-0 z-30"
value={[progress]}
onValueChange={onManualSeek}
onValueCommit={onStopManualSeek}
@ -580,7 +586,7 @@ function InProgressPreview({
onLoad={handleLoad}
/>
<Slider
className="absolute inset-x-0 bottom-0"
className="absolute inset-x-0 bottom-0 z-30"
value={[key]}
onValueChange={onManualSeek}
onValueCommit={onStopManualSeek}

View File

@ -0,0 +1,38 @@
import { MutableRefObject, useCallback, useEffect, useState } from "react";
import { isMobile } from "react-device-detect";
export function useScrollLockout(ref: MutableRefObject<HTMLElement | null>) {
const [scrollLock, setScrollLockout] = useState(false);
const onScroll = useCallback(() => {
if (!scrollLock) {
setScrollLockout(true);
}
}, [scrollLock, setScrollLockout]);
const onMouseMove = useCallback(() => {
if (scrollLock) {
setScrollLockout(false);
}
}, [scrollLock, setScrollLockout]);
useEffect(() => {
if (isMobile) {
return;
}
if (!ref.current) {
return;
}
const content = ref.current;
content.addEventListener("scroll", onScroll);
content.addEventListener("mousemove", onMouseMove);
return () => {
content.removeEventListener("scroll", onScroll);
content.removeEventListener("mousemove", onMouseMove);
};
}, [ref, onScroll, onMouseMove]);
return scrollLock;
}

View File

@ -7,6 +7,7 @@ import EventReviewTimeline from "@/components/timeline/EventReviewTimeline";
import ActivityIndicator from "@/components/ui/activity-indicator";
import { ToggleGroup, ToggleGroupItem } from "@/components/ui/toggle-group";
import { useEventUtils } from "@/hooks/use-event-utils";
import { useScrollLockout } from "@/hooks/use-mouse-listener";
import { FrigateConfig } from "@/types/frigateConfig";
import { Preview } from "@/types/preview";
import { ReviewFilter, ReviewSegment, ReviewSeverity } from "@/types/review";
@ -192,6 +193,7 @@ export default function EventView({
// preview playback
const [previewTime, setPreviewTime] = useState<number>();
const scrollLock = useScrollLockout(contentRef);
// review interaction
@ -220,7 +222,7 @@ export default function EventView({
onOpenReview(reviewId);
}
},
[selectedReviews, setSelectedReviews],
[selectedReviews, setSelectedReviews, onOpenReview],
);
const exportReview = useCallback(
@ -236,7 +238,7 @@ export default function EventView({
{ playback: "realtime" },
);
},
[selectedReviews],
[currentItems],
);
if (!config) {
@ -342,6 +344,7 @@ export default function EventView({
review={value}
allPreviews={relevantPreviews}
setReviewed={markItemAsReviewed}
scrollLock={scrollLock}
onTimeUpdate={setPreviewTime}
onClick={onSelectReview}
/>