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)
This commit is contained in:
matt 2026-02-12 01:39:33 +00:00
parent f01d545ee3
commit 4ab6b4b584
2 changed files with 24 additions and 1 deletions

View file

@ -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 (
<ErrorBoundary>
<ContextSwitchOverlay />
<TabbedLayout />
</ErrorBoundary>
);

View file

@ -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()) {