mirror of
https://github.com/blakeblackshear/frigate.git
synced 2024-11-21 19:07:46 +01:00
Better segment clicking (#10321)
* better segment clicking on motion segments * move handlebar on click when handlebar is showing * only scroll handlebar if needed
This commit is contained in:
parent
507c6afa2c
commit
dfab850b61
@ -97,6 +97,7 @@ export function EventReviewTimeline({
|
|||||||
minimapEndTime={minimapEndTime}
|
minimapEndTime={minimapEndTime}
|
||||||
severityType={severityType}
|
severityType={severityType}
|
||||||
contentRef={contentRef}
|
contentRef={contentRef}
|
||||||
|
setHandlebarTime={setHandlebarTime}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
@ -29,6 +29,7 @@ type EventSegmentProps = {
|
|||||||
minimapEndTime?: number;
|
minimapEndTime?: number;
|
||||||
severityType: ReviewSeverity;
|
severityType: ReviewSeverity;
|
||||||
contentRef: RefObject<HTMLDivElement>;
|
contentRef: RefObject<HTMLDivElement>;
|
||||||
|
setHandlebarTime?: React.Dispatch<React.SetStateAction<number>>;
|
||||||
};
|
};
|
||||||
|
|
||||||
export function EventSegment({
|
export function EventSegment({
|
||||||
@ -41,6 +42,7 @@ export function EventSegment({
|
|||||||
minimapEndTime,
|
minimapEndTime,
|
||||||
severityType,
|
severityType,
|
||||||
contentRef,
|
contentRef,
|
||||||
|
setHandlebarTime,
|
||||||
}: EventSegmentProps) {
|
}: EventSegmentProps) {
|
||||||
const {
|
const {
|
||||||
getSeverity,
|
getSeverity,
|
||||||
@ -192,6 +194,10 @@ export function EventSegment({
|
|||||||
element.classList.add("outline-0", "shadow-none");
|
element.classList.add("outline-0", "shadow-none");
|
||||||
}, 3000);
|
}, 3000);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (setHandlebarTime) {
|
||||||
|
setHandlebarTime(startTimestamp);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// we know that these deps are correct
|
// we know that these deps are correct
|
||||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
|
@ -82,6 +82,19 @@ export function MotionSegment({
|
|||||||
return isMobile ? 30 : 50;
|
return isMobile ? 30 : 50;
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
const segmentWidth = useMemo(() => {
|
||||||
|
return interpolateMotionAudioData(
|
||||||
|
getMotionSegmentValue(segmentTime + segmentDuration / 2),
|
||||||
|
maxSegmentWidth,
|
||||||
|
);
|
||||||
|
}, [
|
||||||
|
segmentTime,
|
||||||
|
segmentDuration,
|
||||||
|
maxSegmentWidth,
|
||||||
|
getMotionSegmentValue,
|
||||||
|
interpolateMotionAudioData,
|
||||||
|
]);
|
||||||
|
|
||||||
const alignedMinimapStartTime = useMemo(
|
const alignedMinimapStartTime = useMemo(
|
||||||
() => alignStartDateToTimeline(minimapStartTime ?? 0),
|
() => alignStartDateToTimeline(minimapStartTime ?? 0),
|
||||||
[minimapStartTime, alignStartDateToTimeline],
|
[minimapStartTime, alignStartDateToTimeline],
|
||||||
@ -154,13 +167,18 @@ export function MotionSegment({
|
|||||||
};
|
};
|
||||||
|
|
||||||
const segmentClick = useCallback(() => {
|
const segmentClick = useCallback(() => {
|
||||||
if (startTimestamp && setHandlebarTime) {
|
if (startTimestamp && setHandlebarTime && segmentWidth > 1) {
|
||||||
setHandlebarTime(startTimestamp);
|
setHandlebarTime(startTimestamp);
|
||||||
}
|
}
|
||||||
}, [startTimestamp, setHandlebarTime]);
|
}, [startTimestamp, setHandlebarTime, segmentWidth]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div key={segmentKey} className={segmentClasses}>
|
<div
|
||||||
|
key={segmentKey}
|
||||||
|
className={segmentClasses}
|
||||||
|
onClick={segmentClick}
|
||||||
|
onTouchStart={(event) => handleTouchStart(event, segmentClick)}
|
||||||
|
>
|
||||||
<MinimapBounds
|
<MinimapBounds
|
||||||
isFirstSegmentInMinimap={isFirstSegmentInMinimap}
|
isFirstSegmentInMinimap={isFirstSegmentInMinimap}
|
||||||
isLastSegmentInMinimap={isLastSegmentInMinimap}
|
isLastSegmentInMinimap={isLastSegmentInMinimap}
|
||||||
@ -185,13 +203,8 @@ export function MotionSegment({
|
|||||||
<div
|
<div
|
||||||
key={`${segmentKey}_motion_data_1`}
|
key={`${segmentKey}_motion_data_1`}
|
||||||
className={`h-[2px] rounded-full bg-motion_review`}
|
className={`h-[2px] rounded-full bg-motion_review`}
|
||||||
onClick={segmentClick}
|
|
||||||
onTouchStart={(event) => handleTouchStart(event, segmentClick)}
|
|
||||||
style={{
|
style={{
|
||||||
width: interpolateMotionAudioData(
|
width: segmentWidth,
|
||||||
getMotionSegmentValue(segmentTime + segmentDuration / 2),
|
|
||||||
maxSegmentWidth,
|
|
||||||
),
|
|
||||||
}}
|
}}
|
||||||
></div>
|
></div>
|
||||||
</div>
|
</div>
|
||||||
@ -202,13 +215,8 @@ export function MotionSegment({
|
|||||||
<div
|
<div
|
||||||
key={`${segmentKey}_motion_data_2`}
|
key={`${segmentKey}_motion_data_2`}
|
||||||
className={`h-[2px] rounded-full bg-motion_review`}
|
className={`h-[2px] rounded-full bg-motion_review`}
|
||||||
onClick={segmentClick}
|
|
||||||
onTouchStart={(event) => handleTouchStart(event, segmentClick)}
|
|
||||||
style={{
|
style={{
|
||||||
width: interpolateMotionAudioData(
|
width: segmentWidth,
|
||||||
getMotionSegmentValue(segmentTime),
|
|
||||||
maxSegmentWidth,
|
|
||||||
),
|
|
||||||
}}
|
}}
|
||||||
></div>
|
></div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -130,6 +130,7 @@ function useDraggableHandler({
|
|||||||
scrollIntoView(thumb, {
|
scrollIntoView(thumb, {
|
||||||
block: "center",
|
block: "center",
|
||||||
behavior: "smooth",
|
behavior: "smooth",
|
||||||
|
scrollMode: "if-needed",
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -43,7 +43,7 @@ export const useMotionSegmentUtils = (
|
|||||||
const matchingEvent = motion_events.find((event) => {
|
const matchingEvent = motion_events.find((event) => {
|
||||||
return (
|
return (
|
||||||
time >= getSegmentStart(event.start_time) &&
|
time >= getSegmentStart(event.start_time) &&
|
||||||
time < getSegmentEnd(event.start_time)
|
time <= getSegmentEnd(event.start_time)
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -124,7 +124,7 @@ function UIPlayground() {
|
|||||||
const [mockEvents, setMockEvents] = useState<ReviewSegment[]>([]);
|
const [mockEvents, setMockEvents] = useState<ReviewSegment[]>([]);
|
||||||
const [mockMotionData, setMockMotionData] = useState<MotionData[]>([]);
|
const [mockMotionData, setMockMotionData] = useState<MotionData[]>([]);
|
||||||
const [handlebarTime, setHandlebarTime] = useState(
|
const [handlebarTime, setHandlebarTime] = useState(
|
||||||
Math.floor(Date.now() / 1000) - 15 * 60,
|
Math.round((Date.now() / 1000 - 15 * 60) / 60) * 60,
|
||||||
);
|
);
|
||||||
|
|
||||||
useMemo(() => {
|
useMemo(() => {
|
||||||
@ -285,7 +285,7 @@ function UIPlayground() {
|
|||||||
<MotionReviewTimeline
|
<MotionReviewTimeline
|
||||||
segmentDuration={zoomSettings.segmentDuration} // seconds per segment
|
segmentDuration={zoomSettings.segmentDuration} // seconds per segment
|
||||||
timestampSpread={zoomSettings.timestampSpread} // minutes between each major timestamp
|
timestampSpread={zoomSettings.timestampSpread} // minutes between each major timestamp
|
||||||
timelineStart={Math.floor(Date.now() / 1000)} // timestamp start of the timeline - the earlier time
|
timelineStart={Math.round(((Date.now() / 1000) * 60) / 60) * 60} // timestamp start of the timeline - the earlier time
|
||||||
timelineEnd={Math.floor(Date.now() / 1000) - 6 * 60 * 60} // end of timeline - the later time
|
timelineEnd={Math.floor(Date.now() / 1000) - 6 * 60 * 60} // end of timeline - the later time
|
||||||
showHandlebar // show / hide the handlebar
|
showHandlebar // show / hide the handlebar
|
||||||
handlebarTime={handlebarTime} // set the time of the handlebar
|
handlebarTime={handlebarTime} // set the time of the handlebar
|
||||||
|
Loading…
Reference in New Issue
Block a user