Skip to content

fix(core): truncate channel state before reloading latest messages#2690

Merged
xsahil03x merged 1 commit into
masterfrom
fix/reload-channel-truncate
May 26, 2026
Merged

fix(core): truncate channel state before reloading latest messages#2690
xsahil03x merged 1 commit into
masterfrom
fix/reload-channel-truncate

Conversation

@xsahil03x
Copy link
Copy Markdown
Member

@xsahil03x xsahil03x commented May 26, 2026

Summary

StreamChannel.reloadChannel was leaving the previously loaded window in place and merging the latest page on top of it via channel.query. After a loadChannelAtMessage(...) jump, that left the around-message window glued to the freshly loaded latest 30 — older messages from before the reload were still in channel.state.messages, and the "scroll to bottom" FAB landed the user on a state that didn't match a fresh open of the channel.

Repro

  1. Open a channel scrolled to the bottom (X is one of the visible messages).
  2. Tap a quoted reference inside X to jump to an older message Y (the quoted target).
  3. loadChannelAtMessage(Y) runs; channel state becomes the around-Y window — X is no longer loaded.
  4. Tap the scroll-to-bottom FAB. StreamMessageListView calls reloadChannel() because !_upToDate.
  5. Before the fix: state is around-Y ∪ latest 30 (~60 messages). X is unreachable without paginating back; the FAB lands on a state with stale older messages glued underneath the latest.
  6. After the fix: state is just the latest 30 — same as a fresh open.

What changed

-/// Reloads the channel with latest message
-Future<void> reloadChannel() => _queryAtMessage();
+/// Reloads the channel with latest messages, replacing the loaded window.
+Future<void> reloadChannel() {
+  channel.state?.truncate();
+  return _queryAtMessage();
+}

The truncate has no effect on persistence — only the in-memory loaded window is cleared. Persistence still hydrates older messages on a fresh session.

The three callers of reloadChannel() semantically want "reset to latest":

Caller Trigger Now
MessageListCore.paginate* pagination failure on a stale window reload to a fresh latest 30
StreamMessageInput-style send-from-stale-state sending while not at the latest reload to a fresh latest 30 before sending
StreamMessageListView.scrollToBottomDefaultTapAction FAB tap when !_upToDate reload to a fresh latest 30, then scroll to index 0

Test plan

  • flutter test packages/stream_chat_flutter_core/test/stream_channel_test.dart — 25/25 pass (2 new)
  • flutter test packages/stream_chat_flutter_core — 191/191 pass
  • dart analyze --fatal-infos packages/stream_chat_flutter_core/lib/src/stream_channel.dart — clean
  • CI green
  • Manual: tap quoted older message → scroll-to-bottom FAB → state is just the latest page

New tests

reloadChannel truncates the existing window before querying the latest messages
reloadChannel queries with no around-anchor (loads the latest page)

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes

    • Fixed channel reload so new messages replace the existing message window instead of merging with it, matching a fresh open behavior.
  • Tests

    • Added tests verifying previous messages are cleared before fetching and only the latest page is retained after reload.

Review Change Stack

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 26, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: b5c367cb-e4bd-4efd-a36b-539b19af3c2c

📥 Commits

Reviewing files that changed from the base of the PR and between 9452ad4 and efa259c.

📒 Files selected for processing (3)
  • packages/stream_chat_flutter_core/CHANGELOG.md
  • packages/stream_chat_flutter_core/lib/src/stream_channel.dart
  • packages/stream_chat_flutter_core/test/stream_channel_test.dart
✅ Files skipped from review due to trivial changes (1)
  • packages/stream_chat_flutter_core/CHANGELOG.md

📝 Walkthrough

Walkthrough

Calls channel.state?.truncate() before reloading latest messages so reload replaces the existing pagination window; adds widget tests verifying truncation-order, pagination args (no around anchors), and that old messages are dropped; updates CHANGELOG.

Changes

reloadChannel Truncation and Reload

Layer / File(s) Summary
reloadChannel implementation and tests
lib/src/stream_channel.dart, test/stream_channel_test.dart
StreamChannelState.reloadChannel() calls channel.state?.truncate() before _queryAtMessage(). New widget tests setup mutable stateMessages, verify truncate() is called before channel.query() (ordered), assert messagesPagination passed to query() has idAround and createdAtAround null, and confirm final state contains only the latest page.
Changelog documentation
CHANGELOG.md
Adds an "Upcoming" → "🐞 Fixed" note stating reloadChannel now replaces the loaded pagination window instead of merging new pages onto the previous window.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Suggested reviewers

  • VelikovPetar
  • Brazol

Poem

🐰 I nibbled old pages, then made them go,
Truncate the past, let the new messages show.
Fetch fresh pages in tidy array,
No more old crumbs left in the way. 🥕

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'fix(core): truncate channel state before reloading latest messages' clearly and specifically describes the main change: calling truncate() before reloading. It accurately reflects the core modification in the codebase.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/reload-channel-truncate

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@xsahil03x xsahil03x force-pushed the fix/reload-channel-truncate branch from 4822e25 to 9452ad4 Compare May 26, 2026 13:19
`StreamChannel.reloadChannel` was leaving the previously loaded window in
place and merging the latest page on top of it via `channel.query`. After
a `loadChannelAtMessage(...)` jump, that left the around-message window
glued to the freshly loaded latest 30 — older messages from before the
reload were still in `channel.state.messages`, and the "scroll to bottom"
FAB landed the user on a state that didn't match a fresh open of the
channel.

Truncate the existing state before the `_queryAtMessage()` call so a
reload behaves like the initial open.

Adds two tests:
- `truncates the existing window before querying the latest messages`
- `queries with no around-anchor (loads the latest page)`

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@xsahil03x xsahil03x force-pushed the fix/reload-channel-truncate branch from 9452ad4 to efa259c Compare May 26, 2026 13:24
@xsahil03x xsahil03x enabled auto-merge (squash) May 26, 2026 13:26
@xsahil03x xsahil03x merged commit 8b7b890 into master May 26, 2026
20 checks passed
@xsahil03x xsahil03x deleted the fix/reload-channel-truncate branch May 26, 2026 13:33
@codecov
Copy link
Copy Markdown

codecov Bot commented May 26, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 65.33%. Comparing base (508c019) to head (efa259c).
⚠️ Report is 1 commits behind head on master.

Additional details and impacted files
@@           Coverage Diff           @@
##           master    #2690   +/-   ##
=======================================
  Coverage   65.33%   65.33%           
=======================================
  Files         423      423           
  Lines       26646    26648    +2     
=======================================
+ Hits        17408    17410    +2     
  Misses       9238     9238           

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants