From be970248686c0af7d8506cba8c64bf507419da3d Mon Sep 17 00:00:00 2001 From: Maze Winther Date: Sun, 22 Jun 2025 13:07:02 +0200 Subject: so much stuff??? --- apps/web/src/stores/app-store.ts | 35 ++++++++++++++++ apps/web/src/stores/media-store.ts | 35 ++++++++++++++++ apps/web/src/stores/panel-store.ts | 79 +++++++++++++++++++++++++++++++++++ apps/web/src/stores/project-store.ts | 28 +++++++++++++ apps/web/src/stores/timeline-store.ts | 61 +++++++++++++++++++++++++++ 5 files changed, 238 insertions(+) create mode 100644 apps/web/src/stores/app-store.ts create mode 100644 apps/web/src/stores/media-store.ts create mode 100644 apps/web/src/stores/panel-store.ts create mode 100644 apps/web/src/stores/project-store.ts create mode 100644 apps/web/src/stores/timeline-store.ts (limited to 'apps/web/src/stores') diff --git a/apps/web/src/stores/app-store.ts b/apps/web/src/stores/app-store.ts new file mode 100644 index 00000000..746fdc45 --- /dev/null +++ b/apps/web/src/stores/app-store.ts @@ -0,0 +1,35 @@ +import { create } from "zustand"; + +interface AppState { + // Loading states + isInitializing: boolean; + isPanelsReady: boolean; + + // Actions + setInitializing: (loading: boolean) => void; + setPanelsReady: (ready: boolean) => void; + initializeApp: () => Promise; +} + +export const useAppStore = create((set, get) => ({ + // Initial states + isInitializing: true, + isPanelsReady: false, + + // Actions + setInitializing: (loading) => { + set({ isInitializing: loading }); + }, + + setPanelsReady: (ready) => { + set({ isPanelsReady: ready }); + }, + + initializeApp: async () => { + console.log("Initializing video editor..."); + set({ isInitializing: true, isPanelsReady: false }); + + set({ isPanelsReady: true, isInitializing: false }); + console.log("Video editor ready"); + }, +})); diff --git a/apps/web/src/stores/media-store.ts b/apps/web/src/stores/media-store.ts new file mode 100644 index 00000000..25d11af8 --- /dev/null +++ b/apps/web/src/stores/media-store.ts @@ -0,0 +1,35 @@ +import { create } from "zustand"; + +export interface MediaItem { + id: string; + name: string; + type: "image" | "video" | "audio"; +} + +interface MediaStore { + mediaItems: MediaItem[]; + + // Actions + addMediaItem: (item: Omit) => void; + removeMediaItem: (id: string) => void; +} + +export const useMediaStore = create((set, get) => ({ + mediaItems: [], + + addMediaItem: (item) => { + const newItem: MediaItem = { + ...item, + id: crypto.randomUUID(), + }; + set((state) => ({ + mediaItems: [...state.mediaItems, newItem], + })); + }, + + removeMediaItem: (id) => { + set((state) => ({ + mediaItems: state.mediaItems.filter((item) => item.id !== id), + })); + }, +})); diff --git a/apps/web/src/stores/panel-store.ts b/apps/web/src/stores/panel-store.ts new file mode 100644 index 00000000..ea2dacb9 --- /dev/null +++ b/apps/web/src/stores/panel-store.ts @@ -0,0 +1,79 @@ +import { create } from "zustand"; +import { persist } from "zustand/middleware"; + +interface PanelState { + // Horizontal panel sizes + toolsPanel: number; + previewPanel: number; + propertiesPanel: number; + + // Vertical panel sizes + mainContent: number; + timeline: number; + + // Flag to prevent initial overwrites + isInitialized: boolean; + + // Actions + setToolsPanel: (size: number) => void; + setPreviewPanel: (size: number) => void; + setPropertiesPanel: (size: number) => void; + setMainContent: (size: number) => void; + setTimeline: (size: number) => void; + setInitialized: () => void; +} + +export const usePanelStore = create()( + persist( + (set, get) => ({ + // Default sizes + toolsPanel: 20, + previewPanel: 60, + propertiesPanel: 20, + mainContent: 50, + timeline: 50, + isInitialized: false, + + // Actions + setToolsPanel: (size) => { + const state = get(); + if (!state.isInitialized) return; + set({ toolsPanel: size }); + }, + setPreviewPanel: (size) => { + const state = get(); + if (!state.isInitialized) return; + set({ previewPanel: size }); + }, + setPropertiesPanel: (size) => { + const state = get(); + if (!state.isInitialized) return; + set({ propertiesPanel: size }); + }, + setMainContent: (size) => { + const state = get(); + if (!state.isInitialized) return; + set({ mainContent: size }); + }, + setTimeline: (size) => { + const state = get(); + if (!state.isInitialized) return; + set({ timeline: size }); + }, + setInitialized: () => { + console.log("Panel store initialized for resize events"); + set({ isInitialized: true }); + }, + }), + { + name: "panel-sizes", + partialize: (state) => ({ + toolsPanel: state.toolsPanel, + previewPanel: state.previewPanel, + propertiesPanel: state.propertiesPanel, + mainContent: state.mainContent, + timeline: state.timeline, + }), + } + ) +); diff --git a/apps/web/src/stores/project-store.ts b/apps/web/src/stores/project-store.ts new file mode 100644 index 00000000..734c07e2 --- /dev/null +++ b/apps/web/src/stores/project-store.ts @@ -0,0 +1,28 @@ +import { TProject } from "@/types/project"; +import { create } from "zustand"; + +interface ProjectStore { + activeProject: TProject | null; + + // Actions + createNewProject: (name: string) => void; + closeProject: () => void; +} + +export const useProjectStore = create((set) => ({ + activeProject: null, + + createNewProject: (name: string) => { + const newProject: TProject = { + id: crypto.randomUUID(), + name, + createdAt: new Date(), + updatedAt: new Date(), + }; + set({ activeProject: newProject }); + }, + + closeProject: () => { + set({ activeProject: null }); + }, +})); diff --git a/apps/web/src/stores/timeline-store.ts b/apps/web/src/stores/timeline-store.ts new file mode 100644 index 00000000..66fb085c --- /dev/null +++ b/apps/web/src/stores/timeline-store.ts @@ -0,0 +1,61 @@ +import { create } from "zustand"; + +export interface TimelineClip { + id: string; + mediaId: string; + name: string; + duration: number; +} + +export interface TimelineTrack { + id: string; + name: string; + type: "video" | "audio" | "effects"; + clips: TimelineClip[]; +} + +interface TimelineStore { + tracks: TimelineTrack[]; + + // Actions + addTrack: (type: "video" | "audio" | "effects") => void; + removeTrack: (trackId: string) => void; + addClipToTrack: (trackId: string, clip: Omit) => void; +} + +export const useTimelineStore = create((set) => ({ + tracks: [], + + addTrack: (type) => { + const newTrack: TimelineTrack = { + id: crypto.randomUUID(), + name: `${type.charAt(0).toUpperCase() + type.slice(1)} Track`, + type, + clips: [], + }; + set((state) => ({ + tracks: [...state.tracks, newTrack], + })); + }, + + removeTrack: (trackId) => { + set((state) => ({ + tracks: state.tracks.filter((track) => track.id !== trackId), + })); + }, + + addClipToTrack: (trackId, clipData) => { + const newClip: TimelineClip = { + ...clipData, + id: crypto.randomUUID(), + }; + + set((state) => ({ + tracks: state.tracks.map((track) => + track.id === trackId + ? { ...track, clips: [...track.clips, newClip] } + : track + ), + })); + }, +})); -- cgit v1.3.1