feat: so much stuff

This commit is contained in:
Maze Winther
2025-06-22 19:28:03 +02:00
parent e22aa6620c
commit 6ee16f9df8
9 changed files with 1229 additions and 83 deletions

View File

@ -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<TimelineClip, "id">) => 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<TimelineStore>((set) => ({
@ -36,6 +48,7 @@ export const useTimelineStore = create<TimelineStore>((set) => ({
set((state) => ({
tracks: [...state.tracks, newTrack],
}));
return newTrack.id;
},
removeTrack: (trackId) => {
@ -58,4 +71,67 @@ export const useTimelineStore = create<TimelineStore>((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 };
}),
}));
},
}));