"use client"; import { Button } from "../../ui/button"; import { Scissors, ArrowLeftToLine, ArrowRightToLine, Trash2, Snowflake, Copy, SplitSquareHorizontal, Pause, Play, } from "lucide-react"; import { Tooltip, TooltipContent, TooltipTrigger, TooltipProvider, } from "../../ui/tooltip"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from "../../ui/select"; import { useTimelineStore } from "@/stores/timeline-store"; import { usePlaybackStore } from "@/stores/playback-store"; import { toast } from "sonner"; interface TimelineToolbarProps {} export function TimelineToolbar({}: TimelineToolbarProps) { const { tracks, addTrack, addClipToTrack, removeClipFromTrack, selectedClips, clearSelectedClips, updateClipTrim, } = useTimelineStore(); const { currentTime, duration, isPlaying, toggle, setSpeed, speed } = usePlaybackStore(); const handleSplitSelected = () => { if (selectedClips.length === 0) { toast.error("No clips selected"); return; } selectedClips.forEach(({ trackId, clipId }) => { const track = tracks.find((t) => t.id === trackId); const clip = track?.clips.find((c) => c.id === clipId); if (clip && track) { const splitTime = currentTime; const effectiveStart = clip.startTime; const effectiveEnd = clip.startTime + (clip.duration - clip.trimStart - clip.trimEnd); if (splitTime > effectiveStart && splitTime < effectiveEnd) { updateClipTrim( track.id, clip.id, clip.trimStart, clip.trimEnd + (effectiveEnd - splitTime) ); addClipToTrack(track.id, { mediaId: clip.mediaId, name: clip.name + " (split)", duration: clip.duration, startTime: splitTime, trimStart: clip.trimStart + (splitTime - effectiveStart), trimEnd: clip.trimEnd, }); } } }); toast.success("Split selected clip(s)"); }; const handleDuplicateSelected = () => { if (selectedClips.length === 0) { toast.error("No clips selected"); return; } selectedClips.forEach(({ trackId, clipId }) => { const track = tracks.find((t) => t.id === trackId); const clip = track?.clips.find((c) => c.id === clipId); if (clip && track) { addClipToTrack(track.id, { mediaId: clip.mediaId, name: clip.name + " (copy)", duration: clip.duration, startTime: clip.startTime + (clip.duration - clip.trimStart - clip.trimEnd) + 0.1, trimStart: clip.trimStart, trimEnd: clip.trimEnd, }); } }); toast.success("Duplicated selected clip(s)"); }; const handleFreezeSelected = () => { if (selectedClips.length === 0) { toast.error("No clips selected"); return; } selectedClips.forEach(({ trackId, clipId }) => { const track = tracks.find((t) => t.id === trackId); const clip = track?.clips.find((c) => c.id === clipId); if (clip && track) { // Add a new freeze frame clip at the playhead addClipToTrack(track.id, { mediaId: clip.mediaId, name: clip.name + " (freeze)", duration: 1, // 1 second freeze frame startTime: currentTime, trimStart: 0, trimEnd: clip.duration - 1, }); } }); toast.success("Freeze frame added for selected clip(s)"); }; const handleDeleteSelected = () => { if (selectedClips.length === 0) { toast.error("No clips selected"); return; } selectedClips.forEach(({ trackId, clipId }) => { removeClipFromTrack(trackId, clipId); }); clearSelectedClips(); toast.success("Deleted selected clip(s)"); }; return (
{/* Play/Pause Button */} {isPlaying ? "Pause (Space)" : "Play (Space)"}
{/* Time Display */}
{Math.floor(currentTime * 10) / 10}s /{" "} {Math.floor(duration * 10) / 10}s
{/* Test Clip Button - for debugging */} {tracks.length === 0 && ( Add a test clip to try playback )}
Split clip (S) Split and keep left (A) Split and keep right (D) Separate audio (E) Duplicate clip (Ctrl+D) Freeze frame (F) Delete clip (Delete)
{/* Speed Control */} Playback Speed
); }