Skip to main content

VoicePlayer

Location: src/components/voice/VoicePlayer.jsx

Overview

VoicePlayer provides playback controls for voice notes attached to posts. It supports both full-size and compact display modes, tracks playback progress visually, and automatically fades out audio when the component scrolls out of view. Respects global audio settings and output device selection.

Relevant Invariants

  • Invariant #2: "Calm Is the Default State" -- Uses preload="none" to avoid auto-loading audio; fades out when scrolled away instead of abrupt stop
  • Invariant #9: "Time Is Not Weaponized" -- No autoplay; user must explicitly choose to listen

Props

PropTypeRequiredDefaultDescription
voiceUrlstringYes--URL of the audio file to play
durationnumberNo--Duration in milliseconds (displayed as formatted time)
classNamestringNo''Additional CSS class
compactbooleanNofalseUse compact inline layout

Key Behaviors

  • Preload None: Audio uses preload="none" to prevent automatic downloads
  • Scroll Fade-Out: Uses IntersectionObserver to detect when less than 10% visible; fades volume over 500ms then pauses
  • Output Device: Respects outputDeviceId from useVoiceSettings, using setSinkId when available
  • Global Disable: Returns null when audioDisabled is true in VoiceSettings context
  • Event Isolation: Click events use stopPropagation to prevent triggering parent post card clicks

Usage

import VoicePlayer from '../voice/VoicePlayer';

<VoicePlayer
voiceUrl={post.voice_url}
duration={post.voice_duration}
/>

{/* Compact mode for inline display */}
<VoicePlayer
voiceUrl={post.voice_url}
duration={post.voice_duration}
compact
/>

Last updated: 2026-02-07