Skip to content

refactor(ui)!: update design for context menu and message action#2517

Merged
xsahil03x merged 6 commits intofeat/design-refreshfrom
feat/context-menu-refresh
Feb 24, 2026
Merged

refactor(ui)!: update design for context menu and message action#2517
xsahil03x merged 6 commits intofeat/design-refreshfrom
feat/context-menu-refresh

Conversation

@xsahil03x
Copy link
Member

@xsahil03x xsahil03x commented Feb 24, 2026

simulator_screenshot_ACEA61C6-8E73-49C1-9BF3-69D7CF5C5476 simulator_screenshot_B3A8BDFE-810E-46A2-B025-BB7047574425

Summary by CodeRabbit

  • New Features

    • New builder-based actions model allowing richer, self-rendering message actions and context menu items.
  • Breaking Changes

    • Message action APIs redesigned: customActions replaced by actionsBuilder; removed legacy action widget and callbacks (onActionTap/onReactionPicked).
    • Context menu parameter renamed for consistency.
  • Improvements

    • Streamlined context menus, dialog-based action dispatch, and improved icon/theme integration across message actions.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 24, 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.

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
📝 Walkthrough

Walkthrough

This PR redesigns the message actions system: replaces StreamMessageAction/StreamMessageActionItem with StreamContextMenuAction and a builder-based MessageActionsBuilder; renames context menu builder types; routes action selection via dialog returns/onSelected; updates modals, message widget, context menus, exports, docs, tests, and sample app.

Changes

