From 4ab6b4b5840361698422d7612ccec379677410b0 Mon Sep 17 00:00:00 2001 From: matt Date: Thu, 12 Feb 2026 01:39:33 +0000 Subject: [PATCH] feat(03-01): wire overlay into App and add context event listener - Initialize context system on app mount before notification listeners - Render ContextSwitchOverlay as first child in ErrorBoundary - Add context:onChanged listener to sync renderer state on external context switches - Snapshot validation already implemented in contextSlice (validateSnapshot function) --- src/renderer/App.tsx | 9 ++++++++- src/renderer/store/index.ts | 16 ++++++++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/src/renderer/App.tsx b/src/renderer/App.tsx index 82446a5d..b08bade7 100644 --- a/src/renderer/App.tsx +++ b/src/renderer/App.tsx @@ -1,9 +1,10 @@ import React, { useEffect } from 'react'; +import { ContextSwitchOverlay } from './components/common/ContextSwitchOverlay'; import { ErrorBoundary } from './components/common/ErrorBoundary'; import { TabbedLayout } from './components/layout/TabbedLayout'; import { useTheme } from './hooks/useTheme'; -import { initializeNotificationListeners } from './store'; +import { initializeNotificationListeners, useStore } from './store'; export const App = (): React.JSX.Element => { // Initialize theme on app load @@ -18,6 +19,11 @@ export const App = (): React.JSX.Element => { } }, []); + // Initialize context system (before notification listeners) + useEffect(() => { + void useStore.getState().initializeContextSystem(); + }, []); + // Initialize IPC event listeners (notifications, file changes) useEffect(() => { const cleanup = initializeNotificationListeners(); @@ -26,6 +32,7 @@ export const App = (): React.JSX.Element => { return ( + ); diff --git a/src/renderer/store/index.ts b/src/renderer/store/index.ts index 1b4dba73..bfd6238e 100644 --- a/src/renderer/store/index.ts +++ b/src/renderer/store/index.ts @@ -302,6 +302,22 @@ export function initializeNotificationListeners(): () => void { } } + // Listen for context changes from main process (e.g., SSH disconnect) + if (window.electronAPI.context?.onChanged) { + const cleanup = window.electronAPI.context.onChanged((_event: unknown, data: unknown) => { + const { id } = data as { id: string }; + const currentContextId = useStore.getState().activeContextId; + if (id !== currentContextId) { + // Main process switched context externally (e.g., SSH disconnect) + // Trigger renderer-side context switch to sync state + void useStore.getState().switchContext(id); + } + }); + if (typeof cleanup === 'function') { + cleanupFns.push(cleanup); + } + } + // Return cleanup function return () => { for (const timer of pendingSessionRefreshTimers.values()) {