feat(library): liste « À regarder plus tard » (watch later)
CI / build-and-test (push) Successful in 14m55s

Nouvelle liste dans la section Vous de la barre latérale, avec un bouton
horloge a cote du coeur sur toutes les cartes (accueil, themes, provider-
themes, recherche).

- db : les 4 fonctions de listes (like/unlike/isLiked/list) prennent un
  paramètre `tag` — la table `tags` sert déjà de mot-clés génériques, donc
  zéro migration.
- api : les 4 routes likes sont générées par registerVideoTagRoutes(prefix,
  tagName) ; /api/user/watch-later = même fabrique, même enrichissement
  yt-dlp, même middleware cookie-aware. Entrée OpenAPI ajoutée.
- front : LikesService prend un VideoTag, like-button un @Input() list
  (icône horloge, ambre quand enregistré, libellés a11y dédiés) — un seul
  composant pour les deux boutons, pas de copie.
- cartes de recherche : la grille partagée n'avait AUCUN bouton ; cœur +
  horloge ajoutés, masqués sur les lives et cartes chaîne (coin bas-gauche
  déjà occupé par le compteur de spectateurs / pas des vidéos).
- route /library/watch-later = LikedComponent via data.list (titre, icône,
  placeholder et état vide pilotés par la route), clés nav.watchLater FR/EN.

Tests : npm run test:api 41/41 (nouveau test watch-later : ajout, statut,
indépendance vis-à-vis des likes, liste, retrait, 400, 401) + 21 autres
suites vertes. Build OK, instance locale 4200 rebuildée. Sondage Playwright
desktop+mobile : 12/14 (2 faux positifs du sondage : accordéon replié sur
une route hors /library, 3×401 console pendant la phase déconnectée).
This commit is contained in:
2026-10-01 14:13:43 -04:00
parent 88a2d21133
commit 735255b7d8
16 changed files with 246 additions and 114 deletions
+6
View File
@@ -70,6 +70,12 @@ export const APP_ROUTES: Routes = [
loadComponent: () => import('./components/library/liked/liked.component').then(m => m.LikedComponent),
title: 'NewTube - Liked'
},
{
path: 'library/watch-later',
loadComponent: () => import('./components/library/liked/liked.component').then(m => m.LikedComponent),
data: { list: 'watch-later' },
title: 'NewTube - Watch later'
},
{
path: 'library/subscriptions',
loadComponent: () => import('./components/library/subscriptions/subscriptions.component').then(m => m.SubscriptionsComponent),