Cohort / File(s) Summary
Context Menu Architecture
packages/stream_chat_flutter/lib/src/context_menu/context_menu.dart, packages/stream_chat_flutter/lib/src/context_menu/context_menu_region.dart
Renamed typedef and builder parameter shape to accept List<Widget>; typedef renamed to ContextMenuContainerBuilder/menuBuilder; added onSelected to ContextMenuRegion; call sites updated to pass menu items list.
Message Action Core
packages/stream_chat_flutter/lib/src/message_action/message_action.dart, packages/stream_chat_flutter/lib/src/message_action/message_action_type.dart, packages/stream_chat_flutter/lib/src/message_action/message_actions_builder.dart
Introduced sealed MessageAction classes and MessageActionsBuilder typedef; replaced legacy StreamMessageAction usage with StreamContextMenuAction<MessageAction>; updated builders to return context-menu action widgets and switched icon sourcing to context.streamIcons.
Removed Widget
packages/stream_chat_flutter/lib/src/message_action/message_action_item.dart
Deleted the StreamMessageActionItem widget and its tests; rendering moved to StreamContextMenu/StreamContextMenuAction widgets.
Message Modals & Dialogs
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_modal/moderated_message_actions_modal.dart
Removed onActionTap / onReactionPicked callbacks; modals now return MessageAction via Navigator.pop and render actions as widgets (List<Widget> or List<StreamContextMenuAction>); replaced custom action rendering with StreamContextMenu.
Message Widget Core
packages/stream_chat_flutter/lib/src/message_widget/message_widget.dart
Replaced customActions/onCustomActionTap with actionsBuilder (MessageActionsBuilder); action pipelines now return StreamContextMenuAction/Widget; centralized _onActionTap handling; desktop/web menus use onSelected flow.
Fullscreen Media (desktop)
packages/stream_chat_flutter/lib/src/fullscreen_media/full_screen_media_desktop.dart
Updated ContextMenuRegion usage to menuBuilder; _DownloadMenuItem now accepts Attachment (not package); replaced StreamMessageActionItem usage with StreamContextMenuAction and context.streamIcons.
Theme & Dialog Infrastructure
packages/stream_chat_flutter/lib/src/misc/stream_modal.dart, packages/stream_chat_flutter/lib/src/reactions/picker/reaction_picker.dart
showStreamDialog now wraps page content with StreamChatTheme(data: theme, ...); reaction picker default background uses StreamColors.transparent; added stream_core_flutter imports where needed.
Public API & Exports
packages/stream_chat_flutter/lib/stream_chat_flutter.dart
Added re-exports from stream_core_flutter: StreamIcons, StreamThemeExtension, StreamContextMenu, StreamContextMenuAction, StreamContextMenuSeparator; removed export of message_action_item.dart.
Documentation / Migration
migrations/redesign/README.md, migrations/redesign/message_actions.md
Added migration entry and a detailed migration guide documenting the new StreamContextMenuAction model, actionsBuilder usage, removed APIs, and migration checklist.
Tests
packages/stream_chat_flutter/test/src/message_action/*, packages/stream_chat_flutter/test/src/message_modal/*
Removed message_action_item_test.dart; updated tests to use StreamContextMenuAction<MessageAction> and dialog-return flows (showStreamDialog) asserting popped MessageAction values; adjusted extension helpers to check props.value.
Sample App
sample_app/lib/pages/channel_page.dart
Replaced legacy per-message custom action classes with a local actionsBuilder producing StreamContextMenuAction items; removed several custom action classes (Reminder/Bookmark/DeleteForMe/etc.); uses context.streamIcons.

Sequence Diagram

sequenceDiagram
    participant User
    participant MessageWidget as Message Widget
    participant ActionsBuilder as Actions Builder
    participant ContextMenu as Context Menu Region
    participant Dialog as Modal/Dialog
    participant Handler as _onActionTap

    User->>MessageWidget: trigger context menu (long press / click)
    MessageWidget->>ActionsBuilder: actionsBuilder(context, defaultActions)
    ActionsBuilder-->>MessageWidget: List<StreamContextMenuAction/Widget>
    MessageWidget->>ContextMenu: show menu (menuBuilder / menuItems)
    User->>ContextMenu: select action item
    ContextMenu->>Dialog: open modal OR pop with action value
    Dialog-->>ContextMenu: pop with MessageAction result
    ContextMenu->>MessageWidget: onSelected(action)
    MessageWidget->>Handler: _onActionTap(context, channel, action)
    Handler-->Handler: execute action (edit, delete, reaction...)
    Handler-->>User: action applied
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Poem

🐰 Hopping through menus, widgets refined,
Old actions folded, new builders aligned,
Icons from context, modals that pop,
Streamlined flows from bottom to top,
A rabbit applauds this tidy design.

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly describes the main refactoring work: updating the design for context menus and message actions, with the breaking change indicator.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/context-menu-refresh

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
Copy link
Member Author

@coderabbitai review

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 24, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (3)
packages/stream_chat_flutter/test/src/message_action/message_actions_builder_test.dart (1)

136-167: ⚠️ Potential issue | 🟡 Minor

Test named "includes/excludes…" never tests the exclusion side for EditMessage on other-user messages.

Both ownActions and otherUserActions are built with allChannelCapabilities (which includes updateAnyMessage) and both call expects<EditMessage>. The test never verifies that EditMessage is absent when updateAnyMessage is missing for another user's message, which is the most important authorship-based boundary.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@packages/stream_chat_flutter/test/src/message_action/message_actions_builder_test.dart`
around lines 136 - 167, The test wrongly asserts EditMessage exists for both own
and other-user messages; update the second part to verify exclusion by creating
a channel without the updateAnyMessage capability (e.g., use a variant like
channelWithoutUpdateAny or remove updateAnyMessage from allChannelCapabilities)
and call StreamMessageActionsBuilder.buildActions with that channel for the
other-user message, then assert the EditMessage action is absent (use the
appropriate negative assertion helper instead of expects<EditMessage>) to
confirm authorship-based exclusion.
packages/stream_chat_flutter/lib/src/message_action/message_actions_builder.dart (1)

98-106: ⚠️ Potential issue | 🟠 Major

Retry-delete action maps to resend instead of delete.

When isDeletingFailed is true, this action uses ResendMessage, which routes to channel.retryMessage and re-sends the message rather than retrying deletion. It should invoke the delete flow instead.

🔧 Proposed fix
-          StreamContextMenuAction.destructive(
-            value: ResendMessage(message: message),
+          StreamContextMenuAction.destructive(
+            value: DeleteMessage(message: message),
             leading: Icon(icons.trashBin),
             label: Text(
               context.translations.toggleDeleteRetryDeleteMessageText(
                 isDeleteFailed: true,
               ),
             ),
           ),
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@packages/stream_chat_flutter/lib/src/message_action/message_actions_builder.dart`
around lines 98 - 106, The destructive context menu entry currently uses
ResendMessage when message.state.isDeletingFailed, causing a resend instead of
retrying deletion; change the action value passed to
StreamContextMenuAction.destructive from ResendMessage(message: message) to the
message-deletion retry action (e.g., DeleteMessage(message: message) or the
existing retry-delete command used elsewhere) so the menu triggers the delete
flow rather than channel.retryMessage/resend; update any import/usages
accordingly to reference the correct Delete/RetryDelete action class.
packages/stream_chat_flutter/lib/src/message_widget/message_widget.dart (1)

769-801: ⚠️ Potential issue | 🟡 Minor

showPinButton/showDeleteMessage don’t filter Unpin/HardDelete actions.

The filter only checks PinMessage and DeleteMessage, so UnpinMessage (pinned state) and HardDeleteMessage (failed send/delete flows) still appear even when those flags are false.

🔧 Proposed fix
-        )..retainWhere(
-          (it) => switch (it.props.value) {
-            QuotedReply() => widget.showReplyMessage,
-            ThreadReply() => widget.showThreadReplyMessage,
-            MarkUnread() => widget.showMarkUnreadMessage,
-            ResendMessage() => widget.showResendMessage,
-            EditMessage() => widget.showEditMessage,
-            CopyMessage() => widget.showCopyMessage,
-            FlagMessage() => widget.showFlagButton,
-            PinMessage() => widget.showPinButton,
-            DeleteMessage() => widget.showDeleteMessage,
-            _ => true, // Retain all the remaining actions.
-          },
-        );
+        )..retainWhere(
+          (it) => switch (it.props.value) {
+            QuotedReply() => widget.showReplyMessage,
+            ThreadReply() => widget.showThreadReplyMessage,
+            MarkUnread() => widget.showMarkUnreadMessage,
+            ResendMessage() => widget.showResendMessage,
+            EditMessage() => widget.showEditMessage,
+            CopyMessage() => widget.showCopyMessage,
+            FlagMessage() => widget.showFlagButton,
+            PinMessage() || UnpinMessage() => widget.showPinButton,
+            DeleteMessage() || HardDeleteMessage() => widget.showDeleteMessage,
+            _ => true, // Retain all the remaining actions.
+          },
+        );
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/stream_chat_flutter/lib/src/message_widget/message_widget.dart`
around lines 769 - 801, The message actions filtering in _buildMessageActions
currently checks only PinMessage and DeleteMessage, so UnpinMessage and
HardDeleteMessage still appear; update the retainWhere switch (inside
StreamMessageActionsBuilder.buildActions()..retainWhere) to treat UnpinMessage
the same as PinMessage (guard with widget.showPinButton) and HardDeleteMessage
the same as DeleteMessage (guard with widget.showDeleteMessage), ensuring both
UnpinMessage and HardDeleteMessage are covered alongside their counterparts.
🧹 Nitpick comments (1)
packages/stream_chat_flutter/test/src/message_action/message_actions_builder_test.dart (1)

68-68: Remove commented-out fallback registration.

♻️ Proposed fix
  setUpAll(() {
    registerFallbackValue(Message());
-   // registerFallbackValue(const StreamMessageActionType('any'));
  });
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@packages/stream_chat_flutter/test/src/message_action/message_actions_builder_test.dart`
at line 68, Remove the commented-out fallback registration line so tests don't
contain dead/commented code: delete the commented call to
registerFallbackValue(const StreamMessageActionType('any')) from
message_actions_builder_test.dart (the commented symbol is registerFallbackValue
and StreamMessageActionType) leaving only active test setup code.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@packages/stream_chat_flutter/lib/src/context_menu/context_menu.dart`:
- Line 2: Replace the public barrel import in context_menu.dart with a direct
import from the core package to avoid the circular dependency: remove the import
of package:stream_chat_flutter/stream_chat_flutter.dart and instead import only
the symbol you need (StreamContextMenu) from the stream_core_flutter package
(the direct package that exposes StreamContextMenu); update any references in
this file to use the imported StreamContextMenu and ensure no other barrel
symbols are pulled in so message_widget.dart no longer causes a cyclic import
chain.

In `@packages/stream_chat_flutter/lib/src/reactions/picker/reaction_picker.dart`:
- Line 159: Update the StreamReactionPicker parameter docs and CHANGELOG to call
out the behavioral change: in the StreamReactionPicker constructor/doc for the
backgroundColor parameter, replace the terse "Background color for the reaction
picker." with a clear note that when backgroundColor is null the picker now
defaults to StreamColors.transparent (fully transparent, equivalent to
Colors.transparent / Color(0x00000000)), which is a visual breaking change
compared to the previous themed barsBg; advise consumers using the widget
standalone to pass an explicit backgroundColor if they require an opaque or
themed background. Also update the CHANGELOG entry that added
reactionIconBuilder and backgroundColor to explicitly state the
breaking/default-change: that backgroundColor now defaults to fully transparent
(StreamColors.transparent) rather than the previous themed barsBg, and that
callers must supply an explicit backgroundColor to preserve prior visuals.
- Line 159: Update the StreamReactionPicker widget's doc comment to explicitly
state that the backgroundColor parameter defaults to fully transparent
(StreamColors.transparent) and that consumers who relied on the previous opaque
themed barsBg must pass an explicit backgroundColor to retain the old
appearance; locate the StreamReactionPicker class/constructor in
reaction_picker.dart and amend the top-of-widget/docblock text to mention the
new default for backgroundColor and the migration guidance (pass
backgroundColor: StreamTheme.of(context).colorTheme.barsBg to restore prior
look).

---

Outside diff comments:
In
`@packages/stream_chat_flutter/lib/src/message_action/message_actions_builder.dart`:
- Around line 98-106: The destructive context menu entry currently uses
ResendMessage when message.state.isDeletingFailed, causing a resend instead of
retrying deletion; change the action value passed to
StreamContextMenuAction.destructive from ResendMessage(message: message) to the
message-deletion retry action (e.g., DeleteMessage(message: message) or the
existing retry-delete command used elsewhere) so the menu triggers the delete
flow rather than channel.retryMessage/resend; update any import/usages
accordingly to reference the correct Delete/RetryDelete action class.

In `@packages/stream_chat_flutter/lib/src/message_widget/message_widget.dart`:
- Around line 769-801: The message actions filtering in _buildMessageActions
currently checks only PinMessage and DeleteMessage, so UnpinMessage and
HardDeleteMessage still appear; update the retainWhere switch (inside
StreamMessageActionsBuilder.buildActions()..retainWhere) to treat UnpinMessage
the same as PinMessage (guard with widget.showPinButton) and HardDeleteMessage
the same as DeleteMessage (guard with widget.showDeleteMessage), ensuring both
UnpinMessage and HardDeleteMessage are covered alongside their counterparts.

In
`@packages/stream_chat_flutter/test/src/message_action/message_actions_builder_test.dart`:
- Around line 136-167: The test wrongly asserts EditMessage exists for both own
and other-user messages; update the second part to verify exclusion by creating
a channel without the updateAnyMessage capability (e.g., use a variant like
channelWithoutUpdateAny or remove updateAnyMessage from allChannelCapabilities)
and call StreamMessageActionsBuilder.buildActions with that channel for the
other-user message, then assert the EditMessage action is absent (use the
appropriate negative assertion helper instead of expects<EditMessage>) to
confirm authorship-based exclusion.

---

Nitpick comments:
In
`@packages/stream_chat_flutter/test/src/message_action/message_actions_builder_test.dart`:
- Line 68: Remove the commented-out fallback registration line so tests don't
contain dead/commented code: delete the commented call to
registerFallbackValue(const StreamMessageActionType('any')) from
message_actions_builder_test.dart (the commented symbol is registerFallbackValue
and StreamMessageActionType) leaving only active test setup code.

ℹ️ Review info

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 8848ad6 and 74026ef.

📒 Files selected for processing (21)
  • migrations/redesign/README.md
  • packages/stream_chat_flutter/lib/src/context_menu/context_menu.dart
  • packages/stream_chat_flutter/lib/src/context_menu/context_menu_region.dart
  • packages/stream_chat_flutter/lib/src/fullscreen_media/full_screen_media_desktop.dart
  • packages/stream_chat_flutter/lib/src/message_action/message_action.dart
  • packages/stream_chat_flutter/lib/src/message_action/message_action_item.dart
  • packages/stream_chat_flutter/lib/src/message_action/message_action_type.dart
  • packages/stream_chat_flutter/lib/src/message_action/message_actions_builder.dart
  • 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_modal/moderated_message_actions_modal.dart
  • packages/stream_chat_flutter/lib/src/message_widget/message_widget.dart
  • packages/stream_chat_flutter/lib/src/misc/stream_modal.dart
  • packages/stream_chat_flutter/lib/src/reactions/picker/reaction_picker.dart
  • packages/stream_chat_flutter/lib/stream_chat_flutter.dart
  • packages/stream_chat_flutter/test/src/message_action/message_action_item_test.dart
  • packages/stream_chat_flutter/test/src/message_action/message_actions_builder_test.dart
  • packages/stream_chat_flutter/test/src/message_modal/message_actions_modal_test.dart
  • packages/stream_chat_flutter/test/src/message_modal/message_reactions_modal_test.dart
  • packages/stream_chat_flutter/test/src/message_modal/moderated_message_actions_modal_test.dart
  • sample_app/lib/pages/channel_page.dart
💤 Files with no reviewable changes (3)
  • packages/stream_chat_flutter/lib/src/message_action/message_action_type.dart
  • packages/stream_chat_flutter/lib/src/message_action/message_action_item.dart
  • packages/stream_chat_flutter/test/src/message_action/message_action_item_test.dart

@@ -1,16 +1,16 @@
import 'package:flutter/material.dart';
import 'package:stream_chat_flutter/stream_chat_flutter.dart';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

# First, locate the context_menu.dart file
find . -name "context_menu.dart" -type f | head -20

Repository: GetStream/stream-chat-flutter

Length of output: 142


🏁 Script executed:

# Find the main barrel file
find . -path "*stream_chat_flutter/lib/stream_chat_flutter.dart" -type f

Repository: GetStream/stream-chat-flutter

Length of output: 132


🏁 Script executed:

# Search for imports of context_menu across the codebase
rg -n "import.*context_menu" --type=dart

Repository: GetStream/stream-chat-flutter

Length of output: 700


🏁 Script executed:

cat -n packages/stream_chat_flutter/lib/src/context_menu/context_menu.dart | head -50

Repository: GetStream/stream-chat-flutter

Length of output: 2228


🏁 Script executed:

cat -n packages/stream_chat_flutter/lib/stream_chat_flutter.dart | head -100

Repository: GetStream/stream-chat-flutter

Length of output: 6071


🏁 Script executed:

cat -n packages/stream_chat_flutter/lib/src/context_menu/context_menu.dart | tail -50

Repository: GetStream/stream-chat-flutter

Length of output: 2040


🏁 Script executed:

rg -n "StreamContextMenu" packages/stream_chat_flutter/lib/src/context_menu/context_menu.dart

Repository: GetStream/stream-chat-flutter

Length of output: 185


Replace the public barrel import with a direct stream_core_flutter import to avoid a circular dependency.

context_menu.dart needs only StreamContextMenu from stream_core_flutter but imports the package's public barrel. Since message_widget.dart (exported by the barrel) imports context_menu.dart, this creates a circular dependency: context_menu.dartstream_chat_flutter.dartmessage_widget.dartcontext_menu.dart. While Dart tolerates this, it can slow compilation and surface in static-analysis tools.

♻️ Proposed fix
-import 'package:stream_chat_flutter/stream_chat_flutter.dart';
+import 'package:stream_core_flutter/stream_core_flutter.dart' show StreamContextMenu;
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
import 'package:stream_chat_flutter/stream_chat_flutter.dart';
import 'package:stream_core_flutter/stream_core_flutter.dart' show StreamContextMenu;
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/stream_chat_flutter/lib/src/context_menu/context_menu.dart` at line
2, Replace the public barrel import in context_menu.dart with a direct import
from the core package to avoid the circular dependency: remove the import of
package:stream_chat_flutter/stream_chat_flutter.dart and instead import only the
symbol you need (StreamContextMenu) from the stream_core_flutter package (the
direct package that exposes StreamContextMenu); update any references in this
file to use the imported StreamContextMenu and ensure no other barrel symbols
are pulled in so message_widget.dart no longer causes a cyclic import chain.

borderRadius: borderRadius,
clipBehavior: Clip.antiAlias,
color: backgroundColor ?? theme.colorTheme.barsBg,
color: backgroundColor ?? StreamColors.transparent,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

# First, locate the relevant files
fd -t f "stream_colors.dart" --type f 2>/dev/null | head -10

Repository: GetStream/stream-chat-flutter

Length of output: 55


🏁 Script executed:

# Also look for the reaction_picker file
fd -t f "reaction_picker.dart" --type f 2>/dev/null

Repository: GetStream/stream-chat-flutter

Length of output: 147


🏁 Script executed:

# Search for StreamColors.transparent definition
rg -n "transparent" --type dart -B 2 -A 2 | grep -A 5 -B 5 "StreamColors" | head -50

Repository: GetStream/stream-chat-flutter

Length of output: 1206


🏁 Script executed:

# Check imports and context in reaction_picker.dart
cat packages/stream_chat_flutter/lib/src/reactions/picker/reaction_picker.dart | head -30

Repository: GetStream/stream-chat-flutter

Length of output: 1306


🏁 Script executed:

# Search for where StreamColors is defined/imported
rg -n "class StreamColors\|StreamColors\.transparent" --type dart -B 2 -A 2

Repository: GetStream/stream-chat-flutter

Length of output: 55


🏁 Script executed:

# Find all references to barsBg to understand the previous default
rg -n "barsBg" --type dart | head -20

Repository: GetStream/stream-chat-flutter

Length of output: 2872


🏁 Script executed:

# Search more broadly for StreamColors
rg -n "StreamColors\." --type dart | head -30

Repository: GetStream/stream-chat-flutter

Length of output: 209


🏁 Script executed:

# Get broader context around line 159 in reaction_picker.dart
sed -n '130,180p' packages/stream_chat_flutter/lib/src/reactions/picker/reaction_picker.dart

Repository: GetStream/stream-chat-flutter

Length of output: 1372


🏁 Script executed:

# Check what's in stream_core_flutter imports
rg -n "from 'package:stream_core_flutter'" --type dart -A 5 | head -40

Repository: GetStream/stream-chat-flutter

Length of output: 55


🏁 Script executed:

# Search for StreamColors definition anywhere in dart files
rg -n "^\s*(class|const|final|static).*StreamColors" --type dart

Repository: GetStream/stream-chat-flutter

Length of output: 55


🏁 Script executed:

# Check if stream_core_flutter is in this repository
fd -t d "stream_core_flutter" 2>/dev/null

Repository: GetStream/stream-chat-flutter

Length of output: 55


🏁 Script executed:

# Search for CHANGELOG files and look for reaction picker changes
fd -t f "CHANGELOG*" | head -10

Repository: GetStream/stream-chat-flutter

Length of output: 289


🏁 Script executed:

# Look for the previous version to understand what changed
rg -n "barsBg" packages/stream_chat_flutter/lib/src/reactions/picker/ --type dart

Repository: GetStream/stream-chat-flutter

Length of output: 203


🏁 Script executed:

# Search CHANGELOG for reaction picker changes
rg -n "reaction.picker|backgroundColor|transparent" packages/stream_chat_flutter/CHANGELOG.md -i -B 2 -A 2 | head -50

Repository: GetStream/stream-chat-flutter

Length of output: 3087


🏁 Script executed:

# Look at the StreamReactionPicker class doc comment
sed -n '25,100p' packages/stream_chat_flutter/lib/src/reactions/picker/reaction_picker.dart

Repository: GetStream/stream-chat-flutter

Length of output: 2752


🏁 Script executed:

# Check the widget constructor to see if backgroundColor is documented
sed -n '100,145p' packages/stream_chat_flutter/lib/src/reactions/picker/reaction_picker.dart

Repository: GetStream/stream-chat-flutter

Length of output: 1532


Improve documentation for the backgroundColor default change in StreamReactionPicker.

The background color default change from themed barsBg to StreamColors.transparent is confirmed and represents a visual breaking change. However, the documentation is insufficient:

  1. The backgroundColor parameter doc comment (currently "Background color for the reaction picker.") should explain that when null, it defaults to a transparent background, which may require explicit passing of backgroundColor for consumers using this widget standalone.

  2. The CHANGELOG entry (line 86) only notes "Added reactionIconBuilder and backgroundColor parameters" but doesn't communicate the breaking nature or visual impact of the default behavior change.

Update both the parameter documentation and the CHANGELOG entry to clearly state that the default background is now transparent (vs. previously themed), ensuring consumers understand they must supply backgroundColor explicitly if they need an opaque background.

Additionally, StreamColors.transparent should be documented as fully transparent to confirm it matches Colors.transparent / Color(0x00000000) and not a partially-transparent tint.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/stream_chat_flutter/lib/src/reactions/picker/reaction_picker.dart`
at line 159, Update the StreamReactionPicker parameter docs and CHANGELOG to
call out the behavioral change: in the StreamReactionPicker constructor/doc for
the backgroundColor parameter, replace the terse "Background color for the
reaction picker." with a clear note that when backgroundColor is null the picker
now defaults to StreamColors.transparent (fully transparent, equivalent to
Colors.transparent / Color(0x00000000)), which is a visual breaking change
compared to the previous themed barsBg; advise consumers using the widget
standalone to pass an explicit backgroundColor if they require an opaque or
themed background. Also update the CHANGELOG entry that added
reactionIconBuilder and backgroundColor to explicitly state the
breaking/default-change: that backgroundColor now defaults to fully transparent
(StreamColors.transparent) rather than the previous themed barsBg, and that
callers must supply an explicit backgroundColor to preserve prior visuals.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

# First, let me find the StreamColors definition
find . -name "*.dart" -type f | xargs grep -l "StreamColors" | grep -E "(stream_core|colors)" | head -5

Repository: GetStream/stream-chat-flutter

Length of output: 55


🏁 Script executed:

# Check the reaction_picker.dart file around line 159
find . -name "reaction_picker.dart" -type f

Repository: GetStream/stream-chat-flutter

Length of output: 149


🏁 Script executed:

# Search for StreamColors class definition
rg "class StreamColors|const.*transparent" -A 5 -B 2 --type dart

Repository: GetStream/stream-chat-flutter

Length of output: 55


🏁 Script executed:

# Read the reaction_picker.dart file to see the context around line 159
cat -n ./packages/stream_chat_flutter/lib/src/reactions/picker/reaction_picker.dart | sed -n '150,170p'

Repository: GetStream/stream-chat-flutter

Length of output: 878


🏁 Script executed:

# Search for StreamColors definition in all dart files
rg "class StreamColors" --type dart -A 20

Repository: GetStream/stream-chat-flutter

Length of output: 55


🏁 Script executed:

# Look for barsBg usage to understand the previous default
rg "barsBg" --type dart

Repository: GetStream/stream-chat-flutter

Length of output: 13793


🏁 Script executed:

# Search for StreamColors definition more broadly
rg "StreamColors" --type dart -B 2 -A 10 | head -100

Repository: GetStream/stream-chat-flutter

Length of output: 1468


🏁 Script executed:

# Look for where StreamColors is imported from
rg "import.*StreamColors|from.*StreamColors" --type dart

Repository: GetStream/stream-chat-flutter

Length of output: 55


🏁 Script executed:

# Check CHANGELOG files for this change
find . -name "CHANGELOG*" -type f

Repository: GetStream/stream-chat-flutter

Length of output: 299


🏁 Script executed:

# Search for StreamColors class or const definition
rg "StreamColors\s*=" --type dart

Repository: GetStream/stream-chat-flutter

Length of output: 55


🏁 Script executed:

# Look for all files with StreamColors in them to find where it's defined
fd ".*\.dart" -x rg -l "StreamColors" {} \;

Repository: GetStream/stream-chat-flutter

Length of output: 149


🏁 Script executed:

# Check the imports at the top of reaction_picker.dart
head -50 ./packages/stream_chat_flutter/lib/src/reactions/picker/reaction_picker.dart

Repository: GetStream/stream-chat-flutter

Length of output: 2036


🏁 Script executed:

# Search CHANGELOG for reaction picker changes
grep -i "reaction\|picker" ./packages/stream_chat_flutter/CHANGELOG.md | head -30

Repository: GetStream/stream-chat-flutter

Length of output: 3119


🏁 Script executed:

# Look for stream_core_flutter in the project
find . -type d -name "stream_core_flutter"

Repository: GetStream/stream-chat-flutter

Length of output: 55


🏁 Script executed:

# Check if stream_core_flutter is in pubspec or as a package
find . -name "pubspec.yaml" | xargs grep -l "stream_core_flutter"

Repository: GetStream/stream-chat-flutter

Length of output: 116


🏁 Script executed:

# Search for StreamColors in stream_core_flutter if it's part of this repo
find . -path "*/stream_core*" -name "*.dart" | xargs grep -l "StreamColors" 2>/dev/null

