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}
);
}