diff options
| author | Maze Winther <mazewinther@gmail.com> | 2026-04-20 11:31:17 +0200 |
|---|---|---|
| committer | Maze Winther <mazewinther@gmail.com> | 2026-04-20 11:31:17 +0200 |
| commit | 3e89d2998588f8e35c524e523ba2ee853f0f6475 (patch) | |
| tree | 57221f96c1259b3b07e3ddf8c1adefc502b9d8eb /apps/web/src/preview/preview-store.ts | |
| parent | 729d10592f4e802f91c555c309ff3ba4b119f843 (diff) | |
| download | opencut-3e89d2998588f8e35c524e523ba2ee853f0f6475.tar.gz | |
refactor: restructure files to their domains, new preview overlay system, and dep graph
Diffstat (limited to 'apps/web/src/preview/preview-store.ts')
| -rw-r--r-- | apps/web/src/preview/preview-store.ts | 104 |
1 files changed, 104 insertions, 0 deletions
diff --git a/apps/web/src/preview/preview-store.ts b/apps/web/src/preview/preview-store.ts new file mode 100644 index 00000000..0cfcbdff --- /dev/null +++ b/apps/web/src/preview/preview-store.ts @@ -0,0 +1,104 @@ +import { create } from "zustand"; +import { persist } from "zustand/middleware"; +import { isGuideId, type GuideId } from "@/guides"; +import { DEFAULT_GRID_CONFIG } from "@/guides/grid"; +import type { GridConfig } from "@/guides/types"; + +type PreviewOverlaysState = Record<string, boolean>; + +interface PersistedPreviewState { + activeGuide?: string | null; + layoutGuide?: { + platform?: string | null; + }; + overlays?: PreviewOverlaysState; + gridConfig?: GridConfig; +} + +interface PreviewState { + activeGuide: GuideId | null; + overlays: PreviewOverlaysState; + gridConfig: GridConfig; + toggleGuide: (guideId: GuideId) => void; + setGridConfig: (config: Partial<GridConfig>) => void; + setOverlayVisibility: ({ + overlayId, + isVisible, + }: { + overlayId: string; + isVisible: boolean; + }) => void; + toggleOverlayVisibility: ({ overlayId }: { overlayId: string }) => void; +} + +const DEFAULT_PREVIEW_OVERLAYS: PreviewOverlaysState = {}; + +function getPersistedActiveGuide( + state: PersistedPreviewState | undefined, +): GuideId | null { + const persistedGuide = + state?.activeGuide ?? state?.layoutGuide?.platform ?? null; + + if (typeof persistedGuide !== "string") { + return null; + } + + return isGuideId(persistedGuide) ? persistedGuide : null; +} + +export const usePreviewStore = create<PreviewState>()( + persist( + (set) => ({ + activeGuide: null, + overlays: DEFAULT_PREVIEW_OVERLAYS, + gridConfig: DEFAULT_GRID_CONFIG, + toggleGuide: (guideId) => { + set((state) => ({ + activeGuide: state.activeGuide === guideId ? null : guideId, + })); + }, + setGridConfig: (config) => { + set((state) => ({ + gridConfig: { ...state.gridConfig, ...config }, + })); + }, + setOverlayVisibility: ({ overlayId, isVisible }) => { + set((state) => ({ + overlays: { + ...state.overlays, + [overlayId]: isVisible, + }, + })); + }, + toggleOverlayVisibility: ({ overlayId }) => { + set((state) => ({ + overlays: { + ...state.overlays, + [overlayId]: !state.overlays[overlayId], + }, + })); + }, + }), + { + name: "preview-settings", + version: 6, + migrate: (persistedState) => { + const state = persistedState as PersistedPreviewState | undefined; + + return { + activeGuide: getPersistedActiveGuide(state), + overlays: DEFAULT_PREVIEW_OVERLAYS, + gridConfig: { + rows: state?.gridConfig?.rows ?? DEFAULT_GRID_CONFIG.rows, + cols: state?.gridConfig?.cols ?? DEFAULT_GRID_CONFIG.cols, + }, + }; + }, + partialize: (state) => ({ + activeGuide: state.activeGuide, + overlays: state.overlays, + gridConfig: state.gridConfig, + }), + }, + ), +); |
