112 lines
2.7 KiB
TypeScript
112 lines
2.7 KiB
TypeScript
"use client";
|
|
|
|
import {
|
|
useAudioPlayer,
|
|
type AudioTrack,
|
|
AudioWaveAnimation,
|
|
} from "@/components/audio-player";
|
|
import { cn } from "@/lib/utils";
|
|
import { Play } from "lucide-react";
|
|
|
|
type PlayAudioButtonProps = {
|
|
audioUrl: string;
|
|
title: string;
|
|
subtitle?: string;
|
|
sourceUrl: string;
|
|
type?: string;
|
|
className?: string;
|
|
/** Compact icon-only variant for list items */
|
|
variant?: "default" | "compact";
|
|
};
|
|
|
|
export function PlayAudioButton({
|
|
audioUrl,
|
|
title,
|
|
subtitle,
|
|
sourceUrl,
|
|
type,
|
|
className,
|
|
variant = "default",
|
|
}: PlayAudioButtonProps) {
|
|
const { currentTrack, isPlaying, play, togglePlayPause } = useAudioPlayer();
|
|
|
|
const isThisTrack = currentTrack?.url === audioUrl;
|
|
const isThisPlaying = isThisTrack && isPlaying;
|
|
|
|
function handleClick() {
|
|
if (isThisTrack) {
|
|
togglePlayPause();
|
|
} else {
|
|
const track: AudioTrack = {
|
|
url: audioUrl,
|
|
title,
|
|
subtitle,
|
|
sourceUrl,
|
|
type: type ?? "lecture",
|
|
};
|
|
play(track);
|
|
}
|
|
}
|
|
|
|
if (variant === "compact") {
|
|
return (
|
|
<button
|
|
onClick={(e) => {
|
|
e.preventDefault();
|
|
e.stopPropagation();
|
|
handleClick();
|
|
}}
|
|
className={cn(
|
|
"flex items-center justify-center size-8 rounded-full transition-all shrink-0 cursor-pointer!",
|
|
isThisPlaying
|
|
? "bg-primary text-primary-foreground shadow-sm"
|
|
: "bg-primary/10 text-primary hover:bg-primary/20",
|
|
className,
|
|
)}
|
|
title={isThisPlaying ? "Pause" : "Play audio"}
|
|
aria-label={isThisPlaying ? "Pause" : "Play audio"}
|
|
>
|
|
{isThisPlaying ? (
|
|
<AudioWaveAnimation
|
|
paused={false}
|
|
colorClassName="bg-primary-foreground"
|
|
size="sm"
|
|
/>
|
|
) : (
|
|
<Play className="size-3.5 ml-0.5" />
|
|
)}
|
|
</button>
|
|
);
|
|
}
|
|
|
|
return (
|
|
<button
|
|
onClick={handleClick}
|
|
className={cn(
|
|
"inline-flex cursor-pointer items-center gap-2 px-5 py-2.5 rounded-lg text-sm font-semibold transition-all shadow-sm",
|
|
isThisPlaying
|
|
? "bg-primary text-primary-foreground shadow-md"
|
|
: "bg-primary text-primary-foreground hover:bg-primary/90 hover:shadow-md",
|
|
className,
|
|
)}
|
|
aria-label={isThisPlaying ? "Pause audio" : "Play audio"}
|
|
>
|
|
{isThisPlaying ? (
|
|
<>
|
|
<AudioWaveAnimation
|
|
paused={false}
|
|
colorClassName="bg-primary-foreground"
|
|
size="sm"
|
|
/>
|
|
<span>Now Playing</span>
|
|
</>
|
|
) : (
|
|
<>
|
|
<Play className="size-4" />
|
|
<span>Play Audio</span>
|
|
</>
|
|
)}
|
|
</button>
|
|
);
|
|
}
|