Repository: GetStream/stream-chat-flutter

Length of output: 57


🏁 Script executed:

# Let's check the exact CHANGELOG entry for reaction picker and backgroundColor
grep -B 5 -A 5 "backgroundColor.*StreamReactionPicker\|StreamReactionPicker.*backgroundColor" ./packages/stream_chat_flutter/CHANGELOG.md

Repository: GetStream/stream-chat-flutter

Length of output: 384


🏁 Script executed:

# Check stream_chat_flutter pubspec.yaml to see if stream_core_flutter is a local package or external
cat ./packages/stream_chat_flutter/pubspec.yaml | grep -A 5 "stream_core_flutter"

Repository: GetStream/stream-chat-flutter

Length of output: 581


🏁 Script executed:

# Check if there's a git history of this file to see what the previous default was
git log --oneline -20 -- ./packages/stream_chat_flutter/lib/src/reactions/picker/reaction_picker.dart 2>/dev/null | head -10

Repository: GetStream/stream-chat-flutter

Length of output: 147


🏁 Script executed:

# Look at the full CHANGELOG section around the breaking change
grep -B 20 "🛑️ Breaking" ./packages/stream_chat_flutter/CHANGELOG.md | tail -40

Repository: GetStream/stream-chat-flutter

Length of output: 1669


