Your Name and Claude Sonnet 5
4e8f45d7d8
路由从 hash 换成 History API(pushState/replaceState/popstate),不再依赖 location.hash
...
HashNavigation 改名 Navigation(src/lib/navigation.js),接口不变,内部改用真实路径:
parseUrlHash/composeUrlHash 改名 parseUrl/composeUrl;navigateTo/navigateReplace 改调
pushState/replaceState 后手动派发 popstate(pushState/replaceState 不会像赋值 location.hash
那样自动触发事件,这里复用 navigateReplace 早就在用的同一个手动 dispatch 手法);goBack()
不用改,history.back() 本来就是真实浏览器历史机制。新增 Navigation.currentUrl() 替代调用方
原本直接读的 window.location.hash(这个类从来没包装过这个读取)。
一处需要专门处理的边界情况:当 path[0] 是空字符串("不选中侧栏视图、只开一个会话"这个仓库里
的合法状态)时,拼出的真实路径开头会变成双斜杠,被浏览器当协议相对地址解析、试图跳到一个叫
会话id的host,pushState 直接抛 SecurityError。composeUrl/parseUrl 内部用占位 token "_" 处理
这种情况,对外的调用方(19个文件)完全无感。
tinode-web.jsx 的 handleHashRoute 改名 handleRouteChange,监听从 hashchange 换成 popstate;
service-worker.js 的推送通知点击跳转手动改写成同样的路径格式(这个文件在打包之外单独执行,
没法 import Navigation)。index.html/index-dev.html 加了 <base href="/">——所有静态资源引用
都是相对路径,hash 路由下页面路径永远是 /,换真实路径后深层地址刷新会按当前目录解析出错误
资源地址导致白屏,这一行是标准修法。nginx.conf 的 try_files 兜底规则本来就适用两种路由,只
更新了注释。
实机验证:地址栏不再有 #;点击会话/设置等各类视图正常跳转;浏览器前进后退和应用内"返回"
按钮都正常;收藏页内部的类型 tab 切换(navigateReplace)确认不产生新的历史记录;在会话页/
个人中心页刷新、直接用完整深层路径打开新标签页都能正确恢复到位,资源正常加载不白屏。
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com >
2026-09-07 21:00:39 +08:00
Your Name and Claude Sonnet 5
a8b81a51e3
修复本轮UI走查发现的6处样式/交互问题
...
1. 企业注册-统一社会信用代码:扫码图标误用 icon+onIconClick(渲染在输入框左侧、蓝色),
跟设计稿(图标在右侧、深灰色)不符。原因是 Field 组件里 icon 出现在 <input> 之前;
全仓库唯一一处 onIconClick 用法,改用 PasswordField 同款的 action(渲染在右侧),
复用已有的 .auth-inline-icon 灰色样式,不新增CSS。
2. 意见反馈:图片上传按钮跟设计稿差异较大(当前是通栏虚线框+蓝色图标文字,设计稿是
独立白色方块+灰色图标文字);字数"0/300"计数器卡在textarea自带边框和外层白卡的接缝
处,看起来像叠在两层盒子中间。改法:拆分原本跟"举报证据上传"共用的CSS规则,给
.feedback-upload>button 单独设置白底/无边框/灰色/7.5rem方块;去掉textarea自身的
border,让计数器所在的外层卡片成为唯一可见的白色容器。"图片"标题跟数量合并回一行
(原来用space-between分居两端),maxFiles真实上限(5,早前已确认是后端真实值)不变。
3. 青少年模式(开启/关闭/验证三个页面互跳):三处跳转全部误用push(HashNavigation.
navigateTo),导致点返回会先回到流程内已经处理完的页面,跟本工程之前排查过的
同类"tab切换污染历史记录"是同一个模式。新增 navigateReplace()(跟 navigate() 同结构,
内部换成 HashNavigation.navigateReplace,抄的是 message-center-view.jsx/
content-library-view.jsx已验证过的写法),三处调用改用它。
4. 修改密码页面:复用了 profile-editor-page 的通用label/input样式,但没有像
BirthDateEditor那样带上专属wrapper class,导致三个label的<span>不加粗不换行、
紧贴在一起零间距,input还留着给别的编辑器计数器/清空按钮预留的3rem右侧空白。
新增 change-password-fields 样式(参照birth-date-editor的label/span/input规则)。
5. 消息长按弹出菜单:全历史检索确认这个功能从来不是真正的长按手势,唯一实现是点击
气泡右上角一个不透明度只有0.3的小箭头按钮——参考图"消息页面—长按弹出.png"命名的
功能需求和实现从未对齐。给 .bubble 补上真实的touchstart/touchmove/touchend长按
识别(500ms计时器,移动超过10px视为滚动取消),复用同一套菜单构建逻辑(从
handleContextClick里抽出openContextMenu(x,y)公用)。验证时发现并修复了一个重构
引入的真bug:openContextMenu里遗留了两行没改完的e.pageX/e.pageY(应为参数x/y),
会导致点击小按钮和长按两条路径双双抛ReferenceError,已修正并重新验证两条路径都正常。
6. 群公告横幅(群聊导航栏下方常驻提示条):当前是通栏无圆角、贴边无留白、底部硬分隔线、
文字用的是全局默认灰色(#666 )文本token,设计稿是浮在灰底上的白色圆角卡片、四周留白、
无分隔线、文字接近黑色。改法:加margin+border-radius+box-shadow做出浮起的卡片感,
去掉border-bottom,颜色改用--clr-bubble-text(消息正文同款深色token,而不是改全局
的--clr-text-primary,避免影响其它用到这个默认文本色的地方)。
验证:本地dev-proxy逐项验证——企业注册图标位置颜色(截图核对)、意见反馈布局(截图核对,
0/5计数器无缝落在白卡右下角)、青少年模式三处调用grep确认无遗漏+navigateReplace底层
history.replaceState机制单独验证不增加history.length、修改密码页面(截图核对label加粗
间距生效)、长按弹出(真实dispatch TouchEvent触发菜单成功,且验证点击小按钮路径未被
重构破坏)、群公告横幅(getComputedStyle核对margin/borderRadius/boxShadow/color/
borderBottom五个属性全部生效)。
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com >
2026-09-07 17:24:24 +08:00
Your Name and Claude Sonnet 5
605cd12a6e
修复第1章各认证页之间切换会带出上一个页面的报错文案
...
现象:在注册页填错邀请码提交后(正确显示"邀请码错误,请重新输入"),点击"已有账号?登录"
切到登录页,登录表单顶部会原样带出这条"邀请码错误"提示——用户在登录页什么都还没做,却先看到
一句跟登录毫不相关的报错。反过来,登录密码错误后点"马上注册"也会把"账号或密码错误"带到刚打开
的注册页。
根因:errorText/errorLevel 是 tinode-web.jsx 顶层的一份全局共享状态,不跟当前显示哪个
sidepanel 绑定。Login 组件自己的"切换企业"链接会在跳转前先调用一次 onError() 清空,说明
之前已经意识到这个状态会带着走,但企业码/登录/注册/忘记密码等页面之间的其它跳转都没有做
同样的处理——其中 Register 等好几个视图目前甚至没有拿到 onError 这个 prop,需要在各处
分别补,比较分散。
修复:在 AuthOnboardingView(chapterOneViews 统一走的入口组件)里加一个以 view 为依赖的
useEffect,view 变化时统一调用 onError() 清空全局报错状态,一次性覆盖企业码/登录/注册/
忘记密码等视图之间的所有切换路径(含浏览器前进后退),不用逐个跳转调用点分别处理。
验证:注册页提交错误邀请码复现"邀请码错误,请重新输入"后点击"登录",确认登录页不再带出
该提示;反向验证登录页密码错误后点击"马上注册",确认注册页同样不再带出"账号或密码错误"。
注:umd/index.dev.js 本轮未随此提交一起提交——auth-onboarding-view.jsx 不是按路由懒加载的
独立 chunk,此刻工作区里另有并行 agent 正在改 contact-management-view.jsx / call-panel.jsx
且未提交,重新构建的 index.dev.js 会把它们尚未提交的改动一起编译进同一个产物文件,为避免把
不相关改动混进这次提交,本次只提交源码,构建产物留给后续统一重新构建的提交处理。
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com >
2026-09-06 15:40:43 +08:00
Your Name and Claude Sonnet 5
0748f30cc1
实名认证提交成功后补拉一次 GET,用服务端脱敏字段替换本地草稿回显(新增61)
...
现象(IM-后端问题清单-2026-09-04.md"新增61"):POST /security/realname/submissions
成功响应只有 {status, submission_id},从不带 masked_name/masked_id_number,前端此前
的兜底是回显用户本次会话里刚输入的原始姓名/证件号草稿——多数情况下看起来没问题,
但那是未脱敏的原始值,不是服务端认可的脱敏展示值,且只覆盖"这次会话内",换一个
从未在本会话提交过的场景(比如同一账号换设备/清缓存后第一次看提交结果)就没有任何
草稿可回退,只能空白。
之前的复核已经确认 GET /security/realname 从这个功能最初上线的 commit 起就一直带着
masked_name/masked_id_number 这两个字段,只是提交成功后从未再调用过它。
修法:submit() 里 POST 成功后追加一次 getRealnameStatus(),用响应里的
masked_name/masked_id_number 覆盖本地状态,展示服务端脱敏后的真实值;这次追加请求
失败时静默忽略(提交本身已经成功,不应该因为这次锦上添花的请求失败而回退),保留
原有的本会话草稿兜底作为这次请求解析完成前的过渡显示。
验证:注册全新测试账号(无历史提交),提交姓名"测试用户"+证件号
110105199003077856 后,抓包确认 POST 响应确实只有 {status,submission_id},紧接着
自动触发的 GET 响应带 masked_name:"测*"、masked_id_number:"110***********7856";
页面输入框读取到的实际 value 是这两个脱敏值,不是刚输入的原始文本,证实修复生效。
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com >
2026-09-06 13:21:05 +08:00
Your Name and Claude Sonnet 5
ded440078a
补上用户名注册路径缺失的"无法自助找回密码"提醒文案
...
需求文档 1.4 第5条硬性要求:用户名方式注册不发送短信,必须提示用户"未绑定手机号
无法自助找回密码,忘记密码后只能联系企业管理员重置"。这句话在注册表单里从未真正
写出来过——不是视觉上被样式盖住,是 JSX 里压根没有对应节点,选择用户名注册的人
完全不会被告知自己放弃了手机号找回密码的能力。
修法:在邀请码输入框下方补上这行提示,只在 usingPhone 为假(用户名注册路径)时
展示,不影响手机号注册路径(那条路径本来就能自助找回密码)。参考图"注册页面.png"
是两个字段都还没交互的初始态,不代表这条路径相关的提示不应该出现。
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com >
2026-09-06 13:20:29 +08:00
Your Name and Claude Sonnet 5
164a41270c
修复实名认证已认证状态显示臆造标题"认证信息"
...
参考图(实名认证.png / 实名认证-已实名.png)里两种状态标题文案完全
一致,都是"请您使用有效身份证信息认证"——原来按status分叉出的"认证
信息"这句是mock阶段从未核对过参考图的臆造文案。
第十二轮最小粒度测试 Ch1-2 发现(该agent进行中因会话限流中断,此项
修复在中断前已完成,事后确认无误后提交)。
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com >
2026-09-06 04:23:44 +08:00
Your Name and Claude Sonnet 5
35f659249e
修复注册流程不写入持久化登录态、注册失败500错误显示原始英文
...
Register组件缺少Login同款的keep-logged-in挂载副作用,导致注册产生的
新账号在下一次刷新时静默丢失会话(无报错、无跳转登录页)。
另外注册走原生WS {acc}协议而非REST,未接入CTRL_ERROR_TEXT_CN翻译表,
"internal error (500)"等错误会原样展示给用户。
第十轮最小粒度测试 Ch1-2 发现。
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com >
2026-09-06 00:46:27 +08:00
Your Name and Claude Sonnet 5
47148aa75d
修复登录页浏览器后退卡死、已认证态下登录/注册的凭据校验绕过、系统消息分页丢失等第1-2章问题
...
- 最主要的一处:登录成功后点浏览器"后退",会回到一个仍然认为"已登录"的底层连接、但重新挂载出来
的登录表单——按钮永久卡在禁用的"登录中…"(loginDisabled只有失败分支会重置,成功分支从来没有,
因为正常路径下这个页面早就导航走了,没人会看到);如果不管这个直接切换企业码后再次提交,
doLogin()/handleNewAccountRequest()开头的"已认证就直接放行"逻辑会让登录悄悄跳过凭据校验,
或者让注册请求收到后端原始英文错误"already authenticated (409)"。根治方式是在
handleHashRoute加一道门:hash指向登录/注册等纯"未登录态"视图、但连接其实已认证时,直接重定向
离开,不让这类表单有机会被重新渲染出来——已用真实浏览器验证4个入口(login/register/tenant/
reset/cred)全部正确重定向,且确认不影响真正的登录后安全类页面(如identity-check)。
handleLoginSuccessful也顺手补了loginDisabled:false兜底。
- 系统消息列表:后端`GET /system-notifications`明明返回`next_cursor`表示还有更多,前端从来没用过,
未读50+条永远只能看到最近20条、永远没法真正清零。补了"加载更多"分页——已用真实账号(60+条历史
通知)验证,点击后正确追加下一页、游标耗尽后正确不再显示按钮。
- 已处理(通过/拒绝)的好友申请通知,原来只要event_type以"friend.request"开头就显示"查看新朋友"
按钮——不区分"待处理"和"已是历史结果",点了跳到待处理列表也找不到对应项。改成只在
`friend.request.created`时显示,已用真实账号里同时存在created/accepted/rejected三种通知
验证行为符合预期。
- 注册页四处不统一的占位品牌名(讯工捷迅/捷信密使/捷讯/即时通讯,没有一个是真实品牌名)与
系统消息页脚"即时通讯安全团队",统一改用BASE_APP_NAME("MeetingIM")。
- config.js的KNOWN_HOSTS.hosted从web.tinode.co改为web.118im.com(这是WS连接失败时的最终
兜底地址,指向无关第三方域名不只是品牌问题,是真实会连错服务器);host-name.js的
detectServerAddress()原来只要hostname是localhost就无条件返回硬编码的localhost:6060,
完全不管页面实际监听的端口——本项目自己的开发代理跑在8093,清缓存后首次连接必然先撞一次
死连接,改成和非localhost分支一样用页面自己的真实端口。
- 实名认证提交成功后,姓名/证件号输入框原来会变成空白(后端成功响应不含masked_name/
masked_id_number,组件切到只读态时又没有回退到用户自己刚输入的草稿值)——改成没有脱敏字段时
回退显示用户本次会话里刚输入的原始值,不是留白。
- Firebase推送通知初始化失败原来复用登录/注册表单的错误提示通道,可能盖住一个同时发生的真实
登录错误,或在用户还没操作登录表单时就先弹出一条无关提示——推送本身是锦上添花功能,改成只
console记录+静默关闭开关,不再抢占登录页的错误展示位。
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com >
2026-09-05 18:36:03 +08:00
Your Name and Claude Sonnet 5
d573b38d10
第九轮(部分):修复日报徽章配色、彻底重做PIN定位方案、清理静态文件品牌残留
...
- 日报卡片"已提交/未提交"状态徽章补色:DailyReportCard用<article><header><em>结构,原选择器
要求.report-cards直接子<button>,日报卡片永远命中不了、只落到不分状态的兜底样式;月报因为
行本身就是<button>所以没受影响。详情页.report-author em同理补了区分色(原来恒为绿色,"未
提交"用绿色在语义上很怪)。
- 青少年模式/独立密码设置的PIN输入定位改用结构性方案,不再靠猜一个rem偏移量:给
.auth-pin-boxes/.auth-pin-input包一层.auth-pin-wrap,输入框inset:0精确覆盖方块的真实
渲染框,不管外层页面有没有标题、padding多少都自动对齐。上一轮的补丁(.youth-password-gate
.auth-pin-input{top:1.75rem})把重叠率从0%提到32.5%,本轮实测确认还是不够(方块下方
67.5%的面积点不中),根治后4个采样点(四角+中心)全部精确命中输入框。过程中额外发现并
修复了两个更隐蔽的层叠问题:全局input[type=text]的height:2.5rem特异度反超裸class、
textarea/input共享的margin:0.25rem重置——不清掉这两个会让inset:0看起来生效了、实际尺寸/
位置还是被悄悄改掉。
- .report-loading(举报原因页加载态)补基础样式,原来在base.css里零匹配,吃浏览器默认<p>样式。
- 清理静态文件里的Tinode品牌残留:index.html/index-dev.html的<meta>标签(application-name/
description/og:*/canonical,此前只改了<title>,meta标签一直没跟上)、manifest.json(name/
short_name/description改MeetingIM;prefer_related_applications+related_applications整个
删掉——这两个字段会让Android/Chrome"添加到主屏幕"时引导用户去装无关的第三方开源Tinode App,
不只是文案问题);删除.well-known/assetlinks.json(声明了无关第三方App对本域名的URL处理/
登录凭据代理权限,属于遗留模板残留,无真实对应关系,直接移除而非编造虚假内容)。
manifest.json里的图标文件(logo96.png/logo192.png/logo.svg)本身画的就是Tinode的蓝绿橙"t"标志,
是真实的视觉品牌泄漏,但重新设计一套图标涉及视觉识别决策,本次未动,留给用户决定。
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com >
2026-09-05 18:17:48 +08:00
Your Name and Claude Sonnet 5
d759f67b11
第八轮最小粒度测试:修复CSS选择器/JSX结构不匹配的一整类bug,清理Tinode品牌残留
...
第八轮改用"读CSS选择器+核对JSX结构"的方式复测全部11章,命中了7轮纯接口测试从未发现的一类
问题——选择器写对了但目标元素的实际DOM结构/className对不上,样式静默失效:
- 语音通话最小化胶囊按钮尺寸被同特异度规则覆盖;移动端悬浮通话窗口left/right/width三值同时
生效导致过度约束;来电全屏页认证徽章/姓名标题缺少专属样式覆盖
- 我的收藏-语音卡片三列grid对应实际只有1个子元素,播放器被压缩到卡片左侧一角;链接/记录头部
完全没有基础样式,退化成浏览器默认外观
- 多选模式下"收到的"消息气泡被flex auto-margin一起拖到最右侧;.avatar-box/#send-message-panel
两处逗号断句错误导致后半句选择器丢失祖先限定
- 按住说话悬浮反馈渲染成内联胶囊,而参考图要求的居中悬浮卡片样式其实已经存在(挂在了另一个非
生产demo组件上);批量转发确认框沿用了80%视口高度;audio-player.jsx的playback类点在canvas
上而非包裹层,波形和计时器可能纵向堆叠
- "消息已撤回"占位符误拼了日期分隔条的class而非专属的deleted
品牌清理:浏览器标签页标题、未读数标题更新均硬编码"Tinode";LINK_CONTACT_US等三个链接常量
指向开源Tinode项目自己的域名(联系我们改为跟用户条款/隐私协议一致的toast,不再发起外部mailto)。
以及:空会话丢失.chat-box样式类、青少年模式PIN定位、若干收藏/文件类型展示细节。
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com >
2026-09-05 17:09:42 +08:00
Your Name and Claude Sonnet 5
bede45fd7f
第七轮深度测试:修复7个agent发现的12处前端问题,重点是列表分页截断与呼叫/播放状态机
...
- 通话状态机(Ch8):canStartCall 补齐通话中重复发起的防护,callShouldStart 补齐放弃/失败路径的清理
- 分页截断(Ch5-6):新增 fetchAllPages 辅助函数,修复通讯录/黑名单/好友申请/群成员/管理员/禁言等
11 处列表只读首页导致真实成员被遗漏的问题;群角色判断改用不受分页影响的 getGroup().my_role
- 消息与媒体(Ch3-4/Ch7/Ch9):录音超时污染时长、手动重试丢失 head 导致消息被错误分类、批量删除
未取消上传中附件、语音播放器补齐同时只能播一条、workplace-collaboration-view 冗余重试请求
- 独立密码/青少年模式(Ch10-11):设置密码后按调用来源判断是否应自动开启青少年模式,避免关闭流程
中途"忘记密码"被误当成开启;注销账号确认文案补充群主后果说明
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com >
2026-09-05 12:18:25 +08:00
Your Name and Claude Sonnet 5
f42b8536e5
第六轮深度测试:7个并行agent覆盖全部11章,修复21处前端问题
...
Ch1-2: 用户名注册邀请码错误改为友好文案(原为原始TypeError泄露给用户);
企业注册页扫描图标补上点击反馈。
Ch3-4: 发名片消息补传typeHint(此前被后端误分类成text,搜索/历史摘要显示成JSON);
文件卡片按mime大类区分图标颜色(此前所有文件都是同一个灰色通用图标);
表情面板补上专属退格/发送按钮(浅蓝禁用/深蓝启用两态);订正一处与截图不符的代码注释。
Ch5-6: 群聊设置页"群成员"补上可点击的完整成员列表页(复用MemberPicker字母分组);
群文件页去掉无依据的硬编码"/10GB"容量上限显示。
Ch7: 收藏点击图片/视频缩略图补上预览;"查找聊天记录-链接"tab补上定位回原消息;
文件下载页返回入口按来源tab纠正;批量转发成功计数改为按目标会话去重
(原公式混用"收藏条数"和"目标会话数"两个维度,混选多条收藏转发时可能显示负数);
收藏/视频tab切换补上URL路由同步。
Ch8: topic.onInfo在通话期间补上事件转发(此前通话中"对方正在输入"和已读回执静默失效);
主叫等待接听页补上"正在等待对方接受邀请…"文案;语音通话最小化胶囊的还原按钮移出
拖拽区域(原来嵌在draggable内部,指针捕获可能吞掉点击);修复中等窗宽(641-750px)下
本地摄像头预览遮挡"切换摄像头"按钮的CSS重叠。
Ch9: 部门树展开时跳过child_count=0的注定空请求;月报字数上限从硬编码1000改为读取
后端真实的10000;发起会议补上"结束时间需晚于开始时间"的本地校验和更具体的报错;
日报/月报统计接口补上department_id透传(此前包装函数注释断言后端会忽略,实际已支持)。
Ch10-11: URL风险检测补上g标志(原来一条消息只检查第一个链接,第二个链接哪怕是高危
也不会被拦截);补上"安全教育"设置入口(原功能完整实现但零入口,需手改hash才能打开);
修改密码按钮补上busy态反馈;青少年模式PIN页补上"忘记独立密码"入口(后端已支持重置,
前端未接);"关于我们"补上"联系我们"行。
7个agent同时对全部11章存量后端问题条目逐一复核,结论详见待整理的后端问题清单更新
(Ch1-2发现一条P0级后端问题:验证码固定值"123456",已记录未修复,不在此commit修改
im_be仓库范围内)。
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com >
2026-09-05 03:48:28 +08:00
Your Name and Claude Opus 5
02b98cceae
修复全页面走查发现的问题(第二批:登录、通讯录、群聊)
...
第1章
- tinode-web: 手输密码登录失败会 navigateTo('') 把用户弹回企业码页,刚输的账号丢了,而
TenantEntry 不渲染 FormAlert,那句错误提示根本看不到。改成只有存储的 token 失效才回登录入口。
- auth-onboarding IdentityCheck: 限流 429 时服务端会连同未过期的 challenge_id 一起返回,
原来只显示错误文案、challengeId 留空,于是 submit 开头的守卫静默吞掉点击——输完验证码点
"确定"毫无反应也无提示。同文件 VerificationButton 早就处理对了,这里是漏抄。
- auth-onboarding Register: 手机号注册路径硬传 invite_code:'',把用户填的邀请码丢了。后端
user.go:175-181 对邀请码的校验和 RecordUse 不区分注册路径,UI 上也摆着这个输入框。
第5章
- 好友列表主副行显示同一串字:后端在有备注时把 display_name 也设成备注(im_http.go:8500-8507),
两个字段同值。加"不同才显示"的守卫。
- 拉黑确认弹窗把设置页当背景渲染并摆出"操作之后"的样子,但背景组件自己的 getUserProfile
回来后又把开关改回未拉黑、"删除好友"红条重新冒出来。加 pinBlocked 挡住这次覆盖。
第6章
- 群列表把群名显示成 topic id、成员数恒为 0。根因在后端:handler 用 store.Users.GetSubs,而
store 自己的注释就写着它 "Does not load Public/Trusted or Private"(store.go:834-835),
groupListItemPayload 却去读 sub.GetPublic()/GetSubCnt()(应该用 GetTopics)。已记为后端问题;
前端先用本地 Tinode 会话缓存兜底(消息首页一直这么取,是准的)。
- 禁言页每行头像画成群组图标(Avatar 兜底图标默认 'group',没传 icon="person"),
且顺带从成员表带上真实头像。
- 禁言页"以上成员不允许发言"被当成空状态用,语义正好反了——有禁言成员时这句消失、
一个都没有时反而显示。改为列表下方常驻注脚,空态另给文案,并补 .group-inline-note 样式。
- bytesToGB 只输出到 MB,1.4GB 的文件显示成 "1433.6 MB"。
- 群文件"来自"直接显示裸 uploader_id(groupFilePayload 不给昵称),拉成员表交叉引用。
- 群公告从聊天页横幅进入后返回,会把会话一起关掉:navigate 只写 query 参数,path[1] 仍为空,
handleHashRoute 就把 topicSelected 清成 null。Header 支持 onBack,显式把 topic 写回 path[1]。
- 群成员点头像打不开非好友资料页:目标页先读 'profile-seed:' 缓存,因为 getUserProfile 对
非好友直接 403。第5章入口一直有 seed,这里漏了。
- 群简介上限 225 超过后端硬限 200(im_http.go:4667),写满必被打回。
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com >
2026-09-03 18:40:53 +08:00
Your Name and Claude Opus 5
5a07bb4e3b
修复全页面走查发现的 P0 前端问题(第一批)
...
八个 agent 对 11 章逐页对照设计稿+后端源码后,先修其中"功能不可用/崩溃/谎报成功"级别的:
崩溃与数据错误
- content-library-view: Highlight 按 [start,len] 数组解构后端返回的 {start,end} 对象,
对象不可迭代会直接抛 TypeError,任何文本搜索命中都让整个结果区渲染崩掉。服务端偏移还叠加
两个问题(Go 字节下标 vs JS UTF-16;偏移基准是全文但 snippet 会被开窗截断),改为在展示
文本上本地匹配关键词。
- content-library-view: firstAttachment 用 Drafty.attachments,SDK 里硬过滤 tp=='EX'
只认文件附件,图片(IM)/视频(VD)/语音(AU) 一个都取不到——收藏缩略图、语音播放源、聊天记录
图片视频宫格全部拿不到资源。改用 Drafty.entities 按类型分派(chat-message.jsx 已有先例)。
- message-center-view: 系统通知的机器码兜底会把真实数据吞掉(日报提醒的 summary 就是日期
字符串 "2026-08-20",会议通知的 summary 是标题),改为查表命中才替换。
- message-center-view: 会话列表漏了 avatar 字段,每行都只能落到兜底图标;同文件
frequentContacts() 本来就是对的,照它补上。
功能不可用
- auth-onboarding-view: 首次开启青少年模式是死路——设完密码丢弃了服务端返回的
enable_action_token,从不调 enableYouthMode,用户走完短信验证+设密码后模式仍是关的。
现在拿着这个 token 把最后一步做完。
- group-management-view: "投诉/举报"是个 onToast('暂未开放') 死桩,而 target_type='group'
这条链路早就通了。接上真实举报页。
- tinode-web: 刷新/深链会被弹回首页。两个原因叠加:初始化白名单还是上游 Tinode 的
['cred','reset','register'];handleLoginSuccessful 无条件把 hash 改写成 workbench,
刷新触发的自动登录也走这条。抽出 SIDE_PANEL_VIEWS 常量复用,并区分登录流程与自动登录。
- widgets/meta-message: deleted 分支从未实现,撤回一条消息后时间线上什么都不剩。
谎报成功 / 判定错误
- tinode-web + personal-settings-view: 改密码不返回 Promise,服务端拒绝时照样弹"密码已更新"。
- group-management-view: 禁言批量读 result.succeeded,但该接口返回的是 {topic, items},
succeeded 恒为 undefined,不管成没成都弹"设置成功"。两个接口结构不同,分开判定。
- workplace-collaboration-view: 会议取消状态写成 'cancelled',后端是 'canceled' 单 l,
会议取消后"取消会议"按钮还挂着。
样式与显示
- base.css: 删掉旧版 .organization-department 的 padding-left !important,它压过按层级算出的
内联缩进,导致部门行全平、只有人员行缩进。
- base.css: 补 .youth-password-gate(原来 0 条规则),PIN 框缺 position:relative 和居中。
- security-support-view: shield_lock 不在经典 Material Icons 里(只有 Symbols),会显示成
字面文本;.risk-info-page 也是 0 条规则,整页渲染成裸项目符号列表。改用 verified_user 并
补上 .risk-dialog。
- contact-management-view: 好友资料页性别直接输出后端枚举,显示成 "male"。
- workplace-collaboration-view: 层级标注两条路径两种格式(树形深三层变"3级"、搜索硬传"三"),
统一成一个 helper。
已记录不在前端修的后端缺口:recallMessage 的 version 只能传 1,因为所有消息读取接口
(messagePayload/messageSearchPayload/mediaMessagePayload/favoriteSnapshot)都不下发 version,
冲突错误里也不回传真实值,被编辑过的消息撤回必然失败。
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com >
2026-09-03 18:31:26 +08:00
Your Name and Claude Sonnet 5
251c9de87c
Convert im_webapp from static mock prototypes to real backend integration
...
Implements all 11 product chapters (auth, messaging, contacts, groups,
files/favorites, calls, workplace/reports, settings, security) against the
real /v1/im REST API and native Tinode WS protocol, replacing the hardcoded
mock data the ba8f48ee prototype commit shipped with. Adds src/lib/im-api.js
as the REST client, plus supporting fixes across messages-view.jsx and the
attachment/upload/download pipeline (wrong SDK auth headers, group topic
naming, seq/timezone edge cases) found via live end-to-end testing against
the real backend.
Backup checkpoint before reconciling with origin/dev's parallel rewrite.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com >
2026-09-03 11:40:53 +08:00
richjohnrambo
ba8f48ee83
完成 IM Web Android 端产品页面开发
2026-08-25 18:30:40 +08:00