feat(shorts): page /shorts alimentee par le catalogue + refonte pro/mobile
CI / build-and-test (push) Successful in 14m45s
CI / build-and-test (push) Successful in 14m45s
SearchService.fetchCatalogShorts (type shorts via /api/search : cache, provenance, FF) + pont pur shorts-catalog.ts (mapping, meta, fraicheur, spec 27 assertions). WatchShortComponent : catalogue d'abord (feed, pagination, Pour toi), repli legacy, Twitch clips inchanges, avatars paresseux via channelMeta. UI facon YouTube : plein ecran 100dvh, fond d'ambiance, rail overlay 48px, meta/fraicheur/pastille provider, safe-area.
This commit is contained in:
@@ -476,6 +476,14 @@ La table est **additive**. Le Phase 5.3 (LEFT JOIN) est le seul changement de le
|
||||
- [x] Un provider en échec affiche un bandeau ; un provider réellement vide affiche un état vide neutre.
|
||||
- [x] Aucun onglet d'onglet vide n'est proposé sur les pages chaîne. *(`canShowPill()`)*
|
||||
|
||||
### 9.9 Shorts-catalogue — la page `/shorts` alimentée par le catalogue (hors plan initial)
|
||||
|
||||
- [x] `SearchService.fetchCatalogShorts(providerLong, q, { page, pageSize })` : un provider, filtre `type: 'shorts'` (serveur quand il sait, `matchesFilters` sinon), via `searchAdapter` (cache 60 s, timeout 8 s, 1 retry, erreurs avalées) — le flux ne casse jamais sur un provider lent ou éteint (`providerError` → pastille « Source dégradée »).
|
||||
- [x] `WatchShortComponent` : catalogue d'abord (feed, pagination par pages, mode « Pour toi » via `catalogOrLegacy`), repli historique direct sous `SHORTS_CATALOG_MIN_ITEMS` (= 3) ou en erreur ; Twitch garde ses clips (pas d'équivalent catalogue) ; enrichissement des durées YouTube et portes `accepts()` inchangés.
|
||||
- [x] Pont pur `src/app/search/shorts-catalog.ts` (`catalogShortToVideo`, `formatShortMeta`, `formatCapturedAgo`) + spec hors-ligne `npm run test:shorts-catalog` (27 assertions : pas d'id fantôme, pas de fraîcheur inventée, pas de « 0 vue »).
|
||||
- [x] Avatars paresseux via `channelMeta` (`GET /channels/:provider/:externalId`, une requête par vidéo, silence en échec) + initiale de repli — plus d'image cassée quand la recherche ne fournit pas d'avatar.
|
||||
- [x] Refonte pro façon YouTube + mobile : scène plein écran (`100dvh`, fond d'ambiance flouté), rail d'actions **overlay dans le cadre** (J'aime / Commentaires / Partager / Son, cibles 48 px), méta sous le titre (« 12 k vues • il y a 2 j » + « capturé il y a 4 min • api »), pastille provider, safe-area, `touch-action: pan-y`, cadre sans radius sur mobile.
|
||||
|
||||
---
|
||||
|
||||
## 10. Phase 8 — Architecture de fond
|
||||
|
||||
Reference in New Issue
Block a user