diff options
| author | Maze Winther <mazewinther@gmail.com> | 2025-07-17 19:46:23 +0200 |
|---|---|---|
| committer | Maze Winther <mazewinther@gmail.com> | 2025-07-17 19:46:23 +0200 |
| commit | 648f0b8529b9f3bafb3bfd9a84a31bc9ac6623ae (patch) | |
| tree | 00a438ce93f12b3b58f705189142a9385d497e4a /apps/web/src/components/editor/timeline/index.tsx | |
| parent | 0b919d4df84ea523ac9e069bdad5c3b34b7c603d (diff) | |
| download | opencut-648f0b8529b9f3bafb3bfd9a84a31bc9ac6623ae.tar.gz | |
stable timeline
Diffstat (limited to 'apps/web/src/components/editor/timeline/index.tsx')
| -rw-r--r-- | apps/web/src/components/editor/timeline/index.tsx | 193 |
1 files changed, 0 insertions, 193 deletions
diff --git a/apps/web/src/components/editor/timeline/index.tsx b/apps/web/src/components/editor/timeline/index.tsx deleted file mode 100644 index 6d90670a..00000000 --- a/apps/web/src/components/editor/timeline/index.tsx +++ /dev/null @@ -1,193 +0,0 @@ -"use client"; - -import { useState, useRef, useEffect, useCallback } from "react"; -import { useTimelineStore } from "@/stores/timeline-store"; -import { usePlaybackStore } from "@/stores/playback-store"; -import { useTimelineZoom } from "@/hooks/use-timeline-zoom"; -import { useSelectionBox } from "@/hooks/use-selection-box"; -import { SnapPoint } from "@/hooks/use-timeline-snapping"; -import { TIMELINE_CONSTANTS } from "@/constants/timeline-constants"; -import { TimelineToolbar } from "./timeline-toolbar"; -import { TimelineContent } from "./timeline-content"; -import { useTimelineDragHandlers } from "./timeline-drag-handlers"; -import { useTimelineActionHandlers } from "./timeline-action-handlers"; -import { useTimelineScrollSync } from "./timeline-scroll-sync"; -import { useTimelineContentClick } from "./timeline-content-click"; -import { useTimelineWheelHandler } from "./timeline-wheel-handler"; - -export function Timeline() { - // Timeline shows all tracks (video, audio, effects) and their elements. - // You can drag media here to add it to your project. - // elements can be trimmed, deleted, and moved. - - const { - tracks, - getTotalDuration, - selectedElements, - clearSelectedElements, - setSelectedElements, - dragState, - snappingEnabled, - } = useTimelineStore(); - const { currentTime, duration, seek, setDuration } = usePlaybackStore(); - const [isDragOver, setIsDragOver] = useState(false); - const [isProcessing, setIsProcessing] = useState(false); - const [progress, setProgress] = useState(0); - const timelineRef = useRef<HTMLDivElement>(null); - const rulerRef = useRef<HTMLDivElement>(null); - const [isInTimeline, setIsInTimeline] = useState(false); - - // Timeline zoom functionality - const { zoomLevel, setZoomLevel, handleWheel } = useTimelineZoom({ - containerRef: timelineRef, - isInTimeline, - }); - - // Dynamic timeline width calculation based on playhead position and duration - const dynamicTimelineWidth = Math.max( - (duration || 0) * TIMELINE_CONSTANTS.PIXELS_PER_SECOND * zoomLevel, // Base width from duration - (currentTime + 30) * TIMELINE_CONSTANTS.PIXELS_PER_SECOND * zoomLevel, // Width to show current time + 30 seconds buffer - timelineRef.current?.clientWidth || 1000 // Minimum width - ); - - // Scroll synchronization and auto-scroll to playhead - const rulerScrollRef = useRef<HTMLDivElement>(null); - const tracksScrollRef = useRef<HTMLDivElement>(null); - const trackLabelsRef = useRef<HTMLDivElement>(null); - const playheadRef = useRef<HTMLDivElement>(null); - const trackLabelsScrollRef = useRef<HTMLDivElement>(null); - - // Selection box functionality - const tracksContainerRef = useRef<HTMLDivElement>(null); - const { - selectionBox, - handleMouseDown: handleSelectionMouseDown, - isSelecting, - justFinishedSelecting, - } = useSelectionBox({ - containerRef: tracksContainerRef, - playheadRef, - onSelectionComplete: (elements) => { - console.log(JSON.stringify({ onSelectionComplete: elements.length })); - setSelectedElements(elements); - }, - }); - - // Calculate snap indicator state - const [currentSnapPoint, setCurrentSnapPoint] = useState<SnapPoint | null>( - null - ); - const showSnapIndicator = - dragState.isDragging && snappingEnabled && currentSnapPoint !== null; - - // Callback to handle snap point changes from TimelineTrackContent - const handleSnapPointChange = useCallback((snapPoint: SnapPoint | null) => { - setCurrentSnapPoint(snapPoint); - }, []); - - // Timeline content click handler - const { handleTimelineContentClick } = useTimelineContentClick({ - duration, - zoomLevel, - seek, - rulerScrollRef, - tracksScrollRef, - clearSelectedElements, - isSelecting, - justFinishedSelecting, - playheadRef, - }); - - // Update timeline duration when tracks change - useEffect(() => { - const totalDuration = getTotalDuration(); - setDuration(Math.max(totalDuration, 10)); // Minimum 10 seconds for empty timeline - }, [tracks, setDuration, getTotalDuration]); - - // Drag handlers - const { dragProps } = useTimelineDragHandlers({ - isDragOver, - setIsDragOver, - isProcessing, - setIsProcessing, - progress, - setProgress, - }); - - // Action handlers - const { - handleSplitSelected, - handleDuplicateSelected, - handleFreezeSelected, - handleSplitAndKeepLeft, - handleSplitAndKeepRight, - handleSeparateAudio, - handleDeleteSelected, - } = useTimelineActionHandlers(); - - // Scroll synchronization - useTimelineScrollSync({ - rulerScrollRef, - tracksScrollRef, - }); - - // Wheel event handling - useTimelineWheelHandler({ - timelineRef, - isInTimeline, - handleWheel, - }); - - return ( - <div - className={`h-full flex flex-col transition-colors duration-200 relative bg-panel rounded-sm overflow-hidden`} - {...dragProps} - onMouseEnter={() => setIsInTimeline(true)} - onMouseLeave={() => setIsInTimeline(false)} - > - {/* Toolbar */} - <TimelineToolbar - handleSplitSelected={handleSplitSelected} - handleSplitAndKeepLeft={handleSplitAndKeepLeft} - handleSplitAndKeepRight={handleSplitAndKeepRight} - handleSeparateAudio={handleSeparateAudio} - handleDuplicateSelected={handleDuplicateSelected} - handleFreezeSelected={handleFreezeSelected} - handleDeleteSelected={handleDeleteSelected} - /> - - {/* Timeline Container */} - <div - ref={timelineRef} - className="relative h-full w-full overflow-auto border" - onMouseEnter={() => setIsInTimeline(true)} - onMouseLeave={() => setIsInTimeline(false)} - onMouseDown={handleSelectionMouseDown} - onClick={handleTimelineContentClick} - > - <TimelineContent - dynamicTimelineWidth={dynamicTimelineWidth} - tracks={tracks} - duration={duration} - zoomLevel={zoomLevel} - currentTime={currentTime} - seek={seek} - rulerRef={rulerRef} - rulerScrollRef={rulerScrollRef} - tracksScrollRef={tracksScrollRef} - playheadRef={playheadRef} - trackLabelsRef={trackLabelsRef} - timelineRef={timelineRef} - handleSelectionMouseDown={handleSelectionMouseDown} - handleTimelineContentClick={handleTimelineContentClick} - handleSnapPointChange={handleSnapPointChange} - clearSelectedElements={clearSelectedElements} - selectionBox={selectionBox} - tracksContainerRef={tracksContainerRef} - currentSnapPoint={currentSnapPoint} - showSnapIndicator={showSnapIndicator} - /> - </div> - </div> - ); -} |
