Skip to content

Conversation

@VelikovPetar
Copy link
Contributor

@VelikovPetar VelikovPetar commented Jan 2, 2026

🎯 Goal

Fixes a case where a newly sent Giphy message does not appear immediately in the channel.

Note: While this seems like a compose glitch, I wasn't able to figure out why the Giphy doesn't render. But we were anyway wrongly deleting the message from the state instead of upserting it, when we get a result from sending the Giphy. Fixing this seems to resolve the UI glitch as well, so my assumption is that the rendering fails because we rapidly delete and insert a new message (after receiving message.new event) with the same Giphy URL.

🛠 Implementation details

Upsert the relevant Giphy message in the state instead of deleting it.

🎨 UI Changes

Before After
before.mp4
after.mp4

🧪 Testing

  1. Open Compose sample
  2. Open channel
  3. Send Giphy
  4. The Giphy should be rendered immediately, without any UI glitches

Summary by CodeRabbit

  • Bug Fixes

    • Fixed an issue where Giphy messages may not appear in a channel after being sent.
  • Tests

    • Added unit tests to validate Giphy send behavior across channels, threads, and query states.

✏️ Tip: You can customize this high-level summary in your review settings.

@github-actions
Copy link
Contributor

github-actions bot commented Jan 2, 2026

SDK Size Comparison 📏

SDK Before After Difference Status
stream-chat-android-client 5.25 MB 5.25 MB 0.00 MB 🟢
stream-chat-android-offline 5.48 MB 5.48 MB 0.00 MB 🟢
stream-chat-android-ui-components 10.60 MB 10.60 MB 0.00 MB 🟢
stream-chat-android-compose 12.81 MB 12.81 MB 0.00 MB 🟢

@VelikovPetar VelikovPetar marked this pull request as ready for review January 2, 2026 14:43
@VelikovPetar VelikovPetar requested a review from a team as a code owner January 2, 2026 14:43
@coderabbitai
Copy link

coderabbitai bot commented Jan 2, 2026

Walkthrough

This PR fixes a bug where a sent Giphy message may not appear in the channel by replacing three deleteMessage calls with upsertMessage in the Giphy send success handler and adding unit tests to validate the behavior.

Changes

Cohort / File(s) Summary
Documentation
CHANGELOG.md
Added an entry under "Fixed" documenting the Giphy message visibility issue.
Implementation
stream-chat-android-state/src/main/java/io/getstream/chat/android/state/plugin/listener/internal/SendGiphyListenerState.kt
On Giphy send success, replaced three deleteMessage calls with upsertMessage calls for channel-level state, active query threads, and thread-specific state; header comment updated.
Tests
stream-chat-android-state/src/test/java/io/getstream/chat/android/state/plugin/listener/internal/SendGiphyListenerStateTest.kt
Added tests verifying that on success upsertMessage(testMessage) is called on ChannelStateLogic, QueryThreadsLogic, and ThreadStateLogic, and that on failure upsertMessage is not called.

Sequence Diagram(s)

sequenceDiagram
    autonumber
    participant Client
    participant SendGiphyListener as Listener
    participant ChannelLogic as ChannelStateLogic
    participant QueryLogic as QueryThreadsLogic
    participant ThreadLogic as ThreadStateLogic

    Client->>Listener: onGiphySendResult(Result.Success(message))
    activate Listener
    Listener->>ChannelLogic: upsertMessage(message)
    Note right of ChannelLogic `#DFF0D8`: channel state updated
    Listener->>QueryLogic: upsertMessage(message)
    Note right of QueryLogic `#DFF0D8`: active queries updated
    Listener->>ThreadLogic: upsertMessage(message)
    Note right of ThreadLogic `#DFF0D8`: thread state updated
    deactivate Listener
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Suggested reviewers

  • gpunto
  • aleksandar-apostolov

Poem

