-
Notifications
You must be signed in to change notification settings - Fork 371
refactor!(ui): add support for customising reaction picker #2248
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
…eat/reactions-v2 # Conflicts: # packages/stream_chat_flutter/lib/src/message_modal/message_actions_modal.dart # packages/stream_chat_flutter/lib/src/message_modal/message_reactions_modal.dart # packages/stream_chat_flutter/lib/src/message_widget/message_widget.dart
This reverts commit 9551f18.
Co-authored-by: xsahil03x <[email protected]>
# Conflicts: # packages/stream_chat_flutter/lib/src/fullscreen_media/full_screen_media_desktop.dart # packages/stream_chat_flutter/lib/src/message_action/message_action_type.dart # packages/stream_chat_flutter/lib/src/message_modal/message_actions_modal.dart # packages/stream_chat_flutter/lib/src/message_modal/message_modal.dart # packages/stream_chat_flutter/lib/src/message_modal/message_reactions_modal.dart # packages/stream_chat_flutter/lib/src/message_widget/message_widget.dart # packages/stream_chat_flutter/lib/src/message_widget/reactions/reaction_picker.dart # packages/stream_chat_flutter/lib/src/message_widget/reactions/reaction_picker_icon_list.dart # packages/stream_chat_flutter/lib/src/message_widget/reactions/reactions_align.dart # packages/stream_chat_flutter/test/src/message_modal/message_reactions_modal_test.dart
Co-authored-by: xsahil03x <[email protected]>
# Conflicts: # packages/stream_chat_flutter/test/src/message_modal/goldens/ci/stream_message_reactions_modal_dark.png # packages/stream_chat_flutter/test/src/message_modal/goldens/ci/stream_message_reactions_modal_light.png # packages/stream_chat_flutter/test/src/message_modal/goldens/ci/stream_message_reactions_modal_reversed_dark.png # packages/stream_chat_flutter/test/src/message_modal/goldens/ci/stream_message_reactions_modal_reversed_light.png # packages/stream_chat_flutter/test/src/message_widget/reactions/goldens/ci/reaction_icon_button_selected_light.png # packages/stream_chat_flutter/test/src/message_widget/reactions/goldens/ci/reaction_icon_button_unselected_light.png # packages/stream_chat_flutter/test/src/message_widget/reactions/goldens/ci/reaction_picker_icon_list_light.png # packages/stream_chat_flutter/test/src/message_widget/reactions/goldens/ci/reaction_picker_icon_list_selected_light.png # packages/stream_chat_flutter/test/src/message_widget/reactions/goldens/ci/stream_reaction_picker_light.png # packages/stream_chat_flutter/test/src/message_widget/reactions/goldens/ci/stream_reaction_picker_selected_light.png # packages/stream_chat_flutter/test/src/misc/goldens/ci/reaction_bubble_2.png # packages/stream_chat_flutter/test/src/misc/goldens/ci/reaction_bubble_3_dark.png # packages/stream_chat_flutter/test/src/misc/goldens/ci/reaction_bubble_3_light.png # packages/stream_chat_flutter/test/src/misc/goldens/ci/reaction_bubble_like_dark.png # packages/stream_chat_flutter/test/src/misc/goldens/ci/reaction_bubble_like_light.png
# Conflicts: # packages/stream_chat_flutter/lib/src/message_action/message_action_type.dart # packages/stream_chat_flutter/lib/src/message_modal/message_actions_modal.dart # packages/stream_chat_flutter/lib/src/message_modal/message_modal.dart # packages/stream_chat_flutter/lib/src/message_modal/message_reactions_modal.dart # packages/stream_chat_flutter/lib/src/message_widget/message_widget.dart # packages/stream_chat_flutter/lib/src/message_widget/message_widget_content_components.dart # packages/stream_chat_flutter/lib/src/message_widget/reactions/reaction_picker.dart # packages/stream_chat_flutter/lib/src/message_widget/reactions/reactions_align.dart # packages/stream_chat_flutter/lib/src/reactions/reaction_picker_icon_list.dart # packages/stream_chat_flutter/test/src/message_modal/goldens/ci/stream_message_reactions_modal_dark.png # packages/stream_chat_flutter/test/src/message_modal/goldens/ci/stream_message_reactions_modal_light.png # packages/stream_chat_flutter/test/src/message_modal/goldens/ci/stream_message_reactions_modal_reversed_dark.png # packages/stream_chat_flutter/test/src/message_modal/goldens/ci/stream_message_reactions_modal_reversed_light.png # packages/stream_chat_flutter/test/src/message_modal/message_reactions_modal_test.dart # packages/stream_chat_flutter/test/src/misc/goldens/ci/reaction_bubble_2.png # packages/stream_chat_flutter/test/src/misc/goldens/ci/reaction_bubble_3_dark.png # packages/stream_chat_flutter/test/src/misc/goldens/ci/reaction_bubble_3_light.png # packages/stream_chat_flutter/test/src/misc/goldens/ci/reaction_bubble_like_dark.png # packages/stream_chat_flutter/test/src/misc/goldens/ci/reaction_bubble_like_light.png
9718aae to
3a60f29
Compare
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
WalkthroughThis update introduces enhanced customization for reaction pickers in the Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant StreamMessageWidget
participant reactionPickerBuilder (custom or default)
participant Modal (Actions/Reactions)
User->>StreamMessageWidget: Long press / context menu on message
StreamMessageWidget->>Modal: Show actions/reactions modal with reactionPickerBuilder
Modal->>reactionPickerBuilder: Build custom reaction picker UI
reactionPickerBuilder->>Modal: Return picker widget
User->>reactionPickerBuilder: Select reaction
reactionPickerBuilder->>Modal: onReactionPicked callback
Modal->>StreamMessageWidget: Update message with new reaction
Assessment against linked issues
Poem
🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
🔭 Outside diff range comments (3)
sample_app/lib/app.dart (1)
448-472:⚠️ Potential issueFix observer inconsistency with router caching.
The router caching optimization introduces a potential issue: the
LocalNotificationObserveris recreated on every_setupRouter()call, but the cached router retains the original observer reference. This means navigation events may not be properly observed after the first router creation.Consider one of these solutions:
Solution 1: Cache the observer along with the router
GoRouter _setupRouter() { + if (router != null) { + return router!; + } + if (localNotificationObserver != null) { localNotificationObserver!.dispose(); } localNotificationObserver = LocalNotificationObserver( _initNotifier.initData!.client, _navigatorKey); return router ??= GoRouter( refreshListenable: _initNotifier, initialLocation: Routes.CHANNEL_LIST_PAGE.path, navigatorKey: _navigatorKey, observers: [localNotificationObserver!], redirect: (context, state) { // ... rest of the method }, routes: appRoutes, ); }Solution 2: Reset router when observer needs to be recreated
GoRouter _setupRouter() { if (localNotificationObserver != null) { localNotificationObserver!.dispose(); + router = null; // Force router recreation when observer changes } localNotificationObserver = LocalNotificationObserver( _initNotifier.initData!.client, _navigatorKey); return router ??= GoRouter( // ... rest unchanged ); }packages/stream_chat_flutter/lib/src/stream_chat_configuration.dart (1)
123-136: 🛠️ Refactor suggestionGuard against accidental mutation of the default reaction icon list
StreamReactionIcon.defaultReactionsis now used as the global default.
Because lists are mutable, any downstream code could inadvertently add / remove
entries and thereby affect the whole application at runtime.A small defensive copy (wrapped in
List.unmodifiable) makes the intent
explicit and protects against hard-to-trace bugs.- reactionIcons: reactionIcons ?? StreamReactionIcon.defaultReactions, + reactionIcons: + List.unmodifiable(reactionIcons ?? StreamReactionIcon.defaultReactions),packages/stream_chat_flutter/lib/src/reactions/picker/reaction_picker_icon_list.dart (1)
125-145: 🛠️ Refactor suggestionRe-initialising animations only when the length changes can miss updates
didUpdateWidgetrecreates the_iconAnimationslist only whenreactionIcons.lengthchanges.
If a caller swaps the list with icons of the same length (e.g. reordered or replaced with theme-specific builders), the old animations persist and are now out of sync with the new icons.-if (oldWidget.reactionIcons.length != widget.reactionIcons.length) { +if (!const ListEquality().equals( + oldWidget.reactionIcons.map((e) => e.type).toList(), + widget.reactionIcons.map((e) => e.type).toList(), + )) {Using
collection’sListEquality(already imported) keeps the cost low and guarantees the animations align with the actual icon list.
🧹 Nitpick comments (8)
packages/stream_chat_flutter/lib/src/reactions/user_reactions.dart (1)
59-66: Consider adding empty state handling.While the current implementation handles null reactions gracefully, consider adding explicit handling for when
message.latestReactionsis empty to provide better user feedback.You could add an empty state message:
children: [ if (message.latestReactions?.isEmpty ?? true) Text( context.translations.noReactionsLabel, style: textTheme.body, textAlign: TextAlign.center, ) else ...message.latestReactions!.map((reaction) { return _UserReactionItem( key: Key('${reaction.userId}-${reaction.type}'), reaction: reaction, onTap: onUserAvatarTap, ); }), ],packages/stream_chat_flutter/lib/src/message_list_view/message_list_view.dart (1)
1477-1513: Excellent refactor using modern Dart pattern matching!The refactor from nested
if-elsestatements to aswitchexpression with tuple pattern matching significantly improves code readability and maintainability. The logic is well-structured with clear cases:
- Case 1: Uses provided
onThreadTapcallback- Case 2: Creates default navigation with
StreamChatConfigurationwrapper- Case 3: Falls back to
nullThe addition of
StreamChatConfigurationwrapper in Case 2 (lines 1491-1505) is particularly important as it ensures reaction icons and other configuration are properly propagated to the thread page, which aligns with the PR's reaction picker customization objectives.Consider adding tests for the new switch expression cases to improve coverage, though this refactor preserves existing behavior and the logic is straightforward.
🧰 Tools
🪛 GitHub Check: codecov/patch
[warning] 1481-1482: packages/stream_chat_flutter/lib/src/message_list_view/message_list_view.dart#L1481-L1482
Added lines #L1481 - L1482 were not covered by tests
[warning] 1484-1484: packages/stream_chat_flutter/lib/src/message_list_view/message_list_view.dart#L1484
Added line #L1484 was not covered by tests
[warning] 1490-1491: packages/stream_chat_flutter/lib/src/message_list_view/message_list_view.dart#L1490-L1491
Added lines #L1490 - L1491 were not covered by tests
[warning] 1494-1497: packages/stream_chat_flutter/lib/src/message_list_view/message_list_view.dart#L1494-L1497
Added lines #L1494 - L1497 were not covered by tests
[warning] 1499-1500: packages/stream_chat_flutter/lib/src/message_list_view/message_list_view.dart#L1499-L1500
Added lines #L1499 - L1500 were not covered by tests
[warning] 1502-1502: packages/stream_chat_flutter/lib/src/message_list_view/message_list_view.dart#L1502
Added line #L1502 was not covered by tests
[warning] 1507-1508: packages/stream_chat_flutter/lib/src/message_list_view/message_list_view.dart#L1507-L1508
Added lines #L1507 - L1508 were not covered by testspackages/stream_chat_flutter/lib/src/stream_chat_configuration.dart (1)
180-189: Nit: preferconstwhere possible
CenterandStreamGradientAvatar(with only compile-time literals) can be
markedconst, enabling a tiny performance gain and clearer intent.- return Center( - child: StreamGradientAvatar( + return const Center( + child: StreamGradientAvatar(packages/stream_chat_flutter/lib/src/reactions/reaction_bubble.dart (1)
108-118: Avoid repeated O(N²) look-ups when rendering many reactions
firstWhereis executed once per reaction, scanning the full
reactionIconslist each time.
With many, custom reaction sets this becomes unnecessarily expensive.Consider building a
Map<String, StreamReactionIcon>once and doing O(1)
look-ups inside the loop.- final reactionIcon = reactionIcons.firstWhere( - (it) => it.type == reaction.type, - orElse: () => const StreamReactionIcon.unknown(), - ); + final reactionIcon = + _iconCache.putIfAbsent(reaction.type, () { + return reactionIcons.firstWhere( + (it) => it.type == reaction.type, + orElse: () => const StreamReactionIcon.unknown(), + ); + });Where
_iconCacheis a smallfinal _iconCache = <String, StreamReactionIcon>{};
kept in the widget (or passed in).This keeps the hot build path lean without altering behaviour.
packages/stream_chat_flutter/lib/src/message_widget/message_widget.dart (1)
885-891: Context-menu reaction picker lacks width constraintsOn desktop/web the picker widget is inserted directly into the context-menu
column. A custom picker with a fixed width could overflow or push the standard
action items off-screen.Consider wrapping the builder result in a
ConstrainedBoxor allowing the menu
to scroll.- widget.reactionPickerBuilder( + ConstrainedBox( + constraints: const BoxConstraints(maxWidth: 280), + child: widget.reactionPickerBuilder( context, message, (reaction) => onActionTap( SelectReaction(message: message, reaction: reaction), ), ), + ),🧰 Tools
🪛 GitHub Check: codecov/patch
[warning] 885-885: packages/stream_chat_flutter/lib/src/message_widget/message_widget.dart#L885
Added line #L885 was not covered by tests
[warning] 888-888: packages/stream_chat_flutter/lib/src/message_widget/message_widget.dart#L888
Added line #L888 was not covered by testspackages/stream_chat_flutter/lib/src/reactions/picker/reaction_picker_icon_list.dart (3)
163-170: Avoid O(m × n) look-ups when determining selected icons
Inside themapIndexedloop we rebuildownReactionsandfirstWhereOrNullfor every icon. For long reaction sets this quickly becomes quadratic.- ...widget.reactionIcons.mapIndexed((index, icon) { + final ownTypes = { + for (final r in widget.message.ownReactions ?? const []) r.type + }; + ...widget.reactionIcons.mapIndexed((index, icon) { bool reactionCheck(Reaction reaction) => reaction.type == icon.type; - final ownReactions = [...?widget.message.ownReactions]; - final reaction = ownReactions.firstWhereOrNull(reactionCheck); + final isSelected = ownTypes.contains(icon.type);This flattens the complexity to O(m + n) and eliminates repeated list allocations.
Also applies to: 166-168
262-266: Hard-coded size limits customisability
icon.builder(context, icon.isSelected, 24)locks the icon to24 dp. Consider forwarding theIconButton.iconSizeor exposing asizeproperty onReactionPickerIconso theme builders can resize consistently with text scale factors.
270-276: Minor: the arrow-function needn’treturnavoidresult
onPressedultimately expects avoidcallback, yet the closure returns the (void) result ofonPressed(type). Omitting thereturnavoids an unnecessary expression and silences the “value of type ‘void’ used” lint in strict analysis.-final onPressed? => () { - final type = icon.type; - return onPressed(type); - }, +final onPressed? => () => onPressed(icon.type),
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (33)
packages/stream_chat_flutter/test/src/message_modal/goldens/ci/stream_message_reactions_modal_dark.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/message_modal/goldens/ci/stream_message_reactions_modal_light.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/message_modal/goldens/ci/stream_message_reactions_modal_reversed_dark.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/message_modal/goldens/ci/stream_message_reactions_modal_reversed_light.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/message_widget/reactions/goldens/ci/reaction_icon_button_selected_dark.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/message_widget/reactions/goldens/ci/reaction_icon_button_selected_light.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/message_widget/reactions/goldens/ci/reaction_icon_button_unselected_dark.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/message_widget/reactions/goldens/ci/reaction_icon_button_unselected_light.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/message_widget/reactions/goldens/ci/reaction_picker_icon_list_dark.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/message_widget/reactions/goldens/ci/reaction_picker_icon_list_light.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/message_widget/reactions/goldens/ci/reaction_picker_icon_list_selected_dark.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/message_widget/reactions/goldens/ci/reaction_picker_icon_list_selected_light.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/message_widget/reactions/goldens/ci/stream_reaction_picker_dark.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/message_widget/reactions/goldens/ci/stream_reaction_picker_light.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/message_widget/reactions/goldens/ci/stream_reaction_picker_selected_dark.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/message_widget/reactions/goldens/ci/stream_reaction_picker_selected_light.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/misc/goldens/ci/reaction_bubble_2.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/misc/goldens/ci/reaction_bubble_3_dark.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/misc/goldens/ci/reaction_bubble_3_light.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/misc/goldens/ci/reaction_bubble_like_dark.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/misc/goldens/ci/reaction_bubble_like_light.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/reactions/goldens/ci/reaction_icon_button_selected_dark.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/reactions/goldens/ci/reaction_icon_button_selected_light.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/reactions/goldens/ci/reaction_icon_button_unselected_dark.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/reactions/goldens/ci/reaction_icon_button_unselected_light.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/reactions/goldens/ci/reaction_picker_icon_list_dark.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/reactions/goldens/ci/reaction_picker_icon_list_light.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/reactions/goldens/ci/reaction_picker_icon_list_selected_dark.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/reactions/goldens/ci/reaction_picker_icon_list_selected_light.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/reactions/goldens/ci/stream_reaction_picker_dark.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/reactions/goldens/ci/stream_reaction_picker_light.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/reactions/goldens/ci/stream_reaction_picker_selected_dark.pngis excluded by!**/*.pngpackages/stream_chat_flutter/test/src/reactions/goldens/ci/stream_reaction_picker_selected_light.pngis excluded by!**/*.png
📒 Files selected for processing (26)
packages/stream_chat_flutter/CHANGELOG.md(1 hunks)packages/stream_chat_flutter/lib/platform_widget_builder/src/platform_widget_builder.dart(2 hunks)packages/stream_chat_flutter/lib/src/message_action/message_action_type.dart(2 hunks)packages/stream_chat_flutter/lib/src/message_list_view/message_list_view.dart(1 hunks)packages/stream_chat_flutter/lib/src/message_modal/message_actions_modal.dart(4 hunks)packages/stream_chat_flutter/lib/src/message_modal/message_modal.dart(1 hunks)packages/stream_chat_flutter/lib/src/message_modal/message_reactions_modal.dart(5 hunks)packages/stream_chat_flutter/lib/src/message_widget/message_widget.dart(8 hunks)packages/stream_chat_flutter/lib/src/message_widget/message_widget_content.dart(2 hunks)packages/stream_chat_flutter/lib/src/message_widget/message_widget_content_components.dart(0 hunks)packages/stream_chat_flutter/lib/src/message_widget/reactions/reaction_indicator.dart(0 hunks)packages/stream_chat_flutter/lib/src/message_widget/reactions/reactions_card.dart(0 hunks)packages/stream_chat_flutter/lib/src/misc/reaction_icon.dart(2 hunks)packages/stream_chat_flutter/lib/src/reactions/desktop_reactions_builder.dart(1 hunks)packages/stream_chat_flutter/lib/src/reactions/picker/reaction_picker.dart(2 hunks)packages/stream_chat_flutter/lib/src/reactions/picker/reaction_picker_icon_list.dart(5 hunks)packages/stream_chat_flutter/lib/src/reactions/reaction_bubble.dart(2 hunks)packages/stream_chat_flutter/lib/src/reactions/reaction_indicator.dart(1 hunks)packages/stream_chat_flutter/lib/src/reactions/user_reactions.dart(1 hunks)packages/stream_chat_flutter/lib/src/stream_chat_configuration.dart(2 hunks)packages/stream_chat_flutter/lib/stream_chat_flutter.dart(1 hunks)packages/stream_chat_flutter/test/platform_widget_builder/platform_widget_builder_test.dart(1 hunks)packages/stream_chat_flutter/test/src/message_modal/message_reactions_modal_test.dart(2 hunks)packages/stream_chat_flutter/test/src/reactions/reaction_picker_icon_list_test.dart(5 hunks)packages/stream_chat_flutter/test/src/reactions/reaction_picker_test.dart(1 hunks)sample_app/lib/app.dart(2 hunks)
💤 Files with no reviewable changes (3)
- packages/stream_chat_flutter/lib/src/message_widget/message_widget_content_components.dart
- packages/stream_chat_flutter/lib/src/message_widget/reactions/reaction_indicator.dart
- packages/stream_chat_flutter/lib/src/message_widget/reactions/reactions_card.dart
🧰 Additional context used
🪛 LanguageTool
packages/stream_chat_flutter/CHANGELOG.md
[style] ~50-~50: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...nable custom reaction picker widgets. - Added StreamReactionIcon.defaultReactions p...
(ENGLISH_WORD_REPEAT_BEGINNING_RULE)
🪛 GitHub Check: codecov/patch
packages/stream_chat_flutter/lib/src/message_list_view/message_list_view.dart
[warning] 1481-1482: packages/stream_chat_flutter/lib/src/message_list_view/message_list_view.dart#L1481-L1482
Added lines #L1481 - L1482 were not covered by tests
[warning] 1484-1484: packages/stream_chat_flutter/lib/src/message_list_view/message_list_view.dart#L1484
Added line #L1484 was not covered by tests
[warning] 1490-1491: packages/stream_chat_flutter/lib/src/message_list_view/message_list_view.dart#L1490-L1491
Added lines #L1490 - L1491 were not covered by tests
[warning] 1494-1497: packages/stream_chat_flutter/lib/src/message_list_view/message_list_view.dart#L1494-L1497
Added lines #L1494 - L1497 were not covered by tests
[warning] 1499-1500: packages/stream_chat_flutter/lib/src/message_list_view/message_list_view.dart#L1499-L1500
Added lines #L1499 - L1500 were not covered by tests
[warning] 1502-1502: packages/stream_chat_flutter/lib/src/message_list_view/message_list_view.dart#L1502
Added line #L1502 was not covered by tests
[warning] 1507-1508: packages/stream_chat_flutter/lib/src/message_list_view/message_list_view.dart#L1507-L1508
Added lines #L1507 - L1508 were not covered by tests
packages/stream_chat_flutter/lib/src/message_widget/message_widget.dart
[warning] 547-547: packages/stream_chat_flutter/lib/src/message_widget/message_widget.dart#L547
Added line #L547 was not covered by tests
[warning] 679-679: packages/stream_chat_flutter/lib/src/message_widget/message_widget.dart#L679
Added line #L679 was not covered by tests
[warning] 683-683: packages/stream_chat_flutter/lib/src/message_widget/message_widget.dart#L683
Added line #L683 was not covered by tests
[warning] 688-688: packages/stream_chat_flutter/lib/src/message_widget/message_widget.dart#L688
Added line #L688 was not covered by tests
[warning] 693-695: packages/stream_chat_flutter/lib/src/message_widget/message_widget.dart#L693-L695
Added lines #L693 - L695 were not covered by tests
[warning] 699-699: packages/stream_chat_flutter/lib/src/message_widget/message_widget.dart#L699
Added line #L699 was not covered by tests
[warning] 701-701: packages/stream_chat_flutter/lib/src/message_widget/message_widget.dart#L701
Added line #L701 was not covered by tests
[warning] 703-704: packages/stream_chat_flutter/lib/src/message_widget/message_widget.dart#L703-L704
Added lines #L703 - L704 were not covered by tests
[warning] 752-756: packages/stream_chat_flutter/lib/src/message_widget/message_widget.dart#L752-L756
Added lines #L752 - L756 were not covered by tests
[warning] 885-885: packages/stream_chat_flutter/lib/src/message_widget/message_widget.dart#L885
Added line #L885 was not covered by tests
[warning] 888-888: packages/stream_chat_flutter/lib/src/message_widget/message_widget.dart#L888
Added line #L888 was not covered by tests
[warning] 908-910: packages/stream_chat_flutter/lib/src/message_widget/message_widget.dart#L908-L910
Added lines #L908 - L910 were not covered by tests
[warning] 916-916: packages/stream_chat_flutter/lib/src/message_widget/message_widget.dart#L916
Added line #L916 was not covered by tests
[warning] 919-920: packages/stream_chat_flutter/lib/src/message_widget/message_widget.dart#L919-L920
Added lines #L919 - L920 were not covered by tests
[warning] 922-923: packages/stream_chat_flutter/lib/src/message_widget/message_widget.dart#L922-L923
Added lines #L922 - L923 were not covered by tests
[warning] 925-925: packages/stream_chat_flutter/lib/src/message_widget/message_widget.dart#L925
Added line #L925 was not covered by tests
[warning] 927-927: packages/stream_chat_flutter/lib/src/message_widget/message_widget.dart#L927
Added line #L927 was not covered by tests
[warning] 929-929: packages/stream_chat_flutter/lib/src/message_widget/message_widget.dart#L929
Added line #L929 was not covered by tests
[warning] 931-931: packages/stream_chat_flutter/lib/src/message_widget/message_widget.dart#L931
Added line #L931 was not covered by tests
[warning] 940-942: packages/stream_chat_flutter/lib/src/message_widget/message_widget.dart#L940-L942
Added lines #L940 - L942 were not covered by tests
[warning] 1035-1035: packages/stream_chat_flutter/lib/src/message_widget/message_widget.dart#L1035
Added line #L1035 was not covered by tests
[warning] 1038-1039: packages/stream_chat_flutter/lib/src/message_widget/message_widget.dart#L1038-L1039
Added lines #L1038 - L1039 were not covered by tests
[warning] 1041-1041: packages/stream_chat_flutter/lib/src/message_widget/message_widget.dart#L1041
Added line #L1041 was not covered by tests
🔇 Additional comments (34)
packages/stream_chat_flutter/lib/src/message_action/message_action_type.dart (2)
75-78: Consistent multi-line constructor formatting for MuteUser
This change brings theMuteUserconstructor in line with the existing style (multi-line params with a trailing comma), improving readability and diff clarity.
87-90: Consistent multi-line constructor formatting for UnmuteUser
Similarly, updatingUnmuteUserto use the same parameter-format style ensures consistency across message action types.sample_app/lib/app.dart (1)
437-437: Good addition of router caching field.The nullable
GoRouter? routerfield enables router caching to improve performance by avoiding unnecessary recreations.packages/stream_chat_flutter/lib/platform_widget_builder/src/platform_widget_builder.dart (3)
28-28: LGTM: Well-designed parameter addition.The
desktopOrWebparameter provides a clean way to specify a unified widget for both desktop and web platforms while maintaining backward compatibility.
43-47: Excellent documentation and design.The documentation clearly explains the precedence behavior, ensuring developers understand that explicit
desktoporwebbuilders will override thedesktopOrWebfallback.
51-58: Clean fallback implementation.The null-aware operator usage provides clean fallback logic that correctly prioritizes specific platform builders over the unified
desktopOrWebbuilder.packages/stream_chat_flutter/lib/src/message_modal/message_modal.dart (1)
144-144: Good layout improvement.Wrapping the content in
Flexibleprevents potential overflow issues and allows the modal content to adapt flexibly to available space within theColumnlayout.packages/stream_chat_flutter/test/src/reactions/reaction_picker_test.dart (1)
186-186: Consistent theming update.The background color change from
appBgtooverlayaligns the test environment with the modal/overlay theming used in the actual application, ensuring visual consistency.packages/stream_chat_flutter/lib/src/reactions/desktop_reactions_builder.dart (1)
103-103: Good component modernization.The replacement of
ReactionsCardwithStreamUserReactionssimplifies the API by removing explicitcurrentUserandmessageThemeparameters, suggesting better internal encapsulation and cleaner component interfaces.packages/stream_chat_flutter/test/src/message_modal/message_reactions_modal_test.dart (1)
70-70: LGTM! Test updates correctly reflect widget refactoring.The replacement of
ReactionsCardwithStreamUserReactionsin test expectations properly aligns with the main codebase refactoring described in the AI summary.Also applies to: 96-96
packages/stream_chat_flutter/test/platform_widget_builder/platform_widget_builder_test.dart (1)
75-98: Good test coverage for the new desktopOrWeb feature.The test properly verifies that
PlatformWidgetBuildercorrectly handles the newdesktopOrWebbuilder parameter across multiple desktop platforms and web (using the Fuchsia hack). The test structure is consistent with existing tests.packages/stream_chat_flutter/test/src/reactions/reaction_picker_icon_list_test.dart (2)
57-63: Well-implemented test updates for ReactionPickerIcon abstraction.The changes correctly implement the new
ReactionPickerIconabstraction, properly extractingtypeandbuilderproperties from the originalreactionIcons.first. The updated callback signature with thetypeparameter aligns with the newOnReactionPickerIconPressedtypedef.Also applies to: 80-86, 109-114, 125-131
385-385: Background color change aligns with UI updates.The change from
theme.colorTheme.appBgtotheme.colorTheme.overlayfor the scaffold background is consistent with UI theming updates mentioned in the AI summary.packages/stream_chat_flutter/lib/src/reactions/picker/reaction_picker.dart (2)
4-19: Excellent API design with comprehensive documentation.The
ReactionPickerBuildertypedef provides a clean, well-documented interface for customizing reaction pickers. The template documentation clearly explains usage in modal components and parameter purposes.
111-114: Good improvement from DecoratedBox to Material widget.Changing from
DecoratedBoxtoMaterialfollows Flutter best practices and provides better platform integration, touch feedback, and accessibility while maintaining the same visual properties (border radius, color, clip behavior).packages/stream_chat_flutter/lib/stream_chat_flutter.dart (1)
106-110: LGTM! Well-organized export restructuring.The reorganization of reaction-related exports from
message_widget/reactionsto a dedicatedreactionsdirectory improves code organization and makes the reaction functionality more discoverable. The export paths are correctly structured and follow Flutter package conventions.packages/stream_chat_flutter/CHANGELOG.md (1)
46-50: Clear and comprehensive feature documentation.The changelog entries effectively document the new features being introduced. The descriptions are concise yet informative, properly explaining the purpose and scope of each addition. The formatting is consistent with existing changelog conventions.
🧰 Tools
🪛 LanguageTool
[style] ~50-~50: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...nable custom reaction picker widgets. - AddedStreamReactionIcon.defaultReactionsp...(ENGLISH_WORD_REPEAT_BEGINNING_RULE)
packages/stream_chat_flutter/lib/src/message_widget/message_widget_content.dart (4)
4-4: Import path correctly updated for reorganized directory structure.The import path has been properly updated to reflect the movement of
desktop_reactions_builder.dartfrommessage_widget/reactionsto the newreactionsdirectory structure.
288-294: Simplified reaction indicator configuration.The
portalFolloweris now always assigned aReactionIndicatorinstance, removing the previous conditional logic. This simplification appears to streamline the reaction display logic while maintaining functionality.
296-300: Enhanced anchor positioning with improved alignment controls.The anchor configuration has been restructured with more explicit alignment properties and added
offsetandshiftToWithinBoundparameters. This provides better control over reaction indicator positioning and boundary handling.
306-306: Verify visual impact of increased padding.The top padding has been increased from 18 to 28 pixels when reactions are shown. This change affects the visual spacing around the reaction indicator.
Please review the visual impact of this padding change to ensure it doesn't create excessive spacing or alignment issues with the reaction indicator layout, especially across different screen sizes and orientations.
packages/stream_chat_flutter/lib/src/reactions/user_reactions.dart (2)
15-75: Well-structured widget implementation with good Material Design principles.The
StreamUserReactionswidget is well-implemented with:
- Proper theme integration using
StreamChatTheme- Responsive layout with
FlexibleandSingleChildScrollView- Appropriate use of Material Design with rounded corners and theme-based colors
- Good accessibility with proper text styling and localized strings
92-92: Good null safety handling for reaction users.The null check for
reactionUserproperly handles cases where reaction data might be incomplete, returning an empty widget instead of causing runtime errors.packages/stream_chat_flutter/lib/src/message_modal/message_actions_modal.dart (3)
2-2: Import path updated for folder reorganization.The import path change from
src/message_widget/reactions/reactions_align.darttosrc/reactions/reactions_align.dartaligns with the broader package reorganization to consolidate reaction-related components into a dedicatedreactionsfolder.
24-24: Well-implemented builder pattern for reaction picker customization.The addition of the
reactionPickerBuilderparameter with a sensible default (StreamReactionPicker.builder) enables customization while maintaining backward compatibility. This follows the established builder pattern conventions in the Flutter ecosystem.Also applies to: 62-63
100-100: Clean abstraction using the injected builder.Replacing the direct
StreamReactionPickerinstantiation with the injectedreactionPickerBuilderfunction call properly abstracts the reaction picker creation, allowing for flexible customization while maintaining the same interface.packages/stream_chat_flutter/lib/src/reactions/reaction_indicator.dart (2)
38-57: Robust reaction filtering and sorting logic.The implementation correctly handles reaction deduplication and sorting:
- Filtering (lines 38-45): Ensures only one reaction per type, prioritizing the current user's reactions when duplicates exist
- Sorting (lines 47-57): Properly handles null user IDs and places current user's reactions last for better UX
The logic handles edge cases well, including null user IDs and ensures consistent behavior.
59-72: Clean widget composition with proper theming.The widget structure is well-designed:
GestureDetectorfor interaction handlingStreamReactionBubblefor consistent visual presentation- Proper integration with
messageThemeproperties for styling consistencyThe use of
ValueKeywith message ID ensures proper widget rebuilding when reactions change.packages/stream_chat_flutter/lib/src/misc/reaction_icon.dart (3)
26-29: Useful unknown reaction constructor for fallback scenarios.The
unknownconstructor provides a sensible fallback for unrecognized reaction types, using a help icon which clearly indicates an unknown state to users.
37-54: Well-documented default reactions list.The
defaultReactionsstatic list provides a comprehensive set of common reactions (love, like, sad, haha, wow) with excellent documentation. This serves as both a ready-to-use default and a clear example for developers implementing custom reactions.
56-162: Consistent and well-structured reaction builders.All reaction builders follow a consistent pattern:
- Proper theme integration using
StreamChatTheme.of(context)- Clean color logic with switch expressions for highlighted/unhighlighted states
- Consistent use of
StreamSvgIconfor SVG assets and standardIconfor the unknown fallback- Appropriate parameterization (context, highlighted state, size)
The color switching between
accentPrimaryandprimaryIconTheme.colorprovides clear visual feedback for user interaction states.packages/stream_chat_flutter/lib/src/message_modal/message_reactions_modal.dart (1)
93-96: Null-safety check foronReactionPicked
reactionPickerBuilderis invoked withonReactionPicked, which can benull
(line 84). If a custom builder assumes a non-null callback it will throw at
runtime.Either:
- Document that the third parameter may be
null, or- Pass a default no-op callback when
showReactionPicker == true.- child: reactionPickerBuilder(context, message, onReactionPicked), + child: reactionPickerBuilder( + context, + message, + onReactionPicked ?? (_) {}, + ),Please pick one approach so custom builders have a clear contract.
packages/stream_chat_flutter/lib/src/reactions/picker/reaction_picker_icon_list.dart (2)
54-66: Great addition – open-endediconBuilderunlocks theming flexibility
The newiconBuilderparameter (with a sensible default) decouples rendering from business logic, allowing callers to plug in fully-custom widgets – nice!
213-238: Documentation ✨
Clear, concise docs forReactionPickerIconmake the new data object self-explanatory – nicely done.
Resolves: #2225, #2216
Description of the pull request
This pull request Introduces a
reactionPickerBuilderparameter inStreamMessageWidget, enabling developers to provide custom reaction picker implementations. Also fixed the issue where overriding the reaction icons in a subtree was not getting used in the reaction picker.Screen.Recording.2025-05-26.at.02.29.35.mov
Summary by CodeRabbit
New Features
Refactor
Bug Fixes
Tests
Chores