Skip to content

Remove divider from the message actions - #1549

Merged
martinmitrevski merged 6 commits into
developfrom
message-actions-divider
Jul 30, 2026
Merged

martinmitrevski merged 6 commits into
developfrom
message-actions-divider

Conversation

@martinmitrevski

@martinmitrevski martinmitrevski commented Jul 29, 2026 •

Copy link
Copy Markdown
Contributor

πŸ”— Issue Links

Resolves https://linear.app/stream/issue/IOS-1917/v5-ui-polish-message-action-menu-shows-separators-between-every-item.

🎯 Goal

Remove divider from the message actions per the design.

πŸ“ Summary

Provide bullet points with the most important changes in the codebase.

πŸ›  Implementation

Provide a detailed description of the implementation and explain your decisions if you find them relevant.

🎨 Showcase

Add relevant screenshots and/or videos/gifs to easily see what this PR changes, if applicable.

Before After
img img

πŸ§ͺ Manual Testing Notes

Explain how this change can be tested manually, if applicable.

β˜‘οΈ Contributor Checklist

  • I have signed the Stream CLA (required)
  • This change should be manually QAed
  • Changelog is updated with client-facing changes
  • Changelog is updated with new localization keys
  • New code is covered by unit tests
  • Documentation has been updated in the docs-content repo

Summary by CodeRabbit

  • Style / UI
    • Refined message action menu separators so non-destructive actions are grouped without dividers, while a divider is still shown before destructive actions.
  • Tests
    • Updated snapshot coverage for message action layouts to validate: single destructive action, grouped destructive actions, and non-destructive-only lists.
  • Documentation
    • Updated the upcoming changelog entry to reflect the message action separator behavior change.

@martinmitrevski
martinmitrevski requested a review from a team as a code owner July 29, 2026 11:38

@laevandus laevandus left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

βœ…

@coderabbitai

coderabbitai Bot commented Jul 29, 2026 •

Copy link
Copy Markdown
Contributor

Review Change Stack

πŸ“ Walkthrough

Walkthrough

The message action menu now renders a divider only before a trailing group of destructive actions. Snapshot tests cover single-destructive, grouped-destructive, and non-destructive layouts, and the changelog documents the behavior.

Changes

Message action menu

Layer / File(s) Summary
Conditional action menu separators
Sources/StreamChatSwiftUI/ChatMessageList/Reactions/MessageActions/MessageActionsView.swift, CHANGELOG.md
Action rows compute divider placement so only the first trailing destructive action is separated from preceding actions; the changelog records the change.
Snapshot coverage for action layouts
StreamChatSwiftUITests/Tests/ChatChannel/MessageActionsView_Tests.swift, StreamChatSwiftUI.xcodeproj/project.pbxproj
Snapshot tests cover single-destructive, grouped-destructive, and non-destructive arrangements, with the test file registered in the test target.

Estimated code review effort: 2 (Simple) | ~10 minutes

Possibly related PRs

Suggested reviewers: laevandus, nuno-vieira

πŸš₯ Pre-merge checks | βœ… 5
βœ… Passed checks (5 passed)
Check name Status Explanation
Description Check βœ… Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check βœ… Passed The title matches the main change: removing dividers in the message actions menu.
Docstring Coverage βœ… Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check βœ… Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check βœ… Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
πŸ“ Generate docstrings
  • Create stacked PR
  • Commit on current branch
πŸ§ͺ Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch message-actions-divider

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.

@martinmitrevski
martinmitrevski enabled auto-merge (squash) July 29, 2026 11:55
Comment on lines -60 to -61

Divider()

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

According to Figma, it looks like destructive actions should have the divider, and should be at the end πŸ€”

Image

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

updated now

@martinmitrevski
martinmitrevski disabled auto-merge July 29, 2026 13:08

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

