M0-M11 狩夜人笔记初始实现:11里程碑+86测试
This commit is contained in:
@@ -0,0 +1,65 @@
|
||||
// IPC handlers — 主进程侧通道注册(类型链约束于 @hunter/shared)
|
||||
import nodePath from 'node:path';
|
||||
import { ipcMain, shell, dialog, clipboard } from 'electron';
|
||||
import { IPC } from '@hunter/shared';
|
||||
import type { VaultService } from '../services/vault-service.js';
|
||||
import { buildGraphData } from '../services/graph-builder.js';
|
||||
|
||||
export function registerIpc(vault: VaultService) {
|
||||
const fs2 = () => {
|
||||
if (!vault.fileService) throw new Error('vault not initialized');
|
||||
return vault.fileService;
|
||||
};
|
||||
|
||||
ipcMain.handle(IPC.vaultList, async () => vault.getMeta());
|
||||
ipcMain.handle(IPC.vaultSwitch, async (_e, p: { root: string }) => vault.switch(p.root));
|
||||
ipcMain.handle(IPC.vaultSetDefault, async (_e, p: { root: string }) => { await vault.setDefaultRoot(p.root); });
|
||||
ipcMain.handle(IPC.vaultPick, async () => vault.pickAndSwitch());
|
||||
|
||||
ipcMain.handle(IPC.treeList, async () => fs2().listTree());
|
||||
ipcMain.handle(IPC.treeRefresh, async () => fs2().listTree());
|
||||
|
||||
ipcMain.handle(IPC.fileCreate, async (_e, p: { basePath: string; name: string; isFolder: boolean }) =>
|
||||
fs2().create(p.basePath, p.name, p.isFolder));
|
||||
ipcMain.handle(IPC.fileRename, async (_e, p: { from: string; toName: string }) =>
|
||||
fs2().rename(p.from, p.toName));
|
||||
ipcMain.handle(IPC.fileMove, async (_e, p: { src: string; destDir: string }) =>
|
||||
fs2().move(p.src, p.destDir));
|
||||
ipcMain.handle(IPC.fileDelete, async (_e, p: { path: string; recursive: boolean }) =>
|
||||
fs2().delete(p.path, p.recursive));
|
||||
ipcMain.handle(IPC.fileImport, async (_e, p: { sources: string[]; destDir: string }) => {
|
||||
// 若 sources 为空,弹出系统选择对话框
|
||||
let sources = p.sources;
|
||||
if (sources.length === 0) {
|
||||
const r = await dialog.showOpenDialog({ properties: ['openFile', 'multiSelections'], filters: [{ name: 'Markdown', extensions: ['md'] }] });
|
||||
if (r.canceled) return { ok: [], failed: [] };
|
||||
sources = r.filePaths;
|
||||
}
|
||||
return fs2().importFiles(sources, p.destDir);
|
||||
});
|
||||
|
||||
ipcMain.handle(IPC.docRead, async (_e, p: { path: string }) => fs2().readDoc(p.path));
|
||||
ipcMain.handle(IPC.docWrite, async (_e, p: { path: string; meta: any; body: string }) =>
|
||||
fs2().writeDoc({ path: p.path, meta: p.meta, body: p.body }));
|
||||
ipcMain.handle(IPC.search, async (_e, p: { query: string }) => vault.searchService?.search(p.query) ?? []);
|
||||
ipcMain.handle(IPC.tagStats, async () => vault.searchService?.tagStats() ?? []);
|
||||
ipcMain.handle(IPC.graph, async () => {
|
||||
const fs2 = vault.fileService;
|
||||
if (!fs2) return { nodes: [], edges: [] };
|
||||
const tree = await fs2.listTree();
|
||||
return buildGraphData(fs2.getRoot(), tree);
|
||||
});
|
||||
|
||||
ipcMain.handle(IPC.copyMd, async (_e, p: { path: string }) => {
|
||||
const fs2 = vault.fileService; if (!fs2) return '';
|
||||
const { body } = await fs2.readDoc(p.path);
|
||||
clipboard.writeText(body);
|
||||
return body;
|
||||
});
|
||||
|
||||
ipcMain.handle(IPC.docReveal, async (_e, p: { path: string }) => {
|
||||
const fs2 = vault.fileService;
|
||||
if (!fs2) return;
|
||||
shell.showItemInFolder(nodePath.join(fs2.getRoot(), p.path));
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user