"use client"; import { useEffect, useRef, useState } from "react"; import { cn } from "@/lib/utils"; import { trackClientEvent } from "@/lib/analytics-client"; type AudioPlayerProps = { src: string; title: string; locale: "ar" | "en"; downloadable?: boolean; analytics?: { entityId: string }; className?: string; }; function formatTime(value: number) { if (!Number.isFinite(value) || value < 0) return "0:00"; const minutes = Math.floor(value / 60); const seconds = Math.floor(value % 60).toString().padStart(2, "0"); return `${minutes}:${seconds}`; } export default function AudioPlayer({ src, title, locale, downloadable = false, analytics, className }: AudioPlayerProps) { const audioRef = useRef(null); const [isPlaying, setIsPlaying] = useState(false); const [currentTime, setCurrentTime] = useState(0); const [duration, setDuration] = useState(0); const [volume, setVolume] = useState(1); const hasTrackedPlay = useRef(false); const labels = locale === "ar" ? { play: "تشغيل", pause: "إيقاف مؤقت", back: "تأخير 10 ثوانٍ", forward: "تقديم 10 ثوانٍ", seek: "موضع التشغيل", volume: "مستوى الصوت", download: "تحميل الصوت" } : { play: "Play", pause: "Pause", back: "Back 10 seconds", forward: "Forward 10 seconds", seek: "Playback position", volume: "Volume", download: "Download audio" }; useEffect(() => { const audio = audioRef.current; if (!audio) return; const onLoadedMetadata = () => setDuration(audio.duration); const onTimeUpdate = () => setCurrentTime(audio.currentTime); const onEnded = () => setIsPlaying(false); audio.addEventListener("loadedmetadata", onLoadedMetadata); audio.addEventListener("timeupdate", onTimeUpdate); audio.addEventListener("ended", onEnded); audio.volume = volume; return () => { audio.removeEventListener("loadedmetadata", onLoadedMetadata); audio.removeEventListener("timeupdate", onTimeUpdate); audio.removeEventListener("ended", onEnded); }; }, [volume]); const togglePlayback = async () => { const audio = audioRef.current; if (!audio) return; if (audio.paused) { await audio.play(); setIsPlaying(true); if (analytics && !hasTrackedPlay.current) { hasTrackedPlay.current = true; trackClientEvent({ type: "MELODY_PLAY", entityId: analytics.entityId }); } } else { audio.pause(); setIsPlaying(false); } }; const seekBy = (seconds: number) => { const audio = audioRef.current; if (!audio) return; audio.currentTime = Math.max(0, Math.min(audio.duration || 0, audio.currentTime + seconds)); setCurrentTime(audio.currentTime); }; const updateTime = (value: number) => { const audio = audioRef.current; if (!audio) return; audio.currentTime = value; setCurrentTime(value); }; const updateVolume = (value: number) => { setVolume(value); if (audioRef.current) audioRef.current.volume = value; }; return (
); }