🐰 I hopped through code with a joyful cheer,
Replaced a delete so the GIFs appear.
Three gentle upserts, a tidy little dance,
Now messages show — give the users a chance! 🎞️✨

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely describes the main bug being fixed in the pull request.
Description check ✅ Passed The description covers Goal, Implementation details, UI Changes with videos, and Testing steps, but lacks several required checklist items and the GIF section.
✨ Finishing touches
  • 📝 Generate docstrings

📜 Recent review details

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between d967254 and ac39128.

📒 Files selected for processing (1)
  • stream-chat-android-state/src/main/java/io/getstream/chat/android/state/plugin/listener/internal/SendGiphyListenerState.kt
🚧 Files skipped from review as they are similar to previous changes (1)
  • stream-chat-android-state/src/main/java/io/getstream/chat/android/state/plugin/listener/internal/SendGiphyListenerState.kt
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (6)
  • GitHub Check: compare-sdk-sizes / Compare SDK sizes
  • GitHub Check: Build / compose apks
  • GitHub Check: base-android-ci / Build
  • GitHub Check: base-android-ci / Run static checks
  • GitHub Check: base-android-ci / Run unit tests
  • GitHub Check: Detekt

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: 0

Caution

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

⚠️ Outside diff range comments (2)
stream-chat-android-state/src/main/java/io/getstream/chat/android/state/plugin/listener/internal/SendGiphyListenerState.kt (2)

24-26: Update the class-level KDoc to reflect the new behavior.

The KDoc states "Handles removing ephemeral message from the state", but the implementation now upserts the Giphy message instead of deleting it. Update the documentation to accurately describe the current behavior.

🔎 Proposed fix
 /**
  * [SendGiphyListener] implementation for [StatePlugin].
- * Handles removing ephemeral message from the state.
+ * Handles upserting Giphy message to the state.
  *
  * @param logic [LogicRegistry]
  */

32-36: Update the method KDoc to reflect the new behavior.

The KDoc states "Removes ephemeral message from the state if the request was successful", but the implementation now upserts the Giphy message. Update the documentation to accurately describe the current behavior.

🔎 Proposed fix
     /**
-     * Removes ephemeral message from the state if the request was successful.
+     * Upserts Giphy message to the state if the request was successful.
      *
      * @param cid The full channel id, i.e. "messaging:123".
      * @param result The API call result.
      */
📜 Review details

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between df39c96 and d967254.

📒 Files selected for processing (3)
  • CHANGELOG.md
  • stream-chat-android-state/src/main/java/io/getstream/chat/android/state/plugin/listener/internal/SendGiphyListenerState.kt
  • stream-chat-android-state/src/test/java/io/getstream/chat/android/state/plugin/listener/internal/SendGiphyListenerStateTest.kt
🧰 Additional context used
📓 Path-based instructions (3)
**/*.{kt,kts}

📄 CodeRabbit inference engine (AGENTS.md)

Format and apply Kotlin style with Spotless (4 spaces, no wildcard imports, licence headers)

Files:

  • stream-chat-android-state/src/main/java/io/getstream/chat/android/state/plugin/listener/internal/SendGiphyListenerState.kt
  • stream-chat-android-state/src/test/java/io/getstream/chat/android/state/plugin/listener/internal/SendGiphyListenerStateTest.kt
**/*.kt

📄 CodeRabbit inference engine (AGENTS.md)

**/*.kt: Use @OptIn annotations explicitly; avoid suppressions unless documented
Document public APIs with KDoc, including thread expectations and state notes

Files:

  • stream-chat-android-state/src/main/java/io/getstream/chat/android/state/plugin/listener/internal/SendGiphyListenerState.kt
  • stream-chat-android-state/src/test/java/io/getstream/chat/android/state/plugin/listener/internal/SendGiphyListenerStateTest.kt
**/src/test/**/*.kt

📄 CodeRabbit inference engine (AGENTS.md)