🏁 Script executed:

# Get the git diff for the reaction picker file to see what changed
git show 74026ef3:./packages/stream_chat_flutter/lib/src/reactions/picker/reaction_picker.dart | grep -A 5 -B 5 "color:" | tail -20

Repository: GetStream/stream-chat-flutter

Length of output: 408


🏁 Script executed:

# Check the current version of the file in git to see if there's an older version
git log --all --format="%H %s" -- ./packages/stream_chat_flutter/lib/src/reactions/picker/reaction_picker.dart | head -10

Repository: GetStream/stream-chat-flutter

Length of output: 345


🏁 Script executed:

# Look for references to StreamColors.transparent in stream_core_flutter (external dependency)
# First, let's check if there's documentation or source files visible
find . -type f -name "*.md" | xargs grep -l "StreamColors" 2>/dev/null

Repository: GetStream/stream-chat-flutter

Length of output: 57


🏁 Script executed:

# Try to find the definition of StreamColors in any dart files
rg "static.*transparent|const.*transparent.*Color" --type dart | head -20

Repository: GetStream/stream-chat-flutter

Length of output: 55


🏁 Script executed:

# Show the git history more completely for the reaction_picker file
git log --all --format="%H %s" --follow -- ./packages/stream_chat_flutter/lib/src/reactions/picker/reaction_picker.dart

