Skip to content

[finding] CommentThread 遗留两处:纯 emoji 按钮没有无障碍名;7 天以上时间戳不跟随会话语言 #3441

Description

@yinlianghui

实现 #3424(把 CommentThread 全部硬编码英文接入 i18n)时看到的两处,都不属于该单的范围(它治的是硬编码英文),所以没有顺手改。

标 finding:CommentThread 在本仓没有任何消费者(全仓只有 packages/collaboration/ 内部引用它;app-shell 用的是同包的 PresenceAvatars / usePresence / useRealtimeSubscription / useConflictResolution),所以今天没有用户经由 ObjectUI 自己的应用撞到它。但它是已发布的导出组件,包外宿主直接用得到 —— 严重度请 PM 自行判定,不要因为我贴了 finding 就当成不重要。

一、三个纯 emoji / 符号按钮没有无障碍名

packages/collaboration/src/CommentThread.tsx:

  • 每条评论下的快捷回应按钮,内容分别就是 '👍' 和 '❤️',没有 aria-label、没有 title。屏幕阅读器只能念出 emoji 本身的 Unicode 名称(还依赖 AT 实现),完全说不出这个按钮是干什么的。
  • 回复提示条右侧的关闭按钮内容是 '✕',同样没有名字。

注意旁边那颗加号按钮(表情选择器)是有名字的 —— 它走 title,#3424 已经把它接进了 collaboration.addThumbsUp。所以这三颗是明确的遗漏,不是设计如此。

修的时候可以直接用 #3424 已经建好的接线:useCollaborationTranslation / COLLAB_DEFAULT_TRANSLATIONS(packages/collaboration/src/useCollaborationTranslation.ts),新键十个语言包全补即可。

二、7 天以上的评论时间戳不跟随会话语言

同文件 formatTimestamp,最后一档:

if (days < 7) return t('collaboration.daysAgo', { count: String(days) });
return date.toLocaleDateString();

toLocaleDateString() 不带参数用的是运行时默认 locale(浏览器/Node 的),不是会话语言。所以 zh 会话下,同一条评论列表里 6 天前的显示"6 天前",8 天前的却可能显示 8/1/2026。

这不是硬编码英文(它本来就跟随环境),所以 #3424 有意没动它。要修的话有个真实的坑,请在实现时考虑:整个函数体外面包着 try { … } catch { return iso; },而 toLocaleDateString(tag) 遇到不认识的语言 tag 会抛 RangeError —— 直接把 language 传进去,会让异常静默落进那个 catch,渲染出原始 ISO 串,比现在更糟。要么先校验 tag,要么就地单独 try/catch 回退到无参调用。

language 是现成的:createSafeTranslation 返回的对象里就带(const { t, language } = useCollaborationTranslation()),不需要额外的 hook,也不需要引入日期库。

Refs #3424,objectstack-ai/objectstack#5506

Activity

  1. yinlianghui commented on Aug 6, 2026

    @yinlianghui
    CollaboratorAuthor

    发现分诊轮(晋级):摘 finding 换 bug+pm:queue。前提复核 live:CommentThread.tsx:574-579,655 emoji/✕ 按钮仍无可访问名,:82 toLocaleDateString 仍不随会话语言。已发布导出组件的具体 a11y 缺陷,i18n 通道(useCollaborationTranslation)已就位,修复面小。RangeError 陷阱见原始记录。


    Generated by Claude Code

  2. self-assigned this
    on Aug 6, 2026
  3. yinlianghui commented on Aug 6, 2026

    @yinlianghui
    CollaboratorAuthor

    认领:objectui 分片 PM 并行批第 47 单
    会话:session_01GTRjn8xBqp75dk7kFupVRt
    分支:claude/issue-3441-commentthread-a11y-time
    Worktree:objectui-issue-3441
    文件面:packages/collaboration/src/CommentThread.tsx、useCollaborationTranslation.ts 兜底表、该包测试、packages/i18n/src/locales/*(十包,本批独占)、changeset。issue 里的 RangeError 陷阱处理方案(先校验 tag 或就地 try/catch 回退无参调用)按其指引实施并加测试钉住。
    与同批 48(workflows)/49(console configs)/50(console samples)/51(kanban 测试)互不相交。


    Generated by Claude Code

  4. yinlianghui commented on Aug 6, 2026

    @yinlianghui
    CollaboratorAuthor

    验收:ACCEPT → PR #3481(并行批第 47 单,会话 session_01GTRjn8xBqp75dk7kFupVRt),已跑检查零失败(shards/Lint/Type Check 在飞,dev 如实报告未冒领)。ready + auto-merge 因 GraphQL 配额排队,恢复即执行。

    复核要点:

    1. 承重技术判断正确且有规范依据:三颗按钮用 aria-label 而非照抄 '+' 按钮的 title——accname 计算中按钮内容(2F)优先于 title(2I),title 方案只装饰鼠标、名字仍是 emoji 字形。这个判断顺带用两条本 PR 里全绿的断言证出了 '+' 按钮自己也没有可访问名(getByTitle 命中而 byRole name 零命中)→ 已立 CommentThread 的 "+" 表情选择器:title 永远不会成为它的可访问名(内容 "+" 优先),#3424 只命名了 tooltip #3478。
    2. 键分离的理由成立:reactThumbsUp ≠ addThumbsUp——已有回应的评论上两个控件同屏,一键两名是新缺陷;cancelReply 不复用 common.cancel(可访问名要说明取消的是什么)。
    3. 时间戳修法取局部 catch 而非 tag 预校验:最坏情形可证等于现状——正确的保守方向;RangeError 测试如实标注为「防错误修法的钉」而非回归钉,并用 REVERSE B(对朴素修法)完成反向验证。
    4. 两处报告模板偏差(新名字用例在含 en 的所有语言红、RangeError 钉的反事实是错误修法)全部如实声明。
    5. CommentThread 的 "+" 表情选择器:title 永远不会成为它的可访问名(内容 "+" 优先),#3424 只命名了 tooltip #3478('+' 按钮 title 永远成不了可访问名)已分诊 bug+pm:queue——同文件串行:等本 PR 落地后再派。

    Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions