feat: implement AddPodcast page with RSS subscription and discovery search functionality

This commit is contained in:
Michael committed 2026-04-16 15:45:20 +02:00
1 parent acd9a1a2c5
commit ea4fdb38d5
4 files changed
+61 -24

No files matched your search

+13 -2
View File
@@ -33,6 +33,7 @@ export default function AudioPlayer({ episode, onClose, userId }: AudioPlayerPro
const [playbackSpeed, setPlaybackSpeed] = useState(() => parseFloat(localStorage.getItem('podcastic-speed') || '1'));
const [isMuted, setIsMuted] = useState(false);
const [isExpanded, setIsExpanded] = useState(false);
const [isResuming, setIsResuming] = useState(false);
const [error, setError] = useState<string | null>(null);
const podcast = typeof episode?.podcastId === 'object' ? episode.podcastId : null;
@@ -67,11 +68,17 @@ export default function AudioPlayer({ episode, onClose, userId }: AudioPlayerPro
// Load previous progress
useEffect(() => {
if (!episode || !userId) return;
setIsResuming(true);
episodeService.getProgress(episode._id).then((r) => {
if (r.progress?.position && audioRef.current) {
console.log(`[AudioPlayer] Resuming at ${r.progress.position}s`);
audioRef.current.currentTime = r.progress.position;
setCurrentTime(r.progress.position);
}
}).catch(() => {});
setIsResuming(false);
}).catch(() => {
setIsResuming(false);
});
}, [episode, userId]);
const handlePlayPause = () => {
@@ -167,7 +174,11 @@ export default function AudioPlayer({ episode, onClose, userId }: AudioPlayerPro
</div>
<div className="min-w-0">
<p className="text-sm font-bold truncate leading-tight">{episode.title}</p>
<p className="text-[10px] text-[var(--text-secondary)] font-bold truncate uppercase tracking-wider">{podcast?.title || ''}</p>
{isResuming ? (
<p className="text-[9px] text-[var(--accent-primary)] font-black uppercase animate-pulse">Reprise de lecture...</p>
) : (
<p className="text-[10px] text-[var(--text-secondary)] font-bold truncate uppercase tracking-wider">{podcast?.title || ''}</p>
)}
</div>
</div>
+15 -4
View File
@@ -1,6 +1,7 @@
import React from 'react';
import { Episode } from '../services/episodeService';
import { Play, Calendar } from 'lucide-react';
import { Play, Calendar, Activity } from 'lucide-react';
import { useAudio } from '../context/AudioContext';
interface EpisodeCardProps {
episode: Episode;
@@ -9,6 +10,8 @@ interface EpisodeCardProps {
}
export default function EpisodeCard({ episode, onPlay, onDetails }: EpisodeCardProps) {
const { currentEpisode, isPlaying } = useAudio();
const isCurrent = currentEpisode?._id === episode._id;
const podcast = typeof episode.podcastId === 'object' ? episode.podcastId : null;
const pubDate = new Date(episode.pubDate).toLocaleDateString('fr-FR', {
month: 'short',
@@ -57,9 +60,17 @@ export default function EpisodeCard({ episode, onPlay, onDetails }: EpisodeCardP
</div>
</div>
{/* Duration Badge */}
<div className="absolute bottom-3 right-3 px-2 py-1 rounded-lg bg-black/60 backdrop-blur-md border border-white/10 text-[9px] font-black text-white uppercase tracking-widest">
{durationMinutes} MIN
{/* Duration/Status Badge */}
<div className="absolute bottom-3 right-3 flex items-center gap-2">
{isCurrent && (
<div className="px-2 py-1 rounded-lg bg-[var(--accent-primary)] border border-[var(--accent-primary)]/20 text-[9px] font-black text-white uppercase tracking-widest flex items-center gap-1.5 shadow-glow-indigo animate-pulse">
<Activity className="w-3 h-3" />
{isPlaying ? "EN COURS" : "EN PAUSE"}
</div>
)}
<div className="px-2 py-1 rounded-lg bg-black/60 backdrop-blur-md border border-white/10 text-[9px] font-black text-white uppercase tracking-widest">
{durationMinutes} MIN
</div>
</div>
</div>