feat(M8): FR-T4/T5/T6/W2/W6/W7 标签页/布局接线——固定标签悬停浮现关闭按钮(T4); tab-store updateScroll+restore恢复滚动位置(T5); tabbarVisible接线App+TitleBar切换按钮(T6/W6); winIsMaximized IPC+最大化/还原图标切换(W2); 极简模式隐藏TabBar(W7); layout-tabs E2E 3 项

This commit is contained in:
hunter-dev
2026-08-26 15:20:30 +08:00
parent 8f6fd7082b
commit 1f3ede9956
7 changed files with 128 additions and 19 deletions
+6 -3
View File
@@ -37,7 +37,10 @@ export function App() {
const layout = useLayout();
useEffect(() => { loadVault(); loadTree(); restore(); appearance.load(); useKeymap.getState().load(); useSettings.getState().loadGpu(); }, []);
useEffect(() => { if (activeId && tabs.length > 0) { const t = tabs.find(x => x.id === activeId); if (t) openDoc(t.path).catch(() => {}); } }, []);
useEffect(() => { if (activeId && tabs.length > 0) { const t = tabs.find(x => x.id === activeId); if (t) openDoc(t.path).then(() => {
// FR-T5:恢复标签页保存的滚动位置
if (t.scrollTop > 0) { setTimeout(() => { const ed = document.querySelector('.ProseMirror'); const c = ed?.closest('[class*="editor"]') as HTMLElement | null; if (c) c.scrollTop = t.scrollTop; }, 100); }
}).catch(() => {}); } }, [activeId]);
// FR-S4:关窗前冲刷未保存内容
useEffect(() => {
const onBeforeUnload = () => { try { useStore.getState().saveNow(); } catch {} };
@@ -52,9 +55,9 @@ export function App() {
<div style={{ position: 'relative', display: 'flex', flexDirection: 'column', height: '100vh', background: 'var(--bg-primary, #1a1a1a)', color: '#ddd' }}>
{appearance.bgImage && <div style={{ position: 'absolute', inset: 0, backgroundImage: 'url(' + appearance.bgImage + ')', backgroundSize: 'cover', backgroundPosition: 'center', filter: settings.perfMode ? 'none' : 'blur(var(--blur-px,0px))', opacity: 0.45, zIndex: 0, pointerEvents: 'none' }} />}
<div style={{ position: 'relative', zIndex: 1, display: 'flex', flexDirection: 'column', height: '100vh' }}>
<TitleBar view={view} onToggleView={() => setView(v => v === 'editor' ? 'graph' : 'editor')} onSettings={() => setShowSettings(true)} onAppearance={() => setShowAppearance(true)} onToggleSidebar={() => layout.toggleSidebar()} onToggleMinimal={() => layout.toggleMinimal()} minimal={layout.minimal} />
<TitleBar view={view} onToggleView={() => setView(v => v === 'editor' ? 'graph' : 'editor')} onSettings={() => setShowSettings(true)} onAppearance={() => setShowAppearance(true)} onToggleSidebar={() => layout.toggleSidebar()} onToggleMinimal={() => layout.toggleMinimal()} onToggleTabbar={() => layout.toggleTabbar()} minimal={layout.minimal} tabbarVisible={layout.tabbarVisible} />
<Toolbar />
{view === 'editor' && <TabBar />}
{view === 'editor' && layout.tabbarVisible && !layout.minimal && <TabBar />}
<div style={{ flex: 1, display: 'flex', overflow: 'hidden' }}>
{layout.minimal ? (<Editor />) : (<>
{layout.sidebarVisible && (<>