现象:在会话A输入含链接的消息并点发送,POST /security/urls/check 请求还未返回时切换到 会话B,请求返回后风控弹窗会在会话B里弹出(本该属于会话A),此时点"继续发送",消息被 真实发进了会话B,而不是最初输入它的会话A——跨会话消息误投递。 复现:会话A(kcg051307)输入"https://example.com/racefix?token=fix002"点发送,立即 (在checkURL网络请求返回前)切换到会话B(r12c56b2),风控弹窗在会话B视图下弹出;点 "继续发送"后消息被投递进会话B,会话A完全没有收到,会话B收到了本不该发给它的内容 (本次因B恰好还不是好友触发"发送失败"提示,但发送动作本身已经指向了错误的会话, 如果B是好友会真实送达)。 根因:`getDerivedStateFromProps`在话题切换时会把`riskDialog`重置为null,但这只能防住 "弹窗已经弹出、随后切换话题"这一种时序——它防不住"checkURL还在进行中就切换话题, 此时机的.then()回调在切换之后才执行"这种反过来的时序:这次setState({riskDialog:{...}}) 是在切换完成之后才发生的,不会被这次重置覆盖,于是在当前(错误的)话题下重新弹出弹窗, 且弹窗里的`doSend`闭包沿用的是`this.props.sendMessage`,按确认时的当前话题发送, 不是消息最初输入时所在的话题。 修法:sendMessage()进入URL风险检测分支时已经缓存了`topicForDraft`(用于清草稿), 在checkURL的.then()回调最开头加一道判断——如果`this.state.topic`已经不等于 `topicForDraft`,说明用户已经离开发起这次检测的会话,直接返回false(视同消息被放弃, 不弹窗、不发送),不再继续读取风控结果或setState。这与本文件已有的"两条风险消息连续 触发、后一个覆盖前一个"场景处理逻辑(resolve(false)后覆盖)是同一种"宁可丢弃، 不可 错误投递"的一贯取舍,只是这次要防的是切换会话而不是重复触发。 验证:npm run build:dev后浏览器实测——(1) 会话A输入风险链接点发送,立即切换到会话B, 2秒后确认会话B里没有弹出风控弹窗(修复前必现);(2) 切回会话A确认最后一条消息仍是修复 前测试遗留的旧消息,本次新消息没有出现在A也没有出现在B,两个会话都没有收到,符合 "宁可丢弃不可错投"的设计;(3) 对照组(不切换话题、正常触发风控)依旧能看到弹窗并正确 发送/取消,未被这次改动影响。 Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Tinode Web
Briefing
Single-page web chat application for Tinode. The app is built on React. The Tinode javascript SDK has no external dependencies. Overall, it's a lot like open source WhatsApp or Telegram web apps.
Although the app is generally usable, keep in mind that this is work in progress. Some bugs probably exist, some features are missing. The app was tested in the latest Chrome & Firefox only. NPM package is available.
Try possibly newer or older version live at https://sandbox.tinode.co/.
For demo access and other instructions see here.
Installing and running
This is NOT a standalone app, this is just a frontend, a client. It requires a backend. See installation instructions. See instructions for enabling push notifications.
Getting support
- Read client-side and server-side API documentation.
- For support, general questions, discussions post to https://groups.google.com/d/forum/tinode.
- For bugs and feature requests open an issue.
- Use https://tinode.co/contact for commercial inquiries.
Helping out
- If you appreciate our work, please help spread the word! Sharing on Reddit, HN, and other communities helps more than you think.
- Consider buying paid support: https://tinode.co/support.html
- If you are a software developer, send us your pull requests with bug fixes and new features.
- If you use the app and discover bugs or missing features, let us know by filing bug reports and feature requests. Vote for existing feature requests you find most valuable.
- If you speak a language other than English, translate the apps into your language. You may also review and improve existing translations.
- If you are a UI/UX expert, help us polish the app UI.
- Use it: install it for your colleagues or friends at work or at home.
Internationalization
The app is fully internationalized using React-Intl. The UI language is selected automatically from the language specified by the browser. A specific language can be forced by adding #?hl=XX parameter to the URL when starting the app, e.g. https://web.tinode.co/#?hl=fr.
The app is currently available in the following languages:
- English - default
- Arabic
- Chinese simplified
- Chinese traditional
- French
- German
- Italian
- Korean
- Romanian
- Russian
- Spanish
- Thai
- Ukrainian
- Vietnamese
More translations are welcome. See instructions.
Not done yet
- End-to-End encryption.
- Emoji support is weak.
- Mentions, hashtags.
- Previews not generated for links and docs.
- Location and contact sharing.
- Recording video messages.
Other
- Demo avatars and some other graphics are from https://www.pexels.com/ under CC0 license.
- Background patterns from http://subtlepatterns.com/, commercial and non-commercial use allowed with attribution.
- Fonts and icons from Google under license which permits commercial and non-commercial use.
- Push notifications built with https://firebase.google.com/.






