chore(repo): merge master into v10.0.0#2682
Merged
xsahil03x merged 20 commits intoMay 26, 2026
Merged
Conversation
Contributor
|
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 |
7 tasks
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1056e0d to
2b455a2
Compare
…ce recording test The generated copyWith returns ThemeExtension<StreamChatThemeData>, not StreamChatThemeData, so it could not be passed where the latter was expected. The factory accepts voiceRecordingAttachmentTheme directly, which avoids the wide return type entirely. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…eme part files These were left untracked locally — CI fails analyze because the .dart files reference them with `part`. Aligns with the rest of the .g.theme.dart files in the package, which are committed. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…roll tests stream_chat_theme_test pins StreamChatTheme.of ancestor lookup. auto_scroll_test covers the scroll-position behavior of StreamMessageListView when remote messages arrive (do not flap at the bottom, do not auto-scroll while scrolled up, etc.). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Dart 3.12's formatter (Flutter 3.44 in CI) collapses `value\n;` to `value;` on the final enum entry. Dart 3.10 left them split. Reformat to match CI. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This reverts commit ea3d56d.
The format check used \`flutter-version: 3.x\` which resolved to 3.44 / Dart 3.12 — newer than the SDK floor (Flutter 3.38.1 / Dart 3.10). \`dart format\` output diverged between versions for trailing enum semicolons, so CI rejected code that's correctly formatted at the min SDK. Pin format to the floor so contributors on supported Dart versions can produce identical output locally. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The replacement \`alignment\` property was added after Flutter 3.41, but our SDK floor is 3.38.1. Suppress the deprecation warning so analyze passes on newer Flutter versions while remaining buildable on the min. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Match the existing style of inline ignore directives in this repo. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
… changelogs stream_chat: SortedListX.merge from 9.24.0 was split into SortedListX.mergeSorted (two-pointer, sorted output) and IterableMergeX.merge (keyed-map, unsorted) — breaking for any direct caller of the former. stream_chat_flutter: DateTimeComparisonUtils extension and DateTimeUnit enum are now exported; formatRecentDateTime emits the new five-state cascade matching the Figma design. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This reverts commit b07ff9b.
`dart format` from Dart 3.10 incorrectly emits `value\n ;` for enums with parameters under `trailing_commas: preserve` (dart-lang/dart_style#1785, fixed in 3.12). CI now runs on the fixed formatter; rerun across the repo to land the corrected output. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…e_crashlytics Completes the Sentry → Firebase Crashlytics migration (#2665) for v10's redesigned sample app. main.dart was already on Crashlytics; auth_controller was the last sentry consumer. Removes the dep, swaps Sentry.captureException for FirebaseCrashlytics.instance.recordError, and unblocks the iOS build — sentry_flutter 8.14.2 wasn't compatible with the latest Sentry-iOS pod (\`SentryBinaryImageCache has no member 'image'\`). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…ndler Matches master's log handler (#2665) — the StreamChat log message becomes the Crashlytics report reason, making errors triageable in the dashboard instead of surfacing as bare stack traces. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
renefloor
reviewed
May 26, 2026
renefloor
reviewed
May 26, 2026
renefloor
reviewed
May 26, 2026
renefloor
approved these changes
May 26, 2026
In thread mode the message list was reading streamChannel.initialMessageId as a fallback when the thread-local highlight wasn't set. But initialMessageId is a channel-scoped pointer (set when navigating to the channel via deep link); inside a thread it points at a message that doesn't belong to the thread, leading _moveToAndHighlight into the wrong loader. Switch on the conversation mode instead so each scope reads only its own highlight source — _ThreadHighlightScope in threads, initialMessageId in the channel. Matches Android's parentMessageId-discriminated focus path and SwiftUI's per-view-model highlight environment. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…vior - Rename _moveToAndHighlight → _scrollToMessage; matches Android's scrollToMessage naming and the sibling scrollToBottom*/scrollToUnread* helpers in this file. - Drop the unused `messages` param (always read `this.messages` so we stay current across awaits), the dead `initialScrollIndex` branch (SPL already mounts at it), and the `scrollTo: false` toggle (the jumpTo path was only used at initial highlight, where the SPL is already at the target). - Make `messageId` required (no more nullable wrap), add `alignment` (default 0.5) and `highlight` (default true) knobs. - Guard on `controller.isAttached` before calling `scrollTo`. - In thread mode, bail when the target reply isn't loaded instead of falling through to loadChannelAtMessage (which would paginate the parent channel with a thread-reply id — wrong scope, clobbers the channel window). Matches Android/RN until a proper around-reply loader is wired. - _ThreadHighlightScope.of switches to dependOnInheritedWidgetOfExactType (O(1) via the element's inheritance map, idiomatic for InheritedWidget). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- LoadingIndicator becomes a StatefulWidget and caches the queryTopMessages / queryBottomMessages stream as State (matches MessageListCore's `_messagesStream` pattern) — the getters on StreamChannelState return a fresh BehaviorSubject view per access, so reading them inside `build` caused BetterStreamBuilder to resubscribe on every rebuild. - StreamChannelState is now read via StreamChannel.of(context); dropped the externally-passed `streamChannelState` field and the unused `streamTheme` / `isThreadConversation` fields. - Retry callback is injected via onRetryPressed; the call site routes it through the existing _paginateData helper (which itself dispatches channel vs thread via MessageListController). - In-flight spinner: now uses StreamLoadingSpinner (consistent with the other v10 scroll views) and `widget.builders.paginationLoadingIndicator` can still override it. - Error tile: shows StreamScrollViewLoadMoreError.list with retry tap, replacing the previous plain Text — matches reaction / member / user grid views. - _paginateData drops the unused `channel` parameter. - Removed `_streamTheme` State field from StreamMessageListView (no remaining consumers after the indicator no longer needs it). Also upgrades the initial-load defaultErrorBuilder in MessageListView from plain text to StreamScrollViewErrorWidget with a retry that calls streamChannel.reloadChannel(), so the empty/loading/error states all share the same v10 visual language. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
15dff4f to
ab9e403
Compare
…ll check Aligns with the `if (X case final Y?)` style used in LoadingIndicator and drops the bang-assertion calls. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Without an explicit key, an unrelated rebuild in the surrounding tree can drop the SPL's state — scroll position, item-position cache, itemKeyBuilder anchors — and force a fresh mount. Keying on \`cid:parentId\` makes the SPL stable across same-channel/same-thread rebuilds, and forces a clean remount when the channel swaps or the user enters/leaves a thread. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Brings master's perf / security / CI work into the v10 design-refresh branch.
Master is 17 commits ahead of v10.0.0 — this PR carries them into v10 so the upcoming v10 release ships with the latest LLC perf rewrites, the in-flight
queryChannelsdedup, the jose security floor, and the relaxed URL detection. On top of those, this PR ports the same perf approach into v10's design-refresh code (single-message fast path in_mergeMessagesIntoExisting, Jiffy removal from message-list predicates), rewrites the date formatter as a clock-driven extension, and overhauls the message-list pagination / scroll / highlight plumbing.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).list_extensions.dartadded —IterableMergeX.merge(keyed-map merge, unsorted output) plusSortedListX.mergeSorted(two-pointer merge requiring a sorted receiver). Duplicate-keyed inputs tolerated (chore(llc): tolerate duplicate-keyed inputs inSortedListX.merge#2660). v10'sIterableMergeExtensioncallers route throughmerge; the perf paths usemergeSorted. RenamingSortedListX.merge(added in 9.24.0) →mergeSortedis breaking for any direct caller of the former.Channel._mergeMessagesIntoExistinggains a single-message fast path (lastIndexWhere+sortedUpsertAt) — skips the full keyed merge for the steady-state new-message case.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.josefloor bumped to 0.3.5+1 for CVE-2026-34240 (fix(llc): bump jose floor to 0.3.5+1 for CVE-2026-34240 #2658).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_flutterDate formatting
date_formatter.dartrewritten — replaces Jiffy predicates with aDateTimeComparisonUtilsextension (isToday,isYesterday,isWithinLastMinute,isWithinLastWeek,isInSameYear, singleisSame(unit:)entry point with aDateTimeUnitenum). Usespackage:clockfor testable time. Cuts ~1.5s on the trace per the latest DevTools profile.formatRecentDateTimeoutput reworked to a five-state cascade matching the Figma design:Just now/Today at H:mm/Yesterday at H:mm/Weekday at H:mm/MMM do at H:mm.Message-list view internals
mlv_utils.dart:_isGroupBoundary,_resolveSpacingRules, andcomputeStackPositiondrop Jiffy in favor of the new extension.scrollable_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 on top of the perf changes.Scroll, highlight, pagination plumbing
_moveToAndHighlightrenamed to_scrollToMessageand tightened:messageIdis required (was nullable), dropped the unusedmessages/initialScrollIndex/scrollToparameters, addedalignment(default 0.5) andhighlight(default true) knobs, guards oncontroller.isAttachedbefore scrolling. In thread mode, bails when the target reply isn't loaded (no thread-around-reply loader is exposed today — matches Android/RN; iOS/SwiftUI haveloadPageAroundReplyIdand remain the proper-fix template)._ThreadHighlightScopeonly, the channel readsstreamChannel.initialMessageIdonly. Previously the channel-scoped id leaked into thread mode and could mis-route_scrollToMessageinto the channel pagination path. Matches Android'sparentMessageId-discriminated focus and SwiftUI's per-VM highlight environment._ThreadHighlightScope.ofswitched todependOnInheritedWidgetOfExactTypefor O(1) lookup.LoadingIndicatorreworked:StatefulWidgetthat caches thequeryTopMessages/queryBottomMessagesstream (matchesMessageListCore's pattern — the getters onStreamChannelStatereturn a fresh BehaviorSubject view per access), readsStreamChannel.of(context)instead of taking it as a prop, drops the unusedstreamTheme/isThreadConversationfields. In-flight spinner usesStreamLoadingSpinnerand the existingwidget.builders.paginationLoadingIndicatoroverride; the error tile is a tappableStreamScrollViewLoadMoreError.listthat retries via_paginateData. Initial-loaddefaultErrorBuilderupgraded from plainTexttoStreamScrollViewErrorWidgetwith retry →streamChannel.reloadChannel()._paginateDatadrops its unusedchannelparameter.ScrollablePositionedList.separatedgets a stableKey('mlv-${cid}-${parentId}')— same-channel/same-thread rebuilds keep the SPL's scroll position and item-position cache; channel swap or thread enter/leave forces a clean remount.MessageListViewdefault builders switched fromif (X != null) return X!(...)toif (X case final builder?) return builder(...), dropping the bang-assertions.Other
stream_chat_theme.g.theme.dart,thread_list_tile_theme.g.theme.dart) — CI analyze couldn't compile without them.SizeTransition.axisAlignment— its replacementalignmentwas added after Flutter 3.41, beyond the SDK floor (3.38.1).auto_scroll_test.dartandstream_chat_theme_test.dart(10 tests covering message-list scroll behavior and theme ancestor lookup).sample_appsentry_flutterfrompubspec.yamland swapped theSentry.captureExceptioncall inauth_controller.dartforFirebaseCrashlytics.instance.recordError(error, stack, reason: record.message).main.dartwas already on Crashlytics; the log handler inauth_controllerwas the last sentry consumer.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(chore(samples): replace Sentry with Firebase Crashlytics #2665); droppedsentry_flutter.release-prskill added (chore(repo): add release-pr skill #2657).dart formatoutput. Dart 3.10 had a bug (dart-lang/dart_style#1785) that left a stray\n ;on enum declarations with parameters whentrailing_commas: preserveis set; CI's Dart 3.12 (Flutter 3.44) correctly collapses them.Docs / tests
docs_screenshots/voice_recording_test.dart: replacedStreamChatThemeData().copyWith(...)with the factory constructor — the generator-emittedcopyWithreturns the baseThemeExtension<StreamChatThemeData>type, which isn't assignable to aStreamChatThemeData?parameter.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). chore(samples): replace Sentry with Firebase Crashlytics #2665's Sentry → Crashlytics work is now fully ported (see above).mark_read_test.dart: dropped a deadwhen(() => channel.on(any(), any(), any(), any()))stub that leakedany()matchers into the nextsetUp(sinceMockChannel.on()is a concrete override, not a mocktail stub).formatRecentDateTimehardcodes English'at'separator — needs adateAtTimeText({date, time})Translations method for locale support. Tracked.StreamTimestamp/StreamDateDividerstill call Jiffy (~684ms / 11.8% in the latest profile) — should move to a cachedintl.DateFormat.melos run update:goldensif needed.Channel.query()truncate-on-reload: after aloadChannelAtMessage(Y)jump, callingreloadChannel()merges the latest 30 with the around-Y window instead of replacing — older messages (including the one that contained the quoted tap) end up unreachable without paginating back. Fix needs to land in v9 first (same LLC code), then port to v10. Tracked._scrollToMessagebails in thread mode when the target reply isn't loaded. Backend supportsid_aroundonGET /messages/{parent_id}/repliesand the LLC already exposes it viaChannel.getReplies(parentId, options: PaginationParams(idAround: ...)); iOS UIKit (MessageController.loadPageAroundReplyId) and SwiftUI wire it through, Android and React Native do not. Wire aloadPageAroundReplyId-style helper intoStreamChannel/ the thread controller as a follow-up.Test plan
dart test packages/stream_chat— 1381/1381 passflutter test packages/stream_chat_flutter_core— 239/239 passflutter test packages/stream_chat_flutter— touched-area tests all pass (date_formatter_test,message_list_view_test,mark_read_test,auto_scroll_test,timestamp_test,stream_chat_test,stream_channel_test)analyze,format,test,build (android)greenbuild (ios)— Sentry/Crashlytics archive failure was the prior blocker; should clear now thatsentry_flutteris gone (first run since the migration)sample_appboots against v10 on at least one platform🤖 Generated with Claude Code