import React from 'react'; import { useTranslation } from 'react-i18next'; import { createPortal } from 'react-dom'; import { Play, Pause, Volume2, VolumeX, Maximize2, PlayCircle, PauseCircle, RotateCcw, Gauge, Info, Download, X, ExternalLink, Radio, MoreVertical, MoreHorizontal, } from 'lucide-react'; import { Slider } from '../../ui/slider'; import { Button } from '../../ui/button'; import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '../../ui/tooltip'; import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger, DropdownMenuSeparator, } from '../../ui/dropdown-menu'; import { FloatingMediaWrapper } from '../FloatingMediaWrapper'; import { cn } from '../../shared/utils'; import { useAudioPlayer } from './use-audio-player'; export interface AudioPlayerProps { /** Source URL of the audio file */ src?: string; /** Title of the audio track/podcast */ title?: string; /** Artist or subtitle information */ artist?: string; /** Subtitle or source information (specific to 'bar' variant) */ subtitle?: string; /** URL for cover art (specific to 'card' variant) */ coverArt?: string; /** Whether to play automatically */ autoPlay?: boolean; /** CSS class name for the container */ className?: string; /** Display variant: 'card' (standard floating) or 'bar' (global fixed bar) */ variant?: 'card' | 'bar'; /** Whether the player is currently visible and open (only for 'bar' variant) */ isOpen?: boolean; /** Callback to close the player bar (only for 'bar' variant) */ onClose?: () => void; /** Total duration in seconds (optional, will be loaded from metadata if not provided) */ duration?: number; /** Initial playback time in seconds */ currentTime?: number; /** Color theme variant for the bar layout */ colorVariant?: 'default' | 'primary'; /** Whether the player should automatically float when scrolled out of view */ enableAutoFloat?: boolean; /** Callback fired when user manually closes the floating player */ onCloseFloating?: () => void; } /** * Unified Audio Player component. * * All state and logic is managed by the `useAudioPlayer` headless hook. * This component is responsible only for rendering. */ export function AudioPlayer({ src, title, artist, subtitle, autoPlay = false, className, variant = 'card', isOpen = true, onClose, duration: initialDuration, currentTime: initialTime = 0, colorVariant = 'default', enableAutoFloat = true, onCloseFloating, }: AudioPlayerProps) { const { t } = useTranslation(); const { audioRef, containerRef, isPlaying, currentTime, duration, volume, isMuted, playbackSpeed, isFloating, isManualFloating, isVisible, isMobile, enableAutoFloatLocal, sidebarExpanded, sidebarWidth, assistenteExpanded, togglePlay, toggleMute, handleSeek, handleVolumeChange, handleSetFloating, handleEnableManualFloat, setPlaybackSpeed, resetAudio, formatTime, onPlay, onPause, onEnded, onTimeUpdate, onLoadedMetadata, } = useAudioPlayer({ src, autoPlay, initialTime, initialDuration, variant, isOpen, enableAutoFloat, onCloseFloating, }); // ── Audio element (hidden) ────────────────────────────────────────────────── const audioElement = (