From a72a93099a2ea980b5e12965518792c8aa970722 Mon Sep 17 00:00:00 2001 From: Val Alexander Date: Sun, 5 Apr 2026 20:03:09 -0500 Subject: [PATCH] Clamp persisted custom preview viewports - Normalize stored custom viewport dimensions on read - Reuse shared clamping logic when setting preview sizes --- apps/web/src/previewStateStore.ts | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/apps/web/src/previewStateStore.ts b/apps/web/src/previewStateStore.ts index 0b23a617..f7a00b92 100644 --- a/apps/web/src/previewStateStore.ts +++ b/apps/web/src/previewStateStore.ts @@ -67,6 +67,13 @@ function isValidCustomViewport(value: unknown): value is CustomViewport { ); } +function clampCustomViewport(viewport: CustomViewport): CustomViewport { + return { + width: Math.max(320, Math.min(3840, Math.round(viewport.width))), + height: Math.max(320, Math.min(2160, Math.round(viewport.height))), + }; +} + function createEmptyPersistedPreviewUiState(): PersistedPreviewUiState { return { openByProjectId: {}, @@ -153,9 +160,10 @@ function readPersistedPreviewUiState(): PersistedPreviewUiState { customViewportByProjectId: parsed.customViewportByProjectId && typeof parsed.customViewportByProjectId === "object" ? Object.fromEntries( - Object.entries(parsed.customViewportByProjectId).filter( - (entry): entry is [string, CustomViewport] => - typeof entry[0] === "string" && isValidCustomViewport(entry[1]), + Object.entries(parsed.customViewportByProjectId).flatMap(([projectId, viewport]) => + typeof projectId === "string" && isValidCustomViewport(viewport) + ? [[projectId, clampCustomViewport(viewport)] as const] + : [], ), ) : {}, @@ -304,10 +312,7 @@ export const usePreviewStateStore = create((set, get) => ({ }, setCustomViewport: (projectId, viewport) => { - const clamped: CustomViewport = { - width: Math.max(320, Math.min(3840, Math.round(viewport.width))), - height: Math.max(320, Math.min(2160, Math.round(viewport.height))), - }; + const clamped = clampCustomViewport(viewport); set((state) => { const nextCustomViewportByProjectId = { ...state.customViewportByProjectId,