v1.1.3 — 笔记数据安全修复 + IPC 监听器泄漏修复
本次发布修复笔记/文件保存逻辑中的严重数据安全问题,并修复由此衍生的 IPC 监听器累积问题。确立核心设计原则:笔记模式(草稿/收藏)永远实时保存,不弹窗、不丢弃。
Bug 修复
严重(数据安全)
- 打开外部文件时收藏笔记内容被覆盖(Bug 2/5):
checkUnsavedAndExecute重构为区分文件模式和笔记模式- 文件模式(fileInfo 存在)且有修改:弹窗询问是否保存文件
- 笔记模式(fileInfo 为空)且有修改:自动保存笔记后执行操作(不弹窗,不丢弃)
- 收藏笔记内 Ctrl+S 弹出文件保存框(Bug 3):笔记模式下 Ctrl+S 调用
saveCurrentNote()保存到笔记数据库 + toast 反馈,不再弹出另存为对话框 loadFileFromExternal/handleDrop打开外部文件时清除currentNote/currentNoteId,避免后续自动保存用文件内容覆盖旧笔记handleNew/handleSelectNote在文件模式下不调用saveCurrentNote,避免把文件内容误存为草稿handleUnsavedDialogSave区分文件模式和笔记模式,笔记模式走笔记数据库保存
严重(交互体验,v1.1.3 重新发布新增)
- 新建文本后打开 TXT 文件重复弹出保存确认框(Bug M-2,根因修复):
- 根因:
onRequestClose/onLoadFileInWindow使用ipcRenderer.on()无法移除特定监听器,每次 state 变化(text/fileInfo/currentNote 等)触发useEffect重新注册监听器,旧监听器闭包捕获过期 state(如isFileDirty=true),导致后续打开文件时所有累积的监听器全部触发,旧监听器误判为"文件已修改未保存"弹出确认框 - 修复:preload.ts 中
onRequestClose/onLoadFileInWindow返回移除函数;App.tsx 中useEffectcleanup 调用移除函数,确保每次只保留一个监听器
- 根因:
- checkUnsavedAndExecute 闭包捕获过期 state(防御性修复):
- 将
fileInfo/isFileDirty/currentNote/text/saveCurrentNote镜像到 ref,checkUnsavedAndExecute读取 ref 而非闭包变量,依赖数组稳定为空数组,避免闭包过期问题 - 副作用:监听器只注册一次,性能提升
- 将
- newShortcut 绕过未保存检查(Bug M-4):
handleKeyDown中newShortcut原直接调用handleNew(),绕过checkUnsavedAndExecute,文件模式下未保存的修改会被静默丢弃- 修复:改走
handleNewWithCheck(),统一经过未保存检查
- 未保存对话框文案不明确(UX 优化):
- 原文案"文件内容已修改但未保存,是否保存?"未指明具体文件,用户反馈"搞不懂在说哪个文件"
- 修复:文件模式下显示
文件 "{{fileName}}" 已修改但未保存,是否保存?,11 种语言同步新增unsaved.messageFile键
严重(数据安全,v1.1.3 第二次重新发布新增)
- 切换笔记时文件未保存修改丢失(Bug M-5):
- 根因:
handleSelectNote在文件模式下有未保存修改时,直接加载笔记内容覆盖编辑区,不调用checkUnsavedAndExecute弹窗询问,导致文件未保存的修改丢失 - 修复:
handleSelectNote用checkUnsavedAndExecute包装,文件模式下有未保存修改时弹窗询问;笔记模式自动保存当前笔记后加载新笔记(不丢弃)
- 根因:
- 收藏操作时文件未保存修改丢失(Bug M-6):
- 根因:
togglePin(收藏按钮)在文件模式下直接调用ensureCurrentNote,不弹窗询问,导致文件未保存的修改被意外存为草稿/收藏 - 修复:
togglePin用checkUnsavedAndExecute包装,文件模式下有未保存修改时弹窗询问
- 根因:
- checkUnsavedAndExecute 笔记模式分支优化(防御性修复):
- 原笔记模式分支
else if (!fi && cn && tx !== cn.content)只处理currentNote存在且内容变化的情况,currentNote为 null 但text有内容(刚输入未自动保存的草稿)时不会保存,切换笔记会丢失 - 修复:改为
else if (!fi && tx && tx.trim() && (cn ? tx !== cn.content : true)),处理currentNote为 null 但text有内容的情况
- 原笔记模式分支
下载
| 文件 | 说明 |
|---|---|
OncePad-Setup-1.1.3.exe |
Windows 安装版(推荐,注册 40+ 文件类型关联) |
OncePad-1.1.3.exe |
Windows 便携版(免安装,直接运行) |
Full Changelog: v1.1.2...v1.1.3