Files
mnote/bugs/04-tree-domain/done/4-27-filetree-open-reveal-active-row-jump-v1.md
T
lix-2026 274779c0d8 fix(tree): stabilize filetree mindmap switching
Open filetree mindmap assets inside the primary document pane so the sidebar root is not rebuilt during rapid mindmap/page switching.

Keep filetree active rows on doc:<documentId> and asset:<mindmapId>, shorten generated mindmap filenames, and preserve legacy index rows only as compatibility input.

Add task438-task445 browser smokes and close the 4-27/4-38/4-39/4-40 tree-domain bug records.
2026-05-16 07:11:06 +08:00

9.7 KiB
Raw Blame History

4-27 [done][bug] File Tree 打开对象后 active / reveal 跳动 v1

更新时间:2026-05-16

分类归属:

  • 04-tree-domain/done
  • 涉及边界:05-editor-mainline/object editor active identityfile_tree row selection/focus/reveal

用户反馈:

  • “目前文件树中思维导图点击后文件树会闪一下,然后跳到对应的 index。”
  • “文件树中,点击页面下方(滚动条到下部分)的页面,有时候会跳一下,然后就看不到点的那个文件里。”

1. 问题定义

File Tree 中点击某个对象后,树 UI 会发生短暂闪烁或滚动跳动,最终 active / reveal 位置可能落到同页面的 index.md,或者滚动到别处导致刚点击的文件不可见。

这类问题不是简单的路由跳转慢,而是 file_tree row click -> object open intent -> active object identity -> selection/focus/reveal -> virtual/DOM tree render 链路不一致。尤其是 mindmap asset 点击后如果页面 active identity 被降级成 document/index identity,就会把用户刚点击的 asset 行“纠正”为同页面 index.md 行,表现为文件树闪一下并跳到 index。

2. 初步判断

当前不应直接把它当成 5-10 mindmap 污染 index.md 的重复问题。5-10 已经关闭的是“mindmap 打开/保存污染正文真源”;本问题关注的是打开动作之后 File Tree 的 active row 和 scroll reveal 是否稳定。

更可能存在三类根因:

  1. tree.asset.open 打开 mindmap 后,主编辑区 active state 只回传 documentId,没有保留 objectIdentity=resource:mindmap:{documentId}:{assetId},导致 File Tree active row 映射回 index:{documentId}
  2. 点击文件树下半部分页面时,导航成功、sidebar snapshot 校准、tree live delta/resync 或本地 projection rebuild 触发了 reveal 当前文档逻辑,未区分“用户刚点击的 row”与“路由推导出的默认 index row”。
  3. File Tree 在大列表滚动区域内重新渲染时,expanded/selected/focused/active/reveal 状态没有按 rowId 稳定合并,导致 scroll anchor 丢失,用户看到跳动后目标行被滚出视口。

3. 与既有 done bug 的关系

关联但不重复:

  • bugs/05-editor-mainline/done/5-10-mindmap-filetree-index-single-truth-split-v1.md:关闭 mindmap object 与 index.md 正文真源混淆。
  • bugs/04-tree-domain/done/4-26-sidebar-filetree-projection-refresh-stalled-after-tree-asset-mutations-v1.md:关闭新建/删除/新建 mindmap 后 File Tree 不刷新的问题。

本 bug 的新增点是:对象已经可见、也能打开,但打开后的 active/reveal/scroll 行为仍不稳定。

4. 建议复现路径

  1. 登录真实测试账号,进入 http://localhost:3000/ 或主文档页。
  2. 新建测试页面 TEST-FILETREE-REVEAL-<timestamp>,在页面内新建一个 mindmap。
  3. 在 File Tree 中滚动到该页面及其 mindmap asset 行。
  4. 点击 mindmap asset 行。
  5. 记录点击前 rowId、点击后 active rowId、scrollTop、URL、主编辑区 object identity。
  6. 期望:active row 应保持在 mindmap asset 或明确的 object tab row,不应自动跳到 index:{documentId}
  7. 在长列表中滚动到下半部分,点击一个页面或其 index.md
  8. 期望:导航后目标 row 仍在视口内,不能被 reveal 到其它位置后消失。

5. 验收标准

  • 点击 File Tree 的 mindmap asset 后,不刷新浏览器,不发生无解释的整树闪烁。
  • 点击 mindmap asset 后,File Tree active / selected / focused row 不得被降级成同页面 index.md,除非产品明确决定普通点击只打开 index;如果这样决定,UI 必须不展示为 asset 被打开。
  • 点击长列表下半部分页面或 index.md 后,目标 row 在导航完成和 projection 校准后仍保持可见。
  • reveal 逻辑必须区分用户点击产生的 explicit focus 与路由/文档 active 推导的 implicit reveal,不能让 implicit reveal 覆盖刚发生的 explicit focus。
  • 增加真实浏览器 smoke,至少记录:点击前后 rowId、active object identity、scrollTop 变化、是否发生 navigation/reload、最终目标 row 是否在 viewport 内。

6. 建议修复方向

先补 smoke 复现,不要直接改实现。修复时优先沿以下边界排查:

  1. File Tree row click 发出的 tree.asset.open 是否携带完整 objectIdentity
  2. 主编辑区打开 mindmap object editor 后是否把 active identity 回传给 Sidebar / File Tree。
  3. index:{documentId} 的 active 高亮是否只在打开 page/index 时生效,而不是覆盖 asset object。
  4. 本地 projection rebuild 后是否按 rowId 恢复 expanded/selected/focused/reveal,不按 documentId 粗粒度重置。
  5. scroll reveal 是否只在目标 row 不在 viewport 内时执行,并避免重复 reveal。

7. 当前状态

