diff --git a/apps/tolaria/README.md b/apps/tolaria/README.md index ec51e59..1dedf18 100644 --- a/apps/tolaria/README.md +++ b/apps/tolaria/README.md @@ -39,6 +39,12 @@ - 恢复 toggle heading / toggle list 折叠块入口; - 增加批注块、关系卡和路径包,继续复用可携带 Markdown callout 协议; - 保留现有代码块、引用、Mermaid、表格、白板与媒体块。 +8. `0008-fix-restore-internal-note-links-and-reading-rhythm.patch` + - 将 Notion 导出的相对 Markdown 页面链接接回 Tolaria 内部导航; + - 普通单击直接打开目标笔记,外部网址仍保留 `⌘ + 点击`; + - 增强引用提示面板、段落节奏、代码块、表格与行内代码层次。 +9. `0009-test-lock-in-readable-editor-theme-defaults.patch` + - 固化更宽的阅读列与带颜色的行内代码主题默认值。 ## 恢复与验证 @@ -50,12 +56,14 @@ git am /path/to/0004-20260715-tolaria-lightweight-themes-drag-fix.patch git am /path/to/0005-Add-portable-callout-page-blocks.patch git am /path/to/0006-fix-make-Guanghu-home-and-themes-visible.patch git am /path/to/0007-feat-complete-portable-page-block-set.patch +git am /path/to/0008-fix-restore-internal-note-links-and-reading-rhythm.patch +git am /path/to/0009-test-lock-in-readable-editor-theme-defaults.patch pnpm build pnpm lint ``` `0001`、`0002` 保留为早期两补丁拆分档案;只有在不使用 `0003` -原型系列时才单独应用。上述 `0003 → 0007` 顺序已于 2026-07-17 +原型系列时才单独应用。上述 `0003 → 0009` 顺序已于 2026-07-17 在服务器最新 `bingshuo/guanghu@514ab19` 的新克隆上完整复现。 ## 研发规则 diff --git a/apps/tolaria/modules/02-knowledge-rendering/README.md b/apps/tolaria/modules/02-knowledge-rendering/README.md index 193b00c..f738664 100644 --- a/apps/tolaria/modules/02-knowledge-rendering/README.md +++ b/apps/tolaria/modules/02-knowledge-rendering/README.md @@ -5,11 +5,19 @@ 当前冰湖 UI 补丁位于 [`../../patches/`](../../patches/)。 -## 下一批内容块 +## 当前恢复状态 + +- 彩色 callout、批注、关系卡、路径包与折叠块已经恢复; +- 普通引用现在显示为有背景、有边界的提示面板; +- 标题、正文、代码块和表格之间已恢复清楚的阅读节奏; +- Notion 导出的相对 `.md` 页面链接会在 Tolaria 内普通单击跳转; +- 外部网址仍使用 `⌘ + 点击`,避免编辑时误开浏览器。 + +## 已完成内容块 冰朔在 2026-07-16 反馈:当前页面太单一,缺少类似 Notion 的内容块能力,尤其是彩色提示块和高亮代码块。 -下一批优先实现: +首批完成项: ```text 1. 高亮代码块 @@ -21,8 +29,6 @@ 7. 媒体 / 图表块 ``` -明日待办入口见: +当前验收入口见: -```text -docs/NEXT-TODO-20260717.md -``` +- [NEXT-TODO-20260717 · 明日待办](../../../../docs/NEXT-TODO-20260717.md) diff --git a/apps/tolaria/patches/0008-fix-restore-internal-note-links-and-reading-rhythm.patch b/apps/tolaria/patches/0008-fix-restore-internal-note-links-and-reading-rhythm.patch new file mode 100644 index 0000000..401a6ad --- /dev/null +++ b/apps/tolaria/patches/0008-fix-restore-internal-note-links-and-reading-rhythm.patch @@ -0,0 +1,246 @@ +From 5dcdcd8a6b2a983af46d37f5e89d522402badcbd Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=E5=86=B0=E6=9C=94?= <565183519@qq.com> +Date: Fri, 17 Jul 2026 11:12:33 +0800 +Subject: [PATCH 8/9] fix: restore internal note links and reading rhythm + +--- + src/components/Editor.css | 6 ++-- + src/components/EditorTheme.css | 32 ++++++++++++++++-- + .../useEditorLinkActivation.test.tsx | 25 ++++++++++++++ + src/components/useEditorLinkActivation.ts | 33 ++++++++++++++++++- + src/theme.json | 20 +++++------ + 5 files changed, 99 insertions(+), 17 deletions(-) + +diff --git a/src/components/Editor.css b/src/components/Editor.css +index 11a0813..910def1 100644 +--- a/src/components/Editor.css ++++ b/src/components/Editor.css +@@ -87,10 +87,10 @@ + grid-template-columns: 4px minmax(0, 1fr); + gap: 12px; + width: 100%; +- margin: 0.45rem 0; +- padding: 11px 13px 11px 0; ++ margin: 0.8rem 0; ++ padding: 15px 16px 15px 0; + border: 1px solid color-mix(in srgb, var(--tolaria-callout-accent) 28%, var(--border)); +- border-radius: 8px; ++ border-radius: 10px; + background: var(--tolaria-callout-bg); + } + +diff --git a/src/components/EditorTheme.css b/src/components/EditorTheme.css +index 862e474..3885574 100644 +--- a/src/components/EditorTheme.css ++++ b/src/components/EditorTheme.css +@@ -350,6 +350,12 @@ + cursor: text; + } + ++.editor__blocknote-container .bn-editor a[href*=".md"] { ++ cursor: pointer; ++ text-decoration-thickness: 1px; ++ text-underline-offset: 0.18em; ++} ++ + /* --- Wikilinks (override from Editor.css with theme vars) --- */ + .editor__blocknote-container .wikilink { + color: var(--inline-styles-wikilink-color); +@@ -657,9 +663,15 @@ body.tldraw-whiteboard-fullscreen-open { + background-color: var(--editor-code-block-background) !important; + border: 1px solid var(--editor-code-block-border); + color: var(--editor-code-block-text) !important; ++ border-radius: 10px; ++ box-shadow: 0 1px 0 color-mix(in srgb, var(--editor-code-block-border) 55%, transparent); + position: relative; + } + ++.editor__blocknote-container .bn-block-outer:has(> .bn-block > [data-content-type="codeBlock"]) { ++ margin-block: 10px 16px; ++} ++ + .editor__code-block-copy { + position: absolute; + z-index: 4; +@@ -681,6 +693,8 @@ body.tldraw-whiteboard-fullscreen-open { + + .editor__blocknote-container .bn-block-content[data-content-type="codeBlock"] > pre { + color: inherit; ++ scrollbar-color: color-mix(in srgb, var(--accent-blue) 48%, transparent) transparent; ++ scrollbar-width: thin; + } + + .editor__blocknote-container .bn-block-content[data-content-type="codeBlock"] > div > select { +@@ -706,12 +720,24 @@ body.tldraw-whiteboard-fullscreen-open { + /* --- Blockquote --- */ + .editor__blocknote-container [data-content-type="blockquote"], + .editor__blocknote-container blockquote { +- border-inline-start: var(--blockquote-border-left-width) solid var(--blockquote-border-left-color); +- padding-inline-start: var(--blockquote-padding-left); ++ background: color-mix(in srgb, var(--accent-blue) 12%, var(--bg-primary)); ++ border: 1px solid color-mix(in srgb, var(--accent-blue) 28%, var(--border-primary)); ++ border-inline-start: 4px solid var(--blockquote-border-left-color); ++ border-radius: 10px; ++ padding: 16px 18px; + margin-top: var(--blockquote-margin-vertical); + margin-bottom: var(--blockquote-margin-vertical); + color: var(--blockquote-color); +- font-style: var(--blockquote-font-style); ++ font-style: normal; ++} ++ ++.editor__blocknote-container .bn-block-outer:has(> .bn-block > [data-content-type="table"]) { ++ margin-block: 12px 18px; ++} ++ ++.editor__blocknote-container [data-content-type="table"] table { ++ border-radius: 8px; ++ overflow: hidden; + } + + /* --- Table --- */ +diff --git a/src/components/useEditorLinkActivation.test.tsx b/src/components/useEditorLinkActivation.test.tsx +index ab3b62a..bbfcaee 100644 +--- a/src/components/useEditorLinkActivation.test.tsx ++++ b/src/components/useEditorLinkActivation.test.tsx +@@ -128,6 +128,31 @@ describe('useEditorLinkActivation', () => { + expect(modifiedClick.defaultPrevented).toBe(true) + }) + ++ it('opens relative Markdown note links inside Tolaria on a plain click', async () => { ++ const { container, onNavigateWikilink } = renderHarness() ++ const link = appendUrl(container, '../Migration/Related%20Page%20abc123.md#current-status') ++ ++ const plainClick = dispatchMouseEvent(link, 'click') ++ ++ expect(plainClick.defaultPrevented).toBe(true) ++ expect(mockOpenLocalFile).not.toHaveBeenCalled() ++ await Promise.resolve() ++ expect(onNavigateWikilink).toHaveBeenCalledWith('../Migration/Related Page abc123') ++ }) ++ ++ it('consumes Markdown note link mousedown before editor internals can select it', async () => { ++ const { container, onNavigateWikilink } = renderHarness() ++ const link = appendUrl(container, 'docs/Related.md') ++ ++ const mouseDown = dispatchMouseEvent(link, 'mousedown') ++ const click = dispatchMouseEvent(link, 'click') ++ ++ expect(mouseDown.defaultPrevented).toBe(true) ++ expect(click.defaultPrevented).toBe(true) ++ await Promise.resolve() ++ expect(onNavigateWikilink).toHaveBeenCalledWith('docs/Related') ++ }) ++ + it('opens modified URL mousedown before editor internals see stale link nodes', () => { + const { container } = renderHarness() + const link = appendUrl(container, 'https://example.com') +diff --git a/src/components/useEditorLinkActivation.ts b/src/components/useEditorLinkActivation.ts +index f29c624..79a2dad 100644 +--- a/src/components/useEditorLinkActivation.ts ++++ b/src/components/useEditorLinkActivation.ts +@@ -26,6 +26,24 @@ function resolveAnchorHref(target: HTMLElement) { + return target.closest('a[href]')?.getAttribute('href')?.trim() ?? null + } + ++function decodeLinkPath(path: string) { ++ try { ++ return decodeURIComponent(path) ++ } catch { ++ return path ++ } ++} ++ ++function resolveMarkdownNoteTarget(href: string) { ++ const path = href.split(/[?#]/u, 1)[0]?.trim() ?? '' ++ if (!path || path.startsWith('//') || /^[a-z][a-z\d+.-]*:/iu.test(path)) return null ++ ++ const decodedPath = decodeLinkPath(path).replace(/\\/gu, '/') ++ if (!/\.md(?:own)?$/iu.test(decodedPath)) return null ++ ++ return decodedPath.replace(/\.md(?:own)?$/iu, '') ++} ++ + function blurActiveEditable(container: HTMLElement) { + const active = document.activeElement + if (!(active instanceof HTMLElement) || !container.contains(active)) return +@@ -84,7 +102,15 @@ function handleEditorLinkClick( + } + + const href = resolveAnchorHref(target) +- if (href) activateUrl(event, href, vaultPath) ++ if (!href) return ++ ++ const markdownTarget = resolveMarkdownNoteTarget(href) ++ if (markdownTarget) { ++ activateWikilink(event, container, markdownTarget, onNavigateWikilink) ++ return ++ } ++ ++ activateUrl(event, href, vaultPath) + } + + function handleEditorLinkMouseDown(event: MouseEvent, vaultPath?: string): string | null { +@@ -97,6 +123,11 @@ function handleEditorLinkMouseDown(event: MouseEvent, vaultPath?: string): strin + } + + const href = resolveAnchorHref(target) ++ if (href && resolveMarkdownNoteTarget(href)) { ++ consumeEditorLinkEvent(event) ++ return null ++ } ++ + if (hasFollowModifier(event) && href) { + activateUrl(event, href, vaultPath) + return href +diff --git a/src/theme.json b/src/theme.json +index 84b5e4c..92999d2 100644 +--- a/src/theme.json ++++ b/src/theme.json +@@ -1,12 +1,12 @@ + { + "editor": { + "fontFamily": "'Inter', -apple-system, BlinkMacSystemFont, sans-serif", +- "fontSize": 15, +- "lineHeight": 1.5, +- "maxWidth": 820, ++ "fontSize": 16, ++ "lineHeight": 1.65, ++ "maxWidth": 880, + "paddingHorizontal": 40, +- "paddingVertical": 20, +- "paragraphSpacing": 8, ++ "paddingVertical": 28, ++ "paragraphSpacing": 12, + "dividerFollowedByHeadingMarginTop": 8 + }, + "headings": { +@@ -80,11 +80,11 @@ + "code": { + "fontFamily": "'SF Mono', 'Fira Code', monospace", + "fontSize": 14, +- "backgroundColor": "var(--bg-hover-subtle)", +- "paddingHorizontal": 4, ++ "backgroundColor": "color-mix(in srgb, var(--accent-blue) 11%, var(--bg-hover-subtle))", ++ "paddingHorizontal": 5, + "paddingVertical": 2, + "borderRadius": 3, +- "color": "var(--text-secondary)" ++ "color": "var(--accent-blue)" + }, + "link": { + "color": "var(--accent-blue)", +@@ -100,8 +100,8 @@ + "blockquote": { + "borderLeftWidth": 3, + "borderLeftColor": "var(--accent-blue)", +- "paddingLeft": 16, +- "marginVertical": 12, ++ "paddingLeft": 18, ++ "marginVertical": 16, + "color": "var(--text-secondary)", + "fontStyle": "italic" + }, +-- +2.50.1 (Apple Git-155) + diff --git a/apps/tolaria/patches/0009-test-lock-in-readable-editor-theme-defaults.patch b/apps/tolaria/patches/0009-test-lock-in-readable-editor-theme-defaults.patch new file mode 100644 index 0000000..1763c19 --- /dev/null +++ b/apps/tolaria/patches/0009-test-lock-in-readable-editor-theme-defaults.patch @@ -0,0 +1,38 @@ +From 59ce6261d3dff070a138934d8038e0a935c003c7 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=E5=86=B0=E6=9C=94?= <565183519@qq.com> +Date: Fri, 17 Jul 2026 11:15:45 +0800 +Subject: [PATCH 9/9] test: lock in readable editor theme defaults + +--- + src/hooks/useTheme.test.ts | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/src/hooks/useTheme.test.ts b/src/hooks/useTheme.test.ts +index aecc7bd..27d1f6c 100644 +--- a/src/hooks/useTheme.test.ts ++++ b/src/hooks/useTheme.test.ts +@@ -3,11 +3,11 @@ import { renderHook } from '@testing-library/react' + import { useEditorTheme } from './useTheme' + + describe('useEditorTheme', () => { +- it('keeps inline code on the muted editor surface without exporting code block overrides', () => { ++ it('gives inline code a subtle accent surface without exporting code block overrides', () => { + const { result } = renderHook(() => useEditorTheme()) + + expect(result.current.cssVars['--inline-styles-code-background-color']).toBe( +- 'var(--bg-hover-subtle)' ++ 'color-mix(in srgb, var(--accent-blue) 11%, var(--bg-hover-subtle))' + ) + expect(result.current.cssVars['--code-blocks-background-color']).toBeUndefined() + }) +@@ -27,6 +27,6 @@ describe('useEditorTheme', () => { + it('exports the default editor max width', () => { + const { result } = renderHook(() => useEditorTheme()) + +- expect(result.current.cssVars['--editor-max-width']).toBe('820px') ++ expect(result.current.cssVars['--editor-max-width']).toBe('880px') + }) + }) +-- +2.50.1 (Apple Git-155) + diff --git a/docs/NEXT-TODO-20260717.md b/docs/NEXT-TODO-20260717.md index 5e8d693..8c227ea 100644 --- a/docs/NEXT-TODO-20260717.md +++ b/docs/NEXT-TODO-20260717.md @@ -31,9 +31,7 @@ Actions 页面能识别 build-windows-manual.yml。 参考文档: -```text -docs/ops/GITEA-ACTIONS-RUNNER-WINDOWS-INTERNAL.md -``` +- [Gitea Actions Runner · Windows 内测安装包构建](ops/GITEA-ACTIONS-RUNNER-WINDOWS-INTERNAL.md) ## 2 · 光湖 App 页面内容块增强 @@ -96,19 +94,12 @@ TypeScript、ESLint 与 Vite production build 通过。 相关模块: -```text -apps/tolaria/modules/02-knowledge-rendering/README.md -research/progress/HLP-DEV-0001-ICE-GL-INFINITY-TOLARIA-UI-BASELINE.md -research/progress/HLP-DEV-0002-ICE-GL-INFINITY-HOLOLAKE-ERA-PROTOTYPE-REVIEW.md -``` +- [HLP-MOD-0002 · 视觉与知识渲染](../apps/tolaria/modules/02-knowledge-rendering/README.md) +- [HLP-DEV-0001 · Tolaria UI 基线](../research/progress/HLP-DEV-0001-ICE-GL-INFINITY-TOLARIA-UI-BASELINE.md) +- [HLP-DEV-0002 · HoloLake Era 原型评审](../research/progress/HLP-DEV-0002-ICE-GL-INFINITY-HOLOLAKE-ERA-PROTOTYPE-REVIEW.md) ## 3 · 明日开工入口 -```text -先补 runner: - docs/ops/GITEA-ACTIONS-RUNNER-WINDOWS-INTERNAL.md - -页面内容块已进入验收与打包: - apps/tolaria/modules/02-knowledge-rendering/README.md - docs/NEXT-TODO-20260717.md -``` +1. [先补 Gitea Actions Runner](ops/GITEA-ACTIONS-RUNNER-WINDOWS-INTERNAL.md) +2. [继续验收视觉与知识渲染模块](../apps/tolaria/modules/02-knowledge-rendering/README.md) +3. [回到本页继续执行](NEXT-TODO-20260717.md) diff --git a/research/progress/HLP-DEV-0005-NOTION-READING-AND-PAGE-LINK-RESTORATION.md b/research/progress/HLP-DEV-0005-NOTION-READING-AND-PAGE-LINK-RESTORATION.md new file mode 100644 index 0000000..b8a4d21 --- /dev/null +++ b/research/progress/HLP-DEV-0005-NOTION-READING-AND-PAGE-LINK-RESTORATION.md @@ -0,0 +1,48 @@ +# HLP-DEV-0005 · Notion 阅读层与页面关系恢复 + +> 日期:2026-07-17 +> +> 关联模块:`HLP-MOD-0002` +> +> 状态:0.1.4 Review 已完成原生验收 + +## 问题 + +Tolaria 软件壳本身正常,但知识页出现两项回退: + +1. 标题、提示、正文、代码和表格挤在一起,普通引用只剩一根细线; +2. Notion 导出的 `[页面](相对路径.md)` 没有接到 Tolaria 内部导航,普通单击没有反应。 + +原生 `[[wikilink]]` 实现并未消失。真正缺失的是普通 Markdown 页面链接到 +Tolaria 页面路由的兼容层;当前页面还把部分参考路径放在代码块里,代码文本本来也不可点击。 + +## 恢复内容 + +- 相对 `.md` / `.markdown` 链接普通单击后直接打开目标笔记; +- 解码 Notion 导出文件名里的 URL 编码,并去除查询串、锚点和扩展名后交给现有页面解析器; +- 不改变外部网址与附件的安全交互; +- 普通引用升级为蓝色提示面板,增加背景、边框、圆角和内边距; +- 增大正文行距、段落间距和阅读列宽; +- 代码块、表格、callout 与行内代码恢复独立视觉层次; +- `NEXT-TODO-20260717` 的参考路径已改为真实 Markdown 页面链接。 + +## 补丁与构建 + +- `apps/tolaria/patches/0008-fix-restore-internal-note-links-and-reading-rhythm.patch` +- `apps/tolaria/patches/0009-test-lock-in-readable-editor-theme-defaults.patch` +- 桌面验收包:`HoloLake Era 0.1.4 Review` +- Bundle ID:`com.guanghu.desktop.review.20260717.page` +- DMG SHA-256:`846884e8…c66bc303a` + +## 验证 + +- 回归测试先失败后修复:相对 Markdown 页面链接普通单击跳转; +- 定向 Vitest:16 项通过; +- ESLint、TypeScript 与 Vite production build 通过; +- Tauri Apple Silicon App 与 DMG 构建通过; +- 原生视觉验收:元信息提示面板、段落节奏、代码块层次可见; +- CodeScene / Codacy:本机仍无 MCP、CLI 或 API 环境,未伪造结果。 + +全量 Vitest 运行了 4822 项,其中 4809 项通过、13 项失败;2 项是主题快照预期, +已随补丁更新并通过。其余失败来自 5 个既有测试文件,和本次链接、CSS 改动无直接路径, +后续应在正式依赖安装环境中单独复跑,不把它们误记为本次功能通过。