From 51105f6e53b11d8e7c352bc80c009a73fc61db92 Mon Sep 17 00:00:00 2001 From: KiriAky 107 Date: Mon, 7 Sep 2026 22:33:10 +0800 Subject: [PATCH] =?UTF-8?q?feat(desktop):=20=E5=AE=8C=E6=88=90=E7=BC=96?= =?UTF-8?q?=E8=BE=91=E5=BF=AB=E6=8D=B7=E9=94=AE=E4=B8=8E=E8=AD=A6=E5=91=8A?= =?UTF-8?q?=E6=A1=86=E8=8F=9C=E5=8D=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Tauri-Rust桌面客户端需求说明-第三阶段.md | 2 + frontend/src-tauri/tauri.conf.json | 2 +- .../components/common/TitleBarMenu.spec.ts | 9 ++++ .../src/components/common/TitleBarMenu.vue | 46 ++++++++++++---- .../editor/VisualMarkdownEditor.spec.ts | 10 ++++ .../features/editor/VisualMarkdownEditor.vue | 25 ++++++++- .../src/services/platform/lifecycle.spec.ts | 20 +++++++ frontend/src/services/platform/lifecycle.ts | 54 +++++++++++++++++-- 8 files changed, 151 insertions(+), 17 deletions(-) create mode 100644 frontend/src/services/platform/lifecycle.spec.ts diff --git a/docs/contracts/Tauri-Rust桌面客户端需求说明-第三阶段.md b/docs/contracts/Tauri-Rust桌面客户端需求说明-第三阶段.md index 8f674e7..149e5f2 100644 --- a/docs/contracts/Tauri-Rust桌面客户端需求说明-第三阶段.md +++ b/docs/contracts/Tauri-Rust桌面客户端需求说明-第三阶段.md @@ -25,6 +25,8 @@ 无边框桌面窗口在标题栏下方固定显示“文件 / 编辑 / 段落 / 格式 / 视图 / 主题 / 帮助”菜单行。段落菜单提供正文、六级标题、列表、引用、代码块和属性导入;格式菜单复用编辑器已有的加粗、斜体、行内代码、代码块、公式及警告框命令;主题菜单列出当前已安装主题并可进入主题管理。保存使用 `Ctrl+S`;撤销和重做沿用编辑器已有的 `Ctrl+Z` 与 `Ctrl+Shift+Z`,菜单只调用相同编辑器命令,不额外注册按键监听,以免一次按键执行两次。 +除编辑器原有的加粗、斜体、撤销和重做外,桌面键表还注册正文/标题 `Ctrl+0…6`、删除线 `Alt+Shift+5`、行内代码 `Ctrl+反引号`、链接 `Ctrl+K`、代码块 `Ctrl+Shift+K`、公式块 `Ctrl+Shift+M`、行内公式 `Ctrl+Shift+L`、表格 `Ctrl+Alt+T`、默认警告框 `Ctrl+Alt+C`、分割线 `Ctrl+Shift+H`、三类列表和引用。`Ctrl+Alt+P` 在源码模式执行属性导入,在写作模式创建或聚焦 YAML Front Matter。警告框菜单列出 `note`、`abstract`、`info`、`todo`、`tip`、`important`、`success`、`question`、`warning`、`failure`、`danger`、`bug`、`example`、`quote` 十四种样式。 + Markdown 格式(含警告框)与元数据共用 `editorCommandService` 的能力查询和命令分发接口,详见 [警告框与桌面编辑命令开发说明](../development/警告框与桌面编辑命令开发说明.md)。Host 根据 supported / enabled 显隐或禁用菜单,不能把已预留的命令 ID 当作已可执行能力;原生快捷键不绕过活动文档、只读和冲突检查。 ### 2.2 输入与转换规则 diff --git a/frontend/src-tauri/tauri.conf.json b/frontend/src-tauri/tauri.conf.json index bf4cdd1..f9c874e 100644 --- a/frontend/src-tauri/tauri.conf.json +++ b/frontend/src-tauri/tauri.conf.json @@ -10,7 +10,7 @@ "frontendDist": "../dist" }, "app": { - "windows": [{"label": "main", "title": "NotesAgent Preview", "width": 1200, "height": 800, "minWidth": 640, "minHeight": 480, "decorations": false}], + "windows": [{"label": "main", "title": "NotesAgent Preview", "width": 1280, "height": 960, "minWidth": 720, "minHeight": 700, "center": true, "decorations": false}], "security": { "csp": "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data: blob: http://127.0.0.1:8000; font-src 'self' data:; connect-src ipc: http://ipc.localhost http://127.0.0.1:8000; frame-src 'self' blob:; object-src 'none'; base-uri 'self'", "capabilities": ["main"] diff --git a/frontend/src/components/common/TitleBarMenu.spec.ts b/frontend/src/components/common/TitleBarMenu.spec.ts index 1123703..33e5085 100644 --- a/frontend/src/components/common/TitleBarMenu.spec.ts +++ b/frontend/src/components/common/TitleBarMenu.spec.ts @@ -58,4 +58,13 @@ describe('桌面顶部段落菜单', () => { expect(wrapper.get('.import-properties').text()).toContain('Ctrl+Alt+P') wrapper.unmount() }) + + it('格式菜单列出十四种警告框和元数据快捷键', async () => { + const wrapper = mount(TitleBarMenu) + await wrapper.get('[data-menu="format"] .menu-trigger').trigger('click') + expect(wrapper.findAll('.callout-options button')).toHaveLength(14) + expect(wrapper.get('.submenu-heading').text()).toContain('Ctrl+Alt+C') + expect(wrapper.get('.metadata-command').text()).toContain('Ctrl+Alt+P') + wrapper.unmount() + }) }) diff --git a/frontend/src/components/common/TitleBarMenu.vue b/frontend/src/components/common/TitleBarMenu.vue index 7ec630f..23a649e 100644 --- a/frontend/src/components/common/TitleBarMenu.vue +++ b/frontend/src/components/common/TitleBarMenu.vue @@ -14,6 +14,11 @@ const open = ref(null) const bar = ref(null) const error = ref('') const shortcut = computed(() => /Mac|iPhone|iPad/.test(navigator.platform) ? '⌘⌥P' : 'Ctrl+Alt+P') +const callouts = [ + ['note', '笔记'], ['abstract', '摘要'], ['info', '信息'], ['todo', '待办'], ['tip', '技巧'], + ['important', '重要'], ['success', '成功'], ['question', '问题'], ['warning', '警告'], + ['failure', '失败'], ['danger', '危险'], ['bug', '缺陷'], ['example', '示例'], ['quote', '引用'], +] as const function enabled(id: EditorCommandId) { return getEditorCommandCapabilities().find(item => item.id === id)?.enabled ?? false @@ -31,6 +36,11 @@ async function command(id: EditorCommandId, params?: unknown) { if (result.ok) close() else error.value = t('当前编辑器无法执行此命令。', 'The active editor cannot run this command.') } +async function metadataCommand() { + const imported = await executeEditorCommand('editor.import-note-properties') + if (imported.ok) { close(); return } + await command('editor.metadata.edit') +} async function save() { await editor.save(); close() } function setMode(mode: 'source' | 'wysiwyg') { editor.setMode(mode); close() } function toggleTheme() { theme.toggleTheme(); close() } @@ -63,14 +73,14 @@ onBeforeUnmount(() => window.removeEventListener('pointerdown', dismiss))