From 2272598d420cf078aaa3928246bfa3a414f6eddb Mon Sep 17 00:00:00 2001 From: Maze Winther Date: Mon, 13 Apr 2026 04:40:56 +0200 Subject: feat: clipboard with keyframe paste Made-with: Cursor --- apps/web/src/stores/timeline-store.ts | 113 +++++++++++++++++----------------- 1 file changed, 57 insertions(+), 56 deletions(-) (limited to 'apps/web/src/stores') diff --git a/apps/web/src/stores/timeline-store.ts b/apps/web/src/stores/timeline-store.ts index c8428355..b7ddb885 100644 --- a/apps/web/src/stores/timeline-store.ts +++ b/apps/web/src/stores/timeline-store.ts @@ -1,56 +1,57 @@ -/** - * UI state for the timeline - * For core logic, use EditorCore instead. - */ - -import { create } from "zustand"; -import { persist } from "zustand/middleware"; -import type { ClipboardItem } from "@/lib/timeline"; - -interface TimelineStore { - snappingEnabled: boolean; - toggleSnapping: () => void; - rippleEditingEnabled: boolean; - toggleRippleEditing: () => void; - clipboard: { - items: ClipboardItem[]; - } | null; - setClipboard: ( - clipboard: { - items: ClipboardItem[]; - } | null, - ) => void; -} - -export const useTimelineStore = create()( - persist( - (set) => ({ - snappingEnabled: true, - - toggleSnapping: () => { - set((state) => ({ snappingEnabled: !state.snappingEnabled })); - }, - - rippleEditingEnabled: false, - - toggleRippleEditing: () => { - set((state) => ({ - rippleEditingEnabled: !state.rippleEditingEnabled, - })); - }, - - clipboard: null, - - setClipboard: (clipboard) => { - set({ clipboard }); - }, - }), - { - name: "timeline-store", - partialize: (state) => ({ - snappingEnabled: state.snappingEnabled, - rippleEditingEnabled: state.rippleEditingEnabled, - }), - }, - ), -); +/** + * UI state for the timeline + * For core logic, use EditorCore instead. + */ + +import { create } from "zustand"; +import { persist } from "zustand/middleware"; + +interface TimelineStore { + snappingEnabled: boolean; + toggleSnapping: () => void; + rippleEditingEnabled: boolean; + toggleRippleEditing: () => void; + expandedElementIds: Set; + toggleElementExpanded: (elementId: string) => void; +} + +export const useTimelineStore = create()( + persist( + (set) => ({ + snappingEnabled: true, + + toggleSnapping: () => { + set((state) => ({ snappingEnabled: !state.snappingEnabled })); + }, + + rippleEditingEnabled: false, + + toggleRippleEditing: () => { + set((state) => ({ + rippleEditingEnabled: !state.rippleEditingEnabled, + })); + }, + + expandedElementIds: new Set(), + + toggleElementExpanded: (elementId) => { + set((state) => { + const next = new Set(state.expandedElementIds); + if (next.has(elementId)) { + next.delete(elementId); + } else { + next.add(elementId); + } + return { expandedElementIds: next }; + }); + }, + }), + { + name: "timeline-store", + partialize: (state) => ({ + snappingEnabled: state.snappingEnabled, + rippleEditingEnabled: state.rippleEditingEnabled, + }), + }, + ), +); -- cgit v1.3.1