From 6ee16f9df8aeabfef0ca533f9f5b13daab3a3758 Mon Sep 17 00:00:00 2001 From: Maze Winther Date: Sun, 22 Jun 2025 19:28:03 +0200 Subject: feat: so much stuff --- apps/web/src/stores/timeline-store.ts | 78 ++++++++++++++++++++++++++++++++++- 1 file changed, 77 insertions(+), 1 deletion(-) (limited to 'apps/web/src/stores/timeline-store.ts') diff --git a/apps/web/src/stores/timeline-store.ts b/apps/web/src/stores/timeline-store.ts index 66fb085c..243ed220 100644 --- a/apps/web/src/stores/timeline-store.ts +++ b/apps/web/src/stores/timeline-store.ts @@ -18,9 +18,21 @@ interface TimelineStore { tracks: TimelineTrack[]; // Actions - addTrack: (type: "video" | "audio" | "effects") => void; + addTrack: (type: "video" | "audio" | "effects") => string; removeTrack: (trackId: string) => void; addClipToTrack: (trackId: string, clip: Omit) => void; + removeClipFromTrack: (trackId: string, clipId: string) => void; + moveClipToTrack: ( + fromTrackId: string, + toTrackId: string, + clipId: string, + insertIndex?: number + ) => void; + reorderClipInTrack: ( + trackId: string, + clipId: string, + newIndex: number + ) => void; } export const useTimelineStore = create((set) => ({ @@ -36,6 +48,7 @@ export const useTimelineStore = create((set) => ({ set((state) => ({ tracks: [...state.tracks, newTrack], })); + return newTrack.id; }, removeTrack: (trackId) => { @@ -58,4 +71,67 @@ export const useTimelineStore = create((set) => ({ ), })); }, + + removeClipFromTrack: (trackId, clipId) => { + set((state) => ({ + tracks: state.tracks.map((track) => + track.id === trackId + ? { + ...track, + clips: track.clips.filter((clip) => clip.id !== clipId), + } + : track + ), + })); + }, + + moveClipToTrack: (fromTrackId, toTrackId, clipId, insertIndex) => { + set((state) => { + // Find the clip to move + const fromTrack = state.tracks.find((track) => track.id === fromTrackId); + const clipToMove = fromTrack?.clips.find((clip) => clip.id === clipId); + + if (!clipToMove) return state; + + return { + tracks: state.tracks.map((track) => { + if (track.id === fromTrackId) { + // Remove clip from source track + return { + ...track, + clips: track.clips.filter((clip) => clip.id !== clipId), + }; + } else if (track.id === toTrackId) { + // Add clip to destination track + const newClips = [...track.clips]; + const index = + insertIndex !== undefined ? insertIndex : newClips.length; + newClips.splice(index, 0, clipToMove); + return { + ...track, + clips: newClips, + }; + } + return track; + }), + }; + }); + }, + + reorderClipInTrack: (trackId, clipId, newIndex) => { + set((state) => ({ + tracks: state.tracks.map((track) => { + if (track.id !== trackId) return track; + + const clipIndex = track.clips.findIndex((clip) => clip.id === clipId); + if (clipIndex === -1) return track; + + const newClips = [...track.clips]; + const [movedClip] = newClips.splice(clipIndex, 1); + newClips.splice(newIndex, 0, movedClip); + + return { ...track, clips: newClips }; + }), + })); + }, })); -- cgit v1.3.1