Commit Graph
116 Commits
Author SHA1 Message Date
Michael a89c08fd55 fix: race condition AudioContext + autoPlay sur élément analyse
shouldResumeCtxRef: si onPlay fire avant l'effet Web Audio,
ctx.resume() appelé dès que l'effet setup se termine.
autoPlay sur l'élément analyse pour démarrage sans attendre handleMainPlay.
2026-05-04 00:42:46 +02:00
Michael c04fa4e346 fix: GainNode=0 pour activer le graphe Web Audio sans sortie son 2026-05-04 00:38:51 +02:00
Michael 45417c7d7f fix: deux éléments audio - direct (rapide) + proxy muet (analyse)
Audio principal: URL directe, démarre instantanément comme avant.
Élément caché muet: proxy URL, Web Audio uniquement pour waveform.
Synchronisé sur play/pause/seek du principal.
2026-05-04 00:31:04 +02:00
Michael 20765ba653 perf: keep-alive + cache URL finale pour proxy audio
Agent keep-alive réutilise connexions TLS. Cache URL résolue 10min
→ seeks/reprises sautent la chaîne de redirects.
2026-05-03 23:14:17 +02:00
Michael 4ae7cf2d4e fix: normalisation par bande, bords aussi actifs que le centre 2026-05-03 23:09:52 +02:00
Michael 52bf15d82b fix: proxy par défaut, supprime tentative CORS directe 2026-05-03 23:06:32 +02:00
Michael fdcba26c7f fix: proxy suit les redirects côté serveur (302 → CORS bypass) 2026-05-03 23:01:00 +02:00
Michael 1f800c4afc fix: resume AudioContext suspendu au onPlay pour activer l'analyse 2026-05-03 22:44:56 +02:00
Michael c86887f037 feat: proxy audio backend pour Web Audio API sans CORS
Nouveau endpoint /api/audio/proxy?url=... re-stream l'audio externe
avec Access-Control-Allow-Origin:*. Fallback: direct → proxy → no-cors.
Analyser actif en mode proxy → vraie synchronisation waveform/son.
2026-05-03 21:52:13 +02:00
Michael 59ecd7a747 fix: reprise position + visualizer speech-like
Resume: savedPositionRef appliqué sur loadedmetadata pour survivre
au remontage audio après échec CORS. Analyser: fftSize 256,
smoothing 0.55. Simulation: rythme syllabique avec consonantes.
2026-05-03 21:26:53 +02:00
Michael 4574abb3e4 refactor: supprime dot progression, garde égaliseur seul 2026-05-03 21:22:26 +02:00
Michael 4b117ced19 feat: égaliseur symétrique depuis le centre vers les bords
Waveform miroir: centre=basses fréquences, bords=aigus.
Phase basée sur distance au centre pour oscillation symétrique.
2026-05-03 21:19:32 +02:00
Michael 36bc786410 fix: amplitude égaliseur trop plate, boost voix parlée
MAX_AMPLITUDE 0.22→0.42, courbe puissance sur données réelles
pour amplifier fréquences faibles, simulation 3 couches d'ondulation.
2026-05-03 21:15:57 +02:00
Michael c683ce366c fix: fluidité égaliseur - sin continu au lieu de signe binaire
Remplace le signe binaire (>0.05?1:-1) par Math.sin() direct,
éliminant les sauts brusques aux zero-crossings. Réduit lerp rates
et fréquence spatiale pour oscillation plus douce.
2026-05-03 21:11:32 +02:00
MichaelandClaude Opus 4.7 3d73ed1e62 fix: onde réelle quand CORS dispo, son + simulation sinon
Approche hybride CORS retry:
- Tentative 1: crossOrigin="anonymous" + createMediaElementSource
  → données de fréquence réelles si le serveur le permet
- Tentative 2 (si CORS bloque): sans crossOrigin, audio direct
  → son fonctionne, visualiseur simulé

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-01 23:22:11 +02:00
MichaelandClaude Opus 4.7 3a90f77d65 fix: son coupé par createMediaElementSource sur audio cross-origin
createMediaElementSource détache l'audio de sa sortie par défaut.
Pour les ressources cross-origin sans CORS, le graphe Web Audio
produit du silence — aucun son.

- Retire createMediaElementSource et tout le pipeline Web Audio
- L'audio joue directement via l'élément <audio> (fiable)
- Le visualiseur utilise une animation simulée (plus de dépendance CORS)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-01 23:17:46 +02:00
MichaelandClaude Opus 4.7 ee04841d9e fix: podcasts ne lisent pas à cause du blocage CORS
crossOrigin="anonymous" sur <audio> forçait le navigateur à exiger
les headers CORS des serveurs audio. Les hébergeurs sans
Access-Control-Allow-Origin bloquaient le chargement entièrement.

