feat(channel): page details chaine multi-providers avec onglets et infinite scroll
CI / build-and-test (push) Successful in 13m34s
CI / build-and-test (push) Successful in 13m34s
- Strategy Pattern front: ChannelProviderInterface + 6 providers (yt/dm/tw/pt/od/ru) + factory (ids longs/courts) - ChannelContentService: cache par onglet/tri/recherche (TTL 5min), pagination nextPage - ChannelPage: header (banniere/avatar/subs/description ...plus), tabs dynamiques par capabilities, grilles videos/shorts 9:16/playlists/live, recherche debounced, tri recent/populaire, infinite scroll IntersectionObserver, skeletons/empty/error - Backend: GET /api/channels/:provider/:id/content (videos/shorts/playlists/live) natif par provider
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
# NewTube — Votre hub vidéo multi-plateformes 🎬🌐
|
||||
|
||||
Agrégez, explorez et regardez des vidéos depuis
|
||||
Agrégez, explorez et regardez des vidéos depuis
|
||||
|
||||
- **YouTube** 🔴
|
||||
- **Dailymotion** 🔵
|
||||
- **Twitch** 🟣
|
||||
@@ -33,17 +34,48 @@ Agrégez, explorez et regardez des vidéos depuis
|
||||
|
||||
| Plateforme | Recherche | Lecture | Shorts | Live | Playlists\* |
|
||||
| ----------------------------- | :-------: | :-----: | :----: | :--: | :---------: |
|
||||
| YouTube 🔴 | ✅ | ✅ | ✅ | ✅ | ✅ |
|
||||
| Dailymotion 🔵 | ✅ | ✅ | ⏳ | ✅ | ⏳ |
|
||||
| Twitch 🟣 | ✅ | ✅ | N/A | ✅ | ⏳ |
|
||||
| PeerTube 🟢 (multi-instances) | ✅ | ✅ | ⏳ | ⏳ | ⏳ |
|
||||
| Odysee 🟡 | ✅ | ✅ | ⏳ | ⏳ | ⏳ |
|
||||
| Rumble 🟠 | ✅ | ✅ | ⏳ | ⏳ | ⏳ |
|
||||
| YouTube 🔴 | ✅ | ✅ | ✅ | ✅ | ✅ |
|
||||
| Dailymotion 🔵 | ✅ | ✅ | ⏳ | ✅ | ⏳ |
|
||||
| Twitch 🟣 | ✅ | ✅ | N/A | ✅ | ⏳ |
|
||||
| PeerTube 🟢 (multi-instances) | ✅ | ✅ | ⏳ | ⏳ | ⏳ |
|
||||
| Odysee 🟡 | ✅ | ✅ | ⏳ | ⏳ | ⏳ |
|
||||
| Rumble 🟠 | ✅ | ✅ | ⏳ | ⏳ | ⏳ |
|
||||
|
||||
\* Playlists = intégration locale NewTube (création/gestion); la synchro native dépend de l’API publique de chaque fournisseur.
|
||||
|
||||
---
|
||||
|
||||
## 🔎 Recherche unifiée (multi-providers)
|
||||
|
||||
Un seul champ, tous les fournisseurs — avec filtres, raccourcis et deep-links :
|
||||
|
||||
* **Chips providers** dans la barre : `All / YT / DM / TW / PT / OD / RU` (raccourcis **Alt+1..6**)
|
||||
* **Autocomplete `@`** : tapez `@yt` dans le champ pour filtrer sur YouTube (flèches + Enter, Esc pour fermer)
|
||||
* **Provider picker** : bouton `@` ou **Ctrl/⌘+K** — modal avec filtre texte, sélection multiple et option **« Remember as default »** (persistée dans vos préférences utilisateur)
|
||||
* **Quick menu Ctrl/⌘+K** : historique des recherches + toggles providers en un écran
|
||||
* **Deep-links** : `/#/search?q=…&providers=yt,ru` relance la recherche filtrée — partageable
|
||||
* **Fallback préférence** : URL sans `providers` → préférence `defaultProviders` de l’utilisateur → provider actif
|
||||
* **Accessibilité** : focus trap dans les modals, Esc pour fermer, aria-combobox sur le champ, focus restauré à la fermeture
|
||||
|
||||
<!-- TODO: add docs/search-ux.gif (capture des chips, du picker Ctrl+K et du deep-link) -->
|
||||
|
||||
### Endpoints API concernés
|
||||
|
||||
* `GET /api/search?q=…&providers=yt,dm` — fan-out parallèle, réponse groupée par provider
|
||||
* `GET/PATCH /api/user/preferences` — `defaultProviders` (tableau JSON, sanitizé serveur)
|
||||
* `POST /api/telemetry/events` — événements UX anonymes (whitelist : `search_submit`, `provider_picker_open`, `provider_apply`, `at_autocomplete_use`, `quick_menu_open`)
|
||||
|
||||
### Tests
|
||||
|
||||
```bash
|
||||
npm run test:search # unitaires SearchService + parsing @ + picker
|
||||
npm run test:search-e2e # scénarios e2e (serveur réel isolé)
|
||||
npm run test:preferences # persistance defaultProviders
|
||||
npm run test:telemetry # télémétrie minimale
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🖥️ Fonctionnalités (vue d’ensemble)
|
||||
|
||||
* 🧭 **Accueil “Tendances & Viral”** par fournisseurs
|
||||
@@ -150,8 +182,13 @@ sudo tee /etc/docker/daemon.json >/dev/null <<'JSON'
|
||||
"debug": false
|
||||
}
|
||||
JSON
|
||||
# debian linux
|
||||
sudo systemctl daemon-reload
|
||||
sudo systemctl restart docker
|
||||
# Alpine linux
|
||||
sudo rc-service docker restart
|
||||
sudo rc-update add docker
|
||||
|
||||
docker info | grep -i registry
|
||||
```
|
||||
|
||||
@@ -196,16 +233,19 @@ Ajoutez au besoin `log-driver`, `log-opts`, `default-address-pools`, etc.
|
||||
* ✅ Thème (système / dark / light / blue / black)
|
||||
* ✅ Préférences (langue, thème, région, qualité par défaut)
|
||||
* ✅ Auth légère (JWT), rate-limit API
|
||||
* ✅ **Recherche unifiée multi-providers** — chips + autocomplete `@`, picker Ctrl/⌘+K, deep-links `?providers=…`, préférence `defaultProviders` persistée, télémétrie minimale, a11y (focus trap, Esc)
|
||||
* ✅ **Recherche unifiée multi-providers** — chips + autocomplete `@`, picker Ctrl/⌘+K, deep-links `?providers=…`, préférence `defaultProviders` persistée, télémétrie minimale, a11y (focus trap, Esc)
|
||||
* ✅ Navigation par thèmes (Trending, Live, Gaming, News, Finance, Tech, Science, Health, Music, Podcasts, Movies/TV, Education, Travel, Food, DIY, Auto…)
|
||||
* ⏳ **Abonnements** (routes + DB)
|
||||
* ⏳ **Tags** & recherche par tags
|
||||
* ⏳ **Page “Shorts”** unifiée (tous fournisseurs) + badges de durée
|
||||
* ⏳ **Téléchargements** intégrés (file queue, répertoires, quotas, reprise)
|
||||
* ✅ **Téléchargements** intégrés — file d'attente **persistée en SQLite** (survit aux redémarrages API), jobs **par utilisateur** (répertoires isolés, ownership sur status/fichier/cancel), **quota de stockage** configurable (`DOWNLOAD_STORAGE_QUOTA_BYTES`, fenêtre `DOWNLOAD_QUOTA_WINDOW_MS`), **reprise** des jobs échoués/interrrompus (bouton Réessayer), **page Bibliothèque > Téléchargements** (filtres par état, progression live, quota), nettoyage auto des fichiers orphelins au boot
|
||||
* 🔧 Variables : `DOWNLOAD_MAX_CONCURRENT` (2), `DOWNLOAD_STORAGE_QUOTA_BYTES` (5 GiB), `DOWNLOAD_QUOTA_WINDOW_MS` (30 j), `DOWNLOAD_PROVIDERS` (peertube,odysee)
|
||||
* ⏳ **Import/Export** playlists (JSON / OPML-like)
|
||||
* ⏳ **Sous-titres & transcripts** (si dispo API; fallback parsing)
|
||||
* ⏳ **PWA** (installable, offline cache des métadonnées)
|
||||
* ⏳ **Chromecast / AirPlay**
|
||||
* ⏳ **Raccourcis clavier** & mode “TV”
|
||||
* ⏳ Mode “TV”
|
||||
* ⏳ **Observabilité** : healthcheck `/healthz`, métriques, page **Admin** (clés OK/KO, logs, versions)
|
||||
* ⏳ **OAuth** (Google/Twitch) pour import favoris/abonnements
|
||||
* ⏳ **Cache serveur** configurable (TTL par provider)
|
||||
@@ -282,9 +322,9 @@ MIT (voir `LICENSE`)
|
||||
|
||||
- Les URLs du type `?q=…&providers=yt,ru` relancent la même recherche. Assurez-vous de propager le paramètre `providers` lors des navigations.
|
||||
|
||||
6) Tests (à compléter)
|
||||
6) Tests
|
||||
|
||||
- Unit: parsing `@yt` dans l’input, toggle ProviderPicker, composition de `SearchService`.
|
||||
- e2e: `@yt + query` → résultats uniquement YouTube; chips `YT+DM` → sections YT/DM visibles; deep‑link restauré.
|
||||
- Unit (`npm run test:search`) : parsing `@yt` dans l’input, toggles ProviderPicker, composition et fan-out de `SearchService`.
|
||||
- e2e (`npm run test:search-e2e`) : `providers=yt,dm` → réponse ciblée sur [yt,dm]; deep-link `providers=pt`; fallback registry complet; préférence persistée; route SPA.
|
||||
|
||||
Astuce: l’ajout d’un provider ne nécessite pas de modifier les composants — il suffit d’ajouter une entrée dans le registry front + un handler API.
|
||||
|
||||
Reference in New Issue
Block a user