veza/apps/web/src/features/player/components/PlaybackSpeedControl.tsx
senke 3b065c8f8a feat: player — controls, audio analyser, spectrum, queue
Enhance player components (GlobalPlayer, PlayerControls, PlayerExpanded,
PlayerQueue, PlayerBarRight, PlaybackSpeedControl). Refactor audio and
spectrum analyser hooks. Update player service and store.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 15:45:59 +01:00

67 lines
1.8 KiB
TypeScript

/**
* PlaybackSpeedControl — Sélecteur de vitesse de lecture (0.5x à 2x)
* Lot F: F1 — Playback speed
*/
import { Button } from '@/components/ui/button';
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuTrigger,
} from '@/components/ui/dropdown-menu';
import { cn } from '@/lib/utils';
const SPEEDS = [0.5, 0.75, 1, 1.25, 1.5, 2] as const;
export type PlaybackSpeed = (typeof SPEEDS)[number];
interface PlaybackSpeedControlProps {
speed?: number;
currentSpeed?: number;
onSpeedChange: (speed: number) => void;
disabled?: boolean;
className?: string;
}
export function PlaybackSpeedControl({
speed,
currentSpeed,
onSpeedChange,
disabled = false,
className,
}: PlaybackSpeedControlProps) {
const value = speed ?? currentSpeed ?? 1;
const displaySpeed = `${value}x`;
return (
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button
variant="ghost"
size="sm"
disabled={disabled}
className={cn(
'h-8 min-w-[2.75rem] px-2 sm:h-9 rounded-full text-muted-foreground hover:text-foreground gap-1',
value !== 1 && 'text-primary',
className,
)}
aria-label={`Vitesse de lecture: ${displaySpeed}`}
>
<span className="text-xs font-bold tabular-nums">{displaySpeed}</span>
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent align="end" className="min-w-24 mb-2">
{SPEEDS.map((s) => (
<DropdownMenuItem
key={s}
onClick={() => onSpeedChange(s)}
className={cn(s === value && 'bg-primary/10 text-primary font-medium')}
>
{s}x
</DropdownMenuItem>
))}
</DropdownMenuContent>
</DropdownMenu>
);
}