refactor(surface): remove the main-area surface concept entirely
activeSurface was permanently 'chat' after the legacy mobile layout
removal, so the whole concept is gone: the store field, surfaceGuard,
setActiveSurface/setSurfaceGuard, the per-runtime surface memory in
prepare/restoreForRuntimeSwitch, and WorkspaceSurface itself. All ~30
setActiveSurface('chat') call sites were no-ops and are deleted;
always-true 'is the chat active' checks in keyboard shortcuts, Header
and ChatContainer are unconditional now. FilesView's dirty-file guard
kept its file-switch and close protection but drops the surface-switch
branch nothing could trigger. TerminalView visibility comes only from
its callers. The router keeps parsing legacy ?tab= links (they open the
matching context-panel surface) via its own RouteTab type and no longer
serializes a tab or diff file into URLs — desktop URLs never carried
them anyway.
This commit is contained in:
@@ -59,7 +59,6 @@ export const useKeyboardShortcuts = () => {
|
||||
}, [currentShortcutDirectory]);
|
||||
const isMobile = useUIStore((s) => s.isMobile);
|
||||
const setSessionSwitcherOpen = useUIStore((s) => s.setSessionSwitcherOpen);
|
||||
const setActiveSurface = useUIStore((s) => s.setActiveSurface);
|
||||
const setSettingsDialogOpen = useUIStore((s) => s.setSettingsDialogOpen);
|
||||
const setModelSelectorOpen = useUIStore((s) => s.setModelSelectorOpen);
|
||||
const setTimelineDialogOpen = useUIStore((s) => s.setTimelineDialogOpen);
|
||||
@@ -154,7 +153,6 @@ export const useKeyboardShortcuts = () => {
|
||||
isAboutDialogOpen,
|
||||
isMultiRunLauncherOpen,
|
||||
isImagePreviewOpen,
|
||||
activeSurface,
|
||||
isPromptNavigatorPanelOpen,
|
||||
} = useUIStore.getState();
|
||||
|
||||
@@ -183,7 +181,7 @@ export const useKeyboardShortcuts = () => {
|
||||
}
|
||||
|
||||
const hasOverlay = isCommandPaletteOpen || isHelpDialogOpen || isSessionSwitcherOpen || isAboutDialogOpen || isMultiRunLauncherOpen || isImagePreviewOpen;
|
||||
const isChatActive = activeSurface === 'chat';
|
||||
const isChatActive = true;
|
||||
|
||||
if (hasOverlay || !isChatActive) {
|
||||
resetAbortPriming();
|
||||
@@ -245,7 +243,6 @@ export const useKeyboardShortcuts = () => {
|
||||
|
||||
if (eventMatchesShortcut(e, combo('toggle_prompt_navigator'))) {
|
||||
const {
|
||||
activeSurface,
|
||||
promptNavigatorEnabled,
|
||||
isSettingsDialogOpen,
|
||||
isCommandPaletteOpen,
|
||||
@@ -257,7 +254,7 @@ export const useKeyboardShortcuts = () => {
|
||||
isImagePreviewOpen,
|
||||
} = useUIStore.getState();
|
||||
|
||||
if (!promptNavigatorEnabled || isMobile || isVSCodeRuntime() || activeSurface !== 'chat') {
|
||||
if (!promptNavigatorEnabled || isMobile || isVSCodeRuntime()) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -308,7 +305,6 @@ export const useKeyboardShortcuts = () => {
|
||||
if (matchedNewSessionShortcut || matchedWorktreeShortcut) {
|
||||
e.preventDefault();
|
||||
|
||||
setActiveSurface('chat');
|
||||
setSessionSwitcherOpen(false);
|
||||
|
||||
if (!isVSCodeRuntime() && matchedWorktreeShortcut) {
|
||||
@@ -394,11 +390,10 @@ export const useKeyboardShortcuts = () => {
|
||||
isHelpDialogOpen,
|
||||
isSessionSwitcherOpen,
|
||||
isAboutDialogOpen,
|
||||
activeSurface,
|
||||
} = useUIStore.getState();
|
||||
|
||||
const hasOverlay = isSettingsDialogOpen || isCommandPaletteOpen || isHelpDialogOpen || isSessionSwitcherOpen || isAboutDialogOpen;
|
||||
if (hasOverlay || activeSurface !== 'chat' || !isChatInputTarget(e.target)) {
|
||||
if (hasOverlay || !isChatInputTarget(e.target)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -525,7 +520,6 @@ export const useKeyboardShortcuts = () => {
|
||||
isHelpDialogOpen,
|
||||
isSessionSwitcherOpen,
|
||||
isAboutDialogOpen,
|
||||
activeSurface,
|
||||
isModelSelectorOpen,
|
||||
} = useUIStore.getState();
|
||||
|
||||
@@ -536,7 +530,7 @@ export const useKeyboardShortcuts = () => {
|
||||
|
||||
// Skip if any overlay open or not on chat tab
|
||||
const hasOverlay = isCommandPaletteOpen || isHelpDialogOpen || isSessionSwitcherOpen || isAboutDialogOpen;
|
||||
const isChatActive = activeSurface === 'chat';
|
||||
const isChatActive = true;
|
||||
|
||||
if (hasOverlay || !isChatActive) {
|
||||
return;
|
||||
@@ -555,7 +549,6 @@ export const useKeyboardShortcuts = () => {
|
||||
isHelpDialogOpen,
|
||||
isSessionSwitcherOpen,
|
||||
isAboutDialogOpen,
|
||||
activeSurface,
|
||||
} = useUIStore.getState();
|
||||
|
||||
if (isSettingsDialogOpen) {
|
||||
@@ -563,7 +556,7 @@ export const useKeyboardShortcuts = () => {
|
||||
}
|
||||
|
||||
const hasOverlay = isCommandPaletteOpen || isHelpDialogOpen || isSessionSwitcherOpen || isAboutDialogOpen;
|
||||
const isChatActive = activeSurface === 'chat';
|
||||
const isChatActive = true;
|
||||
|
||||
if (hasOverlay || !isChatActive) {
|
||||
return;
|
||||
@@ -602,7 +595,6 @@ export const useKeyboardShortcuts = () => {
|
||||
isHelpDialogOpen,
|
||||
isSessionSwitcherOpen,
|
||||
isAboutDialogOpen,
|
||||
activeSurface,
|
||||
favoriteModels,
|
||||
addRecentModel,
|
||||
} = useUIStore.getState();
|
||||
@@ -612,7 +604,7 @@ export const useKeyboardShortcuts = () => {
|
||||
}
|
||||
|
||||
const hasOverlay = isCommandPaletteOpen || isHelpDialogOpen || isSessionSwitcherOpen || isAboutDialogOpen;
|
||||
const isChatActive = activeSurface === 'chat';
|
||||
const isChatActive = true;
|
||||
|
||||
if (hasOverlay || !isChatActive || favoriteModels.length === 0) {
|
||||
return;
|
||||
@@ -644,8 +636,8 @@ export const useKeyboardShortcuts = () => {
|
||||
}
|
||||
|
||||
if (eventMatchesShortcut(e, combo('toggle_dictation'))) {
|
||||
const { activeSurface, isCommandPaletteOpen, isHelpDialogOpen, isSessionSwitcherOpen, isSettingsDialogOpen } = useUIStore.getState();
|
||||
if (activeSurface !== 'chat' || isCommandPaletteOpen || isHelpDialogOpen || isSessionSwitcherOpen || isSettingsDialogOpen) {
|
||||
const { isCommandPaletteOpen, isHelpDialogOpen, isSessionSwitcherOpen, isSettingsDialogOpen } = useUIStore.getState();
|
||||
if (isCommandPaletteOpen || isHelpDialogOpen || isSessionSwitcherOpen || isSettingsDialogOpen) {
|
||||
return;
|
||||
}
|
||||
e.preventDefault();
|
||||
@@ -695,7 +687,6 @@ export const useKeyboardShortcuts = () => {
|
||||
toggleTerminalSurfaceExpanded,
|
||||
isMobile,
|
||||
setSessionSwitcherOpen,
|
||||
setActiveSurface,
|
||||
setSettingsDialogOpen,
|
||||
setModelSelectorOpen,
|
||||
setTimelineDialogOpen,
|
||||
|
||||
@@ -102,7 +102,6 @@ export const useMenuActions = (
|
||||
const toggleHelpDialog = useUIStore((s) => s.toggleHelpDialog);
|
||||
const toggleSidebar = useUIStore((s) => s.toggleSidebar);
|
||||
const setSessionSwitcherOpen = useUIStore((s) => s.setSessionSwitcherOpen);
|
||||
const setActiveSurface = useUIStore((s) => s.setActiveSurface);
|
||||
const setSettingsDialogOpen = useUIStore((s) => s.setSettingsDialogOpen);
|
||||
const setAboutDialogOpen = useUIStore((s) => s.setAboutDialogOpen);
|
||||
const checkForUpdates = useUpdateStore((state) => state.checkForUpdates);
|
||||
@@ -151,10 +150,9 @@ export const useMenuActions = (
|
||||
const nextSession = sessions[nextIndex];
|
||||
if (!nextSession) return;
|
||||
|
||||
setActiveSurface('chat');
|
||||
setSessionSwitcherOpen(false);
|
||||
useSessionUIStore.getState().setCurrentSession(nextSession.id);
|
||||
}, [setActiveSurface, setSessionSwitcherOpen]);
|
||||
}, [setSessionSwitcherOpen]);
|
||||
|
||||
const navigateProject = React.useCallback((direction: -1 | 1) => {
|
||||
const { activeProjectId, projects, setActiveProject } = useProjectsStore.getState();
|
||||
@@ -191,8 +189,7 @@ export const useMenuActions = (
|
||||
break;
|
||||
|
||||
case 'new-session':
|
||||
setActiveSurface('chat');
|
||||
setSessionSwitcherOpen(false);
|
||||
setSessionSwitcherOpen(false);
|
||||
{
|
||||
const sessionState = useSessionUIStore.getState();
|
||||
const directory = useDirectoryStore.getState().currentDirectory;
|
||||
@@ -203,8 +200,7 @@ export const useMenuActions = (
|
||||
break;
|
||||
|
||||
case 'new-worktree-session':
|
||||
setActiveSurface('chat');
|
||||
setSessionSwitcherOpen(false);
|
||||
setSessionSwitcherOpen(false);
|
||||
createWorktreeSession();
|
||||
break;
|
||||
|
||||
@@ -341,7 +337,6 @@ export const useMenuActions = (
|
||||
onToggleMemoryDebug,
|
||||
openNewSessionDraft,
|
||||
setAboutDialogOpen,
|
||||
setActiveSurface,
|
||||
setSessionSwitcherOpen,
|
||||
setCommandPaletteOpen,
|
||||
setSettingsDialogOpen,
|
||||
|
||||
@@ -3,7 +3,6 @@ import { useSessionUIStore } from '@/sync/session-ui-store';
|
||||
import { useUIStore, type ContextPanelMode } from '@/stores/useUIStore';
|
||||
import { parseRoute, updateBrowserURL, hasRouteParams } from '@/lib/router';
|
||||
import type { RouteState, AppRouteState } from '@/lib/router';
|
||||
import type { WorkspaceSurface } from '@/stores/useUIStore';
|
||||
import { resolveSettingsSlug } from '@/lib/settings/metadata';
|
||||
import { isEmbeddedSessionChat } from '@/components/layout/contextPanelEmbeddedChat';
|
||||
import { useDirectoryStore } from '@/stores/useDirectoryStore';
|
||||
@@ -50,7 +49,6 @@ export function useRouter(): void {
|
||||
|
||||
// Get store actions (stable references)
|
||||
const setCurrentSession = useSessionUIStore((state) => state.setCurrentSession);
|
||||
const setActiveSurface = useUIStore((state) => state.setActiveSurface);
|
||||
const setSettingsDialogOpen = useUIStore((state) => state.setSettingsDialogOpen);
|
||||
const setSettingsPage = useUIStore((state) => state.setSettingsPage);
|
||||
const navigateToDiff = useUIStore((state) => state.navigateToDiff);
|
||||
@@ -109,7 +107,7 @@ export function useRouter(): void {
|
||||
isApplyingRouteRef.current = false;
|
||||
}
|
||||
},
|
||||
[setCurrentSession, setActiveSurface, setSettingsDialogOpen, setSettingsPage, navigateToDiff]
|
||||
[setCurrentSession, setSettingsDialogOpen, setSettingsPage, navigateToDiff]
|
||||
);
|
||||
|
||||
/**
|
||||
@@ -121,10 +119,8 @@ export function useRouter(): void {
|
||||
|
||||
return {
|
||||
sessionId: sessionState.currentSessionId,
|
||||
tab: uiState.activeSurface,
|
||||
isSettingsOpen: uiState.isSettingsDialogOpen,
|
||||
settingsPath: uiState.settingsPage,
|
||||
diffFile: uiState.pendingDiffFile,
|
||||
};
|
||||
}, []);
|
||||
|
||||
@@ -170,9 +166,7 @@ export function useRouter(): void {
|
||||
updateBrowserURL({
|
||||
...getCurrentAppState(),
|
||||
sessionId: route.sessionId ?? useSessionUIStore.getState().currentSessionId,
|
||||
tab: route.tab ?? useUIStore.getState().activeSurface,
|
||||
settingsPath: route.settingsPath ?? useUIStore.getState().settingsPage,
|
||||
diffFile: route.diffFile ?? useUIStore.getState().pendingDiffFile,
|
||||
}, { replace: true, force: true });
|
||||
}
|
||||
};
|
||||
@@ -209,10 +203,8 @@ export function useRouter(): void {
|
||||
return;
|
||||
}
|
||||
|
||||
let prevSurface: WorkspaceSurface = useUIStore.getState().activeSurface;
|
||||
let prevSettingsOpen: boolean = useUIStore.getState().isSettingsDialogOpen;
|
||||
let prevSettingsPath: string = useUIStore.getState().settingsPage;
|
||||
let prevDiffFile: string | null = useUIStore.getState().pendingDiffFile;
|
||||
|
||||
const unsubscribe = useUIStore.subscribe((state) => {
|
||||
// Skip if we're currently applying a route
|
||||
@@ -220,19 +212,13 @@ export function useRouter(): void {
|
||||
return;
|
||||
}
|
||||
|
||||
const surfaceChanged = state.activeSurface !== prevSurface;
|
||||
const settingsOpenChanged = state.isSettingsDialogOpen !== prevSettingsOpen;
|
||||
const settingsPathChanged = state.settingsPage !== prevSettingsPath;
|
||||
const diffFileChanged = state.pendingDiffFile !== prevDiffFile && state.activeSurface === 'diff';
|
||||
|
||||
// Update tracking vars
|
||||
prevSurface = state.activeSurface;
|
||||
prevSettingsOpen = state.isSettingsDialogOpen;
|
||||
prevSettingsPath = state.settingsPage;
|
||||
prevDiffFile = state.pendingDiffFile;
|
||||
|
||||
// Only sync if something relevant changed
|
||||
if (surfaceChanged || settingsOpenChanged || settingsPathChanged || diffFileChanged) {
|
||||
if (settingsOpenChanged || settingsPathChanged) {
|
||||
syncURLFromState();
|
||||
}
|
||||
});
|
||||
@@ -260,10 +246,6 @@ export function useRouter(): void {
|
||||
if (uiState.isSettingsDialogOpen) {
|
||||
setSettingsDialogOpen(false);
|
||||
}
|
||||
// Reset to chat when no route view is specified.
|
||||
if (uiState.activeSurface !== 'chat') {
|
||||
setActiveSurface('chat');
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -272,5 +254,5 @@ export function useRouter(): void {
|
||||
return () => {
|
||||
window.removeEventListener('popstate', handlePopState);
|
||||
};
|
||||
}, [applyRoute, isVSCode, isEmbeddedChat, setActiveSurface, setSettingsDialogOpen]);
|
||||
}, [applyRoute, isVSCode, isEmbeddedChat, setSettingsDialogOpen]);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user