import { useEditor } from "@/hooks/use-editor"; import { TooltipProvider, Tooltip, TooltipTrigger, TooltipContent, } from "@/components/ui/tooltip"; import { Button } from "@/components/ui/button"; import { SkipBack, SplitSquareHorizontal } from "lucide-react"; import { SplitButton, SplitButtonLeft, SplitButtonRight, SplitButtonSeparator, } from "@/components/ui/split-button"; import { Slider } from "@/components/ui/slider"; import { formatTimeCode } from "@/lib/time"; import { TIMELINE_CONSTANTS } from "@/constants/timeline-constants"; import { sliderToZoom, zoomToSlider } from "@/lib/timeline/zoom-utils"; import { EditableTimecode } from "@/components/editable-timecode"; import { ScenesView } from "../scenes-view"; import { type TAction, invokeAction } from "@/lib/actions"; import { cn } from "@/utils/ui"; import { useTimelineStore } from "@/stores/timeline-store"; import { ScrollArea } from "@/components/ui/scroll-area"; import { Bookmark02Icon, Delete02Icon, SnowIcon, ScissorIcon, MagnetIcon, Link04Icon, SearchAddIcon, SearchMinusIcon, PauseIcon, PlayIcon, Copy01Icon, AlignLeftIcon, AlignRightIcon, Layers01Icon, } from "@hugeicons/core-free-icons"; import { HugeiconsIcon } from "@hugeicons/react"; export function TimelineToolbar({ zoomLevel, minZoom, setZoomLevel, }: { zoomLevel: number; minZoom: number; setZoomLevel: ({ zoom }: { zoom: number }) => void; }) { const handleZoom = ({ direction }: { direction: "in" | "out" }) => { const newZoomLevel = direction === "in" ? Math.min( TIMELINE_CONSTANTS.ZOOM_MAX, zoomLevel * TIMELINE_CONSTANTS.ZOOM_BUTTON_FACTOR, ) : Math.max(minZoom, zoomLevel / TIMELINE_CONSTANTS.ZOOM_BUTTON_FACTOR); setZoomLevel({ zoom: newZoomLevel }); }; return (
setZoomLevel({ zoom })} onZoom={handleZoom} />
); } function ToolbarLeftSection() { const editor = useEditor(); const currentTime = editor.playback.getCurrentTime(); const isPlaying = editor.playback.getIsPlaying(); const currentBookmarked = editor.scenes.isBookmarked({ time: currentTime }); const handleAction = ({ action, event, }: { action: TAction; event: React.MouseEvent; }) => { event.stopPropagation(); invokeAction(action); }; return (
) : ( ) } tooltip={isPlaying ? "Pause" : "Play"} onClick={({ event }) => handleAction({ action: "toggle-play", event }) } /> } tooltip="Go to start" onClick={({ event }) => handleAction({ action: "goto-start", event })} />
} tooltip="Split element" onClick={({ event }) => handleAction({ action: "split", event })} /> } tooltip="Split left" onClick={({ event }) => handleAction({ action: "split-left", event })} /> } tooltip="Split right" onClick={({ event }) => handleAction({ action: "split-right", event }) } /> } tooltip="Coming soon" /* separate audio */ disabled={true} onClick={({ event: _event }) => {}} /> } tooltip="Duplicate element" onClick={({ event }) => handleAction({ action: "duplicate-selected", event }) } /> } tooltip="Coming soon" /* freeze frame */ disabled={true} onClick={({ event: _event }) => {}} /> } tooltip="Delete element" onClick={({ event }) => handleAction({ action: "delete-selected", event }) } />
} tooltip={currentBookmarked ? "Remove bookmark" : "Add bookmark"} onClick={({ event }) => handleAction({ action: "toggle-bookmark", event }) } />
); } function TimeDisplay() { const editor = useEditor(); const currentTime = editor.playback.getCurrentTime(); const totalDuration = editor.timeline.getTotalDuration(); const fps = editor.project.getActive().settings.fps; return (
editor.playback.seek({ time })} className="text-center" />
/
{formatTimeCode({ timeInSeconds: totalDuration, format: "HH:MM:SS:FF", fps, })}
); } function SceneSelector() { const editor = useEditor(); const currentScene = editor.scenes.getActiveScene(); return (
{currentScene?.name || "No Scene"} {}} type="button">
); } function ToolbarRightSection({ zoomLevel, minZoom, onZoomChange, onZoom, }: { zoomLevel: number; minZoom: number; onZoomChange: (zoom: number) => void; onZoom: (options: { direction: "in" | "out" }) => void; }) { const { snappingEnabled, rippleEditingEnabled, toggleSnapping, toggleRippleEditing, } = useTimelineStore(); return (
} tooltip="Auto snapping" onClick={() => toggleSnapping()} /> } tooltip="Ripple editing" onClick={() => toggleRippleEditing()} />
onZoomChange(sliderToZoom({ sliderPosition: values[0], minZoom })) } min={0} max={1} step={0.005} />
); } function ToolbarButton({ icon, tooltip, onClick, disabled, }: { icon: React.ReactNode; tooltip: string; onClick: ({ event }: { event: React.MouseEvent }) => void; disabled?: boolean; }) { return ( {tooltip} ); }