feat: integrate volume control into PlayerControls and remove PlayerVolume component

This commit is contained in:
JSC
2025-09-22 20:10:37 +02:00
parent 9784d259ba
commit 9366dbca14
5 changed files with 71 additions and 95 deletions

View File

@@ -1,5 +1,6 @@
import { Badge } from '@/components/ui/badge'
import { Button } from '@/components/ui/button'
import { Slider } from '@/components/ui/slider'
import type { PlayerMode, PlayerState } from '@/lib/api/services/player'
import {
ArrowRight,
@@ -13,6 +14,8 @@ import {
SkipBack,
SkipForward,
Square,
Volume2,
VolumeX,
} from 'lucide-react'
import { memo, useMemo } from 'react'
import { useRenderFlash } from '@/hooks/useRenderFlash'
@@ -22,12 +25,15 @@ interface PlayerControlsProps {
mode: PlayerMode
isLoading: boolean
showPlaylistButton?: boolean
volume?: number
onPlayPause: () => void
onStop: () => void
onPrevious: () => void
onNext: () => void
onModeChange: () => void
onTogglePlaylist?: () => void
onVolumeChange?: (volume: number[]) => void
onMute?: () => void
variant?: 'normal' | 'maximized' | 'minimized'
}
@@ -36,17 +42,20 @@ export const PlayerControls = memo(function PlayerControls({
mode,
isLoading,
showPlaylistButton = false,
volume,
onPlayPause,
onStop,
onPrevious,
onNext,
onModeChange,
onTogglePlaylist,
onVolumeChange,
onMute,
variant = 'normal',
}: PlayerControlsProps) {
const isMinimized = variant === 'minimized'
const isMaximized = variant === 'maximized'
const flashClass = useRenderFlash([status, mode], 'green')
const flashClass = useRenderFlash([status, mode, volume], 'green')
const modeIcon = useMemo(() => {
switch (mode) {
@@ -168,6 +177,30 @@ export const PlayerControls = memo(function PlayerControls({
</Button>
<Badge variant="secondary">{modeLabel}</Badge>
</div>
{volume !== undefined && onVolumeChange && onMute && (
<div className="flex items-center gap-2">
<Button size="sm" variant="ghost" onClick={onMute}>
{volume === 0 ? (
<VolumeX className="h-4 w-4" />
) : (
<Volume2 className="h-4 w-4" />
)}
</Button>
<div className="w-24">
<Slider
value={[volume]}
max={100}
step={1}
onValueChange={onVolumeChange}
className="w-full"
/>
</div>
<span className="text-sm text-muted-foreground w-8">
{Math.round(volume)}%
</span>
</div>
)}
</div>
</div>
)
@@ -242,6 +275,32 @@ export const PlayerControls = memo(function PlayerControls({
<Badge variant="secondary" className="text-xs">
{modeLabel}
</Badge>
{volume !== undefined && onVolumeChange && onMute && (
<div className="flex items-center gap-2">
<Button
size="sm"
variant="ghost"
onClick={onMute}
className="h-8 w-8 p-0"
>
{volume === 0 ? (
<VolumeX className="h-4 w-4" />
) : (
<Volume2 className="h-4 w-4" />
)}
</Button>
<div className="w-16">
<Slider
value={[volume]}
max={100}
step={1}
onValueChange={onVolumeChange}
className="w-full"
/>
</div>
</div>
)}
</div>
</div>
)