Extraction du composant MiniPlayer hors d'AudioPlayer pour stabiliser sa référence.
Avant: MiniPlayer était une fonction imbriquée recréée à chaque rendu (4x/sec avec
onTimeUpdate), React le traitait comme un nouveau type de composant → démontage/remontage →
animation slide-up rejouée → clignotement.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- Ajout des variables CSS manquantes (--bg-primary, --bg-secondary, --radius-panel/--radius-card)
- Ajout des classes manquantes (premium-glass, neon-button, input-premium, shadow-glow-indigo, animate-aura)
- Fond du panneau latéral dashboard passé à --bg-elevated pour le décrocher du fond de page
- Fond solide sur le mini-player flottant + correction clignotement IntersectionObserver
- Ombres des cartes renforcées (shadow-card/shadow-card-hover)
- Contour de l'avatar profil amélioré (dégradé plus épais + glow + lettre en gradient)
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- IntersectionObserver avec debounce 250ms pour éviter le clignotement
- Bouton play sur cartes: bg-black/85 text-white (plus de blanc sur blanc)
- Badge LU: fond vert solide (var(--accent-emerald))
- AudioVisualizer: forme d'onde horizontale style Stitch (canvas)
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Refonte du design system (CSS variables, composants glass/card/button/badge),
nouvelle page PodcastDetails avec route /podcast/:id,
lecteur audio immersif avec visualiseur audio,
animations, thème dark/light, responsive mobile/desktop.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Replace class-based animation toggle with inline animationPlayState
style. The transition-all class was conflicting with the CSS keyframe
animation, preventing the artwork from spinning when playing.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Replace static CSS eq-bars with a real-time AudioVisualizer component
using the Web Audio API AnalyserNode. The visualizer is now centered
below the progress bar in the inline hero player, with 28 bars and
boosted mid-range frequencies for better speech visualization.
- AudioContext: wire AnalyserNode, expose getFrequencyData, add
crossOrigin="anonymous" and key on the audio element
- AudioPlayer (inline): remove static eq-bars, add AudioVisualizer
- New AudioVisualizer component: requestAnimationFrame loop,
smooth decay on pause, configurable bar count/height/gap
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- AudioPlayer is now purely presentational — no internal <audio> element or state.
All playback state (currentTime, duration, volume, speed, mute, error, isResuming)
comes from AudioContext, which holds the persistent <audio> at provider level.
This prevents audio from cutting when navigating between pages.
- userId is synced into AudioContext via setUserId() so progress saving/loading
works without the player needing to manage it locally.
- EpisodeCard: isCompleted now triggers at ≥90% listened (progressPercent >= 0.9)
in addition to the isCompleted flag, so the LU badge appears correctly.
Progress bar also hidden when ≥90%.
- Dashboard: episodesInProgress now excludes episodes at ≥90% listened,
removing them from the "Continuer l'écoute" section once effectively finished.
setUserId() called after user loads to wire context progress saving.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replace the old compact floating bar (h-88px rounded-2rem with expand
button) with the same clean mini-bar design as the Dashboard sticky
sub-bar — artwork + title + seeks + play + time + speed/volume/expand/
close + thin progress bar. The Dashboard hero inline player is kept.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Refresh podcast title/author/imageUrl/description on RSS sync (fixes
legacy 'Unknown Podcast' records)
- Always-visible Resync button on Library cards
- LU badge on completed episodes, NOUVEAU badge on <7-day-old episodes
- AudioPlayer gains mode='inline' that embeds in the Dashboard hero card
- Floating player suppressed on /dashboard to avoid dual audio
- Sticky mini-bar appears via IntersectionObserver when inline player
scrolls out of view (shares the same <audio> element)
- Fix: 'Reprendre' button called undefined setSelectedEpisode; now calls
playEpisode
- Add progress field to Episode TS interface
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
EpisodeCard and AudioPlayer now display episode.imageUrl when available,
falling back to the podcast image only if the episode has none.
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
AudioPlayer:
- Supprime section vitesse de lecture
- -30s/+30s (compact et expanded), avec icônes RotateCcw/RotateCw
- Rewind compact passé de -15s à -30s
Thème:
- globals.css refait : animations slide-up/fade-in/reveal définies, glass card améliorée
- Background plus profond (#080d1a), glow/blur plus soignés
- Boutons neon-button avec hover translateY
Corrections:
- Supprime Settings2 (bouton sans action) dans Library
- Supprime stat "2.4k mins listened" inventée dans Navigation
- Stats Library passent de 3 à 2 colonnes (réelles uniquement)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Traduit toutes les pages et composants en français (Dashboard, Login, Discover, Navigation, Header, EpisodeCard, AudioPlayer)
- Corrige l'erreur 500 sur /api/podcasts/discover : z.coerce.number() au lieu de z.number() pour limit/offset (paramètres query string)
- Corrige l'abonnement manuel via URL RSS : crée le podcast depuis le flux RSS au lieu de renvoyer 400
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>