feat(info): 信息面板 UI 重做 + 双向批量关联 + 代码块内全选复制

1. 信息面板 UI 重做:设计 token 统一、lucide 图标、分区小节、星标/标签/关联 chip 化
2. 关联文档升级:新增 doc:link-batch IPC,A↔B 双向写入 links;面板支持快速双向关联 + 批量勾选关联/解除
3. 代码块内全选复制:Ctrl+A 在代码块内仅全选该代码块(TyporaKeys selectInsideCodeBlock),Ctrl+C 复制纯代码;代码块内 Ctrl+V 按纯文本粘贴
4. 修复 React error #62:btn 改为函数后遗漏 style={btn} 裸用,导致 render 期间更新
This commit is contained in:
hunter-dev
2026-09-09 20:11:08 +08:00
parent f77324afe7
commit dc8d844a1f
10 changed files with 353 additions and 58 deletions
+15 -9
View File
@@ -28,6 +28,7 @@ interface EditorState {
toggleStar: () => void;
addLink: (link: string) => void;
removeLink: (link: string) => void;
linkBatch: (targets: string[], remove: boolean) => Promise<void>;
saveNow: () => Promise<void>;
reloadDoc: () => Promise<boolean>; // FR-S6:重新加载——检测 mtime 变化,有未保存改动时返回 false 需确认
resetEditor: () => void; // FR-V6: 切库时重置编辑区
@@ -90,15 +91,20 @@ export const useStore = create<EditorState>((set, get) => ({
set({ meta: { ...get().meta, star: !get().meta.star } });
get().saveNow();
},
addLink: (link: string) => {
const links = [...(get().meta.links ?? []), link].filter((l, i, a) => a.indexOf(l) === i);
set({ meta: { ...get().meta, links } });
get().saveNow();
},
removeLink: (link: string) => {
const links = (get().meta.links ?? []).filter(l => l !== link);
set({ meta: { ...get().meta, links } });
get().saveNow();
addLink: (link: string) => { void get().linkBatch([link], false); },
removeLink: (link: string) => { void get().linkBatch([link], true); },
// 双向批量关联:先冲刷编辑器内容落盘,再由主进程把当前文档与每个目标文档互相写入 links
linkBatch: async (targets: string[], remove: boolean) => {
const { currentPath } = get();
if (!currentPath || targets.length === 0) return;
window.dispatchEvent(new CustomEvent('dsh-flush-body'));
await get().saveNow();
try {
const res = await invoke(IPC.docLinkBatch, { path: currentPath, targets, remove });
set({ meta: { ...get().meta, links: res.links } });
} catch (e) {
console.error('linkBatch failed', e);
}
},
setBody: (body: string) => {
set({ body, saveState: 'saving' });