Skip to content

fix(ux): implement auto-pause audio playback interceptor #531#541

Open
sanikatavate wants to merge 1 commit into
UTKARSHH20:mainfrom
sanikatavate:fix-audio-playback-531
Open

fix(ux): implement auto-pause audio playback interceptor #531#541
sanikatavate wants to merge 1 commit into
UTKARSHH20:mainfrom
sanikatavate:fix-audio-playback-531

Conversation

@sanikatavate

@sanikatavate sanikatavate commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

Summary by CodeRabbit

  • New Features

    • Added coordinated voice note playback—only one audio message can play at a time, with automatic pause when switching between voice notes.
  • Bug Fixes

    • Improved translation toggle button responsiveness and event handling.

@coderabbitai

coderabbitai Bot commented Jun 9, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@sanikatavate, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 33 minutes and 45 seconds. Learn how PR review limits work.

Your organization has run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 56cb464d-7d92-4cd1-9f94-995547b845b6

📥 Commits

Reviewing files that changed from the base of the PR and between 01b661a and 67ab6f5.

📒 Files selected for processing (2)
  • frontend/components/chat/MessageBubble.jsx
  • frontend/src/store/useChatStore.js
📝 Walkthrough

Walkthrough

This PR implements coordinated voice note playback across chat message bubbles. The chat store now tracks which message's audio is currently playing, and MessageBubble components use a useEffect to pause their own audio whenever another message's audio becomes active. The store also resets the active audio ID when switching conversations.

Changes

Audio playback coordination

Layer / File(s) Summary
Chat store audio state and lifecycle
frontend/src/store/useChatStore.js
activeAudioId state field and setActiveAudioId action are added; setSelectedUser also clears activeAudioId when switching or clearing conversations.
MessageBubble audio coordination and UI fixes
frontend/components/chat/MessageBubble.jsx
MessageBubble imports useEffect and useRef hooks plus useChatStore; creates an audioRef and useEffect that pauses audio when another message's audio becomes active; audio element attaches the ref and calls setActiveAudioId on play; translation button click now stops propagation and toggles state.

Sequence Diagram

sequenceDiagram
  participant User
  participant Bubble1 as MessageBubble<br/>(message A)
  participant Bubble2 as MessageBubble<br/>(message B)
  participant Store as useChatStore<br/>(activeAudioId)

  User->>Bubble1: Play audio
  Bubble1->>Store: setActiveAudioId(messageA_id)
  Store-->>Bubble2: activeAudioId changed
  Bubble2->>Bubble2: useEffect pauses own audio
  
  Note over Store: activeAudioId = messageA_id
  
  User->>Bubble2: Play audio
  Bubble2->>Store: setActiveAudioId(messageB_id)
  Store-->>Bubble1: activeAudioId changed
  Bubble1->>Bubble1: useEffect pauses own audio
  
  Note over Store: activeAudioId = messageB_id
Loading

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Poem

A rabbit hops through message streams,
Where audio flows and synchronize beams.
One note plays while others rest—
A harmony of coordination, truly blessed! 🎵🐰

🚥 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 accurately describes the main change: implementing automatic audio pause functionality when switching between message audio playbacks, which aligns with the core modifications in MessageBubble.jsx and useChatStore.js.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
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.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Caution

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

⚠️ Outside diff range comments (1)
frontend/components/chat/MessageBubble.jsx (1)

106-106: ⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

Critical: setSelectedImage is undefined.

The onClick handler calls setSelectedImage(msg.image), but setSelectedImage is not defined in this component. This will cause a runtime error when users click on message images.

🔧 Possible fixes

Option 1: Add missing state

 const [showTranslation, setShowTranslation] = useState(false)
 const [isSelected, setIsSelected] = useState(false)
+const [selectedImage, setSelectedImage] = useState(null)

Then add an image modal/viewer component that uses selectedImage to display the full image.

Option 2: Accept as prop if parent should handle

