morethanwords/tweb/master • 08d07c2 • 4 files, +149/-21
Fix a forum row rendering two '@' badges for one mention
The unread badge turning into an '@' was decided from the unread topics while
the separate mentions badge was decided from the unread messages, so a forum
with a single unread topic holding more than one unread message rendered both
at once (#628). In "view as messages" both came from the same count, which is
why only one of the badges cleared per mode.
Both now come from one helper, which keeps them mutually exclusive by
construction instead of by the two counts happening to agree, and decides
"there is more unread than this mention" from the message count — the forum
tab's All Chats row suppresses its unread badge, so the mentions badge is the
only indicator it has. The Community row counted its chats the same way and
gets the same treatment.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
morethanwords/tweb/master • 108d3f3 • 16 files, +386/-121
Speed up the chat list
The collapsed-Community projection key walked the whole peer store with
Object.values(). That store is a reactive proxy, so the walk allocated a signal
per peer and subscribed the memo to all of them: ~1.1s of main thread on a
2000-chat account, re-run whenever any peer changed at all — an unrelated user
coming online was enough. It now looks up only the known Community ids, the way
the worker's getCollapsedCommunityPeerIds already did.
Every row of the main list also carried the Community child badge as a custom
element, so the virtual list tore its reactive root down and rebuilt it on every
scroll pass — 93% of a row's whole mount cost, paid whether or not the account
belongs to a single Community. The badge's lifetime now follows the dialog
element instead of DOM connectedness.
Rows that arrived already loaded were revealed one per ~8ms timer, so a window
of them needed as many serial hops to show up; the whole ready batch goes at
once now. The shrink check kept its debounce — it must not cut the list out from
under a running scroll — but re-armed the timer on every row mount and unmount,
where one timer re-checking on each tick debounces the same way for a fraction
of the traffic. The awaiting-task debug name was built on every single invoke
even though only the stuck watchdog and the debug log ever read it.
Touching the projection key turned up the predicate behind it spelled out in
seven places, three of them inverted, and the peer-to-Community lookup in four
more; isCollapsedCommunity() and getLinkedCommunityId() now hold both. The copy
in the Community's own settings tab is left alone on purpose and says why: it
mirrors the flag for a toggle rather than asking whether the Community folds
chats into our list, so it must not demand membership.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
morethanwords/tweb/master • 81ac5d4 • 300 files, +1362/-1374
Build
#webk
Post #20526
161
- 🫡 4