Skip to content

fix(dashboard): 会话卡片不显示 bot 头像 - #634

Merged
deepcoldy merged 1 commit into
deepcoldy:masterfrom
xiaoxueSunn:feat/topics-card-bot-avatar-relay
Jul 28, 2026
Merged

fix(dashboard): 会话卡片不显示 bot 头像#634
deepcoldy merged 1 commit into
deepcoldy:masterfrom
xiaoxueSunn:feat/topics-card-bot-avatar-relay

Conversation

@xiaoxueSunn

Copy link
Copy Markdown
Contributor

改了什么

会话控制页「话题 / 状态板」视图里,每张会话卡片本该在 bot 名字旁显示 bot 头像(复用全站统一的 botAvatarHtml,和群组管理等页面同一套),但一直是空白。

根因:.orb-avatar 基础样式只设了 width/height,没设 display。裸 <span> 默认 display:inline 会忽略宽高,内部头像 <img> 又是绝对定位不撑开父级,于是头像球塌成 0×0;卡片头部 .session-card-top 是 grid,那一列被量成 0 宽,头像整个不可见。其他页面正常是因为那里 .orb-avatar 恰好落在 flex 容器里。

修复:给 .orb-avatardisplay:inline-flex + vertical-align:middle,头像球在任意容器都按自身尺寸占位。

为什么

用户反馈 dashboard 会话卡片希望展示 bot 头像而非纯文字。排查发现头像其实已接入、图也正常加载,只是被这个 CSS 缺陷卡住不显示。

影响面

  • 只动 dashboard 前端 CSS 单文件 src/dashboard/web/style.css,不涉及 daemon / core / bot-registry / im 等公共层
  • 不涉及跨平台、跨 CLI、跨会话类型逻辑
  • .orb-avatar 是全站统一头像组件,此修复让所有使用点统一受益;已正常页面本就是 flex 布局,inline-flex 不改变其排布

验证

  • pnpm dashboard:bundle 构建通过
  • 在真实运行的 dashboard(v3.5.2)上实测:.orb-avatar 从 0×0 变为 24×24,卡片正常显示 Claude / botmux / grok 等对应 bot 头像
  • 未跑 pnpm test(纯 CSS 展示修复,无对应断言);tsc 本地因缺 proxy-agent 依赖在无关文件 src/im/lark/event-dispatcher.ts 报错,与本改动无关

截图与完整说明

before / after / 部署后真实效果截图,以及「如何发现 → 根因 → 修复」完整说明见飞书文档:
https://bytedance.larkoffice.com/docx/Kb3HdXBvuolYknxhNeuclUMXnAg

@xiaoxueSunn
xiaoxueSunn requested a review from deepcoldy as a code owner July 28, 2026 08:54
@xiaoxueSunn xiaoxueSunn changed the title fix(dashboard): 会话卡片 bot 头像塌成 0×0 不显示 fix(dashboard): 会话卡片不显示 bot 头像 Jul 28, 2026
看板/话题/状态板视图的会话卡片里,bot 名字旁本该显示 bot 头像
(复用全站统一的 botAvatarHtml),但一直空白。根因:.orb-avatar
只设了 width/height 没设 display,裸 <span> 退回 display:inline
宽高被忽略,父级 grid 把头像列量成 0 宽,头像塌成 0×0。给
.orb-avatar 补 display:inline-flex + vertical-align:middle,
头像球在任意容器都占满自身尺寸,全站头像渲染点统一受益。

Co-Authored-By: Claude <noreply@anthropic.com>
@xiaoxueSunn
xiaoxueSunn force-pushed the feat/topics-card-bot-avatar-relay branch from 6be4fc8 to 0dfbc8d Compare July 28, 2026 09:08

@deepcoldy deepcoldy left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

首审(Claude)— ✅ 无阻塞(LGTM)

结论:改动正确、最小、无回归,已本地复现 bug + 验证修复。建议合入(待 codex 复审 + 申晗确认)。

白话:这个 PR 到底修了什么

现象:会话控制页的「话题 / 状态板」卡片,bot 名字旁本该有头像,却一直空白。

头像组件长什么样:全站头像 botAvatarHtml() 渲染出这样一段:

<span class="orb-avatar orb-avatar-sm ..."><img class="orb-img" .../></span>

关键点:外层 .orb-avatar 只设了 width/height,没设 display;里面的 .orb-img(以及状态点 .orb-dot)全是 position:absolute,不占据文档流。

为什么塌成 0×0:CSS 里 width/heightdisplay:inline 的元素不生效。裸 <span> 默认就是 inline。而 .orb-avatar 自身内容全是绝对定位(脱流),inline 盒子里没有任何撑开高度的在流内容 → 整个球被量成 0×0。放进 grid(.session-card-topdisplay:grid)后,那一列按 max-content 量,结果就是 0 宽,头像彻底不可见。

为什么别的页面正常:这是本 PR 描述里唯一我想更正的一点(见下)。真正的区别不是「flex vs grid 容器」,而是 .orb-avatar 是不是 flex/grid 的直接子元素:

  • 正常页面(overview / bot-defaults / kanban owner 等):.orb-avatar 恰好是 flex/grid 容器的直接子元素。CSS 规范会把 flex/grid 直接子元素「blockify」——inline 被强制提升为 block/flex,width/height 于是生效。有的是走 <Html> 组件(它是 display:contents,透明穿透,让球成为直接子元素),有的是把 botAvatarHtml 的输出直接 innerHTML 到 flex 容器上。
  • 出问题的 sessions-page.tsx:1029:球被包在一个<span> 里,那个 span 才是 grid item(被 blockify),球在它里面一层,不是直接子元素,不会被 blockify → 保持 inline → 塌 0×0。

