diff --git a/web/src/components/timeline/EventReviewTimeline.tsx b/web/src/components/timeline/EventReviewTimeline.tsx index f8fb75817..576344be9 100644 --- a/web/src/components/timeline/EventReviewTimeline.tsx +++ b/web/src/components/timeline/EventReviewTimeline.tsx @@ -74,8 +74,11 @@ export function EventReviewTimeline({ [timelineEnd, timelineStart], ); - const { alignStartDateToTimeline, alignEndDateToTimeline } = - useTimelineUtils(segmentDuration); + const { alignStartDateToTimeline, alignEndDateToTimeline } = useTimelineUtils( + segmentDuration, + timelineDuration, + timelineRef || internalTimelineRef, + ); const timelineStartAligned = useMemo( () => alignStartDateToTimeline(timelineStart), diff --git a/web/src/components/timeline/EventSegment.tsx b/web/src/components/timeline/EventSegment.tsx index 4b703a844..8449daf70 100644 --- a/web/src/components/timeline/EventSegment.tsx +++ b/web/src/components/timeline/EventSegment.tsx @@ -53,8 +53,10 @@ export function EventSegment({ getEventThumbnail, } = useEventSegmentUtils(segmentDuration, events, severityType); - const { alignStartDateToTimeline, alignEndDateToTimeline } = - useTimelineUtils(segmentDuration); + const { alignStartDateToTimeline, alignEndDateToTimeline } = useTimelineUtils( + segmentDuration, + 0, + ); const severity = useMemo( () => getSeverity(segmentTime, displaySeverityType), diff --git a/web/src/components/timeline/MotionReviewTimeline.tsx b/web/src/components/timeline/MotionReviewTimeline.tsx index a3115bb0a..c335d17d8 100644 --- a/web/src/components/timeline/MotionReviewTimeline.tsx +++ b/web/src/components/timeline/MotionReviewTimeline.tsx @@ -76,8 +76,10 @@ export function MotionReviewTimeline({ [timelineEnd, timelineStart, segmentDuration], ); - const { alignStartDateToTimeline, alignEndDateToTimeline } = - useTimelineUtils(segmentDuration); + const { alignStartDateToTimeline, alignEndDateToTimeline } = useTimelineUtils( + segmentDuration, + timelineDuration, + ); const timelineStartAligned = useMemo( () => alignStartDateToTimeline(timelineStart) + 2 * segmentDuration, diff --git a/web/src/components/timeline/MotionSegment.tsx b/web/src/components/timeline/MotionSegment.tsx index 88a9a5663..d8d8b2856 100644 --- a/web/src/components/timeline/MotionSegment.tsx +++ b/web/src/components/timeline/MotionSegment.tsx @@ -42,8 +42,10 @@ export function MotionSegment({ const { getMotionSegmentValue, interpolateMotionAudioData } = useMotionSegmentUtils(segmentDuration, motion_events); - const { alignStartDateToTimeline, alignEndDateToTimeline } = - useTimelineUtils(segmentDuration); + const { alignStartDateToTimeline, alignEndDateToTimeline } = useTimelineUtils( + segmentDuration, + 0, + ); const { handleTouchStart } = useTapUtils(); diff --git a/web/src/components/timeline/SummaryTimeline.tsx b/web/src/components/timeline/SummaryTimeline.tsx index 8b89b88a8..41c6c217f 100644 --- a/web/src/components/timeline/SummaryTimeline.tsx +++ b/web/src/components/timeline/SummaryTimeline.tsx @@ -39,18 +39,22 @@ export function SummaryTimeline({ const observer = useRef(null); - const { alignStartDateToTimeline } = useTimelineUtils(segmentDuration); + const reviewTimelineDuration = useMemo( + () => timelineStart - timelineEnd + 4 * segmentDuration, + [timelineEnd, timelineStart, segmentDuration], + ); + + const { alignStartDateToTimeline } = useTimelineUtils( + segmentDuration, + reviewTimelineDuration, + reviewTimelineRef, + ); const timelineStartAligned = useMemo( () => alignStartDateToTimeline(timelineStart) + 2 * segmentDuration, [timelineStart, alignStartDateToTimeline, segmentDuration], ); - const reviewTimelineDuration = useMemo( - () => timelineStart - timelineEnd + 4 * segmentDuration, - [timelineEnd, timelineStart, segmentDuration], - ); - // Generate segments for the timeline const generateSegments = useCallback(() => { const segmentCount = reviewTimelineDuration / segmentDuration; diff --git a/web/src/hooks/use-draggable-element.ts b/web/src/hooks/use-draggable-element.ts index fd20ebf85..fa4d9a187 100644 --- a/web/src/hooks/use-draggable-element.ts +++ b/web/src/hooks/use-draggable-element.ts @@ -40,8 +40,11 @@ function useDraggableElement({ }: DraggableElementProps) { const [clientYPosition, setClientYPosition] = useState(null); const [initialClickAdjustment, setInitialClickAdjustment] = useState(0); - const { alignStartDateToTimeline, getCumulativeScrollTop } = - useTimelineUtils(segmentDuration); + const { alignStartDateToTimeline, getCumulativeScrollTop } = useTimelineUtils( + timelineDuration, + segmentDuration, + timelineRef, + ); const draggingAtTopEdge = useMemo(() => { if (clientYPosition && timelineRef.current) { diff --git a/web/src/hooks/use-timeline-utils.ts b/web/src/hooks/use-timeline-utils.ts index 7b211b528..75d476905 100644 --- a/web/src/hooks/use-timeline-utils.ts +++ b/web/src/hooks/use-timeline-utils.ts @@ -1,6 +1,10 @@ import { useCallback } from "react"; -export const useTimelineUtils = (segmentDuration: number) => { +export const useTimelineUtils = ( + segmentDuration: number, + timelineDuration: number, + timelineRef?: React.RefObject, +) => { const alignEndDateToTimeline = useCallback( (time: number): number => { const remainder = time % segmentDuration; @@ -28,9 +32,27 @@ export const useTimelineUtils = (segmentDuration: number) => { return scrollTop; }, []); + const getVisibleTimelineDuration = useCallback(() => { + if (timelineRef?.current) { + const { + scrollHeight: timelineHeight, + clientHeight: visibleTimelineHeight, + } = timelineRef.current; + + const segmentHeight = + timelineHeight / (timelineDuration / segmentDuration); + + const visibleTime = + (visibleTimelineHeight / segmentHeight) * segmentDuration; + + return visibleTime; + } + }, [segmentDuration, timelineDuration, timelineRef]); + return { alignEndDateToTimeline, alignStartDateToTimeline, getCumulativeScrollTop, + getVisibleTimelineDuration, }; }; diff --git a/web/src/views/events/EventView.tsx b/web/src/views/events/EventView.tsx index d1a372af9..ed2216722 100644 --- a/web/src/views/events/EventView.tsx +++ b/web/src/views/events/EventView.tsx @@ -379,7 +379,16 @@ function DetectionReview({ // timeline interaction - const { alignStartDateToTimeline } = useTimelineUtils(segmentDuration); + const timelineDuration = useMemo( + () => timeRange.before - timeRange.after, + [timeRange], + ); + + const { alignStartDateToTimeline } = useTimelineUtils( + segmentDuration, + timelineDuration, + reviewTimelineRef, + ); const scrollLock = useScrollLockout(contentRef);