diff --git a/DESIGN.md b/DESIGN.md index 566cf1e..b4ce514 100644 --- a/DESIGN.md +++ b/DESIGN.md @@ -1,4 +1,4 @@ -# MarkLite v0.1.0 — 架构设计文档 +# MarkLite v0.1.1 — 架构设计文档 ## 1. 项目概述 diff --git a/README.md b/README.md index 1d0a458..500dd8d 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ TypeScript React License - Version + Version

diff --git a/package.json b/package.json index 44896ac..fd5c440 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "marklite", - "version": "0.1.0", + "version": "0.1.1", "description": "Lightweight Markdown Editor for Windows", "main": "./dist/main/index.js", "scripts": { diff --git a/src/renderer/App.tsx b/src/renderer/App.tsx index f58e16f..1060834 100644 --- a/src/renderer/App.tsx +++ b/src/renderer/App.tsx @@ -21,9 +21,9 @@ import { ModifiedBanner } from './components/ModifiedBanner/ModifiedBanner' import { DropOverlay } from './components/DropOverlay/DropOverlay' import { AppIcon, Gitee } from './components/Icons' -const APP_VERSION = 'v0.1.0' +const APP_VERSION = 'v0.1.1' -export default function App() { +export function App() { const tabs = useTabStore(s => s.tabs) const activeTabId = useTabStore(s => s.activeTabId) const getActiveTab = useTabStore(s => s.getActiveTab) @@ -89,42 +89,54 @@ export default function App() { // 打开文件 const handleOpenFile = useCallback(async () => { - if (window.electronAPI) { - const result = await window.electronAPI.openFile() - if (result && 'filePath' in result) { - createTab(result.filePath, result.content) - if (result.filePath) recentFilesRepository.add(result.filePath) - setTimeout(() => useTabStore.getState().saveToDB(), 100) + try { + if (window.electronAPI) { + const result = await window.electronAPI.openFile() + if (result && 'filePath' in result) { + createTab(result.filePath, result.content) + if (result.filePath) recentFilesRepository.add(result.filePath) + setTimeout(() => useTabStore.getState().saveToDB(), 100) + } } + } catch { + showToast('操作失败') } - }, [createTab]) + }, [createTab, showToast]) // 保存文件 const handleSave = useCallback(async () => { - const tab = getActiveTab() - if (!tab) return - if (window.electronAPI) { - const result = await window.electronAPI.saveFile({ - filePath: tab.filePath, - content: tab.content - }) - if (result.success) { - useTabStore.getState().setModified(tab.id, false) - showToast('已保存') + try { + const tab = getActiveTab() + if (!tab) return + if (window.electronAPI) { + const result = await window.electronAPI.saveFile({ + filePath: tab.filePath, + content: tab.content + }) + if (result.success) { + useTabStore.getState().setModified(tab.id, false) + showToast('已保存') + } } + } catch { + showToast('操作失败') } }, [getActiveTab, showToast]) // 另存为 const handleSaveAs = useCallback(async () => { - const tab = getActiveTab() - if (!tab) return - if (window.electronAPI) { - const result = await window.electronAPI.saveFileAs({ content: tab.content }) - if (result.success) { - useTabStore.getState().setModified(tab.id, false) - showToast('已保存') + try { + const tab = getActiveTab() + if (!tab) return + if (window.electronAPI) { + const result = await window.electronAPI.saveFileAs({ content: tab.content }) + if (result.success) { + useTabStore.getState().setModified(tab.id, false) + showToast('已保存') + } } + } catch { + showToast('操作失败') } }, [getActiveTab, showToast]) @@ -247,7 +259,7 @@ export default function App() { {/* 关于弹框 */} {showAbout && ( -

setShowAbout(false)}> +
setShowAbout(false)} role="dialog" aria-modal="true" aria-label="关于 MarkLite">
e.stopPropagation()}>
@@ -289,3 +301,7 @@ export default function App() {
) } + +App.displayName = 'App' + +export default App diff --git a/src/renderer/components/Editor/Editor.tsx b/src/renderer/components/Editor/Editor.tsx index e4cf33f..4461fc3 100644 --- a/src/renderer/components/Editor/Editor.tsx +++ b/src/renderer/components/Editor/Editor.tsx @@ -87,9 +87,11 @@ export function Editor({ darkMode }: EditorProps) { }, [viewRef]) return ( -
+
) } + +Editor.displayName = 'Editor' \ No newline at end of file diff --git a/src/renderer/components/Editor/useCodeMirror.ts b/src/renderer/components/Editor/useCodeMirror.ts index f2a4eb7..d247ab3 100644 --- a/src/renderer/components/Editor/useCodeMirror.ts +++ b/src/renderer/components/Editor/useCodeMirror.ts @@ -17,6 +17,12 @@ export function useCodeMirror({ content, onChange, darkMode }: UseCodeMirrorOpti const containerRef = useRef(null) const viewRef = useRef(null) const isExternalUpdate = useRef(false) + const onChangeRef = useRef(onChange) + + // 始终保持 onChangeRef 为最新回调 + useEffect(() => { + onChangeRef.current = onChange + }, [onChange]) // 初始化编辑器 useEffect(() => { @@ -61,7 +67,7 @@ export function useCodeMirror({ content, onChange, darkMode }: UseCodeMirrorOpti EditorView.lineWrapping, EditorView.updateListener.of(update => { if (update.docChanged && !isExternalUpdate.current) { - onChange(update.state.doc.toString()) + onChangeRef.current(update.state.doc.toString()) } }) ] diff --git a/src/renderer/components/Preview/Preview.tsx b/src/renderer/components/Preview/Preview.tsx index e7cf783..a5ba72b 100644 --- a/src/renderer/components/Preview/Preview.tsx +++ b/src/renderer/components/Preview/Preview.tsx @@ -56,8 +56,13 @@ export function Preview() { ref={previewRef} id="preview" className="markdown-body" + role="region" + aria-label="Markdown预览" + aria-live="polite" onClick={handleClick} dangerouslySetInnerHTML={{ __html: html }} /> ) } + +Preview.displayName = 'Preview' \ No newline at end of file diff --git a/src/renderer/components/Sidebar/Sidebar.tsx b/src/renderer/components/Sidebar/Sidebar.tsx index 57c6b80..73979d2 100644 --- a/src/renderer/components/Sidebar/Sidebar.tsx +++ b/src/renderer/components/Sidebar/Sidebar.tsx @@ -128,7 +128,7 @@ export function Sidebar() {
-