Repository: GetStream/stream-chat-flutter

Length of output: 345


🏁 Script executed:

# Get the previous version of the file before the merge
git show 74026ef3^:./packages/stream_chat_flutter/lib/src/reactions/picker/reaction_picker.dart 2>/dev/null | grep -A 10 -B 10 "color:" | tail -30

Repository: GetStream/stream-chat-flutter

Length of output: 55


🏁 Script executed:

# Check the breaking changes section in CHANGELOG to see if backgroundColor change is mentioned
grep -A 100 "🛑️ Breaking" ./packages/stream_chat_flutter/CHANGELOG.md | grep -B 5 -A 5 "backgroundColor\|StreamReactionPicker" | head -30

Repository: GetStream/stream-chat-flutter

Length of output: 1478


🏁 Script executed:

# Look for the issue or PR that introduced this change
git log --all --grep="reaction.*picker\|backgroundColor" --oneline -- ./packages/stream_chat_flutter/lib/src/reactions/picker/ | head -10

Repository: GetStream/stream-chat-flutter

Length of output: 55


🏁 Script executed:

# Look at the previous commit before the merge to see what changed
git show e03a1c05a:./packages/stream_chat_flutter/lib/src/reactions/picker/reaction_picker.dart 2>/dev/null | grep -A 10 -B 10 "color:" | tail -30

