Skip to content

fix(llc, core, ui, localization): latest QA#2636

Merged
xsahil03x merged 28 commits intov10.0.0from
fix/latest-qa
May 1, 2026
Merged

fix(llc, core, ui, localization): latest QA#2636
xsahil03x merged 28 commits intov10.0.0from
fix/latest-qa

Conversation

@xsahil03x
Copy link
Copy Markdown
Member

No description provided.

xsahil03x and others added 14 commits April 30, 2026 17:03
The backend strips `poll` and `quoted_message.poll` on partial payloads
(`/sync` replays of `message.new`, and `message.updated` events fired
after a thread reply). The previous `Message.syncWith` took the server
payload as the base, so these omissions clobbered locally-cached values
— polls and quote-of-poll previews vanished after the app came back
from background.

Replace `syncWith` with `updateWith`, which preserves the local `poll`,
`sharedLocation`, `ownReactions`, and nested `quotedMessage` when the
server payload omits them, and reconciles `quotedMessage` recursively
so two-level quote chains also survive a stripped payload.

Update `_mergeMessagesIntoExisting` to use the new merge and replace
embedded `quotedMessage` references with the fully-formed top-level
copy from the merged set.

Add unit tests for `Message.updateWith` (extend `createTestMessage` so
poll/quotedMessage cases can use the helper) and channel-level tests
exercising the merge via `updateChannelState` and `messageUpdated`
events.

`syncWith` kept as a deprecated shim.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Auto-calculate thumbnail pixel size from each tile's layout × DPR (with a
132px Figma default fallback) so we never decode more bitmap than the tile
actually paints. Extends ThumbnailSizeCalculator with full BoxFit support
(cover/fill use cover-style sizing to avoid upscale blur; null defaults to
scaleDown to match paintImage). Renders StreamImageErrorPlaceholder via
errorBuilder when a thumbnail fails to load.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds entries for the gallery thumbnail placeholder/error handling/
auto-sizing, the poll comment & suggest-option dialog empty-submission
fix, and the new StreamMessageAttachment exports. Also tightens the
verbose llc and core entries (reactions/polls/quotes flicker, attachment
upload hang, recoverStateOnReconnect, backgroundKeepAlive default) to
match the terse sibling style.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 1, 2026

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 327daa54-4f1f-44bf-a08a-37140069f9b1

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/latest-qa

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 and others added 3 commits May 1, 2026 13:56
Suggest-an-option (and other) dialogs were rendering their button
labels in uppercase via `.toUpperCase()` over `cancelLabel` /
`sendLabel`. The widget-side `.toUpperCase()` calls and the legacy
uppercase translation defaults (`flagLabel`, `cancelLabel`,
`deleteLabel`) were both removed; documenting in
`stream_chat_flutter` and `stream_chat_localizations`.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The merge that fixes the poll / quote / reactions flicker introduced
`Message.updateWith` and deprecated `Message.syncWith`. The two have
flipped argument order, so call out the rename and the migration in
the Added and Deprecated sections of stream_chat.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
xsahil03x and others added 8 commits May 1, 2026 15:08
`Channel.sendReaction`'s rollback path calls `state.updateMessage(originalMessage)`
to undo the optimistic reaction. With `ownReactions` preserved when the
incoming payload's was null, the merge would re-keep the optimistic
`[reaction]` for messages that previously had no reactions (the original
message constructor leaves `ownReactions` at null).

Two regression tests in `channel_test.dart`:
- `.sendReaction should restore previous message if client.sendReaction throws`
- `.sendReaction in thread should restore previous thread message if client.sendReaction throws`

The original `syncWith` never preserved `ownReactions`, and the f8f8db3
fix didn't actually need the preservation (the reactions flicker is
addressed at a higher level by `recoverStateOnReconnect` in a5dfcd3).
Drop that one field; the legitimate `poll` / `sharedLocation` /
`quotedMessage` preservation stays intact.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…eWith"

