import useDraggableHandler from "@/hooks/use-handle-dragging"; import { useEffect, useCallback, useMemo, useRef, useState, RefObject, } from "react"; import EventSegment from "./EventSegment"; import { useEventUtils } from "@/hooks/use-event-utils"; import { ReviewSegment, ReviewSeverity } from "@/types/review"; import ReviewTimeline from "./ReviewTimeline"; export type EventReviewTimelineProps = { segmentDuration: number; timestampSpread: number; timelineStart: number; timelineEnd: number; showHandlebar?: boolean; handlebarTime?: number; setHandlebarTime?: React.Dispatch>; showMinimap?: boolean; minimapStartTime?: number; minimapEndTime?: number; events: ReviewSegment[]; severityType: ReviewSeverity; contentRef: RefObject; onHandlebarDraggingChange?: (isDragging: boolean) => void; }; export function EventReviewTimeline({ segmentDuration, timestampSpread, timelineStart, timelineEnd, showHandlebar = false, handlebarTime, setHandlebarTime, showMinimap = false, minimapStartTime, minimapEndTime, events, severityType, contentRef, onHandlebarDraggingChange, }: EventReviewTimelineProps) { const [isDragging, setIsDragging] = useState(false); const scrollTimeRef = useRef(null); const timelineRef = useRef(null); const handlebarTimeRef = useRef(null); const timelineDuration = useMemo( () => timelineStart - timelineEnd, [timelineEnd, timelineStart], ); const { alignStartDateToTimeline, alignEndDateToTimeline } = useEventUtils( events, segmentDuration, ); const { handleMouseDown, handleMouseUp, handleMouseMove } = useDraggableHandler({ contentRef, timelineRef, scrollTimeRef, alignStartDateToTimeline, alignEndDateToTimeline, segmentDuration, showHandlebar, handlebarTime, setHandlebarTime, timelineDuration, timelineStart, isDragging, setIsDragging, handlebarTimeRef, }); // Generate segments for the timeline const generateSegments = useCallback(() => { const segmentCount = timelineDuration / segmentDuration; const segmentAlignedTime = alignStartDateToTimeline(timelineStart); return Array.from({ length: segmentCount }, (_, index) => { const segmentTime = segmentAlignedTime - index * segmentDuration; return ( ); }); // we know that these deps are correct // eslint-disable-next-line react-hooks/exhaustive-deps }, [ segmentDuration, timestampSpread, timelineStart, timelineDuration, showMinimap, minimapStartTime, minimapEndTime, events, ]); const segments = useMemo( () => generateSegments(), // we know that these deps are correct // eslint-disable-next-line react-hooks/exhaustive-deps [ segmentDuration, timestampSpread, timelineStart, timelineDuration, showMinimap, minimapStartTime, minimapEndTime, events, ], ); useEffect(() => { if (onHandlebarDraggingChange) { onHandlebarDraggingChange(isDragging); } }, [isDragging, onHandlebarDraggingChange]); return ( {segments} ); } export default EventReviewTimeline;