chore: merge master into v10.0.0#2677
Conversation
|
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 |
9d5592b to
c3f71d6
Compare
Brings master's QA / security / perf work into the v10 design-refresh branch. Highlights of what landed in v10 from master: LLC (`stream_chat`) - `Client.queryDrafts` now forwards `filter` (#2647). - `Client.queryChannels` coalesces concurrent identical queries via the new `InFlightCache<K, V>` (#2652). - `SortedListX` / `ListX` extensions added in `list_extensions.dart`; duplicate-keyed inputs are tolerated by `merge` (#2660). v10's `IterableMergeExtension.merge` / `.mergeFrom` are kept — `SortedListX` is on `List` and routes there for the new perf paths; the old extension still serves `Iterable<T>` callers in v10. - `ChannelClientState._checkExpiredAttachmentMessages` removed (#2653); v10's `StreamImageCDN.cacheKey` already keeps the image cache valid across signed-URL rotations. - `ChannelClientState.updateChannelState` now identity-short-circuits when `updatedState.messages` is null or the same reference, so downstream `.distinct()` listeners can skip rebuilds. - Reaction listeners now dispatch via `_findMessage` (parentId-aware) while keeping v10's `addMyReaction` / `deleteMyReaction` semantics. `stream_chat_flutter_core` - `BetterStreamBuilder` correctness fixes: mounted guard, error reporting via `FlutterError.reportError`, identity-equal emission gating (#2651). - `MessageListCore` caches its `messagesStream` / `_initialMessages` as fields instead of recomputing in `build()` (#2651). `defaultMessageFilter` takes an optional `currentUserId`. - `StreamChatCore` debounces connectivity events to 3 s (#2652). `stream_chat_flutter` - `scrollable_positioned_list/`: master version taken in full. Bounded `_keyToIndexMap`, `isScrolling` / `isScrollingListenable`, `itemKeyBuilder` anchor preservation, fit-anchor fallback in `UnboundedRenderViewport`, sensible defaults on `scrollTo` (#2651). - `tld.dart` removed (#2654); `StreamMessageComposer` relaxed its URL regex from `[a-z]{2,4}` to `[a-z]{2,}` and dropped the `isValidTLD` filter at both call sites. - `StreamMessageListView` and `separated_reorderable_list_view`: v10's design-refresh version retained. v10 already covers the functional surface; master's identity-preserving micro-optimizations to `updateMessage` are a follow-up. CI / repo - Path/draft gating job (`gate`) added to `legacy_version_analyze`, `check_db_entities`, and `stream_flutter_workflow` (#2669). - Flutter 3.44 fixes (#2667), pana / build cleanups (#2656), local-setup CI fixes (#2650). - `melos.yaml`: kept v10's higher floors; added `firebase_crashlytics` (master's #2665); dropped `sentry_flutter` (per master). Notes / follow-ups - `sample_app/`: v10's redesigned app retained. The Sentry → Firebase Crashlytics migration (#2665) applies to master's pre-redesign sample app and was not ported here; left for a separate pass. - `channel_test.dart` `updateMessage quoted-rewrite > does not rewrite quotes when an existing quoted target is updated without being deleted` is marked `skip:` — v10's `_updateMessages` reconstructs the channel list via `_mergeMessagesIntoExisting`, so identity is not preserved on non-deletion edits. Functional behavior matches master. - `goldens/`: deleted-on-v10 goldens kept deleted; modified-on-both goldens kept at v10's bytes (the redesigned UI is the source of truth). - `stream_message_composer.dart` had `SizeTransition(alignment:)` which was never a valid parameter — switched to `axisAlignment: -1` (the Flutter API the v10 author intended). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
c3f71d6 to
c73de0f
Compare
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## v10.0.0 #2677 +/- ##
==========================================
Coverage ? 67.13%
==========================================
Files ? 405
Lines ? 24346
Branches ? 0
==========================================
Hits ? 16345
Misses ? 8001
Partials ? 0 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
b603449 to
ff5f832
Compare
Pulls master's #2665 migration into v10's redesigned sample app so iOS builds again on Xcode 26.3 (sentry-cocoa fails to compile with the current Xcode). Build / platform config taken from master's #2665 commit verbatim: - sample_app/android/{app/build.gradle,build.gradle,settings.gradle} - sample_app/android/app/src/main/AndroidManifest.xml - sample_app/android/app/google-services.json - sample_app/ios/Runner.xcodeproj/project.pbxproj - sample_app/ios/Runner/Info.plist - sample_app/macos/Runner/{Info.plist,GoogleService-Info.plist} - sample_app/lib/firebase_options.dart Dart wiring ported to v10's redesigned layout: - sample_app/lib/main.dart — rewritten to match master's Crashlytics-only main(): post-Flutter-3.3 pattern with FlutterError.onError + PlatformDispatcher.instance.onError, runZonedGuarded dropped. - sample_app/lib/auth/auth_controller.dart — `_sampleAppLogHandler` now reports via FirebaseCrashlytics.recordError(reason: …) instead of Sentry.captureException. (v10 moved the handler out of app.dart, so master's diff lands here.) - sample_app/lib/utils/app_config.dart — `sentryDsn` removed. - sample_app/pubspec.yaml — drop `sentry_flutter`, add `firebase_crashlytics: ^5.2.0`. `firebase_crashlytics` floor is `^5.2.0` (not `^4.0.0` from #2665) — v10's `firebase_core: ^4.0.0` requires the 5.x line of the plugin. `melos.yaml` bumped to match. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
ff5f832 to
e6905e7
Compare
Audit by a second Claude agent surfaced four real gaps from the merge. Closes them. 1. **#2672 / #2675 — iOS SPM disable + dSYM upload** - Add `upload_dsyms_to_crashlytics` private lane to `sample_app/ios/fastlane/Fastfile` and wire it into `distribute_to_firebase` and `distribute_to_testflight` before the Firebase/TestFlight upload. Without this lane the release Fastfile never uploads Crashlytics symbol files, so iOS crash reports stay unsymbolicated. Master moved this into the Fastfile itself. - Add `flutter config --no-enable-swift-package-manager` step to all three iOS install blocks in `distribute_external.yml` and `distribute_internal.yml`. This follows master's #2675 pattern (disable SPM at CI level, not via the now-removed `pubspec.yaml` `flutter.config` knob). 2. **#2653 — `maximumMessageLimit` API surface on the public view** - `MessageListCore` already exposed `maximumMessageLimit` / `retentionTrimBuffer`, but the public `StreamMessageListView` constructor did not forward them, so consumers couldn't enable trim without dropping down to `MessageListCore`. Add both parameters to `StreamMessageListView` and forward them at the `MessageListCore(...)` call site. Default for `retentionTrimBuffer` is inlined (`30`) because the canonical constant on `MessageRetentionGate` is `@visibleForTesting`. 3. **#2653 — `pruneOldest` LLC tests** - Port master's `group('\`.state.pruneOldest\`', ...)` (7 tests) into `channel_test.dart`. v10's `ChannelClientState.pruneOldest` was already present from the merge; only the regression tests were missing. Not ported (intentionally): - #2667's two duplicate-id regression tests (`should not duplicate when server echoes back…` and `should not duplicate when the locally-sent message is no longer the latest`). v10's `_updateMessages` keyed-map merge can't produce the duplicate shape these tests guard against, and porting them would require splicing into a v10 group with a different setUp. - Master's `scrollPhysics` nullable default — v10's `ClampingScrollPhysics()` default is the documented v10 contract. - Master's `updateMessage`-side `lastIndexWhere` fast path — v10 rewrote the state-update path to a keyed-map merge (O(N+M)) which is functionally equivalent. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Second review pass flagged that the v10 changelogs didn't surface the master-derived additions that landed in the merge. Add them now. - stream_chat: `SortedListX` / `ListX` extensions (#2660), `ChannelClientState.pruneOldest` and `InFlightCache`-backed `queryChannels` coalescing (#2653, #2652), `.distinct()` on read / unread streams, `currentUserReadStream` emits `null` on logout, removed expired-CDN walker (#2653), `queryDrafts` filter forwarding (#2647). - stream_chat_flutter_core: `StreamChannel.pruneOldest` wrapper + `MessageListCore.maximumMessageLimit`/`retentionTrimBuffer` (#2653), `MessageListCore` stream-caching, `StreamChatCore` 3 s connectivity debounce (#2651, #2652), `lastIndexWhere` fast-path in `getFirstUnreadMessage` (#2667). - stream_chat_flutter: `StreamMessageListView.maximumMessageLimit`, `ItemScrollController.isScrolling` + `isScrollingListenable`, `itemKeyBuilder`, `scrollTo` defaults, SPL `_keyToIndexMap` windowing, BetterStreamBuilder correctness fixes (#2651), relaxed URL regex + dropped bundled TLD list (#2654). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
`SizeTransition.alignment` was added in Flutter 3.44; v10's `melos.yaml` floor is `>=3.38.1`. The 3.44-only call broke local builds on the supported floor. Switch back to `axisAlignment: -1` (top/start equivalent on the vertical axis) and silence the 3.44+ deprecation. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Round-1 reviewer flagged these as warning-level and they slipped through the merge. They're actually a build failure: > Overlay manifest:package attribute declared at > AndroidManifest.xml:2:5-34 value=(com.example.example) does not > match the module's namespace (io.getstream.chat.android.flutter.sample) #2667 dropped the obsolete `package="com.example.example"` from `profile/AndroidManifest.xml` and added the `builtInKotlin=false` / `newDsl=false` Flutter-migrator flags to `gradle.properties`. Pull both verbatim from master. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Deep audit (channel.dart / client.dart line-by-line) found the only real master miss in the merge: master's #2653 `_updatePinnedMessages` fast-path that bailed when there were no existing pinned messages and nothing in the incoming batch was pinned. v10's helper takes an `Iterable<Message>` instead of a single message, so the guard's shape changes — same intent. Without this, every non-pinned update touches `pinnedMessages` (alloc + merge + sort + copyWith) just to land back on `[]`. Correctness was fine in the regressed state; this is a perf-only fix. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Summary
Brings master's QA / security / perf work into the v10 design-refresh branch.
Master is 15 commits ahead of v10.0.0 — this PR carries those into v10 so the upcoming v10 release ships with the latest LLC perf rewrites, the in-flight queryChannels dedup, the jose security floor, and the relaxed URL detection.
What landed
LLC (
stream_chat)Client.queryDraftsnow forwardsfilter(fix(llc): forwardfilterparam inClient.queryDrafts#2647).Client.queryChannelscoalesces concurrent identical queries via the newInFlightCache<K, V>(fix(llc, core): coalesce queryChannels on flaky-network reconnects #2652).SortedListX/ListXextensions added inlist_extensions.dart; duplicate-keyed inputs are tolerated bymerge(chore(llc): tolerate duplicate-keyed inputs inSortedListX.merge#2660). v10'sIterableMergeExtension.merge/.mergeFromare kept —SortedListXis onListand routes there for the new perf paths; the old extension still servesIterable<T>callers in v10.ChannelClientState._checkExpiredAttachmentMessagesremoved (perf(llc): faster channel state ingest #2653); v10'sStreamImageCDN.cacheKeyalready keeps the image cache valid across signed-URL rotations.ChannelClientState.updateChannelStatenow identity-short-circuits whenupdatedState.messagesis null or the same reference, so downstream.distinct()listeners can skip rebuilds._findMessage(parentId-aware) while keeping v10'saddMyReaction/deleteMyReactionsemantics.stream_chat_flutter_coreBetterStreamBuildercorrectness fixes: mounted guard, error reporting viaFlutterError.reportError, identity-equal emission gating (perf(repo): cut StreamMessageListView UI-thread work under flood load #2651).MessageListCorecaches itsmessagesStream/_initialMessagesas fields instead of recomputing inbuild()(perf(repo): cut StreamMessageListView UI-thread work under flood load #2651).defaultMessageFiltertakes an optionalcurrentUserId.StreamChatCoredebounces connectivity events to 3 s (fix(llc, core): coalesce queryChannels on flaky-network reconnects #2652).stream_chat_flutterscrollable_positioned_list/: master version taken in full. Bounded_keyToIndexMap,isScrolling/isScrollingListenable,itemKeyBuilderanchor preservation, fit-anchor fallback inUnboundedRenderViewport, sensible defaults onscrollTo(perf(repo): cut StreamMessageListView UI-thread work under flood load #2651).tld.dartremoved (chore(ui): drop the bundled IANA TLD list #2654);StreamMessageComposerrelaxed its URL regex from[a-z]{2,4}to[a-z]{2,}and dropped theisValidTLDfilter at both call sites.StreamMessageListViewandseparated_reorderable_list_view: v10's design-refresh version retained. Master's identity-preserving micro-optimizations toupdateMessageare a follow-up.CI / repo
gate) added tolegacy_version_analyze,check_db_entities, andstream_flutter_workflow(ci(repo): centralize path/draft gating in a per-workflow gate job #2669).panareports #2656), local-setup CI fixes (ci(repo): Resolve local setup related issues #2650).melos.yaml: kept v10's higher floors; addedfirebase_crashlytics(master's chore(samples): replace Sentry with Firebase Crashlytics #2665); droppedsentry_flutter(per master). v10's own pubspec/sample-app still referencessentry_flutter(see follow-ups).Notes / follow-ups
sample_app/: v10's redesigned sample app retained as a unit (gradle, manifest, main.dart, pbxproj — auto-merge would have left it inconsistent with v10's app.dart / pubspec). The Sentry → Firebase Crashlytics migration (chore(samples): replace Sentry with Firebase Crashlytics #2665) applies to master's pre-redesign sample app and is not ported here.channel_test.dart > updateMessage quoted-rewrite > does not rewrite quotes when an existing quoted target is updated without being deletedisskip:-ed. v10's_updateMessagesreconstructs the channel list via_mergeMessagesIntoExisting, so identity is not preserved on non-deletion edits. Functional behavior matches master.stream_message_composer.darthadSizeTransition(alignment:)which was never a valid Flutter parameter — switched toaxisAlignment: -1(the API the v10 author intended).Test plan
dart analyze— clean acrossstream_chat,stream_chat_flutter_core,stream_chat_flutterdart test packages/stream_chat/test— 491 pass, 1 skippeddart test packages/stream_chat/test/src/client/channel_test.dart— 316 pass, 1 skippedflutter test packages/stream_chat_flutter_core/test— 239 passflutter test packages/stream_chat_flutter/test/scrollable_positioned_list/— 194 pass, 2 skippedsample_appboots against v10 on at least one platform🤖 Generated with Claude Code