feat(shorts): vraie variété du flux a chaque chargement
CI / build-and-test (push) Successful in 15m2s
CI / build-and-test (push) Successful in 15m2s
Trois causes du « toujours les mêmes vidéos » (peu importe le fournisseur) : - watch-short : queryIndex repartait à 0 a chaque loadFeed() -> toujours la même requête (« shorts ») et donc les mêmes résultats du fournisseur. Départ désormais aléatoire dans SHORTS_QUERIES (la rotation par page reste). - watch-short : dedup() ne triait rien -> le 1er lot arrivait toujours dans l'ordre du fournisseur. Le lot neuf est maintenant mélangé (Fisher-Yates), comme le chemin « Pour toi » le fait déjà. Un seul point de passage, donc catalogue, historique, repli trending et Twitch sont couverts. - youtube-api : la rotation des top games Twitch démarrait à l'index 0 -> mêmes clips à chaque session. Départ aléatoire, rotation conservée. Le cache serveur (5 min / 30 min YT) n'est pas en cause. Vérif instance locale : YouTube 3/3 premières vidéos distinctes sur 3 rechargements, Twitch 2 distinctes sur 3. tests verts.
This commit is contained in:
@@ -1471,8 +1471,11 @@ export class WatchShortComponent implements OnDestroy {
|
||||
this.index.set(0);
|
||||
this.nextCursor.set(null);
|
||||
this.seenIds = new Set<string>();
|
||||
this.queryIndex = 0;
|
||||
this.exhaustedQueries = new Set<string>();
|
||||
// Requête de départ ALÉATOIRE : sinon chaque rechargement repart de la
|
||||
// même recherche (« shorts ») et le fournisseur renvoie les mêmes vidéos
|
||||
// jour après jour.
|
||||
this.queryIndex = Math.floor(Math.random() * this.queriesFor(this.provider()).length);
|
||||
this.exhaustedQueries = new Set();
|
||||
this.catalogActive = false;
|
||||
this.catalogError.set(null);
|
||||
const ready = this.instances.getProviderReadiness(this.provider());
|
||||
@@ -1772,7 +1775,12 @@ export class WatchShortComponent implements OnDestroy {
|
||||
);
|
||||
}
|
||||
|
||||
/** Dedup inter-pages (clé videoId + provider). */
|
||||
/**
|
||||
* Dedup inter-pages (clé videoId + provider) + mélange du lot neuf.
|
||||
* Le mélange est volontaire : un rechargement du flux Shorts ne doit pas
|
||||
* présenter les mêmes vidéos dans le même ordre (même chemin Pour toi,
|
||||
* qui mélange déjà ses lots par sujet).
|
||||
*/
|
||||
private dedup(list: Video[]): Video[] {
|
||||
const out: Video[] = [];
|
||||
for (const v of list) {
|
||||
@@ -1781,6 +1789,10 @@ export class WatchShortComponent implements OnDestroy {
|
||||
this.seenIds.add(key);
|
||||
out.push(v);
|
||||
}
|
||||
for (let i = out.length - 1; i > 0; i--) {
|
||||
const j = Math.floor(Math.random() * (i + 1));
|
||||
[out[i], out[j]] = [out[j], out[i]];
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
|
||||
@@ -1765,7 +1765,9 @@ export class YoutubeApiService {
|
||||
// tourne sur les top games, ce qui donne toujours des clips récents.
|
||||
// Curseur opaque : "<gameId>::<paginationCursor>" (pagination vide = page 1).
|
||||
private twitchTopGameIds: string[] | null = null;
|
||||
private twitchGameIdx = 0;
|
||||
// Index de départ ALÉATOIRE : un rechargement ne repart pas toujours du
|
||||
// même jeu (sinon mêmes clips jour après jour). `++` garde la rotation.
|
||||
private twitchGameIdx = Math.floor(Math.random() * 1000);
|
||||
private twitchClipsSinceDays = 30;
|
||||
|
||||
private getTwitchTopGameIds(): Observable<string[]> {
|
||||
|
||||
Reference in New Issue
Block a user