v0.3.10: 全面优化增强 — 17项Bug修复/稳定性/功能改进
P0 致命Bug修复: - A1: openFolderDialog 类型/运行时崩溃(文件夹打开功能完全失效) - A2: SourceEditor 受控textarea手动改DOM反模式 - A3: tabStore.updateTabContent 内容相同时误标isModified 死代码清理: - B1: 删除menu:*/save/as/viewMode 三个永不触发的IPC通道 健壮性修复: - E1: rehypeFixImages 路径规范化+防越界加固 - E2: getFileName 尾斜杠返回正确文件名 - E3: EditorToolbar 行内代码按钮改用toggleInlineCodeCommand - E4: ErrorBoundary 内联样式抽为CSS类 功能增强: - D1: 标签页拖拽排序(tabStore.moveTab + TabBar DnD + CSS) - D2: Milkdown自动配对括号/引号(ProseMirror插件) - D3: 状态栏自动保存开关可点击 - D4: 文档大纲活跃标题高亮(useActiveHeading hook) - D5: 关闭窗口前flush防抖数据(flushSaveToDB) - D6: 搜索替换支持正则表达式 类型/架构: - C2: preload类型集中定义(ElectronAPI契约) - __pycache__ typo修复 文档/版本: - README/DESIGN同步为Milkdown + v0.3.10 - 项目结构树/技术栈/快捷键表更新 验证: typecheck(仅7预存), lint✅, test 96/96, vite build✅
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import React, { useCallback, useMemo } from 'react'
|
||||
import React, { useCallback, useMemo, useEffect, useRef } from 'react'
|
||||
import { useTabStore } from '../../stores/tabStore'
|
||||
import { useSidebarStore } from '../../stores/sidebarStore'
|
||||
import { getFileName } from '../../lib/fileUtils'
|
||||
@@ -8,6 +8,7 @@ import { FileTree } from '../FileTree'
|
||||
import { useSidebarResize } from '../../hooks/useSidebarResize'
|
||||
import { useFolderOperations } from '../../hooks/useFolderOperations'
|
||||
import { useAutoExpandDir } from '../../hooks/useAutoExpandDir'
|
||||
import { useActiveHeading } from '../../hooks/useActiveHeading'
|
||||
import { OutlinePanel, parseHeadings } from '../OutlinePanel'
|
||||
import type { Heading } from '../OutlinePanel'
|
||||
import { getEditorView, useEditorStore } from '../../stores/editorStore'
|
||||
@@ -33,6 +34,7 @@ export const Sidebar = React.memo(function Sidebar() {
|
||||
const { sidebarRef, startResize } = useSidebarResize()
|
||||
const { handleOpenFolder } = useFolderOperations()
|
||||
const setLoading = useEditorStore(s => s.setLoading)
|
||||
const viewMode = useEditorStore(s => s.viewMode)
|
||||
useAutoExpandDir(activeFilePath)
|
||||
|
||||
// Parse headings from active tab content
|
||||
@@ -41,6 +43,22 @@ export const Sidebar = React.memo(function Sidebar() {
|
||||
return parseHeadings(activeTab.content)
|
||||
}, [activeTab?.content])
|
||||
|
||||
// D4: 追踪预览面板中的活跃标题
|
||||
const previewRef = useRef<HTMLElement | null>(null)
|
||||
useEffect(() => {
|
||||
// 仅在预览模式时获取 preview DOM 节点
|
||||
if (viewMode === 'preview') {
|
||||
previewRef.current = document.getElementById('preview')
|
||||
} else {
|
||||
previewRef.current = null
|
||||
}
|
||||
}, [viewMode])
|
||||
|
||||
const activeHeadingIndex = useActiveHeading(
|
||||
viewMode === 'preview' ? previewRef : { current: null },
|
||||
headings
|
||||
)
|
||||
|
||||
// Navigate to heading in ProseMirror document tree
|
||||
const handleHeadingNavigate = useCallback((heading: Heading, index: number) => {
|
||||
const view = getEditorView()
|
||||
@@ -149,7 +167,7 @@ export const Sidebar = React.memo(function Sidebar() {
|
||||
<OutlinePanel
|
||||
headings={headings}
|
||||
onNavigate={handleHeadingNavigate}
|
||||
activeHeadingIndex={null}
|
||||
activeHeadingIndex={activeHeadingIndex}
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
|
||||
Reference in New Issue
Block a user