import { useEditor } from "@/hooks/use-editor"; import { TooltipProvider, Tooltip, TooltipTrigger, TooltipContent, } from "@/components/ui/tooltip"; import { Button } from "@/components/ui/button"; import { SplitSquareHorizontal } from "lucide-react"; import { SplitButton, SplitButtonLeft, SplitButtonRight, SplitButtonSeparator, } from "@/components/ui/split-button"; import { Slider } from "@/components/ui/slider"; import { TIMELINE_CONSTANTS } from "@/constants/timeline-constants"; import { sliderToZoom, zoomToSlider } from "@/lib/timeline/zoom-utils"; import { ScenesView } from "@/components/editor/scenes-view"; import { type TActionWithOptionalArgs, 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, 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 isCurrentlyBookmarked = useEditor((e) => e.scenes.isBookmarked({ time: e.playback.getCurrentTime() }), ); const handleAction = ({ action, event, }: { action: TActionWithOptionalArgs; event: React.MouseEvent; }) => { event.stopPropagation(); invokeAction(action); }; return (
} 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="Separate audio (coming soon)" disabled={true} onClick={({ event: _event }) => {}} /> } tooltip="Duplicate element" onClick={({ event }) => handleAction({ action: "duplicate-selected", event }) } /> } tooltip="Freeze frame (coming soon)" disabled={true} onClick={({ event: _event }) => {}} /> } tooltip="Delete element" onClick={({ event }) => handleAction({ action: "delete-selected", event }) } />
} isActive={isCurrentlyBookmarked} tooltip={isCurrentlyBookmarked ? "Remove bookmark" : "Add bookmark"} onClick={({ event }) => handleAction({ action: "toggle-bookmark", event }) } />
); } function SceneSelector() { const editor = useEditor(); const currentScene = editor.scenes.getActiveScene(); return (
{currentScene?.name || "No Scene"} {}}>
); } function ToolbarRightSection({ zoomLevel, minZoom, onZoomChange, onZoom, }: { zoomLevel: number; minZoom: number; onZoomChange: (zoom: number) => void; onZoom: (options: { direction: "in" | "out" }) => void; }) { const snappingEnabled = useTimelineStore((s) => s.snappingEnabled); const rippleEditingEnabled = useTimelineStore((s) => s.rippleEditingEnabled); const toggleSnapping = useTimelineStore((s) => s.toggleSnapping); const toggleRippleEditing = useTimelineStore((s) => s.toggleRippleEditing); return (
} isActive={snappingEnabled} tooltip="Auto snapping" onClick={() => toggleSnapping()} /> } isActive={rippleEditingEnabled} tooltip="Ripple editing" onClick={() => toggleRippleEditing()} />
onZoomChange(sliderToZoom({ sliderPosition: values[0], minZoom })) } min={0} max={1} step={0.005} />
); } function ToolbarButton({ icon, tooltip, onClick, disabled, isActive, }: { icon: React.ReactNode; tooltip: string; onClick: ({ event }: { event: React.MouseEvent }) => void; disabled?: boolean; isActive?: boolean; }) { return ( {tooltip} ); }