From 68da487f304018b6e8d06459def8fb45514ab7d4 Mon Sep 17 00:00:00 2001 From: Maze Winther Date: Fri, 1 Aug 2025 19:57:26 +0200 Subject: style: complete re-design of whole editor --- apps/web/src/components/editor/timeline/index.tsx | 61 ++++----- .../editor/timeline/timeline-element.tsx | 142 +++++---------------- .../editor/timeline/timeline-playhead.tsx | 6 +- 3 files changed, 62 insertions(+), 147 deletions(-) (limited to 'apps/web/src/components/editor/timeline') diff --git a/apps/web/src/components/editor/timeline/index.tsx b/apps/web/src/components/editor/timeline/index.tsx index 85d6a11e..8f41fbf3 100644 --- a/apps/web/src/components/editor/timeline/index.tsx +++ b/apps/web/src/components/editor/timeline/index.tsx @@ -20,6 +20,9 @@ import { ZoomIn, ZoomOut, Bookmark, + Eye, + MicOff, + Mic, } from "lucide-react"; import { Tooltip, @@ -544,7 +547,7 @@ export function Timeline() { {/* Timeline Header with Ruler */}
{/* Track Labels Header */} -
+
{/* Empty space */} . @@ -652,14 +655,14 @@ export function Timeline() { ); }).filter(Boolean); })()} - + {/* Bookmark markers */} {(() => { const { activeProject } = useProjectStore.getState(); if (!activeProject?.bookmarks?.length) return null; - + return activeProject.bookmarks.map((bookmarkTime, i) => ( -
0 && (
@@ -695,17 +698,24 @@ export function Timeline() { {tracks.map((track) => (
-
+
+ {track.muted ? ( + toggleTrackMute(track.id)} + /> + ) : ( + toggleTrackMute(track.id)} + /> + )} +
- {track.muted && ( - - Muted - - )}
))}
@@ -760,7 +770,7 @@ export function Timeline() {
e.stopPropagation()}> Track settings (soon) - {activeProject?.bookmarks?.length && activeProject.bookmarks.length > 0 && ( - <> - Bookmarks - {activeProject.bookmarks.map((bookmarkTime, i) => ( - { - e.stopPropagation(); - seek(bookmarkTime); - }} - > - - {bookmarkTime.toFixed(1)}s - - ))} - - )} ))} @@ -1000,11 +993,11 @@ function TimelineToolbar({ const handleZoomSliderChange = (values: number[]) => { setZoomLevel(values[0]); }; - + const handleToggleBookmark = async () => { await toggleBookmark(currentTime); }; - + // Check if the current time is bookmarked const currentBookmarked = isBookmarked(currentTime); return ( @@ -1142,7 +1135,9 @@ function TimelineToolbar({ diff --git a/apps/web/src/components/editor/timeline/timeline-element.tsx b/apps/web/src/components/editor/timeline/timeline-element.tsx index c7ed833e..b26a14bb 100644 --- a/apps/web/src/components/editor/timeline/timeline-element.tsx +++ b/apps/web/src/components/editor/timeline/timeline-element.tsx @@ -1,16 +1,8 @@ "use client"; -import { useState } from "react"; -import { Button } from "../../ui/button"; import { - MoreVertical, Scissors, Trash2, - SplitSquareHorizontal, - Music, - ChevronRight, - ChevronLeft, - Type, Copy, RefreshCw, EyeOff, @@ -23,23 +15,13 @@ import { useTimelineStore } from "@/stores/timeline-store"; import { usePlaybackStore } from "@/stores/playback-store"; import AudioWaveform from "../audio-waveform"; import { toast } from "sonner"; -import { TimelineElementProps, TrackType } from "@/types/timeline"; +import { TimelineElementProps } from "@/types/timeline"; import { useTimelineElementResize } from "@/hooks/use-timeline-element-resize"; import { getTrackElementClasses, TIMELINE_CONSTANTS, getTrackHeight, } from "@/constants/timeline-constants"; -import { - DropdownMenu, - DropdownMenuContent, - DropdownMenuItem, - DropdownMenuSeparator, - DropdownMenuTrigger, - DropdownMenuSub, - DropdownMenuSubContent, - DropdownMenuSubTrigger, -} from "../../ui/dropdown-menu"; import { ContextMenu, ContextMenuContent, @@ -64,9 +46,6 @@ export function TimelineElement({ removeElementFromTrackWithRipple, dragState, splitElement, - splitAndKeepLeft, - splitAndKeepRight, - separateAudio, addElementToTrack, replaceElementMedia, rippleEditingEnabled, @@ -74,27 +53,20 @@ export function TimelineElement({ } = useTimelineStore(); const { currentTime } = usePlaybackStore(); - const [elementMenuOpen, setElementMenuOpen] = useState(false); - const mediaItem = element.type === "media" ? mediaItems.find((item) => item.id === element.mediaId) : null; const isAudio = mediaItem?.type === "audio"; - const { - resizing, - isResizing, - handleResizeStart, - handleResizeMove, - handleResizeEnd, - } = useTimelineElementResize({ - element, - track, - zoomLevel, - onUpdateTrim: updateElementTrim, - onUpdateDuration: updateElementDuration, - }); + const { resizing, handleResizeStart, handleResizeMove, handleResizeEnd } = + useTimelineElementResize({ + element, + track, + zoomLevel, + onUpdateTrim: updateElementTrim, + onUpdateDuration: updateElementDuration, + }); const effectiveDuration = element.duration - element.trimStart - element.trimEnd; @@ -193,9 +165,7 @@ export function TimelineElement({ if (element.type === "text") { return (
- - {element.content} - + {element.content}
); } @@ -212,86 +182,36 @@ export function TimelineElement({ const TILE_ASPECT_RATIO = 16 / 9; - if (mediaItem.type === "image") { + if ( + mediaItem.type === "image" || + (mediaItem.type === "video" && mediaItem.thumbnailUrl) + ) { // Calculate tile size based on 16:9 aspect ratio const trackHeight = getTrackHeight(track.type); - const tileHeight = trackHeight - 8; // Account for padding + const tileHeight = trackHeight; const tileWidth = tileHeight * TILE_ASPECT_RATIO; - return ( -
-
- {/* Background with tiled images */} -
- {/* Overlay with vertical borders */} -
-
-
- ); - } - - const VIDEO_TILE_PADDING = 16; - const OVERLAY_SPACE_MULTIPLIER = 1.5; - - if (mediaItem.type === "video" && mediaItem.thumbnailUrl) { - const trackHeight = getTrackHeight(track.type); - const tileHeight = trackHeight - 8; // Match image padding - const tileWidth = tileHeight * TILE_ASPECT_RATIO; + const imageUrl = + mediaItem.type === "image" ? mediaItem.url : mediaItem.thumbnailUrl; + const isImage = mediaItem.type === "image"; return (
-
- {/* Background with tiled thumbnails */} +
- {/* Overlay with vertical borders */} -
@@ -346,7 +266,7 @@ export function TimelineElement({
onElementClick && onElementClick(e, element)} @@ -372,11 +292,11 @@ export function TimelineElement({ {isSelected && ( <>
handleResizeStart(e, element.id, "left")} />
handleResizeStart(e, element.id, "right")} /> @@ -407,8 +327,8 @@ export function TimelineElement({ ? "Unmute" : "Mute" : element.hidden - ? "Show" - : "Hide"}{" "} + ? "Show" + : "Hide"}{" "} {element.type === "text" ? "text" : "clip"} diff --git a/apps/web/src/components/editor/timeline/timeline-playhead.tsx b/apps/web/src/components/editor/timeline/timeline-playhead.tsx index ea70419b..695843a4 100644 --- a/apps/web/src/components/editor/timeline/timeline-playhead.tsx +++ b/apps/web/src/components/editor/timeline/timeline-playhead.tsx @@ -70,7 +70,7 @@ export function TimelinePlayhead({ // Use timeline container height minus a few pixels for breathing room const timelineContainerHeight = timelineRef.current?.offsetHeight || 400; - const totalHeight = timelineContainerHeight - 8; // 8px padding from edges + const totalHeight = timelineContainerHeight - 4; // Get dynamic track labels width, fallback to 0 if no tracks or no ref const trackLabelsWidth = @@ -137,12 +137,12 @@ export function TimelinePlayhead({ > {/* The playhead line spanning full height */}
{/* Playhead dot indicator at the top (in ruler area) */}
); -- cgit v1.3.1