From 3ab61821b2be95a8150ed06ff4e2e8d0bc3aff9b Mon Sep 17 00:00:00 2001 From: Bruno Charest Date: Fri, 2 Oct 2026 10:26:58 -0400 Subject: [PATCH] =?UTF-8?q?fix(shorts):=20flux=20vide=20+=20menu=20absent?= =?UTF-8?q?=20+=20fl=C3=A8ches=20invisibles=20(Rumble)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Trois symptômes, deux racines — diagnostiqués au navigateur (Playwright desktop + mobile) et hors navigateur (vraies réponses API + fonctions front réelles importées via ts-node) : 1. Double dedup() dans handleShortsResponse : show() re-dédupliquait une liste déjà dédupliquée par son appelant → le second passage marquait tout comme « déjà vu » et posait items=[] en silence → écran « Aucun short à afficher » sans erreur ni requête suivante, dès que le catalogue type=shorts rendait moins de 3 items (aléa de la requête tirée au sort). Racine des écrans morts, présente depuis le commit 983c6cb. 2. Menu FAB et flèches Préc./Suiv. vivaient dans @if (current()) : absents de TOUS les états vides, donc impossibles à utiliser exactement quand le flux meurt (impossible de changer de fournisseur). Le menu est désormais toujours monté (z-30 au-dessus des placeholders), et la flèche désactivée passe en opacity 0.4 (au 1er item, Préc. était quasi invisible à 0.3). 3. Format : Rumble n'expose AUCUNE dimension — vérifié : vignettes og:image toutes en crop fixe 16:9 (9/9 échantillons, 1280x720 et 480x270) et aucun width/height dans les pages vidéo → un filtre d'orientation par vignette est impossible, la classification reste durée-seule. En revanche le flux natif rumble.com/shorts (les vrais shorts officiels) devient la voie primaire : loadFeed va droit au chemin historique au lieu du catalogue qui ne rendait que des brives 16:9. Tests verts avant commit : npm run build, test:section, test:shorts-catalog, test:filters. --- src/components/shorts/watch-short.component.html | 6 +++--- src/components/shorts/watch-short.component.ts | 16 +++++++++++++++- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/src/components/shorts/watch-short.component.html b/src/components/shorts/watch-short.component.html index 2c6bc5a..a32443e 100644 --- a/src/components/shorts/watch-short.component.html +++ b/src/components/shorts/watch-short.component.html @@ -54,7 +54,6 @@ } - @if (current(); as v) { @@ -146,6 +145,7 @@ Passer (vidéo illisible) + @if (current(); as v) { diff --git a/src/components/shorts/watch-short.component.ts b/src/components/shorts/watch-short.component.ts index a885d1d..d350e4e 100644 --- a/src/components/shorts/watch-short.component.ts +++ b/src/components/shorts/watch-short.component.ts @@ -1492,6 +1492,16 @@ export class WatchShortComponent implements OnDestroy { return; } const provider = this.provider(); + // Rumble : on va droit au chemin historique (flux natif rumble.com/shorts + // + remplissage recherche). Le catalogue `type=shorts` ne rend que des + // vidéos <=75 s HORizontales (Rumble n'expose aucune dimension : ni largeur + // ni hauteur dans les pages, vignettes en crop fixe 16:9 — vérifié 9/9), + // ce qui donnait un feed de « briques » 16:9 au lieu des shorts officiels. + if (provider === 'rumble') { + this.catalogActive = false; + this.loadLegacyFeed(); + return; + } // Shorts via le CATALOGUE d'abord (`/api/search?type=shorts` : cache, // provenance, feature-flags). Twitch garde son flux de clips historique // (pas d'équivalent catalogue : la recherche serveur renvoie des VOD). @@ -1646,8 +1656,12 @@ export class WatchShortComponent implements OnDestroy { const raw = (res.items || []).filter(v => !!v.videoId); this.nextCursor.set(res.nextCursor || null); if (!res.nextCursor) this.exhaustedQueries.add(this.currentQuery()); + // NOTE : `list` est DÉJÀ dédupliqué par chaque appelant (ligne 1671 / + // branche YouTube). Un second passage ici marquait tout comme « déjà vu » + // et posait une liste VIDE en silence — écran « Aucun short » sans erreur + // ni requête suivante (bug reproduit au navigateur, fix racine). const show = (list: Video[]) => { - const deduped = this.dedup(list); + const deduped = list; this.items.set(deduped); this.index.set(0); this.error.set(null);