This reverts commit 1cedf9f47e185474ae4268f9d38e9054d73bbb99.
`Channel.sendReaction` / `deleteReaction` rolled back via
`state.updateMessage(originalMessage)`, which goes through
`_mergeMessagesIntoExisting` → `Message.updateWith`. The merge preserves
the local `ownReactions` when the incoming payload's is `null`, so the
rollback couldn't clear an optimistic reaction added to a message that
previously had no reactions (`ownReactions: null`).

Add `replaceMessage(Message)` for strict overwrites — same shape as
`updateMessage` but bypasses the merge. Internally `_updateMessages`
takes an optional `merge: bool` flag (default `true` keeps every
existing caller on the merge path) that's threaded through to
`_mergeMessagesIntoExisting`. The existing `Message.updateWith`
enrichment preservation (poll, sharedLocation, ownReactions, nested
quote) stays intact for the event-replay paths it was designed for.

Switch the two reaction rollback paths to `replaceMessage`. Tests:
- `.sendReaction should restore previous message if client.sendReaction throws`
- `.sendReaction in thread should restore previous thread message if client.sendReaction throws`
- All 357 channel + message tests pass.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Threads `Message Function(Message, Message) update` through the
internal `_updateMessages` chain instead of `bool merge = true`,
matching how `stream-feeds-flutter` (via `stream_core`'s
`ListExtensions.upsert` / `merge`) lets callers pick semantics by
passing a callback.

Two static helpers on `ChannelClientState`:
- `_mergeUpdate` (default) — reconciles via `Message.updateWith`,
  preserves locally-known enrichment.
- `_replaceUpdate` — takes the incoming as-is, used by `replaceMessage`.

`replaceMessage` now passes `update: _replaceUpdate` instead of
`merge: false`. No behavior change — just the lever shape.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Match the label-case change from e8c3348 so DeleteMessageDialog,
PollDeleteOptionDialog, PollOptionReorderableListView, and PollEndVoteDialog
tests find the actual rendered 'Delete'/'Cancel'/'End' buttons.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
After a5dfcd3 the disconnect always goes through backgroundKeepAlive,
so the test must run async with a short keep-alive and await the timer
before verifying closeConnection — matching the existing timer-expiry test.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
After a5dfcd3 the disconnect path is identical with or without a
handler — both go through the keep-alive timer. The no-handler test
now asserts the only remaining distinction (no client.on subscription),
and a new group covers the recoverStateOnReconnect=false toggle on
initState and on client swap in didUpdateWidget.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@codecov
Copy link
Copy Markdown

codecov Bot commented May 1, 2026

Codecov Report

❌ Patch coverage is 71.87500% with 54 lines in your changes missing coverage. Please review.
✅ Project coverage is 67.13%. Comparing base (45dde33) to head (583191e).
⚠️ Report is 1 commits behind head on v10.0.0.

Files with missing lines Patch % Lines
..._view/photo_gallery/stream_photo_gallery_tile.dart 0.00% 29 Missing ⚠️
...ib/src/poll/interactor/poll_options_list_view.dart 70.27% 11 Missing ⚠️
...r/lib/src/message_list_view/message_list_view.dart 50.00% 4 Missing ⚠️
...flutter/lib/src/message_widget/message_widget.dart 0.00% 4 Missing ⚠️
...ttachment/voice_recording_attachment_playlist.dart 66.66% 3 Missing ⚠️
...at_flutter/lib/src/audio/audio_playlist_state.dart 50.00% 1 Missing ⚠️
...b/src/poll/interactor/poll_add_comment_dialog.dart 83.33% 1 Missing ⚠️
...rc/poll/interactor/poll_suggest_option_dialog.dart 83.33% 1 Missing ⚠️
Additional details and impacted files
@@             Coverage Diff             @@
##           v10.0.0    #2636      +/-   ##
===========================================
+ Coverage    67.04%   67.13%   +0.09%     
===========================================
  Files          418      418              
  Lines        25146    25200      +54     
===========================================
+ Hits         16860    16919      +59     
+ Misses        8286     8281       -5     

☔ 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.

@xsahil03x xsahil03x merged commit c2cdf29 into v10.0.0 May 1, 2026
14 of 15 checks passed
@xsahil03x xsahil03x deleted the fix/latest-qa branch May 1, 2026 15:44
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.

3 participants