Three parallel adversarial code-review passes surfaced real defects across the app. This commit covers the data/logic layer: - CRITICAL: file upload/download used the wrong auth header entirely. Built from docs/IM-前后端对接文档.md as `X-MeetingIM-Auth: token <token>`, but the old app's own upload code carries an explicit comment that the real header is `Authorization: Token <token>` (capitalized scheme, standard header name), "verified live against the real server, not just read from source" -- and separately warns the SDK's own built-in LargeFileHelper gets this wrong too (sends X-Tinode-APIKey/X-Tinode-Auth, which this backend doesn't recognize). This means every external (non-inline) image/file/voice attachment -- anything too large to send as base64 -- was silently broken; only the earlier live tests happened to use small inline attachments, which never exercise this code path. Confirmed fixed live: a real >256KB image now uploads (200, real file_id) and downloads (blob URL, correct 800x600 dimensions) correctly. - CRITICAL: TopicMe.onContactUpdate was never wired. Marking a conversation read (topic.noteRead()) updates the contact's unread count through ONLY this single-slot callback (confirmed against the SDK's own Topic.note()/TopicMe._refreshContact -- it does not also fire onData/ onInfo/onPres, unlike every other _refreshContact call site, which do). Without it the chat list's unread badge/ordering went stale after reading a conversation until an unrelated topic event happened to invalidate the shared snapshot cache. - HIGH: chat-list message preview didn't check isServerDeleted(msg) (the `hi` soft-delete flag), only `content == null` -- a hi-flagged message with non-null content leaked its real text/attachment label into the preview instead of showing "[消息已删除]". - MEDIUM: upload failures showed raw untranslated SDK ctrl.text (e.g. "too large" instead of "文件大小超出限制") -- ported the old app's UPLOAD_CTRL_TEXT_CN table, which it built specifically because this native-protocol endpoint's errors never pass through the REST layer's own reason-code translation. - Ambient SDK type corrections (tinode-sdk.d.ts): AccessMode.mode/given/want are numeric bitmasks at runtime, not the "JRWPS"-string type they were declared as (dormant today, nothing reads them yet, but wrong ahead of Phase 3's group-role logic); Drafty.sanitizeEntities's doc comment claimed a deep copy it doesn't do (verified it mutates entity .data in place); onAutoreconnectIteration's first param was misnamed "seconds" when the SDK always passes milliseconds. - sendVoice() now passes `filename` to Drafty.insertAudio (was the only one of sendImage/sendFile/sendVoice omitting it). - friends.ts's accept/reject-friend-request `version` param used a falsy check (`version ? ... : ...`) that would silently drop a legitimate `0`. 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/.