当前状态:done

2026-05-15 已随 4-35 P0/P1 完成第一层止血:

  • Convex File Tree 页面正文 row 不再显示为页面容器下的 index.md,而是直接显示为 新页面.md 这类 markdown row。
  • 主文档壳本地 create apply 不再手工插入 index:<documentId> 行。
  • 当前文档的 File Tree selected / focused 默认从 index:<documentId> 改为 doc:<documentId>
  • 新增真实浏览器 smokescripts/task438-filetree-title-md-active-reveal-smoke.js,覆盖新建页面后没有 index.md 行、页面正文 row 显示 .md、点击长列表中的页面 row 后 selected 留在 doc:<id>,且目标 row 仍在视口内。
  • P2 继续补齐 File Tree inline rename:输入 {title}.md 时只把 {title} 作为页面标题提交,File Tree 仍显示 {title}.md;非法字符和同级重名会在输入框内提示,不触发 rename command。

已通过:

MNOTE_UI_BASE_URL=http://127.0.0.1:3428 node scripts/task438-filetree-title-md-active-reveal-smoke.js
MNOTE_UI_BASE_URL=http://127.0.0.1:3428 node scripts/task439-filetree-title-md-rename-smoke.js
MNOTE_UI_BASE_URL=http://127.0.0.1:3428 node scripts/task440-page-title-filetree-md-sync-smoke.js

结果文件:tmp/task438-filetree-title-md-active-reveal-smoke/result.json。 补充结果文件:tmp/task439-filetree-title-md-rename-smoke/result.json。 标题栏同步结果文件:tmp/task440-page-title-filetree-md-sync-smoke/result.json

关键结果:

  • ok=true
  • beforeClick.indexRowExists=false
  • beforeClick.rowTitle="新页面.md"
  • afterClick.selectedRows=[{"rowId":"doc:<documentId>", ...}]
  • afterClick.visible=true
  • task439.afterRename.fileTreeTitle="<title>.md"
  • task439.afterRename.pageTreeTitle="<title>"
  • task439.invalidState.validationText="文件名不能包含 / \\ : * ? \" < > |"
  • task439.duplicateState.validationText="同级已存在同名页面"
  • task440.after.fileTreeTitle="<title>.md"
  • task440.after.pageTreeTitle="<title>"
  • task440.after.indexRowExists=false

2026-05-15 P3 口径补充:

  • 后续 File Tree active / reveal 修复不再以可见 index.md 行为目标;Convex 页面正文默认 row 是 doc:<documentId>,显示标题为 {title}.md
  • rowKind=index 只作为历史 projection / command 兼容输入保留,不能重新作为默认 UI 可见行引入。

2026-05-15 P4 子问题关闭:

  • mindmap asset 点击后 active / selected 从 asset:{mindmapId} 闪回父页面 doc:{documentId} 的子问题已单独关闭,记录见 bugs/04-tree-domain/done/4-38-filetree-mindmap-click-active-row-flicker-v1.md
  • 修复点:/mindmap/{documentId}/{mindmapId} 对象页的 SSR filetree active row 改为 asset:{mindmapId};客户端 tree live snapshot renderer 也按 /mindmap 路由恢复 asset:{mindmapId},不再只按 doc:{documentId} 选中。
  • 真实浏览器 smokeMNOTE_UI_BASE_URL=http://127.0.0.1:3428 node scripts/task443-filetree-mindmap-click-active-row-smoke.js,结果文件 tmp/task443-filetree-mindmap-click-active-row-smoke/result.json

2026-05-16 当前口径关闭:

  • mindmap asset 连续点击和其它页面切换时,不再通过整页 /mindmap/... 导航重建 sidebar;主文档壳新增 openPrimaryMindmap(),在当前 primary pane 内挂载 mindmap 对象,并保持 #sidebar-file-tree-root DOM 根节点稳定。
  • mindmap asset 选中语义保持为 asset:{mindmapId},不会回落到父页面 doc:{documentId} 或历史 index:{documentId}
  • Convex 页面正文默认 row 继续保持 doc:{documentId},显示为 {title}.md;历史 index 只作为兼容输入,不再作为默认 UI active / reveal 目标。
  • mindmap 文件名从 mindmap-mindmap_...json 这类技术名收敛为 思维导图-xxxx.json,避免连续切换时标题重绘造成观感跳动。
  • 关闭记录见:
    • bugs/04-tree-domain/done/4-38-filetree-mindmap-click-active-row-flicker-v1.md
    • bugs/04-tree-domain/done/4-39-filetree-create-title-cache-md-conflict-v1.md
    • bugs/04-tree-domain/done/4-40-filetree-mindmap-switch-flicker-and-short-title-v1.md

新增 / 复用真实浏览器 smoke

MNOTE_UI_BASE_URL=http://127.0.0.1:3428 node scripts/task443-filetree-mindmap-click-active-row-smoke.js
MNOTE_UI_BASE_URL=http://127.0.0.1:3428 node scripts/task444-filetree-create-mindmap-title-cache-smoke.js
MNOTE_UI_BASE_URL=http://127.0.0.1:3428 node scripts/task445-filetree-mindmap-switch-no-flicker-smoke.js

task445 关键结果:

  • before.mindmapTitle = "思维导图-7712.json"
  • afterMindmap.fileRootStable = true
  • afterPage.fileRootStable = true
  • afterMindmapAgain.fileRootStable = true
  • failures = []

后续如再次出现,应拆成独立新缺陷跟踪:

  • 更长列表、搜索过滤、恢复后 reveal、双浏览器 resync 场景下是否仍稳定。
  • 明确复现的“点击文件树下半部分页面后跳一下导致看不到刚点击文件”的滚动锚点问题。