feat(sidebar): the avatar opens the account menu on every page (S2)

Off / the footer was a plain link home. It is now the same Menu.Root
everywhere; off / its dialog entries link to /?account=<dialog>, which
Home opens once its account is ready and drops from the URL.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01N4f2nya58RoRu4yEmJgRGE
This commit is contained in:
Jesse_Chen
2026-09-29 00:43:43 +08:00
co-authored by Claude Opus 5.5
parent 8415fdca72
commit c15def0c50
9 changed files with 332 additions and 63 deletions
+25 -11
View File
@@ -508,14 +508,29 @@ one skeleton, none of them carrying the sidebar.
`.session-main`, so they lost the 44px minimum, the row padding and the 2px
current-item marker, while `.session-row` still reserved a 44px column for a
menu button it never rendered.
- **What read-only drops — exactly three things.** The per-row menu trigger (and
with it the reserved column, via `.session-row[data-readonly="true"]`), the
footer chevron, and the account menu behind it. Everything else is the same
element, the same class and the same size: brand row, 新建对话, the three page
actions, the flat 「最近」 list, the 56px `.profile-trigger`. Rows are links to
`/?c=<uuid>`; the footer is a link to `/`. Renaming, pinning, archiving and
deleting stay on `/`, backed by `Home()`'s optimistic-update and rollback
layer, which is far more than these four routes need.
- **What read-only drops — exactly one thing.** The per-row menu trigger (and
with it the reserved column, via `.session-row[data-readonly="true"]`).
Everything else is the same element, the same class and the same size: brand
row, 新建对话, the page actions, the flat 「最近」 list, the 56px
`.profile-trigger` with its chevron. Rows are links to `/?c=<uuid>`.
Renaming, pinning, archiving and deleting stay on `/`, backed by `Home()`'s
optimistic-update and rollback layer, which is far more than these routes
need.
- **The avatar opens the account menu on every page (2026-09-28,
TASK-self-edit-avatar-menu-20260928 S2).** It used to be a plain link to `/`
off the home page, so clicking the avatar on 星盘 / 星历 / 我的报告 / 星盘档案
just left the page. Now it is the same `Menu.Root` everywhere — same popup,
same identity block, same items. On `/` Home controls it and 个人资料 / 通用设置
/ 账户与点数 / 退出登录 open their dialogs in place. Elsewhere the menu keeps
its own open state and those four entries are links to `/?account=<dialog>`:
Home reads the intent once on mount, drops it from the address bar at once
(a reload or Back never reopens it), and opens that dialog when its account
is ready — no waiting state of its own. The theme choice is not a dialog and
applies where the reader is. While the account is still being read the
footer is the same 56px block, inert and without a link; signed out it is
去登录. The dialogs themselves stay on `/`; moving them into every page would
add a loading state to the home first frame (§ reveal rule), so it was not
done.
- **New chat is not a home link.** The read-only 新建对话 action links to
`/?new=1`; Home consumes that intent before activation and opens a fresh local
consultation. It clears `new`, any `c`, and the login-return stub. Before the
@@ -523,8 +538,7 @@ one skeleton, none of them carrying the sidebar.
The first question uses the existing persistence flow. A reserved older
consultation keeps recovering in the background without taking over this
explicit new-chat landing or leaving its startup recovery notice there.
The account footer
still links to `/`, and a bare-home refresh keeps its existing landing rule.
A bare-home refresh keeps its existing landing rule.
The same action and mobile drawer-close behavior are retained; no extra
button, copy, loading state, or visual treatment is introduced.
- **Leaving the chat is a navigation, not a reload.** 星盘 / 星历 / 我的报告 are
@@ -782,7 +796,7 @@ Agent 的 live 标记只有 `InlineSpinner` 一种。曾经并存的 canvas 小
校正面的所有等待复用行内等待:进入前的 hydration 在揭幕之前完成,进入后唯一的等待形态是时间线 live 行(含「正在准备下一个问题…」这一条独立 live 行)。打字回答的 live 行从发出那一帧起就是阶段句「收到,正在对照你的档案…」,按服务端 `turn.progress` 换成「正在记下这件事…」「正在重新对照盘面…」「正在准备下一个问题…」,属于流式生成中(BUG-1047)。区间交付卡只挂在最新那条采用旁白下面,不得留在更早的采集/区分题下。有未答的采集或选择题时卡仍在,「更像这个」置灰并写「先答完上面这道,再选时间」,不得整卡消失。卡上至多三列并排,相同性格句只写一次,点「更像这个」即采用该列分钟,按钮显示「正在采用…」或「已采用」。采用过程中整张卡留在原处,不得因 `busy` 卸掉。采用后前事核对结束走 `verified_idle`:一行收尾文案跟在卡片下面、与助手列对齐,没有 live 行、没有重载、没有采用状态条。卡片与右栏细则见 §11、§12。
**每次打开网页只揭幕一次,客户端返回首页走暖快照(2026-09-26,BUG-1040)。** 整页加载(首次打开、刷新、登录后跳转)照旧放下面这一次加载屏。同一次打开里从星盘 / 星历 / 我的报告 / 星盘档案经侧栏「新建对话」、历史会话行、账户页脚或浏览器返回回到 `/`,不再出现加载环:第一次冷启动成功后,模型目录、校正入口摘要、会话分页游标和今日星语记进模块级暖快照(`lib/home-warm-snapshot.ts`,按账户隔离、只在内存、不落任何存储;账户、资料与会话列表本来就在布局层的会话列表 provider 里跨页存活)。首页重挂时若快照齐全,首帧即可用,落点按冷启动同一套规则同步算出(`?new=1` 新建本地空对话、`?c=` 打开该会话、其余一律当前人物的空白首页,同 BUG-1052),随后后台刷新模型目录、账户、后台回答恢复、入口摘要与今日星语,结果到了静默替换;消息没缓存的历史会话沿用首页内切换会话的留白方式。快照缺任何一项、落点需要去服务端查、或客户端导航没留下目标地址(Next 先渲染新页面、后写地址栏,`AppLink` 在点击时记下目标),一律回到冷启动,不半揭幕。账户变化、退出、任一 401 清空快照;今日星语跨日或换人按新键重取,卡片先用静态句。
**每次打开网页只揭幕一次,客户端返回首页走暖快照(2026-09-26,BUG-1040)。** 整页加载(首次打开、刷新、登录后跳转)照旧放下面这一次加载屏。同一次打开里从星盘 / 星历 / 我的报告 / 星盘档案经侧栏「新建对话」、历史会话行、账户菜单的弹窗项(`/?account=`)或浏览器返回回到 `/`,不再出现加载环:第一次冷启动成功后,模型目录、校正入口摘要、会话分页游标和今日星语记进模块级暖快照(`lib/home-warm-snapshot.ts`,按账户隔离、只在内存、不落任何存储;账户、资料与会话列表本来就在布局层的会话列表 provider 里跨页存活)。首页重挂时若快照齐全,首帧即可用,落点按冷启动同一套规则同步算出(`?new=1` 新建本地空对话、`?c=` 打开该会话、其余一律当前人物的空白首页,同 BUG-1052),随后后台刷新模型目录、账户、后台回答恢复、入口摘要与今日星语,结果到了静默替换;消息没缓存的历史会话沿用首页内切换会话的留白方式。快照缺任何一项、落点需要去服务端查、或客户端导航没留下目标地址(Next 先渲染新页面、后写地址栏,`AppLink` 在点击时记下目标),一律回到冷启动,不半揭幕。账户变化、退出、任一 401 清空快照;今日星语跨日或换人按新键重取,卡片先用静态句。
**打开 `/` 落在哪里(2026-09-27,BUG-1052)。** 地址栏带 `?c=` 就进那条对话(分享链接、侧栏历史、在对话里刷新都靠它);带 `?new=1` 是新建对话;其余——登录后、手输网址、书签、刷新裸 `/`——一律是当前人物的空白首页(开场问候 + 输入框),已有一个没发过消息的新对话就复用它。不再记「上次在哪条对话」:离开首页、登录过期都不存任何返回记录,后台还在恢复的旧回答也不把空白首页切走。