- 将不直接执行的 process-reference 文档迁入各域 reference 目录 - 更新 design/README、AGENTS 和总序文档,固定 process/draft/reference/done 目录语义 - 修正活跃文档中指向旧 process 位置的参考链接 验证:git diff --check;codegraph sync .
938 lines
52 KiB
Markdown
938 lines
52 KiB
Markdown
# 5-7 [reference] Wolai 页面树与主编辑器体验复刻方案 v1
|
||
|
||
> 更新时间:2026-04-30
|
||
>
|
||
> 当前状态:`reference`。本文只保留 Wolai 体验复刻目标和取证基线;持续执行与安全边界以 `08-wolai-aline-test-flow` 和 `wolai-aline` skill 为准。
|
||
|
||
> **Wolai-aline 执行口径更新(2026-05-21):** 本文只保留体验复刻任务拆解和产品目标。所有 Wolai 对标测试、浏览器取证、编辑权限、安全边界、subagent 使用、截图复核和 smoke 补齐,统一以 `/home/lix/.codex/skills/wolai-aline` 与 `/mnt/Data1T/mnote/design/08-wolai-aline-test-flow/reference/wolai-aline-test-flow-v1.md` 为准。若本文旧段落与该 skill 冲突,以 skill 为准。
|
||
>
|
||
> 关联文档:
|
||
> - `/mnt/Data1T/mnote/ARCHITECTURE.md`
|
||
> - `/mnt/Data1T/mnote/design/01-05-current-priority-overview.md`
|
||
> - `/mnt/Data1T/mnote/design/01-tree-first-graph-kernel/process/1-tree-first-graph-kernel-v1.md`
|
||
> - `/mnt/Data1T/mnote/design/02-convex-rust-long-term-architecture/done/2-2-local-first-workspace-convex-control-plane-v1.md`
|
||
> - `/mnt/Data1T/mnote/design/old/02-convex-rust-long-term-architecture/process/2-tree-first-graph-convex-rust-long-term-architecture-v1.md`(历史过渡背景)
|
||
> - `/mnt/Data1T/mnote/design/03-rust-web/process/3-rust-web-long-term-architecture-v1.md`
|
||
> - `/mnt/Data1T/mnote/design/03-rust-web/process/3-3-rust-web-tree-realtime-event-stream-v1.md`
|
||
> - `/mnt/Data1T/mnote/design/04-tree-domain/done/4-2-sidebar-pagetree-filetree-product-interaction-contract-v1.md`
|
||
> - `/mnt/Data1T/mnote/design/04-tree-domain/done/4-6-tree-command-protocol-cutover-stage2-v1.md`
|
||
> - `/mnt/Data1T/mnote/design/05-editor-mainline/reference/5-2-tiptap-notion-like-template-adoption-v1.md`
|
||
> - `/mnt/Data1T/mnote/design/05-editor-mainline/done/5-4-leptos-tiptap-mainline-correction-v1.md`
|
||
> - `/mnt/Data1T/mnote/design/05-editor-mainline/reference/5-5-page-aggregate-single-truth-alignment-v1.md`
|
||
> - `/mnt/Data1T/mnote/design/05-editor-mainline/process/5-6-page-aggregate-alignment-checklist-v1.md`
|
||
> - `/mnt/Data1T/mnote/design/05-editor-mainline/process/5-9-wolai-aline-continuous-checklist-v1.md`
|
||
> - `/mnt/Data1T/mnote/design/05-editor-mainline/done/5-5-1-page-aggregate-contract-v1.md`
|
||
|
||
## 1. 文档目的
|
||
|
||
这份方案只处理一件事:
|
||
|
||
> **以真实 Wolai 页面为视觉和交互 benchmark,继续还原 mnote 的页面树与主编辑器体验。**
|
||
|
||
本轮目标不是重新定义系统架构,也不是把 Wolai 的全部协作能力完整复制过来,而是把当前 `3000` 页面在视觉密度、布局节奏、页面树反馈、主编辑器输入体验上继续向 Wolai 靠近。
|
||
|
||
约束如下:
|
||
|
||
- UI 以像素级复刻为目标。
|
||
- 功能以“高频路径可用、复杂能力可降级”为原则。
|
||
- 当前项目保留“文件树 / Explorer”创新,不要求删除。
|
||
- 默认主编辑器继续是页面内 `leptos-tiptap` island。
|
||
- `BlockNote` 只作为 `recycle/` 历史参考 / 对照材料,不重新变成默认方向。
|
||
- 树、页面结构、标题、正文、页面设置不能在 UI 层再拼第二份真相。
|
||
|
||
这份文档应放在 `05-editor-mainline/process`,因为它的核心不是 Rust Web 壳复刻,也不是单独的树命令合同,而是:
|
||
|
||
> **围绕 Page Aggregate,把页面树、页头、页面设置、正文编辑器统一成接近 Wolai 的产品体验。**
|
||
|
||
---
|
||
|
||
## 2. 本轮取证基线
|
||
|
||
### 2.1 真实 Wolai 参考
|
||
|
||
本轮参考页面:
|
||
|
||
- `https://www.wolai.com/wolai/xhqeop8UHpVTMUSVmgz8nq`
|
||
- `https://www.wolai.com/wolai/qN1Bh9YjLAXs8bxCJoAJ6C`
|
||
- `https://www.wolai.com/liaibo/ikFSSM1a4GgvmHBYFCNfVd`
|
||
|
||
本轮已保存的截图与快照:
|
||
|
||
- `/mnt/Data1T/mnote/tmp/wolai-page1.png`
|
||
- `/mnt/Data1T/mnote/tmp/wolai-page1-snapshot.md`
|
||
- `/mnt/Data1T/mnote/tmp/wolai-page2.png`
|
||
- `/mnt/Data1T/mnote/tmp/wolai-page2-snapshot.md`
|
||
- `/mnt/Data1T/mnote/tmp/wolai-compare/wolai-target-1392x1213.png`
|
||
- `/mnt/Data1T/mnote/tmp/wolai-compare/wolai-target-snapshot.md`
|
||
- `/mnt/Data1T/mnote/tmp/wolai-compare/wolai-public-search-overlay.png`
|
||
- `/mnt/Data1T/mnote/tmp/wolai-compare/wolai-public-search-results-skill.png`
|
||
- `/mnt/Data1T/mnote/tmp/wolai-compare/wolai-public-presentation-mode.png`
|
||
- `/mnt/Data1T/mnote/tmp/wolai-compare/wolai-public-start-edit-overlay.png`
|
||
- `/mnt/Data1T/mnote/tmp/wolai-compare/wolai-public-comment-panel.png`
|
||
- `/mnt/Data1T/mnote/tmp/wolai-compare/wolai-public-good-night-mode.png`
|
||
- `/mnt/Data1T/mnote/tmp/wolai-compare/wolai-help-first-viewport-current.png`
|
||
- `/mnt/Data1T/mnote/tmp/wolai-compare/wolai-help-sidebar-filter-page-reference.png`
|
||
- `/mnt/Data1T/mnote/tmp/wolai-compare/wolai-help-search-overlay.png`
|
||
- `/mnt/Data1T/mnote/tmp/wolai-compare/wolai-help-search-results-page-reference.png`
|
||
- `/mnt/Data1T/mnote/tmp/wolai-compare/wolai-help-search-result-navigated-block-reference.png`
|
||
- `/mnt/Data1T/mnote/tmp/wolai-compare/wolai-help-embedded-page-reference-hover.png`
|
||
- `/mnt/Data1T/mnote/tmp/wolai-compare/wolai-help-block-reference-page-snapshot.md`
|
||
- `/mnt/Data1T/mnote/wolai-basic-editing-reference.png`
|
||
- `/mnt/Data1T/mnote/wolai-basic-editing-reference-snapshot.md`
|
||
- `/mnt/Data1T/mnote/wolai-hermes-public-hover-block.png`
|
||
- `/mnt/Data1T/mnote/wolai-hermes-start-edit-login-dialog.png`
|
||
- `/mnt/Data1T/mnote/wolai-hermes-comment-panel.png`
|
||
- `/mnt/Data1T/mnote/wolai-hermes-presentation-mode.png`
|
||
- `/mnt/Data1T/mnote/wolai-hermes-good-night-mode.png`
|
||
|
||
用户在内置浏览器中提供的登录态截图也作为本轮重要视觉证据:该截图展示了真实个人空间的长页面树、当前页 `Hermes` 选中态、完整顶部图标区、底部垃圾桶 / 模板中心入口、右下角 AI / 帮助浮动入口。
|
||
|
||
补充说明:历史截图和用户提供的登录态截图只作为现有证据池,不再作为后续任务的唯一验收依据。该 owner 态菜单不是单纯样式:它包含“在右侧边栏打开 / 移动到 / 嵌入到 / 复制访问链接 / 复制页面引用链接 / 复制页面 ID / 拷贝副本 / 重命名 / 删除”等页面树动作,应进入后续交互合同,而不是只当成截图复刻。
|
||
|
||
2026-04-30 口径更新:后续取证统一从 `wolai-aline` skill 启动。已知技术路径是 `Playwright Node + /opt/google/chrome/chrome + /mnt/Data1T/mnote/tmp/wolai-playwright-profile`,但本文不再维护独立自动化方案。当前 Hermes 测试页已授权用于最小编辑验证;owner 首屏、搜索浮层、顶部更多菜单、正文块 hover、`.hover-block-menu` 块菜单等行为,都必须通过 subagent 浏览器取证、主线程截图复核和差异矩阵重新确认。`dokobot doko read --local --reuse-tab` 可作为登录态 read evidence,但不能替代键鼠操作验收。
|
||
|
||
### 2.2 当前 mnote 参考
|
||
|
||
当前本地 `3000` 截图:
|
||
|
||
- `/mnt/Data1T/mnote/tmp/wolai-compare/local-3000-playwright-1392x1213.png`
|
||
- `/mnt/Data1T/mnote/tmp/wolai-compare/local-3000-first-viewport.png`
|
||
- `/mnt/Data1T/mnote/tmp/wolai-compare/local-3000-dom-snapshot.txt`
|
||
|
||
当前本地页面已经具备接近 Wolai 的基本壳:
|
||
|
||
- 左侧 workspace / 快捷操作 / 页面树 / 底部入口。
|
||
- 右侧顶部 breadcrumb / 页面操作。
|
||
- 中央文档页标题和正文区。
|
||
- 右下角帮助与 AI 入口。
|
||
|
||
但与真实 Wolai 仍有显著差距:
|
||
|
||
- 左侧树的视觉密度、选中态、图标系统、滚动条和层级缩进仍不够像 Wolai。
|
||
- 文档主内容的起始位置、标题尺寸、正文列宽、页头留白和默认元信息展示不一致。
|
||
- 顶栏按钮体系与 Wolai 的 owner / published 两种状态还没有明确分型。
|
||
- 主编辑器的块级 hover 手柄、slash、浮动工具条和块菜单需要按 Wolai / Notion 风格继续收口。
|
||
- 当前页面树、页头、正文、页面设置仍必须继续服从 Page Aggregate 单一真源主线,不能为了 UI 快速复刻重新制造局部状态。
|
||
|
||
### 2.3 2026-04-30 subagent 基线复核
|
||
|
||
本轮已按 `wolai-aline` skill 派 subagent 同时操作 Wolai Hermes 与本地 `3000`。工具链结论:`Node.js Playwright + /opt/google/chrome/chrome` 可操作两个目标;Wolai 通过 `/mnt/Data1T/mnote/tmp/wolai-playwright-profile` 进入 owner 登录态,本地 `3000` 返回可用页面。无源码改动,证据写入:
|
||
|
||
- `/mnt/Data1T/mnote/tmp/wolai-editor-parity/baseline-20260430/`
|
||
- `/mnt/Data1T/mnote/tmp/wolai-editor-parity/doc-baseline-mini/`
|
||
|
||
主线程已复核关键截图:
|
||
|
||
- Wolai 首屏:`/mnt/Data1T/mnote/tmp/wolai-editor-parity/doc-baseline-mini/wolai-initial.png`
|
||
- 本地首屏:`/mnt/Data1T/mnote/tmp/wolai-editor-parity/doc-baseline-mini/local-initial.png`
|
||
- Wolai 搜索:`/mnt/Data1T/mnote/tmp/wolai-editor-parity/baseline-20260430/wolai-03-search-modal-controls-filled.png`
|
||
- 本地搜索:`/mnt/Data1T/mnote/tmp/wolai-editor-parity/baseline-20260430/local-03-search-modal-controls-filled.png`
|
||
- Wolai 块 hover:`/mnt/Data1T/mnote/tmp/wolai-editor-parity/baseline-20260430/wolai-08-block-hover-insert-entry.png`
|
||
- 本地块 hover:`/mnt/Data1T/mnote/tmp/wolai-editor-parity/baseline-20260430/local-14-block-hover-insert-entry.png`
|
||
- Wolai 编辑清理后:`/mnt/Data1T/mnote/tmp/wolai-editor-parity/baseline-20260430/wolai-14-title-suffix-after.png`
|
||
|
||
当前差异矩阵:
|
||
|
||
| 项 | Wolai Hermes | 本地 `3000` | 后续处理 |
|
||
| --- | --- | --- | --- |
|
||
| 首屏入口 | owner 登录态直接显示 `Hermes` 正文页,标题、正文、页面树同屏 | `task130` 后已改为根页直接进入 document shell + editor island;历史上曾停留在聚合 / 预览壳 | 后续仅继续收口侧栏数据、视觉密度与 owner/published 状态差异 |
|
||
| 侧栏数据与选中态 | 真实空间树,当前页在 `个人 / 软件开发 / Hermes` 路径下,红色选中态明显 | anonymous 示例树,当前页为 `1111`,行密度和图标体系仍偏本地化 | Sidebar checklist 必须同时验视觉和真实 active path |
|
||
| 搜索入口 | 左侧放大镜可打开全局搜索;本轮 `Ctrl+K` 未稳定打开,`Ctrl+P` 在另一轮可 toggle | 顶栏搜索可打开;侧栏搜索曾修为 modal;`Ctrl+P` 可 toggle | 搜索任务不得只测一个入口;需记录每个入口、快捷键和 URL |
|
||
| 搜索控件 | modal 居中,遮罩、结果行、快捷键提示完整;switch 视觉可见 | modal 结构接近,`role="switch"` 可测;不同输入下结果为空或本地数据结果 | switch 默认状态必须同时记录截图和 `aria-checked`,结果态需拆数据差异与控件差异 |
|
||
| 搜索结果 | 输入 `Hermes` 命中页面和块,结果有红色高亮和路径 | 本地同词可出现空态或示例数据结果,取决于当前页面数据 | 建立固定本地 fixture 或 smoke 种子,不能用随机工作区数据验视觉 |
|
||
| 正文编辑区 | 首屏正文 `contenteditable=true`,标题也可编辑 | 当前已在首屏直接出现主编辑区;剩余差异转为标题区、正文密度与块交互细节 | 文档画布任务继续聚焦主编辑器体验,而不是首屏入口纠偏 |
|
||
| 编辑焦点风险 | Wolai 标题和正文均可编辑,测试输入曾误落到标题,已清理 | 本地输入 / 撤销可完成,但页面结构不同 | editable-test mode 前必须先断言焦点 block 类型,优先在正文末尾新建唯一测试块 |
|
||
| 块 hover | 正文块左侧出现轻量块控制入口,视觉很克制 | 本地显示 `+` 与拖拽/块句柄按钮,但位置、密度、内容列差异明显 | E2-E4 必须以截图和 hover 点位复核,不可只看按钮存在 |
|
||
|
||
这轮基线说明:当前最大偏差不是单个按钮,而是本地普通文档首屏仍像“聚合入口 / 预览页”,Wolai 则直接进入可读写的页面正文。后续 P0/P1 checklist 必须优先处理这个入口语义,否则搜索、块 hover、编辑器测试都会测到不同页面状态。
|
||
|
||
### 2.4 Wolai-aline 取证与验收统一口径
|
||
|
||
本节旧版“published / owner readonly / sandbox mutation”分层已经收口到 `wolai-aline` skill。后续执行不再从本文推导测试策略,统一遵循:
|
||
|
||
- Codex skill:`/home/lix/.codex/skills/wolai-aline`
|
||
- 流程文档:`/mnt/Data1T/mnote/design/08-wolai-aline-test-flow/reference/wolai-aline-test-flow-v1.md`
|
||
- 失败模式:`/home/lix/.codex/skills/wolai-aline/references/failure-patterns.md`
|
||
|
||
现行要点:
|
||
|
||
- 每个 Wolai-aline 小任务都必须先取 Wolai 基线,再做本地 RED smoke,再实现,再由 subagent 浏览器复测,最后主线程复核截图和差异矩阵。
|
||
- 浏览器取证必须使用 subagent;subagent 默认只读,但当任务明确需要编辑器行为时,可在当前 Hermes 测试页进入 `Hermes editable-test mode` 做最小编辑验证。
|
||
- 当前 Hermes 测试页 `https://www.wolai.com/liaibo/ikFSSM1a4GgvmHBYFCNfVd` 已授权用于最小编辑验证;可以创建带唯一标记的临时测试块、输入少量测试文本、验证 slash / toolbar / block menu / 快捷键等编辑器行为。
|
||
- 编辑验证必须记录编辑前后截图、动作链、输入内容和清理状态。若安全清理有风险,不扩大操作,报告残留测试内容。
|
||
- 即使在 Hermes 测试页,也禁止未经确认地删除、移动、归档、发布、评论、改权限或批量修改既有非测试内容。
|
||
- 其他 Wolai 页面仍默认只读;写入仍需用户提供沙盒页 URL 和明确授权。
|
||
- 对标不能只看文案或 DOM 是否存在;必须主动检查截图中的控件形态、状态、hover/active、快捷键 toggle、关闭路径和 URL 跳转。
|
||
|
||
硬门槛:
|
||
|
||
- 不能把 subagent 文本结论当作最终对齐证据;主线程必须复核截图。
|
||
- 如果截图里有肉眼可见差异,先补 smoke 捕获差异,再改实现。
|
||
- 任何新发现的稳定失败模式,都要沉淀到 `wolai-aline` skill 的 `failure-patterns.md`。
|
||
|
||
### 2.5 `基本编辑能力` 操作矩阵
|
||
|
||
`https://www.wolai.com/wolai/qN1Bh9YjLAXs8bxCJoAJ6C` 是 Wolai 对“主编辑器基础操作”的官方内容页。本页不只是说明文字,它给出了后续 `3000` 必须能复现的主编辑器操作矩阵:
|
||
|
||
| 操作 | Wolai 参考页说明 | 当前对 `Hermes` 可自动化验证性 | `3000` 后续验收要求 |
|
||
| --- | --- | --- | --- |
|
||
| 普通文本输入 / 回车 / 光标移动 | 像普通文本编辑器一样输入、换行、移动光标 | 可用 Hermes editable-test mode 取基线 | 在本地编辑态 smoke 中验证输入、换行、保存后刷新保持 |
|
||
| 块模型 | 文本、列表项、图片、文件等都是“块” | owner 态只读已可观察块 hover 手柄和 block menu | 本地每个块需有稳定 block id 与 hover target |
|
||
| 拖动块 | 块左侧 `::` 图标可拖动,并显示辅助线 | owner 态只读可观察手柄;真实拖动是写入动作,按 Hermes editable-test mode 最小验证 | 本地必须验证拖拽预览、横向 drop line、分栏 drop line |
|
||
| Esc 选中块 | 输入态按 `esc` 选中当前块,上下方向键切换,`shift + 上/下` 多选,`enter` 回编辑 | 可用 Hermes editable-test mode 取基线 | 本地必须有 block selection state、keyboard smoke |
|
||
| `cmd/ctrl + A` | 输入态第一次选中当前块文字,第二次选中所有块;块选中态直接选中所有块 | 可用 Hermes editable-test mode 取基线 | 本地必须区分 text selection 与 block selection |
|
||
| 上 / 下插入块 | hover 左侧 `::` 上方 / 下方点击 `+`;或 `esc` 选中块后按 `a` / `b` | owner 态可观察手柄;真实插入可用 Hermes editable-test mode 做最小验证 | Hermes editable-test mode 必须验证 before / after 插入与 `Esc, a` / `Esc, b` |
|
||
| 块布局显示 | `cmd/ctrl + shift + U` 显示 / 隐藏块布局虚线框 | 可用 Hermes editable-test mode 取基线 | 本地需有布局 overlay smoke,至少验证虚线框开关 |
|
||
| 分栏 | 拖块到另一个块左 / 右,辅助线由横线变竖线,松开形成分栏 | 可用 Hermes editable-test mode 取拖拽基线 | 本地可先做 drop preview,不要求完整分栏持久化一次到位 |
|
||
| 转换块 | 通过块菜单 `转换为`、快捷键、或 slash 命令转换块类型 | owner 态已可打开块菜单并看到 `转换为`;执行转换可用 Hermes editable-test mode 做最小验证 | 本地必须验证块菜单中的 `转换为` 入口与至少 paragraph/headings/list 的转换 |
|
||
| 复制 / 粘贴 | 文本或块选中后 `cmd/ctrl + C/V`,匹配样式为 `cmd/ctrl + shift + V` | 可用 Hermes editable-test mode 取基线 | 本地需验证纯文本粘贴与块复制的最小路径 |
|
||
| 缩进 / 取消缩进 | `tab` 缩进成为上一块子元素,`shift + tab` 取消缩进 | 可用 Hermes editable-test mode 取基线 | 本地需验证 list / paragraph 缩进语义与 tree projection 不冲突 |
|
||
| 文本样式工具条 | 选中文字出现工具条,支持粗体、斜体、下划线、删除线、行内代码、颜色、链接、页面引用、转换块类型 | 可用 Hermes editable-test mode 取基线 | 本地需验证 selection toolbar 出现、按钮视觉与 command dispatch |
|
||
| slash 菜单 | 输入 `/` 唤起快捷命令菜单;空行左侧 `+` 也可创建块 | 可用 Hermes editable-test mode 取基线 | 本地需验证 `/` 菜单、搜索过滤、选择条目插入块 |
|
||
|
||
本轮已能在目标页 `Hermes` 自动化验证的 published 操作:
|
||
|
||
- 顶栏搜索:打开搜索 modal,输入 `技能`,出现 `共1条匹配结果`。
|
||
- 开始编辑:点击后出现 `登录以编辑` 对话框,文案为“登录后,您才可以编辑该页面,是否继续?”,包含 `取消` 和 `继续`。
|
||
- 评论:点击后打开右侧评论面板,tab 为 `未解决(0)`,空态为 `还没有评论`。
|
||
- 演示模式:点击后进入 presentation view,隐藏侧栏 / 顶栏,画面只保留大字号内容和演示控件。
|
||
- Good Night:右下角主题按钮切换暗色 token。
|
||
- 正文块 hover:owner 态可在块左侧看到手柄,并可点击 `.hover-block-menu` 打开块菜单;上 / 下插入块等写入路径按 `wolai-aline` 的 Hermes editable-test mode 验收。
|
||
|
||
因此,后续 `3000` 的主编辑器验收不能只做“截图像”。每个主编辑器改动都必须绑定一个可执行操作:
|
||
|
||
- 如果是 published 态能力,必须先在 Wolai published 目标页执行同类操作,再在 `3000` 执行同类操作。
|
||
- 如果是 owner/edit 态能力,必须先通过 `wolai-aline` 流程在 Wolai 目标页执行同类操作,再在 `3000` 执行同类操作。
|
||
- 如果是 owner/edit 写入能力,当前 Hermes 测试页允许最小编辑验证;其他 Wolai 页面写入必须先取得沙盒页 URL 与明确授权。
|
||
- 如果动作是在当前 Hermes 测试页做最小编辑验证,例如输入测试文本、创建临时测试块、验证 slash / toolbar / block menu / 快捷键,可按 `Hermes editable-test mode` 执行并记录前后证据;删除、移动、归档、发布、评论、改权限或批量修改既有非测试内容仍必须在动作发生前单独确认。
|
||
|
||
---
|
||
|
||
## 3. 当前代码落点
|
||
|
||
### 3.1 工作区壳与页面树
|
||
|
||
相关入口:
|
||
|
||
- `/mnt/Data1T/mnote/wolai-frontend/src/app/(app)/layout.tsx`
|
||
- `/mnt/Data1T/mnote/wolai-frontend/src/components/app-layout-shell.tsx`
|
||
- `/mnt/Data1T/mnote/wolai-frontend/src/lib/server/sidebar-data.ts`
|
||
- `/mnt/Data1T/mnote/wolai-frontend/src/hooks/use-sidebar-data.ts`
|
||
- `/mnt/Data1T/mnote/wolai-frontend/src/lib/tree-stream/use-sidebar-tree-stream.ts`
|
||
- `/mnt/Data1T/mnote/wolai-frontend/src/components/sidebar/sidebar.tsx`
|
||
- `/mnt/Data1T/mnote/wolai-frontend/src/components/sidebar/tree-shell-surface.tsx`
|
||
- `/mnt/Data1T/mnote/wolai-frontend/src/components/sidebar/tree-shell-host.tsx`
|
||
- `/mnt/Data1T/mnote/wolai-frontend/src/components/sidebar/tree-shell-dom-host.tsx`
|
||
- `/mnt/Data1T/mnote/wolai-frontend/src/lib/tree-projection.ts`
|
||
|
||
判断:
|
||
|
||
- `Sidebar` 外壳和 `tree-shell-*` 是页面树像素复刻的主战场。
|
||
- `tree-shell-dom-host` 承担当前树行渲染与本地展开/选中/拖拽反馈,不应再回到旧 React 树渲染器上做长期改造。
|
||
- `tree-projection` 是页面树 UI 的直接 projection 输入,不应在 UI 层重新推导排序、层级或合法性。
|
||
|
||
### 3.2 文档页与主编辑器
|
||
|
||
相关入口:
|
||
|
||
- `/mnt/Data1T/mnote/wolai-frontend/src/app/(app)/documents/[id]/page.tsx`
|
||
- `/mnt/Data1T/mnote/wolai-frontend/src/lib/documents/page-aggregate-loader.ts`
|
||
- `/mnt/Data1T/mnote/wolai-frontend/src/lib/documents/page-aggregate-builder.ts`
|
||
- `/mnt/Data1T/mnote/wolai-frontend/src/components/editor/document-shell.tsx`
|
||
- `/mnt/Data1T/mnote/wolai-frontend/src/components/editor/document-content.tsx`
|
||
- `/mnt/Data1T/mnote/wolai-frontend/src/components/editor/document-read-view.tsx`
|
||
- `/mnt/Data1T/mnote/wolai-frontend/src/components/editor/leptos-tiptap-island-editor-host.tsx`
|
||
- `/mnt/Data1T/mnote/wolai-frontend/src/lib/documents/page-option-semantics.ts`
|
||
|
||
判断:
|
||
|
||
- `document-content.tsx` 决定 Wolai 页面顶部留白、标题、正文容器、页面元信息、右侧 inspector 和 fallback banner。
|
||
- `document-read-view.tsx` 决定阅读态块样式、任务块、标题层级、附件 / 引用 / 子页面等展示。
|
||
- `leptos-tiptap-island-editor-host.tsx` 决定编辑态输入 surface、保存、slash、工具条、块菜单和 editor runtime page options 的接缝。
|
||
- `page-option-semantics.ts` 是页面设置能否真实进入主编辑器运行时的判断边界,不能只改设置面板外观。
|
||
|
||
### 3.3 全局视觉 token
|
||
|
||
相关入口:
|
||
|
||
- `/mnt/Data1T/mnote/wolai-frontend/src/app/globals.css`
|
||
|
||
判断:
|
||
|
||
- 像素复刻必须先固定字体、字号、行高、颜色、圆角、hover/active token。
|
||
- 当前全局字体口径有冲突:前面偏 Wolai 系统字体,后面 `html` 又偏 `Inter`。若不先收口字体栈,后续所有标题宽度、行高、树行密度都会偏。
|
||
|
||
---
|
||
|
||
## 4. Wolai 视觉目标合同
|
||
|
||
### 4.1 字体与基础排版
|
||
|
||
目标字体栈:
|
||
|
||
- 优先中文系统字体:`PingFang SC`、`Noto Sans CJK SC`、`Microsoft YaHei UI`。
|
||
- 英文字体跟随系统 sans-serif,不单独强行使用 `Inter` 作为全局主字体。
|
||
|
||
目标字号与行高:
|
||
|
||
| 区域 | 字号 | 行高 | 字重 |
|
||
| --- | --- | --- | --- |
|
||
| 页面主标题 | 34px | 44px | 600 |
|
||
| 首页 / 帮助页大分组标题 | 28px | 36px | 600 |
|
||
| 次级分组标题 | 18px | 26px | 600 |
|
||
| 正文基础文字 | 16px | 24px | 400 |
|
||
| 左侧树条目 | 14px | 24px | 400 |
|
||
| 顶栏文字按钮 | 14px | 21px | 400 |
|
||
| 搜索框文字 | 14px | 22px | 400 |
|
||
|
||
目标颜色:
|
||
|
||
| 语义 | 颜色 |
|
||
| --- | --- |
|
||
| 主标题 | `rgb(30, 30, 30)` |
|
||
| 正文 | `rgba(0, 0, 0, 0.85)` |
|
||
| 次级文字 | `rgba(0, 0, 0, 0.65)` |
|
||
| 弱提示 | `rgba(0, 0, 0, 0.35)` |
|
||
| 左侧背景 | `rgb(245, 245, 245)` |
|
||
| 选中强调文字 | `rgb(207, 86, 89)` |
|
||
| 选中强调背景 | `rgba(207, 86, 89, 0.15)` |
|
||
| 顶栏 hover 背景 | `rgb(245, 245, 245)` |
|
||
|
||
### 4.2 左侧页面树
|
||
|
||
Wolai 目标特征:
|
||
|
||
- 左侧栏宽度约 `248px - 260px`,浅灰底。
|
||
- 顶部空间名行高度约 `40px`,头像为 28px 左右方形圆角块。
|
||
- 顶部快捷图标横排,图标弱色,hover 只加浅灰底。
|
||
- 搜索框尺寸约 `236px x 32px`,圆角 `4px`,内边距约 `5px 32px 5px 12px`。
|
||
- 树行高度约 `32px`,内容行内 icon / arrow / title 对齐。
|
||
- 当前项使用红字 + 淡红底,背景覆盖整行可点击区域。
|
||
- 未选中 hover 使用同一红色体系,但透明度更轻。
|
||
- 缩进按层级稳定递增,不靠文本空格。
|
||
- 滚动条细、贴右侧、弱灰色,不抢视觉。
|
||
- 底部垃圾桶 / 模板中心固定在侧栏底部,边界线轻。
|
||
|
||
当前 mnote 允许保留:
|
||
|
||
- `我的页面 / Explorer` 双模式。
|
||
- 文件树作为创新入口。
|
||
- AI / Graph / 文件等自有入口。
|
||
|
||
但这些创新必须满足:
|
||
|
||
- 视觉密度服从 Wolai 左侧栏。
|
||
- 选中态和 hover 态与页面树统一。
|
||
- 不因为多了文件树而破坏 Wolai 的 32px 行节奏。
|
||
|
||
### 4.3 顶部导航与页面操作区
|
||
|
||
Wolai 目标特征:
|
||
|
||
- 顶栏高度约 `40px`。
|
||
- 左侧是菜单按钮 + breadcrumb。
|
||
- breadcrumb 使用图标 / 文本 / 分隔符,字号 `14px`,颜色弱。
|
||
- 右侧按钮是弱文本 / 图标按钮,padding 约 `2px 7px`,圆角 `3px`。
|
||
- owner 态可见:公开状态、收藏、演示、评论、关系、邀请、历史、更多。
|
||
- published 态可见:演示模式、搜索、开始编辑、评论、复制、开始使用 wolai。
|
||
- 顶栏 hover 不用重色按钮,只加浅灰底。
|
||
|
||
mnote 当前差距:
|
||
|
||
- 顶栏右侧已经有 Public、收藏、历史、AI、搜索、更多,但与 Wolai owner 态的 icon 序列和视觉轻重不同。
|
||
- published 视角与 owner 视角没有明确组件分型。
|
||
- breadcrumb 与页面内容标题之间的垂直节奏还需要更接近 Wolai。
|
||
|
||
### 4.4 主文档画布
|
||
|
||
Wolai 目标特征:
|
||
|
||
- 主内容列在大屏中不贴左,普通文档正文列宽约 `760px`。
|
||
- 登录态 `Hermes` 页面首屏标题大约从 y=118px 开始。
|
||
- 标题为 `34px / 44px / 600`,颜色接近 `rgb(30,30,30)`。
|
||
- 标题下方正文块紧跟,不默认显示额外元信息行和横向分割线。
|
||
- 普通正文块使用 `16px / 24px`。
|
||
- 任务块 checkbox 轻边框,小尺寸,和文本基线对齐。
|
||
- 空白区域非常克制,不用额外卡片、阴影或说明文案。
|
||
|
||
mnote 当前差距:
|
||
|
||
- 当前本地文档页标题偏靠左且偏低,内容列与真实 Wolai 相比没有稳定对齐。
|
||
- 当前显示“个人空间 / 工作区首页”元信息和横向分割线,这不是 Wolai 普通文档页默认观感。
|
||
- 历史上首屏正文首块曾是“打开当前页面”链接;`task130` 之后这条差异已收口,当前重点转向主编辑区密度、块 hover 和 toolbar 细节。
|
||
- 右下角绿色 AI 浮动按钮比 Wolai 更重,真实 Wolai 是更轻的 AI 方形入口和问号入口。
|
||
|
||
### 4.5 主编辑器块级体验
|
||
|
||
Wolai / Notion-like 目标:
|
||
|
||
- slash 是主编辑入口之一,菜单跟随 caret。
|
||
- 选中文本才出现浮动工具条。
|
||
- hover 块时只露出左侧手柄,不自动弹菜单。
|
||
- 点击左侧手柄才出现块菜单。
|
||
- 块菜单核心动作是 `turn into / duplicate / delete / drag`。
|
||
- `turn into` 同时存在于文本工具条语境和块菜单语境,但命令上下文不同。
|
||
- 块 identity 由 Rust `EditorBlock.block_id` 持有;Tiptap `UniqueID` 只作为浏览器 runtime 辅助。
|
||
- 页面引用、块引用、嵌入默认位置最终必须回到 Page Aggregate / Rust artifact 边界。
|
||
|
||
#### 4.5.1 hover 上 / 下插入块
|
||
|
||
用户补充的登录态截图显示,Wolai 的块 hover 体验还有一个非常关键的细节:当鼠标停在块左侧手柄区域时,当前块行会出现很轻的淡红背景,手柄上方和下方分别出现一条短横线;继续 hover 短横线时,短横线变成 `+`,并显示黑色 tooltip:
|
||
|
||
- `在上方插入块`,快捷键提示为 `Esc, a`。
|
||
- `在下方插入块`,快捷键提示为 `Esc, b`。
|
||
|
||
这个交互不是装饰性按钮,而是 Wolai 块编辑器的“块级插入光标”。它要和块选中、拖拽手柄、块菜单、slash 菜单、快捷键一起设计,不能只在正文左侧放一个常驻加号。
|
||
|
||
当前仓库已有可复用参考:
|
||
|
||
- `/mnt/Data1T/mnote/recycle/wolai-frontend/src/components/editor/blocknote-editor.tsx` 中,旧 `BlockNoteView` 通过 `SideMenuController` 注入自定义 `CustomSideMenu`。
|
||
- `/mnt/Data1T/mnote/recycle/wolai-frontend/src/components/editor/menus/CustomSideMenu.tsx` 中,`WolaiDragHandleWithInsert` 已实现上方插入、下方插入、手柄菜单、菜单冻结、空段落加号打开 slash、截图失焦状态重置。
|
||
- `/mnt/Data1T/mnote/wolai-frontend/src/components/editor/leptos-tiptap-inline-editor-host.tsx` 当前已有较简化的块手柄和菜单,但没有复刻上 / 下短横线插入态。
|
||
- `/mnt/Data1T/mnote/rust/spikes/leptos-tiptap-spike/src/lib.rs` 已有 leptos/tiptap 手柄雏形,但当前样式偏重,并且 `insert_top_level_paragraph_after_html` 只支持 after 插入。
|
||
|
||
旧 BlockNote 实现中最值得迁移的机制:
|
||
|
||
- 插入控件不是放在块容器上下边界,而是围绕手柄中心点计算位置:上方插入、手柄、下方插入三者垂直对齐。
|
||
- 非 hover 状态显示 `12px` 左右短横线,hover 状态切换为 `Plus` 图标。
|
||
- 插入按钮尺寸约 `16px`,手柄按钮约 `22px`,按钮之间保持小间距,避免插入按钮和拖拽手柄互相遮挡 pointer event。
|
||
- `hoverArea` 要比按钮视觉范围更大,避免鼠标从手柄移到插入按钮时控件闪烁。
|
||
- 手柄菜单打开时需要冻结 hover 状态,否则菜单会因鼠标离开块行而消失。
|
||
- 空段落的中心 `+` 点击应等同打开 slash 菜单,而不是直接创建第二个空段落。
|
||
- 截图、窗口失焦、页面隐藏时要重置 hover / frozen 状态,避免手柄卡住或消失。
|
||
- 思维导图、在线表格、附件这类高块或内部接管鼠标事件的块,需要允许常驻或更稳定的插入控件显示策略。
|
||
|
||
迁移到 `leptos-tiptap` 时,目标行为如下:
|
||
|
||
- hover 普通块:左侧只显示三段控件,上短横线 / 拖拽手柄 / 下短横线;不自动打开块菜单。
|
||
- hover 上短横线:短横线变 `+`,tooltip 显示 `在上方插入块` 和 `Esc, a`。
|
||
- hover 下短横线:短横线变 `+`,tooltip 显示 `在下方插入块` 和 `Esc, b`。
|
||
- 点击上方 `+`:在当前块前插入空段落,焦点进入新段落。
|
||
- 点击下方 `+`:在当前块后插入空段落,焦点进入新段落。
|
||
- 按 `Esc` 进入块选择 / 块聚焦状态后,按 `a` 执行 before 插入,按 `b` 执行 after 插入。
|
||
- 点击拖拽手柄才打开块菜单;拖拽手柄本身不和上 / 下插入按钮抢 hover。
|
||
|
||
实现边界:
|
||
|
||
- `leptos-tiptap` 需要补齐 before / after 两个编辑器命令;不能继续只有 after HTML 插入。
|
||
- 第一阶段可以先在 runtime 内插入空段落并保存正文,但正式命令口径应回到 Page Aggregate / Rust editor block model,例如 `page.body.insertBlockBefore` / `page.body.insertBlockAfter` 或等价 `EditorCommand::InsertBlock { position: Before | After }`。
|
||
- UI 层可以持有当前 hover block、active block、tooltip、menu open 这些临时状态,但不能把插入后的块 id 只存在前端临时结构里。
|
||
- 视觉上应优先复刻 Wolai:轻灰短横线、浅灰 hover 背景、黑色小 tooltip、淡红块 hover 底色;不要沿用 spike 中 32px、大圆角、重阴影、绿色 accent 的手柄样式。
|
||
|
||
首轮不追求:
|
||
|
||
- 完整协作光标。
|
||
- 完整评论系统。
|
||
- 完整表格编辑体验。
|
||
- 完整图片 / 附件上传链。
|
||
- 完整权限和发布链路。
|
||
- 完整全局搜索索引。
|
||
|
||
### 4.6 操作态菜单与浮层
|
||
|
||
真实 Wolai 的体验不能只看静态首屏,必须把操作后出现的浮层也纳入复刻合同。
|
||
|
||
#### 4.6.1 页面树 owner 态菜单
|
||
|
||
用户提供的登录态截图显示,页面树当前页 `Hermes` 的管理菜单为白色浮层,宽约 220px,圆角和阴影都很轻,菜单项按语义分组:
|
||
|
||
- 打开位置:`在右侧边栏打开`,带快捷键提示。
|
||
- 页面组织:`移动到...`、`嵌入到...`。
|
||
- 引用复制:`复制访问链接`、`复制页面引用链接`、`复制页面ID`。
|
||
- 页面副本:`拷贝副本`。
|
||
- 危险或编辑动作:`重命名`、`删除`。
|
||
|
||
这说明页面树行不只是导航节点,还承载页面操作入口。mnote 复刻时必须把这些动作映射到正式命令:
|
||
|
||
- `在右侧边栏打开`:UI state + route / side panel state。
|
||
- `移动到...`:`tree.subtree.move`。
|
||
- `嵌入到...`:`tree.node.embed` 或 Page Aggregate embed plan。
|
||
- `复制页面引用链接`:生成 page reference artifact,不应只复制 URL。
|
||
- `重命名`:`page.head.updateTitle`,并同步 tree projection。
|
||
- `删除`:必须走归档 / 删除确认链,不能前端直接移除节点。
|
||
|
||
首轮可以先复刻菜单壳、分组、hover、禁用态和快捷键提示;真实移动、嵌入、删除等高风险动作按后续命令合同逐步接入。
|
||
|
||
#### 4.6.2 搜索弹层
|
||
|
||
公开页搜索和帮助中心搜索都使用居中 modal overlay:
|
||
|
||
- 背景整体变暗,侧栏和正文保持原位但失焦。
|
||
- 搜索框宽约 680px,高约 56px,白底,圆角轻,阴影明显但不厚重。
|
||
- 输入后出现选项行:`仅匹配标题`、`精确匹配`、`页面内搜索`。
|
||
- 结果区显示匹配数量和快捷键说明:`Ctrl + Enter 新窗口打开 / Alt + Enter 右侧边栏打开`。
|
||
- 结果行左侧是页面 / 块图标,中间是标题与命中摘要,命中词使用红色高亮,右侧显示所在页面或空间。
|
||
|
||
mnote 需要把搜索拆成两层:
|
||
|
||
- 左侧栏 `快速筛选页面`:只过滤当前页面树,结果直接替换树列表。
|
||
- 顶栏搜索 modal:跨页面 / 页面内搜索入口,支持结果列表、快捷键提示、打开方式提示。
|
||
|
||
首轮可以用本地 projection / 当前页面块快照生成结果,不必先接全局索引;但视觉结构、选项行和打开方式提示应先复刻。
|
||
|
||
#### 4.6.3 published 态操作
|
||
|
||
真实 published 态存在几类弱操作入口:
|
||
|
||
- `演示模式`:点击后隐藏侧栏和顶栏,画布变成大字号演示页,只保留主题切换入口。
|
||
- `开始编辑`:未登录时弹出“登录以编辑”确认框,红色主按钮为继续,取消为弱按钮。
|
||
- `评论`:右侧滑出评论面板,顶部有 `未解决(0)` tab、筛选下拉、关闭按钮,空态居中。
|
||
- `Good Night`:右下角主题按钮直接切换暗色主题,暗色主题不重排页面,只替换 token。
|
||
|
||
mnote 首轮不必做完整发布权限,但应该保留这套状态分型:
|
||
|
||
- owner 编辑态。
|
||
- published 阅读态。
|
||
- presentation 演示态。
|
||
- comment side panel。
|
||
- light / dark token 切换。
|
||
|
||
这些状态大多是 UI state,但 `开始编辑` 是否可用、评论权限、发布状态必须来自页面权限或发布 projection,不应在前端硬猜。
|
||
|
||
### 4.7 帮助中心页的内在逻辑
|
||
|
||
`https://www.wolai.com/wolai/xhqeop8UHpVTMUSVmgz8nq` 不是普通内容页,它展示了 Wolai 页面系统的内在组织方式。
|
||
|
||
观察结论:
|
||
|
||
- 左侧页面树是帮助主题的完整目录,根页面下挂大量子页面,既是导航也是信息架构。
|
||
- 正文入口页不是自由排版海报,而是由页面链接、分组标题、四列目录块、子页面引用组成的“文档门户”。
|
||
- `快速上手 / 常见问题 / 视频教程 / 使用技巧短视频` 是高频入口。
|
||
- “让我们先掌握一些基础”下的四列目录把页面按能力分组:基础操作、基础块类型、进阶块类型、媒体与文件。
|
||
- 目录项本质上是页面引用 / 页面链接,不是普通文本。
|
||
- 搜索可以跨整个帮助中心返回页面和块级结果,命中词红色高亮。
|
||
- 搜索结果可以按快捷键在新窗口或右侧边栏打开,说明“右侧边栏打开”是 Wolai 页面导航模型的一等入口。
|
||
|
||
更重要的是,帮助中心中的“块引用”页直接定义了编辑器的语义模型:
|
||
|
||
- 行内块引用:在文字中间引用另一个块,底部有圆点虚线,不能直接编辑,点击跳转原始出处。
|
||
- 嵌入块引用:以独立块引用另一个块,左侧有圆点虚线,可以直接查看或部分编辑,但不能删除被引用块本身。
|
||
- 页面引用:当对象是页面时,菜单从“复制块引用链接”变为“复制页面引用链接”。
|
||
- 行内页面引用:在文本内显示页面标题。
|
||
- 嵌入页面引用:独立引用块显示页面图标和标题。
|
||
- 复制粘贴路径:块菜单复制引用链接,再粘贴生成引用。
|
||
- 快捷键路径:`esc` 选中块,`H` 复制行内块引用链接,`Q` 复制嵌入块引用链接。
|
||
- 嵌入到路径:`cmd/alt + shift + G` 打开“嵌入到”弹窗,搜索目标页面,把块嵌入到目标页面。
|
||
- 当前页面位置快速引用:编辑时输入 `[[` 搜索页面,添加页面行内引用。
|
||
- 右侧边栏拖拽引用:从右侧边栏拖拽产生引用。
|
||
- 引用预览和别名:悬浮行内块引用出现预览,小窗顶部可以设置别名,别名末尾显示箭头。
|
||
|
||
因此,mnote 不应把“引用”当成一个简单链接样式。它至少需要在 Page Aggregate / editor block model 中区分:
|
||
|
||
- `inline_page_reference`
|
||
- `inline_block_reference`
|
||
- `embedded_page_reference`
|
||
- `embedded_block_reference`
|
||
- `reference_alias`
|
||
- `reference_preview`
|
||
- `reference_source_block_id`
|
||
- `reference_target_page_id`
|
||
|
||
首轮实现可以降级,但语义模型不能降级成普通 URL。
|
||
|
||
---
|
||
|
||
## 5. 复刻范围分级
|
||
|
||
### 5.1 P0:先做像素基线
|
||
|
||
P0 只做最影响首屏观感的部分:
|
||
|
||
- 全局字体栈与基础字号行高收口。
|
||
- Sidebar 宽度、背景、顶部栏、树行高度、选中态、hover 态。
|
||
- 顶栏高度、breadcrumb、右侧动作按钮轻量化。
|
||
- 文档标题位置、字号、行高、正文列宽。
|
||
- 默认隐藏普通文档页中的额外元信息行和分割线。
|
||
- 右下角浮动入口减重。
|
||
- 在 `1392 x 1213` 视口下对齐真实 Wolai 截图。
|
||
|
||
### 5.2 P1:补齐高频交互体验
|
||
|
||
P1 做用户会立刻感知的交互:
|
||
|
||
- 页面树展开 / 折叠动画和 hover action。
|
||
- 当前页祖先链展开和选中态保持。
|
||
- 搜索框视觉与本地过滤体验。
|
||
- 树行上下文菜单的视觉壳和核心动作入口。
|
||
- 顶栏搜索 modal 的选项行、结果行、命中高亮和快捷键提示。
|
||
- 评论侧栏、登录编辑确认框、演示模式的基础状态切换。
|
||
- 文档页进入编辑后,slash、浮动工具条、左侧手柄、上 / 下插入块、块菜单的基础可用体验。
|
||
- 页面标题编辑后,标题 / breadcrumb / sidebar / page tree / file tree 保持一致。
|
||
|
||
### 5.3 P2:接近 Wolai 的产品完整感
|
||
|
||
P2 做复杂但可逐步推进的部分:
|
||
|
||
- 拖拽排序与 drop feedback。
|
||
- page reference / block reference 的正式插入体验。
|
||
- `[[` 页面引用搜索、`嵌入到...` 弹窗、右侧边栏打开 / 拖拽引用。
|
||
- 引用预览和别名。
|
||
- 右侧评论、历史、关系图入口的真实面板。
|
||
- published / owner / edit 三态顶栏完整切换。
|
||
- 页面设置项与 editor runtime 的完整联动。
|
||
- 帮助中心类多列目录块的静态展示和后续编辑支持。
|
||
|
||
### 5.4 明确降级项
|
||
|
||
以下功能可以先只做视觉入口或最小实现:
|
||
|
||
- 评论协作。
|
||
- 权限分享。
|
||
- 发布与侵权投诉链路。
|
||
- 全局搜索索引。
|
||
- 完整演示模式。
|
||
- 完整夜间主题。
|
||
- 完整表格、图表、数据库。
|
||
- 完整文件上传和媒体块管理。
|
||
- 完整引用别名编辑器和跨页面引用预览缓存。
|
||
|
||
---
|
||
|
||
## 6. 单一真源边界
|
||
|
||
### 6.1 可以留在前端展示层的内容
|
||
|
||
以下内容允许作为前端展示或临时 UI state:
|
||
|
||
- 色彩、字号、行高、间距、圆角、阴影。
|
||
- Sidebar 宽度与布局。
|
||
- 树行 hover、focus、临时 selection、drag preview。
|
||
- 顶栏按钮排列与 hover。
|
||
- 文档画布宽度、标题留白、正文显示密度。
|
||
- slash 菜单开合状态。
|
||
- 浮动工具条开合状态。
|
||
- 块手柄 hover 状态。
|
||
- 右下角浮动入口显示状态。
|
||
|
||
### 6.2 必须回到 Rust / projection / Page Aggregate 的内容
|
||
|
||
以下内容不能只在前端复刻:
|
||
|
||
- 页面树真实层级。
|
||
- 排序真相。
|
||
- 当前页 active path。
|
||
- 拖拽是否合法。
|
||
- 新建、重命名、移动、归档、恢复结果。
|
||
- 页面标题与 breadcrumb / sidebar / file tree 的一致性。
|
||
- 正文保存与 conflict key。
|
||
- 页面设置对 editor runtime 的正式语义。
|
||
- page reference / block reference / embed 默认位置。
|
||
- 引用类型、引用源、引用目标、引用别名、引用预览数据。
|
||
- AI 写入标题、正文、页面设置的语义边界。
|
||
|
||
原则:
|
||
|
||
> **UI 可以复刻 Wolai,事实源不能复刻成第二份前端状态。**
|
||
|
||
### 6.3 命令口径
|
||
|
||
页面树动作继续沿 `tree.*`:
|
||
|
||
- `tree.node.create`
|
||
- `tree.node.rename`
|
||
- `tree.subtree.move`
|
||
- `tree.node.archive`
|
||
- `tree.node.restore`
|
||
- `tree.node.embed`
|
||
|
||
页面动作继续沿 `page.*`:
|
||
|
||
- `page.head.updateTitle`
|
||
- `page.layout.updateOptions`
|
||
- `page.body.save`
|
||
|
||
兼容 `documents.*` 可以继续存在,但不应作为新增体验的正式命令面。
|
||
|
||
---
|
||
|
||
## 7. 推荐实施路线
|
||
|
||
### Phase A:建立 Wolai 视觉 token
|
||
|
||
目标:
|
||
|
||
> **先让字体、字号、行高、颜色和基础密度可被统一复用。**
|
||
|
||
主要文件:
|
||
|
||
- `/mnt/Data1T/mnote/wolai-frontend/src/app/globals.css`
|
||
|
||
工作内容:
|
||
|
||
- 统一全局字体栈,避免 `Inter` 覆盖中文系统字体。
|
||
- 建立 Wolai-like token:`--wolai-sidebar-bg`、`--wolai-active-fg`、`--wolai-active-bg`、`--wolai-text-primary`、`--wolai-text-secondary`。
|
||
- 固定标题、正文、sidebar、topbar 的字号 / 行高。
|
||
- 用 token 替代散落硬编码颜色。
|
||
|
||
验收:
|
||
|
||
- `local-3000` 截图中标题、树行和顶栏文字宽度明显接近真实 Wolai。
|
||
- 中文字体不再出现 Inter 优先导致的字宽偏差。
|
||
|
||
### Phase B:复刻 Sidebar / 页面树首屏
|
||
|
||
目标:
|
||
|
||
> **让左侧页面树在密度、选中态、hover、滚动条、底部入口上接近 Wolai。**
|
||
|
||
主要文件:
|
||
|
||
- `/mnt/Data1T/mnote/wolai-frontend/src/components/sidebar/sidebar.tsx`
|
||
- `/mnt/Data1T/mnote/wolai-frontend/src/components/sidebar/tree-shell-surface.tsx`
|
||
- `/mnt/Data1T/mnote/wolai-frontend/src/components/sidebar/tree-shell-host.tsx`
|
||
- `/mnt/Data1T/mnote/wolai-frontend/src/components/sidebar/tree-shell-dom-host.tsx`
|
||
- `/mnt/Data1T/mnote/wolai-frontend/src/lib/tree-projection.ts`
|
||
|
||
工作内容:
|
||
|
||
- 固定侧栏宽度和背景。
|
||
- 调整 workspace header 高度、头像尺寸、空间名截断方式。
|
||
- 调整快捷图标行尺寸与 hover。
|
||
- 调整页面树行高到 32px 附近。
|
||
- 当前页改为 Wolai 红字 + 淡红底。
|
||
- hover 态与 active 态同色系但层级更轻。
|
||
- 缩进只由层级和 icon slot 决定。
|
||
- 底部垃圾桶 / 模板中心与 Wolai 对齐,同时保留 mnote 自有入口时不破坏密度。
|
||
- `Explorer` 作为 mnote 创新保留,但视觉上降噪,避免抢过“我的页面”主路径。
|
||
|
||
验收:
|
||
|
||
- 对照用户提供的登录态截图,`Hermes` 选中行的颜色、行高、左侧缩进、滚动条位置接近 Wolai。
|
||
- 页面树长列表滚动时不出现行高抖动。
|
||
- 文件树创新入口仍可访问。
|
||
|
||
### Phase C:复刻顶栏与 breadcrumb
|
||
|
||
目标:
|
||
|
||
> **让顶栏在 owner / published 两种状态下都接近 Wolai 的轻量工具条。**
|
||
|
||
主要文件:
|
||
|
||
- `/mnt/Data1T/mnote/wolai-frontend/src/components/app-layout-shell.tsx`
|
||
- `/mnt/Data1T/mnote/wolai-frontend/src/components/editor/document-content.tsx`
|
||
|
||
工作内容:
|
||
|
||
- 固定顶栏高度约 40px。
|
||
- breadcrumb 文本、图标、分隔符弱化。
|
||
- 右侧按钮统一使用轻量 icon/text button。
|
||
- 区分 owner 态和 published 态的按钮组合。
|
||
- 公开状态 pill 对齐 Wolai 的“全网公开 / Public”视觉。
|
||
- 顶栏 hover 只加浅灰底,不使用重边框或大面积按钮。
|
||
|
||
验收:
|
||
|
||
- 登录态参考图中的顶栏图标序列能在 mnote 中找到对应视觉位置。
|
||
- published 公共页参考图中的“演示模式 / 搜索 / 开始编辑 / 评论 / 复制 / 开始使用 wolai”可先作为视觉分型,不要求一次接齐功能。
|
||
|
||
### Phase D:复刻文档画布与阅读态
|
||
|
||
目标:
|
||
|
||
> **让普通文档页首屏像 Wolai,而不是像调试页或二级详情页。**
|
||
|
||
主要文件:
|
||
|
||
- `/mnt/Data1T/mnote/wolai-frontend/src/components/editor/document-content.tsx`
|
||
- `/mnt/Data1T/mnote/wolai-frontend/src/components/editor/document-read-view.tsx`
|
||
- `/mnt/Data1T/mnote/wolai-frontend/src/lib/documents/page-option-semantics.ts`
|
||
|
||
工作内容:
|
||
|
||
- 标题使用 `34px / 44px / 600`。
|
||
- 普通正文列宽约 760px。
|
||
- 调整首屏 top padding,使标题起点接近 Wolai。
|
||
- 默认隐藏普通文档页的“个人空间 / 工作区首页”元信息行和横向分割线。
|
||
- 保留页面设置控制,但把“显示元信息 / 显示结构”这类调试或增强项作为显式选项,不默认露出。
|
||
- 阅读态任务块、段落、标题、列表、引用、代码块按 Wolai 行高和颜色重调。
|
||
- 右下角 AI / 帮助入口减重,避免绿色大按钮抢主编辑区视觉。
|
||
|
||
验收:
|
||
|
||
- `Hermes` 类普通文档页首屏只突出标题和正文块。
|
||
- 页面不再默认出现明显不像 Wolai 的横线、meta row 或 debug outline。
|
||
- 阅读态和编辑态在基础排版上不出现明显跳动。
|
||
|
||
### Phase E:复刻主编辑器高频块交互
|
||
|
||
目标:
|
||
|
||
> **让 `leptos-tiptap` 的输入体验从“能编辑”推进到“像 Wolai 的块编辑器”。**
|
||
|
||
主要文件:
|
||
|
||
- `/mnt/Data1T/mnote/wolai-frontend/src/components/editor/leptos-tiptap-island-editor-host.tsx`
|
||
- `/mnt/Data1T/mnote/rust/crates/core-protocol/src/editor/model.rs`
|
||
- `/mnt/Data1T/mnote/rust/crates/bridge-runtime/`
|
||
- `/mnt/Data1T/mnote/design/05-editor-mainline/reference-code/tiptap-notion-like-registry/`
|
||
|
||
工作内容:
|
||
|
||
- slash 菜单锚定 caret。
|
||
- selection 存在时显示浮动工具条。
|
||
- hover 块只显示左侧手柄区,上方和下方短横线在 hover 时变成插入 `+`。
|
||
- 点击上方 / 下方插入控件分别创建 before / after 空段落,并把焦点移动到新段落。
|
||
- 支持 `Esc, a` 和 `Esc, b` 的块级插入快捷键。
|
||
- 点击手柄打开块菜单。
|
||
- 块菜单至少提供 `turn into / duplicate / delete` 的视觉与基础命令入口。
|
||
- `turn into` 不直接绕过 Rust block model。
|
||
- Tiptap `UniqueID` 只用于 runtime 辅助,最终块 id 对齐 Rust `EditorBlock.block_id`。
|
||
- 页面引用 / 块引用可先做最小插入体验,复杂搜索和预览后置。
|
||
|
||
验收:
|
||
|
||
- 用户能在主编辑区通过 slash 插入常见块。
|
||
- 用户选中文本时看到 Wolai-like 浮动工具条。
|
||
- 用户 hover 块时不会被重工具条打扰,并能看到 Wolai-like 上 / 下插入短横线。
|
||
- 用户可以通过鼠标或 `Esc, a` / `Esc, b` 在当前块前后插入空段落。
|
||
- 块操作不会制造前端临时 id 作为持久化真相。
|
||
|
||
### Phase F:用 Page Aggregate 守住一致性
|
||
|
||
目标:
|
||
|
||
> **复刻体验时不牺牲单一真源。**
|
||
|
||
主要文件:
|
||
|
||
- `/mnt/Data1T/mnote/wolai-frontend/src/lib/documents/page-aggregate-loader.ts`
|
||
- `/mnt/Data1T/mnote/wolai-frontend/src/lib/documents/page-aggregate-builder.ts`
|
||
- `/mnt/Data1T/mnote/wolai-frontend/src/lib/documents/page-command-client.ts`
|
||
- `/mnt/Data1T/mnote/wolai-frontend/src/app/api/documents/page/route.ts`
|
||
- `/mnt/Data1T/mnote/rust/crates/core-protocol/`
|
||
- `/mnt/Data1T/mnote/rust/crates/bridge-runtime/`
|
||
- `/mnt/Data1T/mnote/rust/crates/mnote-web/`
|
||
|
||
工作内容:
|
||
|
||
- 新增视觉状态时,先判断它是否只是 UI state。
|
||
- 新增页面字段时,必须归入 `page_identity / page_head / page_layout / page_body / page_tree`。
|
||
- 标题变更必须继续让页头、breadcrumb、sidebar、page tree、file tree 同步。
|
||
- 正文保存继续走 `page.body.save`。
|
||
- 页面设置继续按 `page-option-semantics` 判断是否进入 island runtime。
|
||
- 页面树动作继续走 `tree.*`,不新增 `documents.*` 长期动作。
|
||
|
||
验收:
|
||
|
||
- 页面重命名后,所有消费者保持一致。
|
||
- 切页、刷新、实时更新不会把 UI 压回旧标题。
|
||
- 视觉复刻代码里没有新增第二套树排序或页面标题真相。
|
||
|
||
### Phase G:截图回归与像素验收
|
||
|
||
目标:
|
||
|
||
> **把“像 Wolai”变成可复查、可操作、可重复的截图基线。**
|
||
|
||
建议新增或复用:
|
||
|
||
- `/mnt/Data1T/mnote/scripts/task*-smoke.js`
|
||
- `/mnt/Data1T/mnote/tmp/wolai-compare/`
|
||
|
||
验收视口:
|
||
|
||
- 桌面:`1392 x 1213`
|
||
- 宽屏:`1440 x 900`
|
||
- 窄屏:`390 x 844`
|
||
|
||
截图基线:
|
||
|
||
- 真实 Wolai 登录态长页面树。
|
||
- 真实 Wolai `Hermes` 普通文档页。
|
||
- 当前 mnote 同类页面。
|
||
- mnote 文件树创新入口展开态。
|
||
|
||
验收方式:
|
||
|
||
- 每次验收必须按 `wolai-aline` skill 形成差异矩阵,并附 Wolai 截图、本地截图、动作链、DOM/ARIA 线索和剩余差异。
|
||
- 浏览器取证必须由 subagent 执行;主线程必须复核截图,不能只接受 subagent 文本结论。
|
||
- published 阅读态、owner 登录态、editable-test mode 都只表示取证上下文,不再作为三套独立测试方案维护。
|
||
- 先用 Wolai 基线写出本地 RED smoke,再实现,再跑本地 smoke,再派 subagent 复测。
|
||
- 若截图肉眼可见差异但 smoke 未捕获,先增强 smoke 或 checklist 断言,再继续实现。
|
||
- 后续可加入截图 diff,但不能用截图 diff 替代真实交互烟测。
|
||
- 每次改 Sidebar、topbar、document canvas、editor runtime 后都要重新截首屏,并同步更新连续 checklist 的状态。
|
||
- 连续执行清单见 `/mnt/Data1T/mnote/design/05-editor-mainline/process/5-9-wolai-aline-continuous-checklist-v1.md`。
|
||
|
||
owner 态交互验收清单:
|
||
|
||
- 自动化打开 `https://www.wolai.com/liaibo/ikFSSM1a4GgvmHBYFCNfVd` 后确认进入登录 owner 态,而不是 published 态。
|
||
- hover 页面树当前项 `Hermes`,确认 hover action 可见。
|
||
- 打开页面树菜单,截图菜单项和分组。
|
||
- hover 正文块 `事实上`,确认块背景、左侧手柄、上短横线、下短横线可见。
|
||
- hover 上短横线,确认 tooltip 为 `在上方插入块` / `Esc, a`。
|
||
- hover 下短横线,确认 tooltip 为 `在下方插入块` / `Esc, b`。
|
||
- 打开块菜单,截图 `AI 助理 / 转换为 / 拷贝副本 / 删除 / 复制链接 / 移动/嵌入到... / 块历史... / 评论 / 颜色 / 文字居中 / 文字翻译 / 生成海报` 等入口。
|
||
- 在 `3000` 执行同类操作并保存同视口截图。
|
||
- 验收报告中列出 Wolai 截图、本地截图、差异结论和不可测项。
|
||
|
||
---
|
||
|
||
## 8. 验证命令建议
|
||
|
||
前端运行:
|
||
|
||
```bash
|
||
cd /mnt/Data1T/mnote/wolai-frontend && pnpm dev
|
||
```
|
||
|
||
前端相关测试:
|
||
|
||
```bash
|
||
cd /mnt/Data1T/mnote/wolai-frontend && pnpm test src/components/sidebar/tree-shell-host.test.tsx src/components/sidebar/tree-shell-surface.test.tsx src/components/editor/document-content.test.ts src/components/editor/leptos-tiptap-island-editor-host.test.tsx
|
||
```
|
||
|
||
projection / aggregate 测试:
|
||
|
||
```bash
|
||
cd /mnt/Data1T/mnote/wolai-frontend && pnpm test src/lib/tree-projection.test.ts src/lib/tree-projection-contract.test.ts src/lib/documents/page-aggregate-builder.test.ts src/lib/documents/tree-command-client.test.ts
|
||
```
|
||
|
||
Rust 侧测试:
|
||
|
||
```bash
|
||
cd /mnt/Data1T/mnote && cargo test -p mnote-web workspace_shell
|
||
cd /mnt/Data1T/mnote && cargo test -p bridge-runtime
|
||
```
|
||
|
||
浏览器验收:
|
||
|
||
- 先按 `wolai-aline` skill 派 subagent 打开真实 Wolai 参考页和 `http://127.0.0.1:3000/`。
|
||
- 统一视口至少覆盖 `1392 x 1213`;涉及响应式时补 `1440 x 900` 和 `390 x 844`。
|
||
- 每个小任务都要保存 Wolai 与本地截图,并记录入口、关闭路径、URL 变化、控件形态、控件状态、快捷键、hover/active、DOM/ARIA 线索。
|
||
- 主线程复核截图后,把结论写入差异矩阵;发现差异先补 smoke,再改实现。
|
||
- 对照范围至少包含左侧栏宽度、树行高度、选中态、正文标题位置、顶栏按钮密度、搜索 modal、块 hover/插入入口、右下角浮动入口。
|
||
|
||
---
|
||
|
||
## 9. 禁止事项
|
||
|
||
为避免这条线跑偏,后续实现中禁止:
|
||
|
||
- 不把 `BlockNote` 写回默认主编辑器。
|
||
- 不把 Next App Router 恢复成 `3000` 主入口。
|
||
- 不在 UI 层重新拼第二份页面树、排序、标题或正文真相。
|
||
- 不把 compat route 或 debug shell 当正式主链。
|
||
- 不为了像素复刻绕开 `tree.*` / `page.*` 命令族。
|
||
- 不把 Tiptap runtime 临时 id 倒灌成 Rust 持久化块 id。
|
||
- 不把页面设置做成“保存了字段但 editor runtime 不消费”的假功能。
|
||
- 不为了复刻 Wolai 顶栏而提前接入真实权限 / 分享 / 评论复杂链路。
|
||
|
||
---
|
||
|
||
## 10. 当前退出标准
|
||
|
||
这份方案只有在下面条件同时满足后,才能移入 `done`:
|
||
|
||
- `3000` 首屏在左侧页面树、顶栏、文档画布三块视觉上接近真实 Wolai。
|
||
- 页面树保留 mnote 文件树创新,但不破坏 Wolai 主路径密度。
|
||
- 普通文档页默认不再显得像调试页或二级详情页。
|
||
- `leptos-tiptap` 主编辑器具备 slash、浮动工具条、左侧手柄、上 / 下插入块、块菜单的基础 Wolai-like 行为。
|
||
- 标题 / 正文 / 页面设置 / 页面树仍服从 Page Aggregate 与 tree-first graph kernel 主线。
|
||
- 相关 smoke / 单测 / 截图验收有记录。
|
||
- 连续 checklist 中 P0/P1 任务均有 Wolai 基线、本地 RED/GREEN smoke、subagent 复测截图和主线程复核结论。
|
||
|
||
当前结论:
|
||
|
||
> **下一步应先做 P0 像素基线和 Sidebar / 文档画布首屏对齐,再推进编辑器块级交互。功能复杂项可以降级,但页面树和主编辑器的视觉节奏必须优先向真实 Wolai 收口。**
|