πŸ€– Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@StreamChatSwiftUI.xcodeproj/project.pbxproj`:
- Line 200: Remove Tests/ChatChannel/MessageActionsView_Tests.swift from the
membershipExceptions section in the Xcode project configuration, and register it
with the StreamChatSwiftUITests target using Xcode’s target membership/build
phase settings instead.
πŸͺ„ Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
βš™οΈ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 6a13fe99-beef-498e-bf73-59cf55da7d8c

πŸ“₯ Commits

Reviewing files that changed from the base of the PR and between f2b141b and 736a1ba.

β›” Files ignored due to path filters (19)
  • StreamChatSwiftUITests/Tests/ChatChannel/__Snapshots__/MessageActionsView_Tests/test_messageActionsView_destructiveActionsLast_snapshot.default-light.png is excluded by !**/*.png
  • StreamChatSwiftUITests/Tests/ChatChannel/__Snapshots__/MessageActionsView_Tests/test_messageActionsView_destructiveActionsLast_snapshot.extraExtraExtraLarge-light.png is excluded by !**/*.png
  • StreamChatSwiftUITests/Tests/ChatChannel/__Snapshots__/MessageActionsView_Tests/test_messageActionsView_destructiveActionsLast_snapshot.rightToLeftLayout-default.png is excluded by !**/*.png
  • StreamChatSwiftUITests/Tests/ChatChannel/__Snapshots__/MessageActionsView_Tests/test_messageActionsView_destructiveActionsLast_snapshot.small-dark.png is excluded by !**/*.png
  • StreamChatSwiftUITests/Tests/ChatChannel/__Snapshots__/MessageActionsView_Tests/test_messageActionsView_destructiveActionsSeparated_snapshot.default-light.png is excluded by !**/*.png
  • StreamChatSwiftUITests/Tests/ChatChannel/__Snapshots__/MessageActionsView_Tests/test_messageActionsView_destructiveActionsSeparated_snapshot.extraExtraExtraLarge-light.png is excluded by !**/*.png
  • StreamChatSwiftUITests/Tests/ChatChannel/__Snapshots__/MessageActionsView_Tests/test_messageActionsView_destructiveActionsSeparated_snapshot.rightToLeftLayout-default.png is excluded by !**/*.png
  • StreamChatSwiftUITests/Tests/ChatChannel/__Snapshots__/MessageActionsView_Tests/test_messageActionsView_destructiveActionsSeparated_snapshot.small-dark.png is excluded by !**/*.png
  • StreamChatSwiftUITests/Tests/ChatChannel/__Snapshots__/MessageActionsView_Tests/test_messageActionsView_noDestructiveActions_snapshot.default-light.png is excluded by !**/*.png
  • StreamChatSwiftUITests/Tests/ChatChannel/__Snapshots__/MessageActionsView_Tests/test_messageActionsView_noDestructiveActions_snapshot.extraExtraExtraLarge-light.png is excluded by !**/*.png
  • StreamChatSwiftUITests/Tests/ChatChannel/__Snapshots__/MessageActionsView_Tests/test_messageActionsView_noDestructiveActions_snapshot.rightToLeftLayout-default.png is excluded by !**/*.png
  • StreamChatSwiftUITests/Tests/ChatChannel/__Snapshots__/MessageActionsView_Tests/test_messageActionsView_noDestructiveActions_snapshot.small-dark.png is excluded by !**/*.png
  • StreamChatSwiftUITests/Tests/ChatChannel/__Snapshots__/MessageActionsView_Tests/test_messageActionsView_onlyDestructiveActions_snapshot.default-light.png is excluded by !**/*.png
  • StreamChatSwiftUITests/Tests/ChatChannel/__Snapshots__/MessageActionsView_Tests/test_messageActionsView_onlyDestructiveActions_snapshot.extraExtraExtraLarge-light.png is excluded by !**/*.png
  • StreamChatSwiftUITests/Tests/ChatChannel/__Snapshots__/MessageActionsView_Tests/test_messageActionsView_onlyDestructiveActions_snapshot.rightToLeftLayout-default.png is excluded by !**/*.png
  • StreamChatSwiftUITests/Tests/ChatChannel/__Snapshots__/MessageActionsView_Tests/test_messageActionsView_onlyDestructiveActions_snapshot.small-dark.png is excluded by !**/*.png
  • StreamChatSwiftUITests/Tests/ChatChannel/__Snapshots__/ReactionsOverlayView_Tests/test_reactionsOverlayView_noReactions.1.png is excluded by !**/*.png
  • StreamChatSwiftUITests/Tests/ChatChannel/__Snapshots__/ReactionsOverlayView_Tests/test_reactionsOverlayView_snapshot.1.png is excluded by !**/*.png
  • StreamChatSwiftUITests/Tests/ChatChannel/__Snapshots__/ReactionsOverlayView_Tests/test_reactionsOverlayView_translated.1.png is excluded by !**/*.png
πŸ“’ Files selected for processing (4)
  • CHANGELOG.md
  • Sources/StreamChatSwiftUI/ChatMessageList/Reactions/MessageActions/MessageActionsView.swift
  • StreamChatSwiftUI.xcodeproj/project.pbxproj
  • StreamChatSwiftUITests/Tests/ChatChannel/MessageActionsView_Tests.swift
🚧 Files skipped from review as they are similar to previous changes (1)
  • CHANGELOG.md

Comment thread StreamChatSwiftUI.xcodeproj/project.pbxproj

@nuno-vieira nuno-vieira left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Looks good, could be improved in terms of customiziblity, but not a blocker

Comment on lines +92 to +106
/// The divider goes in front of the trailing run of destructive actions, and is skipped
/// when there is nothing above it to separate from.
private var actionRows: [ActionRow] {
let actions = viewModel.messageActions
var dividerIndex: Int?
if let lastRegularIndex = actions.lastIndex(where: { !$0.isDestructive }) {
let destructiveGroupIndex = lastRegularIndex + 1
dividerIndex = destructiveGroupIndex < actions.count ? destructiveGroupIndex : nil
}

return actions.enumerated().map { index, action in
ActionRow(action: action, showsDivider: index == dividerIndex)
}
}
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This works fine, but not very customizable. Would be better if this either stayed on the MessageActionsViewModel or the ChannelInfoViewModel. Since the latter is the one responsible for creating the actions, it would probably make sense to extend the MessageAction with showsDivider, and the info view model would make the logic to show or not show the divider.

An even better approach would be to have a MessageActionItemViewModel so that the UI logic would be decoupled from the actual MessageAction. But I believe this would require some breaking changes, most likely.

Either way, none are blocking at the moment.

@martinmitrevski
martinmitrevski enabled auto-merge (squash) July 30, 2026 09:39

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

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

⚠️ Outside diff range comments (1)
CHANGELOG.md (1)

6-6: πŸ“ Maintainability & Code Quality | 🟑 Minor | ⚑ Quick win

Use a level-2 heading here.

### Added skips from # Upcoming to level 3, triggering markdownlint MD001. Change it to ## Added.

πŸ€– Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@CHANGELOG.md` at line 6, Update the β€œAdded” heading in the changelog from
level 3 to level 2 so it follows the β€œUpcoming” level-1 heading and satisfies
markdown heading hierarchy.

