feat: 更新工作区选项卡逻辑,支持切换和状态管理

This commit is contained in:
cmliu committed 2026-07-29 11:24:12 +08:00
1 parent 8cb4d88b39
commit b8b2f63073
3 files changed
+30 -15

No files matched your search

+3 -2
View File
@@ -293,8 +293,9 @@
class="dock-tab"
type="button"
role="tab"
aria-selected="true"
aria-selected="false"
aria-controls="file-manager-panel"
aria-expanded="false"
tabindex="0"
data-i18n-zh="文件管理"
data-i18n-en="Files"
@@ -314,7 +315,7 @@
</div>
</div>
<section id="file-manager-panel" class="file-manager" role="tabpanel" aria-labelledby="file-manager-tab" tabindex="0">
<section id="file-manager-panel" class="file-manager" role="tabpanel" aria-labelledby="file-manager-tab" tabindex="0" hidden>
<div class="file-toolbar">
<label class="file-path-field" for="file-manager-path">
<span class="sr-only" data-i18n-zh="当前路径" data-i18n-en="Current path">当前路径</span>
+21 -12
View File
@@ -1211,21 +1211,30 @@ function sendHostKeyDecision(accept: boolean): void {
}
type WorkspaceTab = 'files' | 'log';
let activeWorkspaceTab: WorkspaceTab | null = null;
function setWorkspaceTab(tab: WorkspaceTab, focus = false): void {
function setWorkspaceTab(tab: WorkspaceTab | null, focus = false, rovingTab = tab ?? activeWorkspaceTab ?? 'files'): void {
const filesActive = tab === 'files';
const logActive = tab === 'log';
activeWorkspaceTab = tab;
ui.terminalCard.classList.toggle('workspace-panel-open', tab !== null);
ui.fileManagerPanel.hidden = !filesActive;
ui.eventLog.hidden = filesActive;
ui.eventLog.hidden = !logActive;
ui.fileManagerTab.setAttribute('aria-selected', String(filesActive));
ui.eventToggle.setAttribute('aria-selected', String(!filesActive));
ui.eventToggle.setAttribute('aria-expanded', String(!filesActive));
ui.fileManagerTab.tabIndex = filesActive ? 0 : -1;
ui.eventToggle.tabIndex = filesActive ? -1 : 0;
if (!filesActive) requestAnimationFrame(() => { ui.eventLog.scrollTop = ui.eventLog.scrollHeight; });
if (focus) (filesActive ? ui.fileManagerTab : ui.eventToggle).focus();
ui.eventToggle.setAttribute('aria-selected', String(logActive));
ui.fileManagerTab.setAttribute('aria-expanded', String(filesActive));
ui.eventToggle.setAttribute('aria-expanded', String(logActive));
ui.fileManagerTab.tabIndex = rovingTab === 'files' ? 0 : -1;
ui.eventToggle.tabIndex = rovingTab === 'log' ? 0 : -1;
if (logActive) requestAnimationFrame(() => { ui.eventLog.scrollTop = ui.eventLog.scrollHeight; });
if (focus) (rovingTab === 'files' ? ui.fileManagerTab : ui.eventToggle).focus();
requestAnimationFrame(() => fitTerminal(true));
}
function toggleWorkspaceTab(tab: WorkspaceTab): void {
setWorkspaceTab(activeWorkspaceTab === tab ? null : tab, false, tab);
}
function handleWorkspaceTabKey(event: KeyboardEvent): void {
if (!['ArrowLeft', 'ArrowRight', 'Home', 'End'].includes(event.key)) return;
event.preventDefault();
@@ -1847,8 +1856,8 @@ ui.fullscreenTerminal.addEventListener('click', async () => {
else await ui.terminalCard.requestFullscreen();
});
document.addEventListener('fullscreenchange', () => fitTerminal(true));
ui.fileManagerTab.addEventListener('click', () => setWorkspaceTab('files'));
ui.eventToggle.addEventListener('click', () => setWorkspaceTab('log'));
ui.fileManagerTab.addEventListener('click', () => toggleWorkspaceTab('files'));
ui.eventToggle.addEventListener('click', () => toggleWorkspaceTab('log'));
ui.fileManagerTab.addEventListener('keydown', handleWorkspaceTabKey);
ui.eventToggle.addEventListener('keydown', handleWorkspaceTabKey);
ui.languageToggle.addEventListener('click', () => {
@@ -1895,7 +1904,7 @@ async function initialize(): Promise<void> {
setPanelOpen(panelOpen);
setAuthMethod('password');
setState('idle');
setWorkspaceTab('files');
setWorkspaceTab(null);
ui.sessionTitle.textContent = bilingual('无活动会话', 'No active session');
ui.sessionSubtitle.textContent = bilingual('选择目标并连接', 'Choose a target and connect');
ui.eventMessage.textContent = bilingual('Worker 运行时待命', 'Worker runtime standing by');
@@ -1916,6 +1925,6 @@ void initialize().catch(() => {
setPanelOpen(panelOpen);
setAuthMethod('password');
setState('idle');
setWorkspaceTab('files');
setWorkspaceTab(null);
initializeCompatibilityAPI();
});
+6 -1
View File
@@ -953,12 +953,17 @@ button:disabled {
display: grid;
min-width: 0;
min-height: 0;
grid-template-rows: minmax(0, 2fr) minmax(0, 1fr);
grid-template-rows: minmax(0, 1fr) minmax(34px, 0fr);
overflow: hidden;
border: 1px solid var(--border);
border-radius: 12px;
background: var(--terminal);
box-shadow: var(--shadow);
transition: grid-template-rows 220ms cubic-bezier(0.2, 0.75, 0.2, 1);
}
.terminal-card.workspace-panel-open {
grid-template-rows: minmax(0, 2fr) minmax(34px, 1fr);
}
.terminal-pane {