Repository: GetStream/stream-chat-flutter

Length of output: 730


🏁 Script executed:

# Check if there's a reaction_picker.dart in an older state
git log --all --format="%H" -- ./packages/stream_chat_flutter/lib/src/reactions/picker/reaction_picker.dart | while read commit; do echo "=== Commit $commit ==="; git show $commit:./packages/stream_chat_flutter/lib/src/reactions/picker/reaction_picker.dart 2>/dev/null | grep -A 3 "color:" | grep -v "^--$" | head -5; done | head -50

Repository: GetStream/stream-chat-flutter

Length of output: 561


🏁 Script executed:

# Check the feat/design-refresh branch mentioned in the merge
git log --all --oneline --grep="design-refresh\|context-menu-refresh" | head -20

Repository: GetStream/stream-chat-flutter

Length of output: 232


🏁 Script executed:

# Look for what the previous default was - check if barsBg was used
git log -p --all -- ./packages/stream_chat_flutter/lib/src/reactions/picker/reaction_picker.dart 2>/dev/null | grep -B 5 -A 5 "barsBg\|backgroundColor.*??" | head -50

Repository: GetStream/stream-chat-flutter

Length of output: 55


🏁 Script executed:

# Perfect! Now let's verify what StreamColors.transparent actually is
# Check if stream_core_flutter source is available in this repo
find . -path "*stream_core_flutter*" -name "*.dart" -type f | head -20

