From fca99d6126c31fbb18ed9f1034cee6f940b040e8 Mon Sep 17 00:00:00 2001 From: Maze Winther Date: Tue, 10 Feb 2026 16:28:21 +0100 Subject: refactor --- apps/web/src/components/editor/timeline/index.tsx | 535 ---------------------- 1 file changed, 535 deletions(-) delete mode 100644 apps/web/src/components/editor/timeline/index.tsx (limited to 'apps/web/src/components/editor/timeline/index.tsx') 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 2ff17345..00000000 --- a/apps/web/src/components/editor/timeline/index.tsx +++ /dev/null @@ -1,535 +0,0 @@ -"use client"; - -import { ScrollArea } from "@/components/ui/scroll-area"; -import { - Delete02Icon, - TaskAdd02Icon, - ViewIcon, - ViewOffSlashIcon, - VolumeHighIcon, - VolumeOffIcon, -} from "@hugeicons/core-free-icons"; -import { HugeiconsIcon, type IconSvgElement } from "@hugeicons/react"; -import { - ContextMenu, - ContextMenuContent, - ContextMenuItem, - ContextMenuTrigger, -} from "../../ui/context-menu"; -import { useTimelineZoom } from "@/hooks/timeline/use-timeline-zoom"; -import { useState, useRef, useCallback } from "react"; -import { TimelineTrackContent } from "./timeline-track"; -import { TimelinePlayhead } from "./timeline-playhead"; -import { SelectionBox } from "../selection-box"; -import { useSelectionBox } from "@/hooks/timeline/use-selection-box"; -import { SnapIndicator } from "./snap-indicator"; -import type { SnapPoint } from "@/hooks/timeline/use-timeline-snapping"; -import type { TimelineTrack } from "@/types/timeline"; -import { - TIMELINE_CONSTANTS, - TRACK_ICONS, -} from "@/constants/timeline-constants"; -import { useElementInteraction } from "@/hooks/timeline/element/use-element-interaction"; -import { - getTrackHeight, - getCumulativeHeightBefore, - getTotalTracksHeight, - canTracktHaveAudio, - canTrackBeHidden, - getTimelineZoomMin, - getTimelinePaddingPx, - isMainTrack, -} from "@/lib/timeline"; -import { TimelineToolbar } from "./timeline-toolbar"; -import { useScrollSync } from "@/hooks/timeline/use-scroll-sync"; -import { useElementSelection } from "@/hooks/timeline/element/use-element-selection"; -import { useTimelineSeek } from "@/hooks/timeline/use-timeline-seek"; -import { useTimelineDragDrop } from "@/hooks/timeline/use-timeline-drag-drop"; -import { TimelineRuler } from "./timeline-ruler"; -import { TimelineBookmarksRow } from "./bookmarks"; -import { useTimelineStore } from "@/stores/timeline-store"; -import { useEditor } from "@/hooks/use-editor"; -import { useTimelinePlayhead } from "@/hooks/timeline/use-timeline-playhead"; -import { DragLine } from "./drag-line"; -import { invokeAction } from "@/lib/actions"; - -export function Timeline() { - const tracksContainerHeight = { min: 0, max: 800 }; - const { snappingEnabled } = useTimelineStore(); - const { clearElementSelection, setElementSelection } = useElementSelection(); - const editor = useEditor(); - const timeline = editor.timeline; - const tracks = timeline.getTracks(); - const seek = (time: number) => editor.playback.seek({ time }); - - // refs - const timelineRef = useRef(null); - const timelineHeaderRef = useRef(null); - const rulerRef = useRef(null); - const tracksContainerRef = useRef(null); - const tracksScrollRef = useRef(null); - const trackLabelsRef = useRef(null); - const playheadRef = useRef(null); - const trackLabelsScrollRef = useRef(null); - - // state - const [isResizing, setIsResizing] = useState(false); - const [currentSnapPoint, setCurrentSnapPoint] = useState( - null, - ); - - const handleSnapPointChange = useCallback((snapPoint: SnapPoint | null) => { - setCurrentSnapPoint(snapPoint); - }, []); - const handleResizeStateChange = useCallback( - ({ isResizing: nextIsResizing }: { isResizing: boolean }) => { - setIsResizing(nextIsResizing); - if (!nextIsResizing) { - setCurrentSnapPoint(null); - } - }, - [], - ); - - const timelineDuration = timeline.getTotalDuration() || 0; - const minZoomLevel = getTimelineZoomMin({ - duration: timelineDuration, - containerWidth: tracksContainerRef.current?.clientWidth, - }); - - const savedViewState = editor.project.getTimelineViewState(); - - const { zoomLevel, setZoomLevel, handleWheel, saveScrollPosition } = - useTimelineZoom({ - containerRef: timelineRef, - minZoom: minZoomLevel, - initialZoom: savedViewState?.zoomLevel, - initialScrollLeft: savedViewState?.scrollLeft, - initialPlayheadTime: savedViewState?.playheadTime, - tracksScrollRef, - rulerScrollRef: tracksScrollRef, - }); - - const { - dragState, - dragDropTarget, - handleElementMouseDown, - handleElementClick, - lastMouseXRef, - } = useElementInteraction({ - zoomLevel, - timelineRef, - tracksContainerRef, - tracksScrollRef, - headerRef: timelineHeaderRef, - snappingEnabled, - onSnapPointChange: handleSnapPointChange, - }); - - const { handleRulerMouseDown: handlePlayheadRulerMouseDown } = - useTimelinePlayhead({ - zoomLevel, - rulerRef, - rulerScrollRef: tracksScrollRef, - tracksScrollRef, - playheadRef, - }); - - const { isDragOver, dropTarget, dragProps } = useTimelineDragDrop({ - containerRef: tracksContainerRef, - headerRef: timelineHeaderRef, - zoomLevel, - }); - - const { - selectionBox, - handleMouseDown: handleSelectionMouseDown, - isSelecting, - shouldIgnoreClick, - } = useSelectionBox({ - containerRef: tracksContainerRef, - onSelectionComplete: (elements) => { - setElementSelection({ elements }); - }, - tracksScrollRef, - zoomLevel, - }); - - const containerWidth = tracksContainerRef.current?.clientWidth || 1000; - const contentWidth = - timelineDuration * TIMELINE_CONSTANTS.PIXELS_PER_SECOND * zoomLevel; - const paddingPx = getTimelinePaddingPx({ - containerWidth, - zoomLevel, - minZoom: minZoomLevel, - }); - const dynamicTimelineWidth = Math.max( - contentWidth + paddingPx, - containerWidth, - ); - - const showSnapIndicator = - snappingEnabled && - currentSnapPoint !== null && - (dragState.isDragging || isResizing); - - const { - handleTracksMouseDown, - handleTracksClick, - handleRulerMouseDown, - handleRulerClick, - } = useTimelineSeek({ - playheadRef, - trackLabelsRef, - rulerScrollRef: tracksScrollRef, - tracksScrollRef, - zoomLevel, - duration: timeline.getTotalDuration(), - isSelecting, - clearSelectedElements: clearElementSelection, - seek, - }); - - useScrollSync({ - tracksScrollRef, - trackLabelsScrollRef, - }); - - const timelineHeaderHeight = - timelineHeaderRef.current?.getBoundingClientRect().height ?? 0; - - return ( -
- setZoomLevel(zoom)} - /> - -
- -
-
-
- . -
-
- . -
- {tracks.length > 0 && ( -
- -
- {tracks.map((track) => ( -
-
- {process.env.NODE_ENV === "development" && - isMainTrack(track) && ( -
- )} - {canTracktHaveAudio(track) && ( - - editor.timeline.toggleTrackMute({ - trackId: track.id, - }) - } - /> - )} - {canTrackBeHidden(track) && ( - - editor.timeline.toggleTrackVisibility({ - trackId: track.id, - }) - } - /> - )} - -
-
- ))} -
- -
- )} -
- -
- - - - { - const isDirectTarget = event.target === event.currentTarget; - if (!isDirectTarget) return; - event.stopPropagation(); - handleTracksMouseDown(event); - handleSelectionMouseDown(event); - }} - onClick={(event) => { - const isDirectTarget = event.target === event.currentTarget; - if (!isDirectTarget) return; - event.stopPropagation(); - handleTracksClick(event); - }} - onWheel={(event) => { - if ( - event.shiftKey || - Math.abs(event.deltaX) > Math.abs(event.deltaY) - ) { - return; - } - handleWheel(event); - }} - onScroll={() => { - saveScrollPosition(); - }} - > -
-
- - -
- -
- {tracks.length === 0 ? ( -
- ) : ( - tracks.map((track, index) => ( - - -
- { - handleSelectionMouseDown(event); - handleTracksMouseDown(event); - }} - onTrackClick={handleTracksClick} - shouldIgnoreClick={shouldIgnoreClick} - /> -
-
- - } - onClick={(e) => { - e.stopPropagation(); - invokeAction("paste-copied"); - }} - > - Paste elements - - { - e.stopPropagation(); - timeline.toggleTrackMute({ - trackId: track.id, - }); - }} - > - - - {canTracktHaveAudio(track) && track.muted - ? "Unmute track" - : "Mute track"} - - - { - e.stopPropagation(); - timeline.toggleTrackVisibility({ - trackId: track.id, - }); - }} - > - - - {canTrackBeHidden(track) && track.hidden - ? "Show track" - : "Hide track"} - - - { - e.stopPropagation(); - timeline.removeTrack({ - trackId: track.id, - }); - }} - variant="destructive" - > - - Delete track - - -
- )) - )} -
-
- -
-
-
-
- ); -} - -function TrackIcon({ track }: { track: TimelineTrack }) { - return <>{TRACK_ICONS[track.type]}; -} - -function TrackToggleIcon({ - isOff, - icons, - onClick, -}: { - isOff: boolean; - icons: { - on: IconSvgElement; - off: IconSvgElement; - }; - onClick: () => void; -}) { - return ( - <> - {isOff ? ( - - ) : ( - - )} - - ); -} -- cgit v1.3.1