修复:给 .orb-avatar 基础规则补 display:inline-flex + vertical-align:middle。这样无论球落在什么容器、嵌套多深,都按自身尺寸占位。

我怎么验证的(不只看代码)

1. 定位到真正的出错点:sessions-page.tsx:1029 的球包在裸 <span dangerouslySetInnerHTML> 里,而 .session-card-topdisplay:grid(style.css:2657/9313 两处定义都确认是 grid + max-content 列)。同类结构还有 sessions-page.tsx:1342/1468(球在 .term-modal-title 这个 inline-flex 里,同样嵌一层)。

2. 强佐证——这个 bug 之前被打过补丁:仓库里已有两处局部覆盖已经在写 display:inline-flex:

  • .kanban-cluster-avatar .orb-avatar(style.css:3016)
  • .history-avatar-bot .orb-avatar(style.css:3623)

它们正是同一个塌陷问题的早期点修。本 PR 只是把这个值上提到基础规则,一次性覆盖所有嵌套用法,消除「哪里塌了再补哪里」。

3. Headless 浏览器实测(决定性证据):用 Playwright/Chromium 忠实复刻真实 DOM/CSS 结构,分别注入 display:inline(改前)和 display:inline-flex(本 PR)量 getBoundingClientRect:

站点 改前 本 PR
.session-card 裸 span 落 grid(出错点) 0×0 inline 24×24 inline-flex
kanban owner(球是直接 flex 子元素) 24×24 block 24×24 flex
overview 经 <Html>(display:contents) 24×24 block 24×24 flex

出错点从 0×0 精确复现、并被修回 24×24;两个原本正常的站点尺寸不变(唯一差别是计算值 block→flex,而球的子元素全是 position:absolute,视觉完全一致)。无回归

4. 构建:pnpm dashboard:bundle 通过,inline-flex 已进 dist/dashboard-web/style.css 产物(该文件逐字节拷贝,非压缩)。

影响面复核

  • 仅动一个前端 CSS 基础规则,不碰 daemon / core / bot-registry / im 等公共层;不涉及跨平台 / 跨 CLI / 跨会话类型逻辑。
  • 基础规则改动波及全站约 20 个 botAvatarHtml 使用点,但已逐一核对:直接子元素站点本就被 blockify(inlineblock),改成 inline-flex(→flex)语义等价、视觉不变;裸 span 嵌套站点则从塌陷修复。属净正向
  • 底部注释的一处 base 状态点定位(.orb-dot 绝对定位)不受 display 改动影响。

唯一建议(非阻塞)

PR 描述里「其他页面正常是因为那里 .orb-avatar 恰好落在 flex 容器里」这句略不准确——.bd-profile-head 也是 grid 且一直正常。更精确的说法是「正常页面里 .orb-avatar 是 flex/grid 的直接子元素(被 blockify),出错页面里它嵌在一层裸 inline <span> 内」。代码修复本身完全正确,只是描述里的机制解释可再精确。不影响合入。


接下来 @codex 复审。未获申晗确认前不合码。

@chatgpt-codex-connector

Copy link
Copy Markdown

To use Codex here, create a Codex account and connect to github.

@deepcoldy deepcoldy left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

复审(Codex):✅ LGTM,无阻塞。独立按当前 master 合并态复核:仅 style.css 5 行变更,merge-tree 无冲突,diff --check 通过;静态盘点 19 个 bot/chat avatar helper 调用点 + 1 个手写 orb 节点,并用 Chromium 覆盖 18 类代表布局。嵌套裸 span 的 session-card 从 0×0 修为 24×24,term/history modal 标题同类问题也被修复;其余 flex/grid 直接子项站点几何尺寸均不变。vertical-align:middle 在 flex/grid item 上不参与布局,在 inline 嵌套点用于居中,未见副作用。当前 master + PR 的 synthetic merge 执行 pnpm build 通过。GitHub 当前无 status/check run。按约定本次只批准、不合码,等待申晗确认。

@deepcoldy

Copy link
Copy Markdown
Owner

双审收敛 — ✅ LGTM,无阻塞(待 @申晗 拍板合码)

首审(Claude,COMMENTED)+ 复审(codex,APPROVED)独立结论一致:改动正确、最小、无回归。

补一条 review 之后的再验证:两次 review 发出后 master 已前移(fd455bcf → 216da4a6,合入了 #635)。已复核:

  • fix(desktop): 修复 dashboard v2 兼容误判 #635 的两个新提交(4dee422b/216da4a6)均不触碰 src/dashboard/web/style.css,与本 PR 零重叠。
  • 对当前 master 216da4a6git merge-tree --write-tree:exit 0,单一干净 tree,无冲突路径
  • 本 PR 相对自身 base 的净改动仍是style.css 5 行(基础规则补 display:inline-flex + vertical-align:middle)。

结论保持不变,可安全合入当前 master。未获申晗确认前不合码。

@deepcoldy
deepcoldy merged commit 06f5030 into deepcoldy:master Jul 28, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants