Keep hidden channels out of the channel list when member or channel updates arrive - #6702
Conversation
PR checklist ✅All required conditions are satisfied:
🎉 Great job! This PR is ready for review. |
SDK Size Comparison 📏
|
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Advanced Run ID: 📒 Files selected for processing (7)
Included review availability: Your plan provides up to 4 included reviews per hour; 3 remain after this review. WalkthroughThe PR prevents hidden channels from being re-added by membership and grouped event handlers. It adds sequential event regression tests. It also passes the current user ID to unread-count synchronization and verifies behavior without a connected user. ChangesHidden channel routing
Unread user context
Priority: ⬇️ Low Estimated code review effort: 3 (Moderate) | ~25 minutes Change: Bug fix Suggested reviewers: Merge Risk: ⚪ Minimal · up to The change keeps hidden channels out of query results after update events and avoids disconnected-user unread-count failures. No merge-blocking risk was identified. 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches 💡 1📝 Generate docstrings 💡
🧪 Generate unit tests (beta)
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. A rabbit guards the hidden stream, Comment |
andremion
left a comment
There was a problem hiding this comment.
Looks good. One optional nit inline.
|
|
🚀 Available in v7.12.0 |



Goal
A channel hidden via
channel.hiddenis put back into the channel list by achannel.updatedormember.updatedfor the same channel, and stays there until the app restarts. Neither add path checks whether thechannel is hidden.
Port of #6697 to develop.
Part of AND-1530
Implementation
DefaultChatEventHandler.addIfMembershipUpdatedwhen the cached channel is hidden. This is themember.updatedpath, and the only one that applies to plain channel lists, since the base handler already skipschannel.updated.GroupAwareChatEventHandler.routeByGroupwhen the cached channel is hidden, and remove the channel ifit is still listed. This is the
channel.updatedpath; the default group resolver always resolves a channel intothe
allsentinel group, so anallgrouped query took the add unconditionally.ChannelStateLegacyImpl.toChannel()resolves the current user from theuserFlowit already holds instead of theChatClientsingleton. Same value, and it lets the state layer be exercised without a built client.ChannelStateImplneeds no equivalent change, it does not sync unread counts there.hiddenis per-user and absent fromchannel.updatedpayloads, so both guards read the cached channel. Per-channelevent handling runs before query handling in the same batch, so for a channel whose state is active in memory the flag
is current.
parseChatEventResultsfalls back to the database for channels that are not active, and the database isonly written after query handling, so on that fallback the guard sees the pre-batch value and does not fire.
The new-message add paths stay unguarded: a non-shadowed message clears
hiddeninChannelEventHandler, which iswhat makes a hidden channel resurface legitimately. iOS does the same in
ChannelVisibilityEventMiddleware, since thebackend sends no
channel.visiblein that case.Testing
EventHandlerSequentialHiddenChannelTestdrivesEventHandlerSequentialover the realStateRegistryandLogicRegistry. It replays the reported batch (notification.mark_read,channel.hidden,channel.updated,member.updated) against a grouped query, and covers a plain query hidden in one batch and updated in the next.Both fail without the guards. A third case asserts the same batch without the hidden event still adds the channel,
and a fourth asserts a new message brings a hidden channel back.
DefaultChatEventHandlerTestandGroupAwareChatEventHandlerTest, including ahidden channel already in the list being removed.
hidden channel returns to the list on the following
member.updated, with it the channel stays out and a newmessage still brings it back. This port carries no behavioural difference from that build.
Summary by CodeRabbit