feat: implement audio player component with progress tracking and add library page for managing subscriptions

This commit is contained in:
Michael committed 2026-04-16 13:13:12 +02:00
1 parent 872ef5c31a
commit b2d0af639f
2 files changed
+19 -3

No files matched your search

+14 -1
View File
@@ -129,7 +129,14 @@ export default function AudioPlayer({ episode, onClose, userId }: AudioPlayerPro
}
return (
<div className="fixed inset-0 bg-gradient-light z-50 overflow-y-auto">
<div
className="fixed inset-0 bg-white z-[100] overflow-y-auto animate-fade-in"
onClick={(e) => {
// Close if clicking the backdrop itself
if (e.target === e.currentTarget) onClose();
}}
>
<div className="min-h-full gradient-light">
{/* Header */}
<div className="sticky top-0 bg-white/80 backdrop-blur-xl border-b border-light-200">
<div className="max-w-4xl mx-auto px-4 py-4 flex items-center justify-between">
@@ -273,7 +280,13 @@ export default function AudioPlayer({ episode, onClose, userId }: AudioPlayerPro
onTimeUpdate={handleTimeUpdate}
onLoadedMetadata={handleLoadedMetadata}
onEnded={() => setIsPlaying(false)}
onError={(e) => {
const target = e.target as HTMLAudioElement;
console.error('Audio playback error:', target.error);
alert("Erreur de lecture audio. Le lien est peut-être mort ou bloqué.");
}}
crossOrigin="anonymous"
autoPlay
/>
</div>
</div>
+5 -2
View File
@@ -53,12 +53,13 @@ export default function Library() {
queryClient.invalidateQueries({ queryKey: ['podcasts', 'subscriptions'] });
queryClient.invalidateQueries({ queryKey: ['episodes', 'latest'] });
},
onError: (error: any) => {
onError: (error: any, podcastId) => {
console.error(`[Unsubscribe FAILED] Podcast ID: ${podcastId}`, error);
// Rollback: re-fetch the real data from server if the mutation failed
queryClient.invalidateQueries({ queryKey: ['podcasts', 'subscriptions'] });
const errorMessage = error.response?.data?.message || 'Erreur inconnue';
alert(`Erreur lors du désabonnement : ${errorMessage}`);
alert(`Erreur lors du désabonnement (ID: ${podcastId}) : ${errorMessage}`);
},
});
@@ -73,11 +74,13 @@ export default function Library() {
};
const handleUnsubscribeRequest = (podcastId: string) => {
console.log("[UI] Demande de désabonnement reçue pour l'ID:", podcastId);
setConfirmDeleteId(podcastId);
};
const handleConfirmUnsubscribe = () => {
if (confirmDeleteId) {
console.log("[UI] Confirmation du désabonnement pour l'ID:", confirmDeleteId);
unsubscribeMutation.mutate(confirmDeleteId);
}
};