refactor(surface): drop the deprecated main-tab aliases and dead diagram surface
MainTab/activeMainTab/setActiveMainTab/setMainTabGuard were deprecated mirrors of the surface names — every call site now uses activeSurface/setActiveSurface/setSurfaceGuard directly and the aliases are gone, including the persisted mirror field. The 'diagram' surface had no way to open it (navigateToDiagram had no callers except a .drawio attachment click that navigated to a surface nothing rendered); the surface, DiagramView, and its store plumbing are removed, and a .drawio attachment now opens in the file panel. ?tab= deep links map to the matching context-panel surface instead of setting a main-area surface nothing renders, and a persisted non-chat surface can no longer rehydrate into a blank main area.
This commit is contained in:
@@ -148,7 +148,7 @@ export const DirectoryExplorerDialog: React.FC<DirectoryExplorerDialogProps> = (
|
||||
const homeDirectory = useDirectoryStore((s) => s.homeDirectory);
|
||||
const projects = useProjectsStore((s) => s.projects);
|
||||
const addProject = useProjectsStore((s) => s.addProject);
|
||||
const setActiveMainTab = useUIStore((s) => s.setActiveMainTab);
|
||||
const setActiveSurface = useUIStore((s) => s.setActiveSurface);
|
||||
const setSessionSwitcherOpen = useUIStore((s) => s.setSessionSwitcherOpen);
|
||||
const openNewSessionDraft = useSessionUIStore((s) => s.openNewSessionDraft);
|
||||
const gitIdentityProfiles = useGitIdentitiesStore((s) => s.profiles);
|
||||
@@ -411,11 +411,11 @@ export const DirectoryExplorerDialog: React.FC<DirectoryExplorerDialogProps> = (
|
||||
}, [onOpenChange]);
|
||||
|
||||
const openProjectDraft = React.useCallback((projectId: string, projectPath: string) => {
|
||||
setActiveMainTab('chat');
|
||||
setActiveSurface('chat');
|
||||
if (isMobile) setSessionSwitcherOpen(false);
|
||||
openNewSessionDraft({ selectedProjectId: projectId, directoryOverride: projectPath });
|
||||
handleClose();
|
||||
}, [handleClose, isMobile, openNewSessionDraft, setActiveMainTab, setSessionSwitcherOpen]);
|
||||
}, [handleClose, isMobile, openNewSessionDraft, setActiveSurface, setSessionSwitcherOpen]);
|
||||
|
||||
const handleQuickAdd = React.useCallback((event: React.MouseEvent, path: string) => {
|
||||
event.stopPropagation();
|
||||
|
||||
@@ -370,7 +370,7 @@ export function ScheduledTasksDialog() {
|
||||
setOpen(false);
|
||||
if (isMobile) {
|
||||
useFilesViewTabsStore.getState().setSelectedPath(selectedProject.path, task.loopFile, { allowOutsideRoot: true });
|
||||
useUIStore.getState().setActiveMainTab('files');
|
||||
useUIStore.getState().setActiveSurface('files');
|
||||
return;
|
||||
}
|
||||
useUIStore.getState().openContextFile(selectedProject.path, task.loopFile);
|
||||
@@ -397,7 +397,7 @@ export function ScheduledTasksDialog() {
|
||||
// this surface (MainLayout closes surfaces on session selection).
|
||||
const project = projects.find((entry) => entry.id === selectedProjectID);
|
||||
useSessionUIStore.getState().setCurrentSession(sessionId, project?.path ?? null);
|
||||
useUIStore.getState().setActiveMainTab('chat');
|
||||
useUIStore.getState().setActiveSurface('chat');
|
||||
}
|
||||
} catch (error) {
|
||||
toast.error(error instanceof Error ? error.message : t('sessions.scheduledTasks.dialog.toast.runFailed'));
|
||||
|
||||
@@ -391,7 +391,7 @@ const SessionSidebarComponent: React.FC<SessionSidebarProps> = ({
|
||||
const updateProjectMeta = useProjectsStore((state) => state.updateProjectMeta);
|
||||
const reorderProjects = useProjectsStore((state) => state.reorderProjects);
|
||||
|
||||
const setActiveMainTab = useUIStore((state) => state.setActiveMainTab);
|
||||
const setActiveSurface = useUIStore((state) => state.setActiveSurface);
|
||||
const openContextPanelTab = useUIStore((state) => state.openContextPanelTab);
|
||||
const setSettingsDialogOpen = useUIStore((state) => state.setSettingsDialogOpen);
|
||||
const toggleHelpDialog = useUIStore((state) => state.toggleHelpDialog);
|
||||
@@ -848,7 +848,7 @@ const SessionSidebarComponent: React.FC<SessionSidebarProps> = ({
|
||||
sessionSearchQuery,
|
||||
setSessionSearchQuery,
|
||||
setIsSessionSearchOpen,
|
||||
setActiveMainTab,
|
||||
setActiveSurface,
|
||||
setSessionSwitcherOpen,
|
||||
setCurrentSession,
|
||||
updateSessionTitle,
|
||||
@@ -1698,7 +1698,7 @@ const SessionSidebarComponent: React.FC<SessionSidebarProps> = ({
|
||||
alwaysShowActions={alwaysShowSidebarActions}
|
||||
activeProjectId={activeProjectId}
|
||||
setActiveProjectIdOnly={setActiveProjectIdOnly}
|
||||
setActiveMainTab={setActiveMainTab}
|
||||
setActiveSurface={setActiveSurface}
|
||||
setSessionSwitcherOpen={setSessionSwitcherOpen}
|
||||
openNewSessionDraft={openNewSessionDraftFromTree}
|
||||
addSessionToFolder={addSessionToFolder}
|
||||
@@ -1741,7 +1741,7 @@ const SessionSidebarComponent: React.FC<SessionSidebarProps> = ({
|
||||
alwaysShowSidebarActions,
|
||||
activeProjectId,
|
||||
setActiveProjectIdOnly,
|
||||
setActiveMainTab,
|
||||
setActiveSurface,
|
||||
setSessionSwitcherOpen,
|
||||
openNewSessionDraftFromTree,
|
||||
addSessionToFolder,
|
||||
@@ -1763,12 +1763,12 @@ const SessionSidebarComponent: React.FC<SessionSidebarProps> = ({
|
||||
|
||||
const handleOpenNewSessionDraftFromHeader = React.useCallback(() => {
|
||||
useUIStore.getState().closeMainSurfaces();
|
||||
setActiveMainTab('chat');
|
||||
setActiveSurface('chat');
|
||||
if (mobileVariant) {
|
||||
setSessionSwitcherOpen(false);
|
||||
}
|
||||
openNewSessionDraft();
|
||||
}, [mobileVariant, openNewSessionDraft, setActiveMainTab, setSessionSwitcherOpen]);
|
||||
}, [mobileVariant, openNewSessionDraft, setActiveSurface, setSessionSwitcherOpen]);
|
||||
|
||||
const renderChatsSection = React.useCallback((items: ActivityItem[]) => {
|
||||
const chatsRoot = getChatsRootForHome(homeDirectory)
|
||||
@@ -1850,12 +1850,12 @@ const SessionSidebarComponent: React.FC<SessionSidebarProps> = ({
|
||||
setBulkDeleteConfirm,
|
||||
});
|
||||
const handleOpenMultiRunFromHeader = React.useCallback(() => {
|
||||
setActiveMainTab('chat');
|
||||
setActiveSurface('chat');
|
||||
if (mobileVariant) {
|
||||
setSessionSwitcherOpen(false);
|
||||
}
|
||||
openMultiRunLauncher();
|
||||
}, [mobileVariant, openMultiRunLauncher, setActiveMainTab, setSessionSwitcherOpen]);
|
||||
}, [mobileVariant, openMultiRunLauncher, setActiveSurface, setSessionSwitcherOpen]);
|
||||
|
||||
return (
|
||||
// One shared tooltip provider for the whole sidebar: session tooltips open
|
||||
@@ -1889,7 +1889,7 @@ const SessionSidebarComponent: React.FC<SessionSidebarProps> = ({
|
||||
handleSessionSelect={stableHandleSessionSelect}
|
||||
mobileVariant={mobileVariant}
|
||||
openNewSessionDraft={openNewSessionDraft}
|
||||
setActiveMainTab={setActiveMainTab}
|
||||
setActiveSurface={setActiveSurface}
|
||||
setSessionSwitcherOpen={setSessionSwitcherOpen}
|
||||
sessionOwnerBySessionId={sessionOwnership.bySessionId}
|
||||
/>
|
||||
@@ -1959,7 +1959,7 @@ const SessionSidebarComponent: React.FC<SessionSidebarProps> = ({
|
||||
alwaysShowActions={alwaysShowSidebarActions}
|
||||
toggleProject={toggleProject}
|
||||
setActiveProjectIdOnly={setActiveProjectIdOnly}
|
||||
setActiveMainTab={setActiveMainTab}
|
||||
setActiveSurface={setActiveSurface}
|
||||
setSessionSwitcherOpen={setSessionSwitcherOpen}
|
||||
openNewSessionDraft={openNewSessionDraftFromTree}
|
||||
openNewWorktreeDialog={openNewWorktreeDialog}
|
||||
@@ -2033,7 +2033,7 @@ const SessionSidebarComponent: React.FC<SessionSidebarProps> = ({
|
||||
open={newWorktreeDialogOpen}
|
||||
onOpenChange={setNewWorktreeDialogOpen}
|
||||
onWorktreeCreated={(worktreePath, options) => {
|
||||
setActiveMainTab('chat');
|
||||
setActiveSurface('chat');
|
||||
if (mobileVariant) {
|
||||
setSessionSwitcherOpen(false);
|
||||
}
|
||||
|
||||
@@ -71,14 +71,14 @@ type SwitcherContentProps = {
|
||||
function SwitcherContent({ onSelect, variant, scopeProjectId }: SwitcherContentProps): React.ReactElement {
|
||||
const items = useSwitcherItems(true, { scopeProjectId });
|
||||
const openNewSessionDraft = useSessionUIStore((state) => state.openNewSessionDraft);
|
||||
const setActiveMainTab = useUIStore((state) => state.setActiveMainTab);
|
||||
const setActiveSurface = useUIStore((state) => state.setActiveSurface);
|
||||
const { t } = useI18n();
|
||||
|
||||
const handleNewSession = React.useCallback(() => {
|
||||
setActiveMainTab('chat');
|
||||
setActiveSurface('chat');
|
||||
onSelect();
|
||||
openNewSessionDraft();
|
||||
}, [onSelect, openNewSessionDraft, setActiveMainTab]);
|
||||
}, [onSelect, openNewSessionDraft, setActiveSurface]);
|
||||
|
||||
const [expandedParents, setExpandedParents] = React.useState<Set<string>>(new Set());
|
||||
const toggleParent = React.useCallback((sessionId: string) => {
|
||||
|
||||
@@ -44,13 +44,13 @@ export const useProjectTodoSend = (options: {
|
||||
const sendMessage = useSessionUIStore((state) => state.sendMessage);
|
||||
const setCurrentSession = useSessionUIStore((state) => state.setCurrentSession);
|
||||
const setPendingInputText = useInputStore((state) => state.setPendingInputText);
|
||||
const setActiveMainTab = useUIStore((state) => state.setActiveMainTab);
|
||||
const setActiveSurface = useUIStore((state) => state.setActiveSurface);
|
||||
const setSessionSwitcherOpen = useUIStore((state) => state.setSessionSwitcherOpen);
|
||||
|
||||
const routeToChat = React.useCallback(() => {
|
||||
setActiveMainTab('chat');
|
||||
setActiveSurface('chat');
|
||||
setSessionSwitcherOpen(false);
|
||||
}, [setActiveMainTab, setSessionSwitcherOpen]);
|
||||
}, [setActiveSurface, setSessionSwitcherOpen]);
|
||||
|
||||
const sendToCurrentSession = React.useCallback(
|
||||
(todoText: string) => {
|
||||
|
||||
@@ -14,7 +14,7 @@ import { Button } from '@/components/ui/button';
|
||||
import { Icon } from "@/components/icon/Icon";
|
||||
import { cn } from '@/lib/utils';
|
||||
import { sessionEvents } from '@/lib/sessionEvents';
|
||||
import type { MainTab } from '@/stores/useUIStore';
|
||||
import type { WorkspaceSurface } from '@/stores/useUIStore';
|
||||
import { SessionFolderItem } from '../SessionFolderItem';
|
||||
import type { SortableDragHandleProps } from './sortableItems';
|
||||
import { DroppableFolderWrapper, SessionFolderDndScope } from './sessionFolderDnd';
|
||||
@@ -84,7 +84,7 @@ type Props = {
|
||||
alwaysShowActions: boolean;
|
||||
activeProjectId: string | null;
|
||||
setActiveProjectIdOnly: (id: string) => void;
|
||||
setActiveMainTab: (tab: MainTab) => void;
|
||||
setActiveSurface: (tab: WorkspaceSurface) => void;
|
||||
setSessionSwitcherOpen: (open: boolean) => void;
|
||||
openNewSessionDraft: (options?: { selectedProjectId?: string | null; directoryOverride?: string | null; targetFolderId?: string; target?: 'chat' | 'project' }) => void;
|
||||
addSessionToFolder: (scopeKey: string, folderId: string, sessionId: string) => void;
|
||||
@@ -265,7 +265,7 @@ const areGroupPropsEqual = (prev: Props, next: Props): boolean => {
|
||||
&& prev.alwaysShowActions === next.alwaysShowActions
|
||||
&& prev.activeProjectId === next.activeProjectId
|
||||
&& prev.setActiveProjectIdOnly === next.setActiveProjectIdOnly
|
||||
&& prev.setActiveMainTab === next.setActiveMainTab
|
||||
&& prev.setActiveSurface === next.setActiveSurface
|
||||
&& prev.setSessionSwitcherOpen === next.setSessionSwitcherOpen
|
||||
&& prev.openNewSessionDraft === next.openNewSessionDraft
|
||||
&& prev.addSessionToFolder === next.addSessionToFolder
|
||||
@@ -307,7 +307,7 @@ function SessionGroupSectionBase(props: Props): React.ReactNode {
|
||||
alwaysShowActions,
|
||||
activeProjectId,
|
||||
setActiveProjectIdOnly,
|
||||
setActiveMainTab,
|
||||
setActiveSurface,
|
||||
setSessionSwitcherOpen,
|
||||
openNewSessionDraft,
|
||||
addSessionToFolder,
|
||||
@@ -880,7 +880,7 @@ function SessionGroupSectionBase(props: Props): React.ReactNode {
|
||||
depth={0}
|
||||
onNewSession={() => {
|
||||
if (projectId && projectId !== activeProjectId) setActiveProjectIdOnly(projectId);
|
||||
setActiveMainTab('chat');
|
||||
setActiveSurface('chat');
|
||||
if (mobileVariant) setSessionSwitcherOpen(false);
|
||||
openNewSessionDraft({
|
||||
selectedProjectId: projectId,
|
||||
@@ -1248,7 +1248,7 @@ function SessionGroupSectionBase(props: Props): React.ReactNode {
|
||||
onClick={(event) => {
|
||||
event.stopPropagation();
|
||||
if (projectId && projectId !== activeProjectId) setActiveProjectIdOnly(projectId);
|
||||
setActiveMainTab('chat');
|
||||
setActiveSurface('chat');
|
||||
if (mobileVariant) setSessionSwitcherOpen(false);
|
||||
openNewSessionDraft({ selectedProjectId: projectId, directoryOverride: group.directory });
|
||||
}}
|
||||
|
||||
@@ -16,7 +16,7 @@ import type { SortableDragHandleProps } from './sortableItems';
|
||||
import { ProjectHeaderIdentity, SortableGroupItem, SortableProjectItem } from './sortableItems';
|
||||
import { formatProjectLabel } from './utils';
|
||||
import { useI18n } from '@/lib/i18n';
|
||||
import type { MainTab } from '@/stores/useUIStore';
|
||||
import type { WorkspaceSurface } from '@/stores/useUIStore';
|
||||
import type { ProjectSortOrder } from '@/stores/useSessionDisplayStore';
|
||||
import { streamPerfCount } from '@/stores/utils/streamDebug';
|
||||
import { Icon } from '@/components/icon/Icon';
|
||||
@@ -91,7 +91,7 @@ type Props = {
|
||||
alwaysShowActions: boolean;
|
||||
toggleProject: (id: string) => void;
|
||||
setActiveProjectIdOnly: (id: string) => void;
|
||||
setActiveMainTab: (tab: MainTab) => void;
|
||||
setActiveSurface: (tab: WorkspaceSurface) => void;
|
||||
setSessionSwitcherOpen: (open: boolean) => void;
|
||||
openNewSessionDraft: (options?: { selectedProjectId?: string | null; directoryOverride?: string | null }) => void;
|
||||
openNewWorktreeDialog: () => void;
|
||||
@@ -362,7 +362,7 @@ function SidebarProjectsListComponent(props: Props): React.ReactNode {
|
||||
}}
|
||||
onNewSession={() => {
|
||||
if (projectKey !== props.activeProjectId) props.setActiveProjectIdOnly(projectKey);
|
||||
props.setActiveMainTab('chat');
|
||||
props.setActiveSurface('chat');
|
||||
if (props.mobileVariant) props.setSessionSwitcherOpen(false);
|
||||
props.openNewSessionDraft({
|
||||
selectedProjectId: projectKey,
|
||||
@@ -371,7 +371,7 @@ function SidebarProjectsListComponent(props: Props): React.ReactNode {
|
||||
}}
|
||||
onNewWorktreeSession={() => {
|
||||
if (projectKey !== props.activeProjectId) props.setActiveProjectIdOnly(projectKey);
|
||||
props.setActiveMainTab('chat');
|
||||
props.setActiveSurface('chat');
|
||||
props.openNewWorktreeDialog();
|
||||
}}
|
||||
onManageWorktrees={() => props.openWorktreesPage(projectKey)}
|
||||
|
||||
@@ -2,7 +2,7 @@ import React from 'react';
|
||||
import type { Session } from '@opencode-ai/sdk/v2';
|
||||
import type { SessionGroup, SessionNode } from '../types';
|
||||
import { normalizePath } from '../utils';
|
||||
import type { MainTab } from '@/stores/useUIStore';
|
||||
import type { WorkspaceSurface } from '@/stores/useUIStore';
|
||||
import { useUIStore } from '@/stores/useUIStore';
|
||||
import { useSessionUIStore } from '@/sync/session-ui-store';
|
||||
|
||||
@@ -22,7 +22,7 @@ type Args = {
|
||||
newSessionDraftOpen: boolean;
|
||||
mobileVariant: boolean;
|
||||
openNewSessionDraft: (options?: { selectedProjectId?: string | null; directoryOverride?: string | null }) => void;
|
||||
setActiveMainTab: (tab: MainTab) => void;
|
||||
setActiveSurface: (tab: WorkspaceSurface) => void;
|
||||
setSessionSwitcherOpen: (open: boolean) => void;
|
||||
};
|
||||
|
||||
@@ -101,7 +101,7 @@ export const useProjectSessionSelection = (args: Args): void => {
|
||||
newSessionDraftOpen,
|
||||
mobileVariant,
|
||||
openNewSessionDraft,
|
||||
setActiveMainTab,
|
||||
setActiveSurface,
|
||||
setSessionSwitcherOpen,
|
||||
} = args;
|
||||
|
||||
@@ -205,7 +205,7 @@ export const useProjectSessionSelection = (args: Args): void => {
|
||||
previousActiveProjectRef.current = activeProjectId;
|
||||
|
||||
if (selection.kind === 'open-draft') {
|
||||
setActiveMainTab('chat');
|
||||
setActiveSurface('chat');
|
||||
if (mobileVariant) {
|
||||
setSessionSwitcherOpen(false);
|
||||
}
|
||||
@@ -232,7 +232,7 @@ export const useProjectSessionSelection = (args: Args): void => {
|
||||
openNewSessionDraft,
|
||||
projectSections,
|
||||
projectSessionMeta,
|
||||
setActiveMainTab,
|
||||
setActiveSurface,
|
||||
setSessionSwitcherOpen,
|
||||
setActiveSessionByProject,
|
||||
]);
|
||||
|
||||
@@ -3,7 +3,7 @@ import type { Session } from '@opencode-ai/sdk/v2';
|
||||
import { toast } from '@/components/ui';
|
||||
import { copyTextToClipboard } from '@/lib/clipboard';
|
||||
import { useI18n } from '@/lib/i18n';
|
||||
import type { MainTab } from '@/stores/useUIStore';
|
||||
import type { WorkspaceSurface } from '@/stores/useUIStore';
|
||||
import { useUIStore } from '@/stores/useUIStore';
|
||||
import { streamPerfMark } from '@/stores/utils/streamDebug';
|
||||
import { useSessionUIStore } from '@/sync/session-ui-store';
|
||||
@@ -30,7 +30,7 @@ type Args = {
|
||||
sessionSearchQuery: string;
|
||||
setSessionSearchQuery: (value: string) => void;
|
||||
setIsSessionSearchOpen: (open: boolean) => void;
|
||||
setActiveMainTab: (tab: MainTab) => void;
|
||||
setActiveSurface: (tab: WorkspaceSurface) => void;
|
||||
setSessionSwitcherOpen: (open: boolean) => void;
|
||||
setCurrentSession: (sessionId: string | null, directoryHint?: string | null) => void;
|
||||
updateSessionTitle: (id: string, title: string) => Promise<void>;
|
||||
@@ -79,7 +79,7 @@ export const useSessionActions = (args: Args) => {
|
||||
};
|
||||
|
||||
if (args.mobileVariant) {
|
||||
args.setActiveMainTab('chat');
|
||||
args.setActiveSurface('chat');
|
||||
args.setSessionSwitcherOpen(false);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user