Repository: GetStream/stream-chat-flutter

Length of output: 55


🏁 Script executed:

# Let's check if there's a pubspec lock or similar that might show stream_core_flutter
cat ./packages/stream_chat_flutter/pubspec.lock 2>/dev/null | grep -A 10 "stream_core_flutter" | head -20

Repository: GetStream/stream-chat-flutter

Length of output: 55


🏁 Script executed:

# Search for any color definitions in the codebase that might hint at StreamColors
rg "StreamColors" -B 5 -A 15 --type dart | head -100

Repository: GetStream/stream-chat-flutter

Length of output: 1960


🌐 Web query:

stream_core_flutter StreamColors.transparent Flutter color definition

💡 Result:

In Flutter, the fully transparent color is defined as:

const Color transparent = Color(0x00000000);

You can use it via Colors.transparent (from package:flutter/material.dart). [1]

Color(0xAARRGGBB) uses the top byte (AA) as the alpha channel, so 00 means fully transparent. [2]

Sources: [1] [2]


Breaking default: reaction picker background is now transparent.

The backgroundColor default changed from the themed opaque barsBg color to StreamColors.transparent (fully transparent, equivalent to Color(0x00000000)). This is a significant visual change—consumers who did not explicitly pass backgroundColor will render with no background.

While this PR is marked as a breaking change in the CHANGELOG, the specific nature of this default shift (from opaque barsBg to transparent) is not explicitly documented. Update the StreamReactionPicker widget's doc comment to clarify that backgroundColor defaults to transparent, and callers must pass an explicit color to match the previous appearance.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/stream_chat_flutter/lib/src/reactions/picker/reaction_picker.dart`
at line 159, Update the StreamReactionPicker widget's doc comment to explicitly
state that the backgroundColor parameter defaults to fully transparent
(StreamColors.transparent) and that consumers who relied on the previous opaque
themed barsBg must pass an explicit backgroundColor to retain the old
appearance; locate the StreamReactionPicker class/constructor in
reaction_picker.dart and amend the top-of-widget/docblock text to mention the
new default for backgroundColor and the migration guidance (pass
backgroundColor: StreamTheme.of(context).colorTheme.barsBg to restore prior
look).

@xsahil03x
Copy link
Member Author

@coderabbitai review

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 24, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@migrations/redesign/message_actions.md`:
- Around line 29-32: Add a brief parenthetical note to the Quick Reference
explaining why StreamMessageActionsModal.messageActions is now List<Widget>
while ModeratedMessageActionsModal.messageActions is
List<StreamContextMenuAction>; update the migration table row or an adjacent
explanatory sentence to say something like: "(accepts arbitrary widgets to allow
custom action UI, unlike the moderated variant which requires
StreamContextMenuAction for built-in moderation behavior)" so readers understand
the intentional type asymmetry and when to use each API. Ensure the note
references StreamMessageActionsModal.messageActions and
ModeratedMessageActionsModal.messageActions by name.
- Around line 196-214: Add a brief introduction or callout for
showStreamDialog<T> under "New Components" (or the first place it appears)
explaining that showStreamDialog is a thin wrapper around Flutter's showDialog
that applies the Stream theme, and note its import
(package:stream_chat_flutter/stream_chat_flutter.dart); mention this once where
StreamMessageActionsModal, StreamMessageReactionsModal, and
ModeratedMessageActionsModal are first shown so readers know what
showStreamDialog is and how it differs from showDialog.
- Around line 448-457: The List declaration for actions is missing the generic
type parameter for StreamContextMenuAction; update the variable declaration and
the type used by StreamMessageActionsBuilder.buildActions to explicitly use the
MessageAction generic (e.g., make actions a
List<StreamContextMenuAction<MessageAction>> and ensure any
StreamContextMenuAction references include <MessageAction>) so the example
matches the rest of the guide and clarifies the expected action type.
- Around line 99-112: The table documents that StreamMessageAction.title:
Widget? became StreamContextMenuAction.label: Widget (now required) but the
Breaking Change section and Migration Checklist don't mention this API polarity
change; update the migration doc to explicitly call out that label is now a
required parameter (so code that relied on a null/omitted title will fail to
compile), add a clear note under the "Breaking Change" heading referencing
StreamMessageAction → StreamContextMenuAction and the required label parameter,
and add an item in the Migration Checklist instructing developers to add a
non-null label wherever they previously omitted title.

ℹ️ Review info

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 74026ef and ac1295a.

📒 Files selected for processing (1)
  • migrations/redesign/message_actions.md

Comment on lines +29 to +32
| `StreamMessageActionsModal.messageActions` | **Type changed**: `List<StreamMessageAction>` → `List<Widget>` |
| `StreamMessageReactionsModal.onReactionPicked` | **Removed** — await the dialog return value (`SelectReaction`) |
| `ModeratedMessageActionsModal.onActionTap` | **Removed** — use `onTap` per-action or await the dialog return value |
| `ModeratedMessageActionsModal.messageActions` | **Type changed**: `List<StreamMessageAction>` → `List<StreamContextMenuAction>` |
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Add a note explaining the intentional type asymmetry between the two modals.

StreamMessageActionsModal.messageActions becomes List<Widget> while ModeratedMessageActionsModal.messageActions becomes List<StreamContextMenuAction> — the Quick Reference table surfaces this inconsistency without any rationale. A brief parenthetical (e.g. "accepts arbitrary widgets, unlike the moderated variant") would prevent confusion.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@migrations/redesign/message_actions.md` around lines 29 - 32, Add a brief
parenthetical note to the Quick Reference explaining why
StreamMessageActionsModal.messageActions is now List<Widget> while
ModeratedMessageActionsModal.messageActions is List<StreamContextMenuAction>;
update the migration table row or an adjacent explanatory sentence to say
something like: "(accepts arbitrary widgets to allow custom action UI, unlike
the moderated variant which requires StreamContextMenuAction for built-in
moderation behavior)" so readers understand the intentional type asymmetry and
when to use each API. Ensure the note references
StreamMessageActionsModal.messageActions and
ModeratedMessageActionsModal.messageActions by name.