Source: Linters/SAST tools

♻️ Duplicate comments (1)
StreamChatSwiftUI.xcodeproj/project.pbxproj (1)

206-206: 🎯 Functional Correctness | 🟠 Major

Remove the test from membershipExceptions.

This exclusion prevents Tests/ChatChannel/MessageActionsView_Tests.swift from being compiled or discovered by StreamChatSwiftUITests. Remove the entry and register the file through the synchronized target membership instead.

As per coding guidelines, source files must be added to the correct Xcode target and project membership.

πŸ€– Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@StreamChatSwiftUI.xcodeproj/project.pbxproj` at line 206, Remove
Tests/ChatChannel/MessageActionsView_Tests.swift from the membershipExceptions
configuration in the Xcode project, then add it through the synchronized
StreamChatSwiftUITests target membership so the test is compiled and discovered
normally.

Source: Coding guidelines

🧹 Nitpick comments (1)
StreamChatSwiftUITests/Tests/ChatChannel/MessageActionsView_Tests.swift (1)

34-39: πŸ“ Maintainability & Code Quality | πŸ”΅ Trivial | ⚑ Quick win

Retain coverage for an all-destructive menu.

The current fixtures cover trailing destructive actions and no destructive actions, but not the lastIndex(where:) == nil branch. Add a snapshot containing only destructive actions to verify that no divider is rendered when there is nothing above the group.

As per coding guidelines, maintain high test coverage for changed SwiftUI behavior.

πŸ€– Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@StreamChatSwiftUITests/Tests/ChatChannel/MessageActionsView_Tests.swift`
around lines 34 - 39, Extend
test_messageActionsView_destructiveActionsGroup_snapshot with a separate
snapshot fixture containing only destructive actions, exercising the
lastIndex(where:) == nil path. Assert the rendered menu has no divider above the
destructive group, while preserving the existing snapshots for trailing and
non-destructive actions.

Source: Coding guidelines

πŸ€– Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@Sources/StreamChatSwiftUI/ChatMessageList/Reactions/MessageActions/MessageActionsView.swift`:
- Around line 92-94: Convert the `///` comments immediately above the private
`actionRows` property to `//` comments, preserving their wording and placement
as an internal implementation note.

---

Outside diff comments:
In `@CHANGELOG.md`:
- Line 6: Update the β€œAdded” heading in the changelog from level 3 to level 2 so
it follows the β€œUpcoming” level-1 heading and satisfies markdown heading
hierarchy.

---

Duplicate comments:
In `@StreamChatSwiftUI.xcodeproj/project.pbxproj`:
- Line 206: Remove Tests/ChatChannel/MessageActionsView_Tests.swift from the
membershipExceptions configuration in the Xcode project, then add it through the
synchronized StreamChatSwiftUITests target membership so the test is compiled
and discovered normally.

---

Nitpick comments:
In `@StreamChatSwiftUITests/Tests/ChatChannel/MessageActionsView_Tests.swift`:
- Around line 34-39: Extend
test_messageActionsView_destructiveActionsGroup_snapshot with a separate
snapshot fixture containing only destructive actions, exercising the
lastIndex(where:) == nil path. Assert the rendered menu has no divider above the
destructive group, while preserving the existing snapshots for trailing and
non-destructive actions.
πŸͺ„ Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
βš™οΈ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 9b41318d-5b7f-4834-a5fd-fc47d63f4523

