fix(llc): keep Channel.memberCount fresh from channel events, make primitive value streams distinct - #2936
Conversation
`Channel.memberCount` / `memberCountStream` only ever reflected the `member_count` returned by `query` / `watch` and `channel.updated`. The `member.added` / `member.removed` handlers update the loaded member list but leave the count untouched, so it went stale for the rest of the session as soon as anyone joined or left. The backend already ships the authoritative count as `channel_member_count` event metadata on channel events, next to the `channel_message_count` we already consume. Parse it into `Event.channelMemberCount` and apply it to the channel state, folding both counters into a single listener so one event produces one state update. Co-authored-by: Claude Opus 5 <noreply@anthropic.com> (cherry picked from commit 9610ce2)
Channel and ClientState getters that map to a single primitive value now dedupe, so listeners only wake up when the value actually changes rather than on every channel state or current user update. The message input's redundant `distinct()` on the draft stream is dropped, as `ChannelClientState.draftStream` and `threadDraftStream` already dedupe. Port of #2935 from master. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Team Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## v9 #2936 +/- ##
=====================================
Coverage ? 67.41%
=====================================
Files ? 431
Lines ? 27444
Branches ? 0
=====================================
Hits ? 18500
Misses ? 8944
Partials ? 0 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
Submit a pull request
Linear: FLU-
Github Issue: #
CLA
Description of the pull request
Backports two
llcchanges frommastertov9, one commit each. They are ordered: the second rewrites thememberCountStreamtest the first adds.1. Keep
Channel.memberCountfresh from channel eventsBackport of
9610ce2(originally #2933).Channel.memberCount/memberCountStreamonly ever reflected themember_countreturned byquery/watchandchannel.updated. Themember.added/member.removedhandlers update the loaded member list but leave the count untouched, so it went stale for the rest of the session as soon as anyone joined or left. The handlers are byte-for-byte identical from3.0.0onwards, so this is not a regression.The backend already ships the authoritative count as
channel_member_countevent metadata on channel events, next to thechannel_message_countwe already consume. This addsEvent.channelMemberCount, applies it toChannelModel.memberCount, and folds both counters into a single_listenChannelCountslistener so an event carrying both produces one state update.Port notes
event.g.darthand-edited, not regenerated. Master's generated output uses Dart 3.10 null-aware map elements ('key': ?instance.x), whichv9'ssdk: ^3.6.2rejects. The two added lines followv9's existingif (instance.x case final value?)form, matching the adjacentchannel_message_countentry.v9at the 80-col default, so the ported test hunks were rewrapped.event_test.dart/test/fixtures/event.json. Extended here forchannel_member_count, following what fix(llc): update watcher count from realtime events and ignore events after dispose #2898 did forwatcher_counton this branch.2. Make primitive value streams distinct
Backport of
5dce4c9(originally #2935).ChannelandClientStategetters that map to a single primitive value emitted on every channel-state / current-user update, even when the value was unchanged — pushing four distinct message counts throughmessageCountStreamproduced 13 emissions, andmemberCountStreamfired on every new message.Those getters now
.distinct(), matching the stream getters inchannel.dartthat already do (ownCapabilitiesStream,messagesStream,draftStream, …). Scope is primitives only (bool,int,String?,DateTime?); model and collection streams are untouched. All 19 call sites from the master change are present onv9and were ported.Port notes
distinct()instream_message_composer.dart, which does not exist onv9. The equivalent line lives instream_message_input.dart:615and covers the same two-arm switch; verified that bothChannelClientState.draftStreamandthreadDraftStreamalready dedupe onv9, so dropping it is a no-op here too.Verification
melos run format— clean (0 changed).melos run analyze— no issues in any package.stream_chat: 1333 pass, 2 skipped, 0 fail.stream_chat_flutter_core: 231 pass.stream_chat_flutter(CI=true): 824 pass, 20 fail — all golden variants inavatars/gradient_avatar_test.dart, pre-existing local-vs-CI rendering drift unrelated to these changes.Screenshots / Videos
No UI changes.