Comment on lines +99 to +112
| `StreamMessageAction` | `StreamContextMenuAction` |
|-----------------------|--------------------------|
| `action: T` | `value: T?` |
| `title: Widget?` | `label: Widget` (required) |
| `leading: Widget?` | `leading: Widget?` |
| `isDestructive: bool` | `isDestructive: bool` (or use `.destructive` constructor) |
| `iconColor: Color?` | Controlled via `StreamContextMenuActionTheme` |
| `titleTextColor: Color?` | Controlled via `StreamContextMenuActionTheme` |
| `titleTextStyle: TextStyle?` | Controlled via `StreamContextMenuActionTheme` |
| `backgroundColor: Color?` | Controlled via `StreamContextMenuActionTheme` |
| — | `onTap: VoidCallback?` (new) |
| — | `trailing: Widget?` (new) |
| — | `enabled: bool` (new) |

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Explicitly call out that label is now a required parameter.

The table shows title: Widget? (optional) → label: Widget (required), but neither the "Breaking Change" sub-heading on line 53 nor the Migration Checklist (line 537) mentions this polarity change. Any code that created StreamMessageAction without title will fail to compile with the new API. Add a note here and in the checklist, e.g.:

 > **Important:**
+> - `label` is now **required** (previously `title` was optional) — every action must supply a label
  > - `onTap` signature changed from `void Function(MessageAction)` to `VoidCallback?` ...

And in the checklist:

-  - [ ] Replace all `StreamMessageAction(action: ..., title: ..., leading: ...)` with `StreamContextMenuAction(value: ..., label: ..., leading: ...)`
+  - [ ] Replace all `StreamMessageAction(action: ..., title: ..., leading: ...)` with `StreamContextMenuAction(value: ..., label: ..., leading: ...)` — note `label` is now **required**
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@migrations/redesign/message_actions.md` around lines 99 - 112, The table
documents that StreamMessageAction.title: Widget? became
StreamContextMenuAction.label: Widget (now required) but the Breaking Change
section and Migration Checklist don't mention this API polarity change; update
the migration doc to explicitly call out that label is now a required parameter
(so code that relied on a null/omitted title will fail to compile), add a clear
note under the "Breaking Change" heading referencing StreamMessageAction →
StreamContextMenuAction and the required label parameter, and add an item in the
Migration Checklist instructing developers to add a non-null label wherever they
previously omitted title.

Comment on lines 196 to 214
**After (await return value):**
```dart
final action = await showStreamDialog<MessageAction>(
context: context,
builder: (_) => StreamMessageActionsModal(
message: message,
messageWidget: messageWidget,
messageActions: [
StreamContextMenuAction<MessageAction>(
value: CopyMessage(message: message),
leading: Icon(context.streamIcons.copy),
label: Text(context.translations.copyMessageLabel),
),
],
),
);

if (action is CopyMessage) _copyMessage(action.message);
```
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

showStreamDialog is used in three examples but never introduced.

It appears in the "await return value" patterns for StreamMessageActionsModal (line 198), StreamMessageReactionsModal (line 243), and ModeratedMessageActionsModal (line 319), but there is no mention of this helper in New Components or anywhere else in the guide. Readers need to know the package it comes from and how it differs from showDialog. Add at minimum a brief entry under New Components or a callout note the first time it appears, e.g.:

showStreamDialog<T> is a thin wrapper around showDialog from stream_chat_flutter that pre-applies the Stream theme; import it from package:stream_chat_flutter/stream_chat_flutter.dart.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@migrations/redesign/message_actions.md` around lines 196 - 214, Add a brief
introduction or callout for showStreamDialog<T> under "New Components" (or the
first place it appears) explaining that showStreamDialog is a thin wrapper
around Flutter's showDialog that applies the Stream theme, and note its import
(package:stream_chat_flutter/stream_chat_flutter.dart); mention this once where
StreamMessageActionsModal, StreamMessageReactionsModal, and
ModeratedMessageActionsModal are first shown so readers know what
showStreamDialog is and how it differs from showDialog.

Comment on lines 448 to 457
```dart
// buildActions no longer accepts customActions — add extras via actionsBuilder
final List<StreamContextMenuAction> actions =
StreamMessageActionsBuilder.buildActions(
context: context,
message: message,
channel: channel,
currentUser: currentUser,
);
```
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Specify the type argument on List<StreamContextMenuAction> for clarity.

The "After" snippet leaves StreamContextMenuAction without its type parameter, which is inconsistent with the rest of the guide and may mislead readers about the expected generic type. Since buildActions returns actions for message handling, the type should be <MessageAction>:

📝 Proposed fix
-final List<StreamContextMenuAction> actions =
+final List<StreamContextMenuAction<MessageAction>> actions =
     StreamMessageActionsBuilder.buildActions(
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@migrations/redesign/message_actions.md` around lines 448 - 457, The List
declaration for actions is missing the generic type parameter for
StreamContextMenuAction; update the variable declaration and the type used by
StreamMessageActionsBuilder.buildActions to explicitly use the MessageAction
generic (e.g., make actions a List<StreamContextMenuAction<MessageAction>> and
ensure any StreamContextMenuAction references include <MessageAction>) so the
example matches the rest of the guide and clarifies the expected action type.

@xsahil03x xsahil03x merged commit d347eb1 into feat/design-refresh Feb 24, 2026
3 of 7 checks passed
@xsahil03x xsahil03x deleted the feat/context-menu-refresh branch February 24, 2026 10:19
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.

2 participants