- Retire crossOrigin="anonymous" de l'élément <audio>
- Ajoute visualisation simulée dans l'egaliseur quand les données
  de fréquence réelles sont indisponibles (audio cross-origin)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-01 23:09:15 +02:00
MichaelandClaude Opus 4.7 e7e971dbae fix: fluidité animation waveform et suppression partie blanche
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-29 12:37:37 +02:00
MichaelandClaude Opus 4.7 9ccdb61c58 fix: correction trou blanc, espacement et alternance de la waveform
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-29 12:03:21 +02:00
MichaelandClaude Opus 4.7 95e51a03f5 fix: waveform ligne plate au repos, oscillation organique, amplitude contenue dans le cadre
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-29 11:38:14 +02:00
MichaelandClaude Opus 4.7 c5428c15a6 fix: waveform moins compact et moins haut pour un rendu plus aéré
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-29 11:19:53 +02:00
MichaelandClaude Opus 4.7 318683b6c4 fix: remplacement égaliseur à barres par waveform continue style Stitch
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-29 10:48:40 +02:00
MichaelandClaude Opus 4.7 31eb884669 fix: egaliseur audio repensé en barres verticales style Stitch
Remplacement du visualiseur horizontal (lignes de波形) par un égaliseur à barres verticales :
- Barres symétriques miroir (croissance depuis le centre vers haut et bas)
- Têtes de barres arrondies (arcTo)
- Dégradé cyan → indigo → cyan sur chaque barre
- Halo lumineux radial sur les barres hautes (>25%)
- Point lumineux au sommet des pics (>50%)
- Ligne de séparation centrale subtile
- Easing fluide entre les trames audio (lerp 0.35)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-29 08:39:27 +02:00
MichaelandClaude Opus 4.7 e66f4cdf1d fix: suppression clignotement barre de lecture pendant la lecture
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>
2026-04-29 08:15:10 +02:00
MichaelandClaude Opus 4.7 550bf81381 fix: fonds modals/panneau dashboard illisibles + clignotement mini-player + ombres cartes + avatar
- 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>
2026-04-28 23:14:41 +02:00
MichaelandClaude Opus 4.7 a49e9f04d8 fix: clignotement mini-bar + bouton play noir + badge LU vert + visualiseur horizontal
- 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>
2026-04-28 13:52:17 +02:00
MichaelandClaude Opus 4.7 66d61595bd fix: equalizer plus proche du design Stitch + couleurs plus profondes
Barres plus pleines et arrondies, halo lumineux sur pics audio,
palette dark plus riche (indigo vibrant, cyan éclatant, bleu profond),
ombres et bordures plus marquées, gradients de fond plus immersifs.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-28 13:32:58 +02:00
MichaelandClaude Opus 4.7 5c2a6438cd feat: redesign complet de l'application basé sur les maquettes Stitch
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>
2026-04-28 13:22:25 +02:00
MichaelandClaude Opus 4.7 ca23996c3b style: symmetric mirrored audio visualizer with edge fade
Replace flat linear bars with a symmetric hill-shaped visualizer.
Bars now mirror from the center outward, with a smooth falloff
toward the edges and a mid-frequency boost for speech clarity.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-22 16:17:07 +02:00
MichaelandClaude Opus 4.7 53b0e68cfd fix: remove spinning animation from podcast artwork
The artwork image in the inline player card should stay static,
not rotate during playback.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-22 16:11:03 +02:00
MichaelandClaude Opus 4.7 d5e3aa3be5 fix: artwork spin animation in inline player
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>
2026-04-22 15:41:10 +02:00
MichaelandClaude Opus 4.7 99c9c299de feat: reactive audio visualizer centered below inline player
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>
2026-04-22 15:22:55 +02:00
Michael 35f34d9d44 Merge branch 'main' of https://github.com/R0m1k3/podcastic 2026-04-22 14:40:01 +02:00
Michael 656046b0bf feat: implement global CSS styling and create AudioPlayer component 2026-04-22 14:39:59 +02:00
MichaelandClaude Sonnet 4.6 e06f342c8e fix: lu badge persistence + remove ? + fix duplicate buttons
- EpisodeCard: change 'Lu ?' → 'Marquer' so the toggle button no longer
  shows a confusing question mark next to completed episodes

- Dashboard: fix episodes reappearing in 'Continuer l'écoute' after
  navigation. handleToggleRead now does an optimistic update on BOTH
  local state AND all TanStack Query cache pages (setQueriesData),
  so the 'lu' state survives page navigation without a server roundtrip.
  On error, cache is invalidated to revert to server truth.

