feat: restore Tolaria reading layer and page links
This commit is contained in:
parent
6fb1c02ddd
commit
2457821eeb
@ -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` 的新克隆上完整复现。
|
||||
|
||||
## 研发规则
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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<HTMLAnchorElement>('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)
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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 改动无直接路径,
|
||||
后续应在正式依赖安装环境中单独复跑,不把它们误记为本次功能通过。
|
||||
Loading…
x
Reference in New Issue
Block a user