**/src/test/**/*.kt: Use backtick test names (for example: fun message list filters muted channels()) for readability
Use deterministic tests with runTest + virtual time for concurrency-sensitive logic (uploads, sync, message state)
Keep helper extensions private/internal in test files

Files:

  • stream-chat-android-state/src/test/java/io/getstream/chat/android/state/plugin/listener/internal/SendGiphyListenerStateTest.kt
🧠 Learnings (3)
📚 Learning: 2025-12-17T15:00:07.506Z
Learnt from: CR
Repo: GetStream/stream-chat-android PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-17T15:00:07.506Z
Learning: Applies to **/stream-chat-android-compose/**/*Test.kt : Add Paparazzi snapshots for Compose UI regressions and run `verifyPaparazziDebug`

Applied to files:

  • stream-chat-android-state/src/test/java/io/getstream/chat/android/state/plugin/listener/internal/SendGiphyListenerStateTest.kt
📚 Learning: 2025-12-17T15:00:07.506Z
Learnt from: CR
Repo: GetStream/stream-chat-android PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-17T15:00:07.506Z
Learning: Applies to **/stream-chat-android-ui-components/**/*Test.kt : Record Shot baselines when behaviour changes in XML kit UI tests

Applied to files:

  • stream-chat-android-state/src/test/java/io/getstream/chat/android/state/plugin/listener/internal/SendGiphyListenerStateTest.kt
📚 Learning: 2025-12-17T15:00:07.506Z
Learnt from: CR
Repo: GetStream/stream-chat-android PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-17T15:00:07.506Z
Learning: Applies to **/src/test/**/*.kt : Use deterministic tests with `runTest` + virtual time for concurrency-sensitive logic (uploads, sync, message state)

Applied to files:

  • stream-chat-android-state/src/test/java/io/getstream/chat/android/state/plugin/listener/internal/SendGiphyListenerStateTest.kt
🧬 Code graph analysis (1)
stream-chat-android-state/src/test/java/io/getstream/chat/android/state/plugin/listener/internal/SendGiphyListenerStateTest.kt (1)
stream-chat-android-core/src/testFixtures/kotlin/io/getstream/chat/android/Mother.kt (1)
  • randomCID (101-101)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: compare-sdk-sizes / Compare SDK sizes
  • GitHub Check: Build / compose apks
🔇 Additional comments (4)
CHANGELOG.md (1)

40-40: Changelog entry looks correct and consistent

The new Giphy fix line is in the right section, uses the same wording and link style as existing entries, and clearly describes the bug being fixed. No changes needed.

stream-chat-android-state/src/main/java/io/getstream/chat/android/state/plugin/listener/internal/SendGiphyListenerState.kt (1)

41-43: LGTM! The fix correctly addresses the Giphy rendering issue.

Replacing deleteMessage with upsertMessage ensures the Giphy message is properly maintained in the state across channel, query threads, and thread contexts. This prevents the delete-then-insert cycle that was causing the UI glitch.

stream-chat-android-state/src/test/java/io/getstream/chat/android/state/plugin/listener/internal/SendGiphyListenerStateTest.kt (2)

43-70: LGTM! Comprehensive test coverage for the success path.

The test correctly validates that upsertMessage is called on channel state logic, all active query threads, and thread state logic when the Giphy send request succeeds. The use of runTest and backtick test naming follows the project's coding guidelines.


72-96: LGTM! Proper test coverage for the failure path.

The test correctly validates that upsertMessage is never called on any state logic when the Giphy send request fails. This ensures the fix doesn't inadvertently update state on error conditions.

@sonarqubecloud
Copy link

sonarqubecloud bot commented Jan 2, 2026

Quality Gate Failed Quality Gate failed

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

See analysis details on SonarQube Cloud

@VelikovPetar VelikovPetar merged commit f06ed8b into develop Jan 2, 2026
13 of 14 checks passed
@VelikovPetar VelikovPetar deleted the bug/AND-967_fix_giphy_not_appearing_in_channel branch January 2, 2026 18:02
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.

3 participants