Timeline tweaks (#10816)

* limit handles from overdragging when segments don't fill up timeline

* use separate state for switch

* add key
This commit is contained in:
Josh Hawkins 2024-04-03 20:20:47 -05:00 committed by GitHub
parent 483d64e419
commit 427c6a6afb
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 33 additions and 11 deletions

View File

@ -2,7 +2,7 @@ import { Button } from "../ui/button";
import { Popover, PopoverContent, PopoverTrigger } from "../ui/popover"; import { Popover, PopoverContent, PopoverTrigger } from "../ui/popover";
import useSWR from "swr"; import useSWR from "swr";
import { CameraGroupConfig, FrigateConfig } from "@/types/frigateConfig"; import { CameraGroupConfig, FrigateConfig } from "@/types/frigateConfig";
import { useCallback, useMemo, useState } from "react"; import { useCallback, useEffect, useMemo, useState } from "react";
import { import {
DropdownMenu, DropdownMenu,
DropdownMenuContent, DropdownMenuContent,
@ -631,16 +631,21 @@ function ShowMotionOnlyButton({
motionOnly, motionOnly,
setMotionOnly, setMotionOnly,
}: ShowMotionOnlyButtonProps) { }: ShowMotionOnlyButtonProps) {
const [motionOnlyButton, setMotionOnlyButton] = useState(motionOnly);
useEffect(
() => setMotionOnly(motionOnlyButton),
[motionOnlyButton, setMotionOnly],
);
return ( return (
<> <>
<div className="hidden md:inline-flex items-center justify-center whitespace-nowrap text-sm bg-secondary hover:bg-secondary/80 text-secondary-foreground h-9 rounded-md px-3 mx-1 cursor-pointer"> <div className="hidden md:inline-flex items-center justify-center whitespace-nowrap text-sm bg-secondary hover:bg-secondary/80 text-secondary-foreground h-9 rounded-md px-3 mx-1 cursor-pointer">
<Switch <Switch
className="ml-1" className="ml-1"
id="collapse-motion" id="collapse-motion"
checked={motionOnly} checked={motionOnlyButton}
onCheckedChange={() => { onCheckedChange={setMotionOnlyButton}
setMotionOnly(!motionOnly);
}}
/> />
<Label <Label
className="mx-2 text-secondary-foreground cursor-pointer" className="mx-2 text-secondary-foreground cursor-pointer"

View File

@ -58,6 +58,7 @@ export function ReviewTimeline({
const [isDraggingExportEnd, setIsDraggingExportEnd] = useState(false); const [isDraggingExportEnd, setIsDraggingExportEnd] = useState(false);
const [exportStartPosition, setExportStartPosition] = useState(0); const [exportStartPosition, setExportStartPosition] = useState(0);
const [exportEndPosition, setExportEndPosition] = useState(0); const [exportEndPosition, setExportEndPosition] = useState(0);
const segmentsRef = useRef<HTMLDivElement>(null);
const handlebarRef = useRef<HTMLDivElement>(null); const handlebarRef = useRef<HTMLDivElement>(null);
const handlebarTimeRef = useRef<HTMLDivElement>(null); const handlebarTimeRef = useRef<HTMLDivElement>(null);
const exportStartRef = useRef<HTMLDivElement>(null); const exportStartRef = useRef<HTMLDivElement>(null);
@ -100,6 +101,7 @@ export function ReviewTimeline({
} = useDraggableElement({ } = useDraggableElement({
contentRef, contentRef,
timelineRef, timelineRef,
segmentsRef,
draggableElementRef: handlebarRef, draggableElementRef: handlebarRef,
segmentDuration, segmentDuration,
showDraggableElement: showHandlebar, showDraggableElement: showHandlebar,
@ -123,6 +125,7 @@ export function ReviewTimeline({
} = useDraggableElement({ } = useDraggableElement({
contentRef, contentRef,
timelineRef, timelineRef,
segmentsRef,
draggableElementRef: exportStartRef, draggableElementRef: exportStartRef,
segmentDuration, segmentDuration,
showDraggableElement: showExportHandles, showDraggableElement: showExportHandles,
@ -147,6 +150,7 @@ export function ReviewTimeline({
} = useDraggableElement({ } = useDraggableElement({
contentRef, contentRef,
timelineRef, timelineRef,
segmentsRef,
draggableElementRef: exportEndRef, draggableElementRef: exportEndRef,
segmentDuration, segmentDuration,
showDraggableElement: showExportHandles, showDraggableElement: showExportHandles,
@ -319,7 +323,7 @@ export function ReviewTimeline({
: "cursor-auto" : "cursor-auto"
}`} }`}
> >
<div className="flex flex-col relative"> <div ref={segmentsRef} className="flex flex-col relative">
<div className="absolute top-0 inset-x-0 z-20 w-full h-[30px] bg-gradient-to-b from-secondary to-transparent pointer-events-none"></div> <div className="absolute top-0 inset-x-0 z-20 w-full h-[30px] bg-gradient-to-b from-secondary to-transparent pointer-events-none"></div>
<div className="absolute bottom-0 inset-x-0 z-20 w-full h-[30px] bg-gradient-to-t from-secondary to-transparent pointer-events-none"></div> <div className="absolute bottom-0 inset-x-0 z-20 w-full h-[30px] bg-gradient-to-t from-secondary to-transparent pointer-events-none"></div>
{children} {children}

View File

@ -6,6 +6,7 @@ import { useTimelineUtils } from "./use-timeline-utils";
type DraggableElementProps = { type DraggableElementProps = {
contentRef: React.RefObject<HTMLElement>; contentRef: React.RefObject<HTMLElement>;
timelineRef: React.RefObject<HTMLDivElement>; timelineRef: React.RefObject<HTMLDivElement>;
segmentsRef: React.RefObject<HTMLDivElement>;
draggableElementRef: React.RefObject<HTMLDivElement>; draggableElementRef: React.RefObject<HTMLDivElement>;
segmentDuration: number; segmentDuration: number;
showDraggableElement: boolean; showDraggableElement: boolean;
@ -29,6 +30,7 @@ type DraggableElementProps = {
function useDraggableElement({ function useDraggableElement({
contentRef, contentRef,
timelineRef, timelineRef,
segmentsRef,
draggableElementRef, draggableElementRef,
segmentDuration, segmentDuration,
showDraggableElement, showDraggableElement,
@ -430,12 +432,18 @@ function useDraggableElement({
useEffect(() => { useEffect(() => {
if ( if (
timelineRef.current && timelineRef.current &&
segmentsRef.current &&
draggableElementTime && draggableElementTime &&
timelineCollapsed && timelineCollapsed &&
timelineSegments && timelineSegments &&
segments segments
) { ) {
setFullTimelineHeight(timelineRef.current.scrollHeight); setFullTimelineHeight(
Math.min(
timelineRef.current.scrollHeight,
segmentsRef.current.scrollHeight,
),
);
const alignedSegmentTime = alignStartDateToTimeline(draggableElementTime); const alignedSegmentTime = alignStartDateToTimeline(draggableElementTime);
let segmentElement = timelineRef.current.querySelector( let segmentElement = timelineRef.current.querySelector(
@ -486,11 +494,16 @@ function useDraggableElement({
}, [timelineCollapsed, segments]); }, [timelineCollapsed, segments]);
useEffect(() => { useEffect(() => {
if (timelineRef.current && segments) { if (timelineRef.current && segments && segmentsRef.current) {
setScrollEdgeSize(timelineRef.current.clientHeight * 0.03); setScrollEdgeSize(timelineRef.current.clientHeight * 0.03);
setFullTimelineHeight(timelineRef.current.scrollHeight); setFullTimelineHeight(
Math.min(
timelineRef.current.scrollHeight,
segmentsRef.current.scrollHeight,
),
);
} }
}, [timelineRef, segments]); }, [timelineRef, segmentsRef, segments]);
return { handleMouseDown, handleMouseUp, handleMouseMove }; return { handleMouseDown, handleMouseUp, handleMouseMove };
} }

View File

@ -830,7 +830,7 @@ function MotionReview({
} }
const detectionType = getDetectionType(camera.name); const detectionType = getDetectionType(camera.name);
return ( return (
<div className={`relative ${spans}`}> <div key={camera.name} className={`relative ${spans}`}>
<PreviewPlayer <PreviewPlayer
key={camera.name} key={camera.name}
className={`rounded-2xl ${spans} ${grow}`} className={`rounded-2xl ${spans} ${grow}`}