Skip to content

Comments

Improve exit animation of the selected message menu#6191

Open
gpunto wants to merge 2 commits intov7from
redesign/selected-message-menu-improvements
Open

Improve exit animation of the selected message menu#6191
gpunto wants to merge 2 commits intov7from
redesign/selected-message-menu-improvements

Conversation

@gpunto
Copy link
Contributor

@gpunto gpunto commented Feb 25, 2026

Goal

Update selected message menu with a custom exit animation

Implementation

  • Implemented exit animation as reverse of the entry one
  • Fixed a bug where the source bounds were incorrect in some cases (i.e. when the message height changed after the first composition, like when showing the full size link preview)
  • Changed animation interpolator

Note: there is still some polishing to do that I'm already aware of (e.g. proper handling of the message footer, pinned state). For this PR, I'm focusing just on the animation.

🎨 UI Changes

Screen_recording_20260225_134503.mp4

Testing

The new animation can be checked as always in the sample

Summary by CodeRabbit

Release Notes

  • New Features
    • Enhanced animation behavior for the selected message menu with improved easing and timing for smoother appearance and dismissal transitions.

@gpunto gpunto added the pr:improvement Improvement label Feb 25, 2026
@github-actions
Copy link
Contributor

github-actions bot commented Feb 25, 2026

PR checklist ✅

All required conditions are satisfied:

  • Title length is OK (or ignored by label).
  • At least one pr: label exists.
  • Sections ### Goal, ### Implementation, and ### Testing are filled.

🎉 Great job! This PR is ready for review.

@github-actions
Copy link
Contributor

github-actions bot commented Feb 25, 2026

SDK Size Comparison 📏

SDK Before After Difference Status
stream-chat-android-client 5.25 MB 5.69 MB 0.44 MB 🟡
stream-chat-android-ui-components 10.60 MB 10.96 MB 0.36 MB 🟡
stream-chat-android-compose 12.81 MB 11.90 MB -0.91 MB 🚀

@gpunto gpunto marked this pull request as ready for review February 25, 2026 13:59
@gpunto gpunto requested a review from a team as a code owner February 25, 2026 13:59
@coderabbitai
Copy link

coderabbitai bot commented Feb 25, 2026

Walkthrough

The SelectedMessageMenu animation system is updated to replace animation easing, introduce coroutine-based dismissal with animation-out sequences before invoking callbacks, restructure animation initialization outside Dialog content, and configure window animation disabling and blur effects.

Changes

Cohort / File(s) Summary
Animation & Dismissal Flow
stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/selectedmessage/SelectedMessageMenu.kt
Replaces EaseOutCubic with FastOutSlowInEasing for animations; introduces coroutine-based animatedDismiss function that plays animation-out before invoking onDismiss; adds NonCancellable to ensure dismissal completes; moves animation initialization outside Dialog content; disables window animations and applies blur; updates MenuAnimationState with new animateOut method and modified onGloballyPositioned behavior.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 Hop along with smoother eases,
FastOutSlowIn now pleases!
Animations dance before goodbye,
With coroutines and blur applied.
MenuAnimations spin their grace,
Dismissals fade without a trace. 🎭

🚥 Pre-merge checks | ✅ 1 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Description check ❓ Inconclusive The description covers the required Goal and Implementation sections but is missing the UI Changes screenshots/table, Testing details, and Contributor Checklist, which are specified in the template. Add comparison screenshots (before/after) in the UI Changes table, provide more detailed testing instructions, and complete the Contributor Checklist with required checkmarks and assignments.
✅ Passed checks (1 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely describes the main change—improving the exit animation of the selected message menu—which directly aligns with the primary focus of the changeset.

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

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch redesign/selected-message-menu-improvements

Tip

Try Coding Plans. Let us write the prompt for your AI agent so you can ship faster (with fewer bugs).
Share your feedback on Discord.


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.

Copy link

@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: 2

🧹 Nitpick comments (1)
stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/selectedmessage/SelectedMessageMenu.kt (1)

126-132: Document the new onDismiss timing semantics in KDoc.

onDismiss now executes after exit animation (not immediately on request). Please document this behavioral change and expected calling thread/state for the public SelectedMessageMenu API.

As per coding guidelines, **/*.kt: "Document public APIs with KDoc, including thread expectations and state notes".

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

In
`@stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/selectedmessage/SelectedMessageMenu.kt`
around lines 126 - 132, Update the public KDoc for SelectedMessageMenu to state
that the onDismiss callback is invoked only after the exit animation completes
(not immediately when dismissal is requested), that the callback is called from
the coroutine scope used by the component (it may be executed within a
NonCancellable context during the animation cleanup), and note any relevant
UI/state expectations (e.g., it runs off the main thread if launched on a
background scope or on the main thread if the component scope is Main). Add
these timing and thread/state semantics next to the SelectedMessageMenu
declaration and reference the animatedDismiss/onDismiss behavior so callers know
to avoid relying on immediate execution.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In
`@stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/selectedmessage/SelectedMessageMenu.kt`:
- Around line 121-124: The rememberMenuAnimation call creates a
MenuAnimationState once and never updates when bounds change; update the
remember usage to include dependency keys so the state is recreated when
relevant inputs change (e.g., pass LocalSelectedMessageBounds.current?.value and
messageAlignment as keys to remember or to rememberMenuAnimation if it accepts
keys), and replace LaunchedEffect(Unit) that starts the animation with a
LaunchedEffect keyed on the changing bounds/state (for example
LaunchedEffect(sourceBounds) or LaunchedEffect(animation) ) so the animation
re-triggers when LocalSelectedMessageBounds.current?.value or messageAlignment
changes; update references to MenuAnimationState, rememberMenuAnimation,
LocalSelectedMessageBounds.current?.value, and the LaunchedEffect invocation
accordingly.
- Around line 126-134: The animatedDismiss lambda currently can be invoked
concurrently causing multiple coroutines to call animation.animateOut() and
onDismiss() repeatedly; fix by adding a single-entry guard (e.g., an
AtomicBoolean flag or a Mutex/Job check) inside the remember block that ensures
only the first invocation proceeds to launch the coroutine which calls
animation.animateOut() and then onDismiss(), and subsequent calls return
immediately; update the KDoc for the onDismiss parameter to state it is invoked
asynchronously once after the exit animation completes.

---

Nitpick comments:
In
`@stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/selectedmessage/SelectedMessageMenu.kt`:
- Around line 126-132: Update the public KDoc for SelectedMessageMenu to state
that the onDismiss callback is invoked only after the exit animation completes
(not immediately when dismissal is requested), that the callback is called from
the coroutine scope used by the component (it may be executed within a
NonCancellable context during the animation cleanup), and note any relevant
UI/state expectations (e.g., it runs off the main thread if launched on a
background scope or on the main thread if the component scope is Main). Add
these timing and thread/state semantics next to the SelectedMessageMenu
declaration and reference the animatedDismiss/onDismiss behavior so callers know
to avoid relying on immediate execution.

ℹ️ Review info

Configuration used: Repository UI

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 e96c509 and 5d04507.

📒 Files selected for processing (1)
  • stream-chat-android-compose/src/main/java/io/getstream/chat/android/compose/ui/components/selectedmessage/SelectedMessageMenu.kt

@sonarqubecloud
Copy link

Quality Gate Failed Quality Gate failed

Failed conditions
50.0% Coverage on New Code (required ≥ 80%)

See analysis details on SonarQube Cloud

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

pr:improvement Improvement

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant