From e89ce3cf8300961d7777d0fdc4fc5ae5dd91eade Mon Sep 17 00:00:00 2001 From: imbingox Date: Thu, 28 May 2026 11:59:56 +0000 Subject: [PATCH] Sync workspace layout mode across windows --- src/components/settings/general-settings.tsx | 16 ++++++++-------- src/contexts/workspace-context.test.tsx | 20 ++++++++++++++++++++ src/contexts/workspace-context.tsx | 14 ++++++++++++++ 3 files changed, 42 insertions(+), 8 deletions(-) diff --git a/src/components/settings/general-settings.tsx b/src/components/settings/general-settings.tsx index 862eda01..81a0be59 100644 --- a/src/components/settings/general-settings.tsx +++ b/src/components/settings/general-settings.tsx @@ -291,25 +291,25 @@ export function GeneralSettings() {
diff --git a/src/contexts/workspace-context.test.tsx b/src/contexts/workspace-context.test.tsx index 7c0a4c4f..c7fd857c 100644 --- a/src/contexts/workspace-context.test.tsx +++ b/src/contexts/workspace-context.test.tsx @@ -39,6 +39,7 @@ const mockedApi = api as unknown as { function WorkspaceProbe() { const { mode, + layoutMode, activePane, fileTabs, activeFileTabId, @@ -53,6 +54,7 @@ function WorkspaceProbe() { return (
{mode} + {layoutMode} {fileTabs.length} {activePane} {String(filesMaximized)} @@ -127,6 +129,24 @@ describe("WorkspaceProvider mode", () => { expect(screen.getByTestId("mode")).toHaveTextContent("conversation") expect(screen.getByTestId("file-tab-count")).toHaveTextContent("0") }) + + it("syncs layoutMode from storage events fired by another window", () => { + renderWorkspace() + + expect(screen.getByTestId("layout-mode")).toHaveTextContent("fusion") + + act(() => { + localStorage.setItem("workspace:layout-mode", "files") + window.dispatchEvent( + new StorageEvent("storage", { + key: "workspace:layout-mode", + newValue: "files", + }) + ) + }) + + expect(screen.getByTestId("layout-mode")).toHaveTextContent("files") + }) }) describe("WorkspaceProvider files-maximized", () => { diff --git a/src/contexts/workspace-context.tsx b/src/contexts/workspace-context.tsx index d49ab439..dde3598f 100644 --- a/src/contexts/workspace-context.tsx +++ b/src/contexts/workspace-context.tsx @@ -278,6 +278,20 @@ export function WorkspaceProvider({ children }: WorkspaceProviderProps) { fileTabsRef.current = fileTabs }, [fileTabs]) + useEffect(() => { + if (typeof window === "undefined") return + + const onStorage = (event: StorageEvent) => { + if (event.key && event.key !== "workspace:layout-mode") return + setLayoutModeState(loadLayoutMode()) + } + + window.addEventListener("storage", onStorage) + return () => { + window.removeEventListener("storage", onStorage) + } + }, []) + const mode: WorkspaceMode = fileTabs.length > 0 ? "fusion" : "conversation" const effectiveFilesMaximized = mode === "fusion" && filesMaximized