fix(llc, core, ui, localization): latest QA#2636
Conversation
…dKeepAlive duration
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>
|
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: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 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. Comment |
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>
`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 Report❌ Patch coverage is 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. 🚀 New features to boost your workflow:
|
No description provided.