-export default function MessageBubble({ msg, isMine, showTime, selectedUser, isOnline, authUser, onContextMenu, onTouchStart, onTouchEnd, onReact }) {
+export default function MessageBubble({ msg, isMine, showTime, selectedUser, isOnline, authUser, onContextMenu, onTouchStart, onTouchEnd, onReact, onImageClick }) {
-    onClick={() => setSelectedImage(msg.image)}
+    onClick={() => onImageClick?.(msg.image)}

Option 3: Remove if functionality not needed

-    onClick={() => setSelectedImage(msg.image)}
🤖 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 `@frontend/components/chat/MessageBubble.jsx` at line 106, The onClick handler
in MessageBubble.jsx calls setSelectedImage(msg.image) but that setter is
undefined; fix by either (A) adding local state const [selectedImage,
setSelectedImage] = useState(null) in the MessageBubble component and wiring an
ImageModal/ImageViewer that consumes selectedImage and a close to
setSelectedImage(null), (B) accept setSelectedImage (and optionally
selectedImage) as props on the MessageBubble component and use the passed-in
setter instead, or (C) remove the onClick and any references to selectedImage if
image-previewing is not required; update the component signature and any parent
usage accordingly so setSelectedImage is always defined when referenced.
🧹 Nitpick comments (1)
frontend/components/chat/MessageBubble.jsx (1)

118-123: ⚡ Quick win

Consider adding cleanup handlers for audio lifecycle.

The current implementation correctly sets activeAudioId when audio starts playing, but doesn't clear it when audio naturally finishes or is manually paused. This leaves stale state where activeAudioId points to a message that isn't actually playing.

🎵 Add onEnded and onPause handlers to clear state
 <audio
     ref={audioRef}
     src={msg.audio}
     controls
     className="max-w-full h-10 mb-1"
     onPlay={() => setActiveAudioId(msg._id)}
+    onEnded={() => setActiveAudioId(null)}
+    onPause={() => setActiveAudioId(null)}
 />
🤖 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 `@frontend/components/chat/MessageBubble.jsx` around lines 118 - 123, The audio
element sets activeAudioId in onPlay but never clears it; update the element
using audioRef/on* props to add onEnded and onPause handlers (or attach
'ended'/'pause' event listeners) that call setActiveAudioId(null) when the
currently playing id (msg._id) stops, and ensure any event listeners are removed
in cleanup to avoid leaks; reference audioRef, setActiveAudioId, onPlay and
msg._id when locating the code.
🤖 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.

Outside diff comments:
In `@frontend/components/chat/MessageBubble.jsx`:
- Line 106: The onClick handler in MessageBubble.jsx calls
setSelectedImage(msg.image) but that setter is undefined; fix by either (A)
adding local state const [selectedImage, setSelectedImage] = useState(null) in
the MessageBubble component and wiring an ImageModal/ImageViewer that consumes
selectedImage and a close to setSelectedImage(null), (B) accept setSelectedImage
(and optionally selectedImage) as props on the MessageBubble component and use
the passed-in setter instead, or (C) remove the onClick and any references to
selectedImage if image-previewing is not required; update the component
signature and any parent usage accordingly so setSelectedImage is always defined
when referenced.

---

Nitpick comments:
In `@frontend/components/chat/MessageBubble.jsx`:
- Around line 118-123: The audio element sets activeAudioId in onPlay but never
clears it; update the element using audioRef/on* props to add onEnded and
onPause handlers (or attach 'ended'/'pause' event listeners) that call
setActiveAudioId(null) when the currently playing id (msg._id) stops, and ensure
any event listeners are removed in cleanup to avoid leaks; reference audioRef,
setActiveAudioId, onPlay and msg._id when locating the code.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 633b2b22-a48d-4cde-94ce-11327ded81be

📥 Commits

Reviewing files that changed from the base of the PR and between 48e8f3e and 01b661a.

📒 Files selected for processing (2)
  • frontend/components/chat/MessageBubble.jsx
  • frontend/src/store/useChatStore.js

@sanikatavate sanikatavate force-pushed the fix-audio-playback-531 branch from 01b661a to 67ab6f5 Compare June 9, 2026 15:26
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.

1 participant