import { create } from 'zustand' // Inpainting types export type InpaintingTool = 'brush' | 'eraser' | 'rect' | 'lasso' export interface StoryboardFrame { id: string index: number narration: string imagePrompt: string imagePath?: string audioPath?: string duration: number order: number } export interface Storyboard { id: string title: string frames: StoryboardFrame[] totalDuration: number } interface EditorState { storyboard: Storyboard | null selectedFrameId: string | null isPlaying: boolean currentTime: number // Inpainting state isInpaintingMode: boolean inpaintingTool: InpaintingTool brushSize: number currentMask: string | null inpaintPrompt: string // Actions setStoryboard: (storyboard: Storyboard) => void selectFrame: (frameId: string | null) => void setSelectedFrameId: (frameId: string | null) => void // Alias for selectFrame reorderFrames: (fromIndex: number, toIndex: number) => void updateFrameDuration: (frameId: string, duration: number) => void updateFrame: (frameId: string, updates: Partial) => void setPlaying: (playing: boolean) => void setCurrentTime: (time: number | ((prev: number) => number)) => void // Inpainting actions setInpaintingMode: (mode: boolean) => void setInpaintingTool: (tool: InpaintingTool) => void setBrushSize: (size: number) => void setCurrentMask: (mask: string | null) => void setInpaintPrompt: (prompt: string) => void resetInpainting: () => void } export const useEditorStore = create((set, get) => ({ storyboard: null, selectedFrameId: null, isPlaying: false, currentTime: 0, // Inpainting initial state isInpaintingMode: false, inpaintingTool: 'brush' as InpaintingTool, brushSize: 20, currentMask: null, inpaintPrompt: '', setStoryboard: (storyboard) => set({ storyboard }), selectFrame: (frameId) => set({ selectedFrameId: frameId }), setSelectedFrameId: (frameId) => set({ selectedFrameId: frameId }), reorderFrames: (fromIndex, toIndex) => { const { storyboard } = get() if (!storyboard) return const frames = [...storyboard.frames] const [removed] = frames.splice(fromIndex, 1) frames.splice(toIndex, 0, removed) // Update order values const reorderedFrames = frames.map((frame, idx) => ({ ...frame, order: idx, })) set({ storyboard: { ...storyboard, frames: reorderedFrames, }, }) }, updateFrameDuration: (frameId, duration) => { const { storyboard } = get() if (!storyboard) return const frames = storyboard.frames.map((frame) => frame.id === frameId ? { ...frame, duration } : frame ) const totalDuration = frames.reduce((sum, f) => sum + f.duration, 0) set({ storyboard: { ...storyboard, frames, totalDuration, }, }) }, updateFrame: (frameId, updates) => { const { storyboard } = get() if (!storyboard) return const frames = storyboard.frames.map((frame) => frame.id === frameId ? { ...frame, ...updates } : frame ) const totalDuration = frames.reduce((sum, f) => sum + f.duration, 0) set({ storyboard: { ...storyboard, frames, totalDuration, }, }) }, setPlaying: (playing) => set({ isPlaying: playing }), setCurrentTime: (time) => { if (typeof time === 'function') { const { currentTime } = get() set({ currentTime: time(currentTime) }) } else { set({ currentTime: time }) } }, // Inpainting actions setInpaintingMode: (mode) => set({ isInpaintingMode: mode }), setInpaintingTool: (tool) => set({ inpaintingTool: tool }), setBrushSize: (size) => set({ brushSize: size }), setCurrentMask: (mask) => set({ currentMask: mask }), setInpaintPrompt: (prompt) => set({ inpaintPrompt: prompt }), resetInpainting: () => set({ isInpaintingMode: false, inpaintingTool: 'brush', brushSize: 20, currentMask: null, inpaintPrompt: '', }), }))