πŸ“₯ Commits

Reviewing files that changed from the base of the PR and between 736a1ba and d71d8fc.

β›” Files ignored due to path filters (8)
  • StreamChatSwiftUITests/Tests/ChatChannel/__Snapshots__/MessageActionsView_Tests/test_messageActionsView_destructiveActionsGroup_snapshot.default-light.png is excluded by !**/*.png
  • StreamChatSwiftUITests/Tests/ChatChannel/__Snapshots__/MessageActionsView_Tests/test_messageActionsView_destructiveActionsGroup_snapshot.extraExtraExtraLarge-light.png is excluded by !**/*.png
  • StreamChatSwiftUITests/Tests/ChatChannel/__Snapshots__/MessageActionsView_Tests/test_messageActionsView_destructiveActionsGroup_snapshot.rightToLeftLayout-default.png is excluded by !**/*.png
  • StreamChatSwiftUITests/Tests/ChatChannel/__Snapshots__/MessageActionsView_Tests/test_messageActionsView_destructiveActionsGroup_snapshot.small-dark.png is excluded by !**/*.png
  • StreamChatSwiftUITests/Tests/ChatChannel/__Snapshots__/MessageActionsView_Tests/test_messageActionsView_singleDestructiveAction_snapshot.default-light.png is excluded by !**/*.png
  • StreamChatSwiftUITests/Tests/ChatChannel/__Snapshots__/MessageActionsView_Tests/test_messageActionsView_singleDestructiveAction_snapshot.extraExtraExtraLarge-light.png is excluded by !**/*.png
  • StreamChatSwiftUITests/Tests/ChatChannel/__Snapshots__/MessageActionsView_Tests/test_messageActionsView_singleDestructiveAction_snapshot.rightToLeftLayout-default.png is excluded by !**/*.png
  • StreamChatSwiftUITests/Tests/ChatChannel/__Snapshots__/MessageActionsView_Tests/test_messageActionsView_singleDestructiveAction_snapshot.small-dark.png is excluded by !**/*.png
πŸ“’ Files selected for processing (4)
  • CHANGELOG.md
  • Sources/StreamChatSwiftUI/ChatMessageList/Reactions/MessageActions/MessageActionsView.swift
  • StreamChatSwiftUI.xcodeproj/project.pbxproj
  • StreamChatSwiftUITests/Tests/ChatChannel/MessageActionsView_Tests.swift

Comment on lines +92 to +94
/// The divider goes in front of the trailing run of destructive actions, and is skipped
/// when there is nothing above it to separate from.
private var actionRows: [ActionRow] {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

πŸ“ Maintainability & Code Quality | 🟑 Minor | ⚑ Quick win

Use // for this private implementation note.

This is documentation for a private property, not a public SDK declaration. Convert the /// comments to // comments.

As per coding guidelines, use /// only for public SDK declarations and inline comments for non-obvious internal reasoning.

Proposed fix
-    /// The divider goes in front of the trailing run of destructive actions, and is skipped
-    /// when there is nothing above it to separate from.
+    // The divider goes in front of the trailing run of destructive actions, and is skipped
+    // when there is nothing above it to separate from.
πŸ“ 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
/// The divider goes in front of the trailing run of destructive actions, and is skipped
/// when there is nothing above it to separate from.
private var actionRows: [ActionRow] {
// The divider goes in front of the trailing run of destructive actions, and is skipped
// when there is nothing above it to separate from.
private var actionRows: [ActionRow] {
πŸ€– Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@Sources/StreamChatSwiftUI/ChatMessageList/Reactions/MessageActions/MessageActionsView.swift`
around lines 92 - 94, Convert the `///` comments immediately above the private
`actionRows` property to `//` comments, preserving their wording and placement
as an internal implementation note.

Source: Coding guidelines

@github-actions

Copy link
Copy Markdown

Public Interface

πŸš€ No changes affecting the public interface.

@Stream-SDK-Bot

Copy link
Copy Markdown
Collaborator

SDK Size

title develop branch diff status
StreamChatSwiftUI 5.79 MB 5.79 MB +1 KB 🟒

@Stream-SDK-Bot

Copy link
Copy Markdown
Collaborator

StreamChatSwiftUI XCSize

Object Diff (bytes)
MessageActionsView.o +2004
ChatChannelInfoViewModel.o +346
Modifiers.o -328
MessageActionsViewModel.o -56

@sonarqubecloud

Copy link
Copy Markdown

@martinmitrevski
martinmitrevski merged commit 70b377b into develop Jul 30, 2026
15 checks passed
@martinmitrevski
martinmitrevski deleted the message-actions-divider branch July 30, 2026 10:20
@Stream-SDK-Bot Stream-SDK-Bot mentioned this pull request Aug 3, 2026
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.

4 participants