- Dashboard: 'Découvrir' button now links to /add (discover new podcasts)
  instead of /trending — was identical to 'Parcourir les tendances' button

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-21 10:06:09 +02:00
MichaelandClaude Sonnet 4.6 454d8517fb ci: add GitHub Actions auto-build + fix Unraid update
- Add .github/workflows/docker-publish.yml: builds Docker image on every
  push to main and publishes to ghcr.io/r0m1k3/podcastic:latest automatically

- docker-compose.yml: replace local `build:` with `image: ghcr.io/r0m1k3/podcastic:latest`
  so Unraid's "Update" button can pull the image directly from the registry
  instead of failing with "no service selected"

- Remove deprecated `version: '3.8'` field

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-21 09:55:03 +02:00
MichaelandClaude Sonnet 4.6 ceafb24f1b style: remove premium labels + fix LU badge
- Remove all visible "premium" text labels across the app:
  Navigation sidebar: "Premium Audio" → "Your audio space"
  Header: "Premium Member" → "Membre"
  Login page badge: "Expérience Audio Premium" → "Votre espace audio"
  Dashboard hero badge: "Podcastic Premium" → "Podcastic"
  EpisodeCard fallback author: "Artiste Premium" → empty string

- LU badge: remove Check icon (was rendering as "?" in some envs),
  now shows clean "LU" text only

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-21 09:45:58 +02:00
Michael 05eaa96e75 feat: implement EpisodeCard component and integrate it into the dashboard view 2026-04-20 10:47:26 +02:00
MichaelandClaude Sonnet 4.6 01c179c68b fix: layout uniforme et max-width sur grand écran
- max-w-[1400px] mx-auto dans le wrapper global (App.tsx)
  pour que les cartes ne soient pas immenses sur 2K/4K
- padding cohérent lg:px-8 sur toutes les pages
- suppression du max-w-5xl parasites sur AddPodcast

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-17 21:50:16 +02:00
MichaelandClaude Sonnet 4.6 77f2a71efd feat: composant PodcastCard unifié pour Library, Trending, AddPodcast
Crée PodcastCard réutilisable avec le même design qu'EpisodeCard
(image carrée, auteur, titre, footer avec actions). Remplace les
3 designs inline différents par un seul composant cohérent.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-17 21:45:39 +02:00
MichaelandClaude Sonnet 4.6 00df4a39ff style: uniform grids, profile border, remove NOUVEAU badge
- Toutes les pages utilisent grid-cols-1 sm:2 lg:3 xl:4 gap-8
- Cadre gradient visible en permanence sur l'avatar profil
- Suppression du badge NOUVEAU sur les épisodes

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-17 21:36:55 +02:00
MichaelandClaude Sonnet 4.6 5a9a0904a1 fix: audio persistence across navigation + LU badge at 90% + filter continuer section
- 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>
2026-04-17 15:08:04 +02:00
MichaelandClaude Sonnet 4.6 842ead6518 style: unify floating player design across all pages
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>
2026-04-17 11:41:25 +02:00
MichaelandClaude Sonnet 4.6 6786226a6c feat: hero player, LU/NOUVEAU badges, metadata resync, sticky mini-bar
- 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>
2026-04-17 11:33:47 +02:00
MichaelandClaude Sonnet 4.5 a3225cb4c4 feat: light/dark theme (cream+gold+grey), reduced radii, stagger animations, search fallback
- globals.css: full dual-theme system via .light-theme/.dark-theme classes
  → Dark: deep navy with indigo/cyan glow gradients
  → Light: warm cream #f7f3eb with gold top-left & grey bottom-right gradients
  → Radius tokens: --radius-card 1rem, --radius-panel 1.25rem (sharper cards)
  → New animations: float, scale-in, shimmer skeleton, ping-slow, spin-slow,
    glow-beat, gold-shimmer + stagger-grid cascade (up to 20 items)
- tailwind.config.js: reduce 2xl/3xl/4xl radii to match CSS vars; add accent-gold
- Navigation.tsx: add Sun/Moon toggle button using useTheme()
- Dashboard.tsx: shimmer skeletons, stagger-grid on episode grid
- Trending.tsx: stagger-grid on podcast grid
- podcastController.ts: iTunes search fallback → local DB regex search

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-04-17 10:51:21 +02:00
Michael e649a16620 feat: improve search UX and backend inclusivity on AddPodcast page 2026-04-16 21:06:54 +02:00
Michael e759cf9471 feat: add trending podcasts discovery page with genre filtering and subscription support 2026-04-16 16:24:43 +02:00
Michael dfd2cce761 feat: implement AudioPlayer component with playback controls, progress tracking, and persistence 2026-04-16 16:22:46 +02:00
Michael 5305f3e5f6 feat: add Trending page to display and subscribe to popular podcasts by genre 2026-04-16 16:18:47 +02:00
Michael f68989c228 feat: implement AudioPlayer component with playback controls, progress tracking, and persistence 2026-04-16 16:11:39 +02:00