From 04621efc528f4127e01d5326fde3bebf2cdda5b0 Mon Sep 17 00:00:00 2001 From: thePR0M3TH3AN <53631862+PR0M3TH3AN@users.noreply.github.com> Date: Wed, 24 Jun 2026 13:13:45 -0400 Subject: [PATCH] feed: stop the grid re-sorting ranked feeds chronologically; Trending defaults MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The real reason every tab looked identical: VideoListView.render re-sorts displayVideos by date UNLESS metadata.preserveOrder is set, and only Explore set it. So For You's tiering, Trending's view-count ranking, and Kids' scoring were all discarded at render and shown in plain chronological order — i.e. the #21 feed-identity work was invisible. Set preserveOrder for For You, Trending, and Kids so their feed-engine order survives to the grid. Also per request: - Sidebar: Trending now sits above Recently Added. - Default homepage: logged-out users land on Trending (gated by FEATURE_TRENDING_FEED, falls back to Recent); logged-in stays For You. The logout-from-For-You redirect follows the same rule. Co-Authored-By: Claude Opus 4.8 --- components/sidebar.html | 18 +++++++++--------- js/app/authSessionCoordinator.js | 8 ++++++-- js/app/feedCoordinator.js | 12 +++++++++--- js/hashChangeHandler.js | 6 +++++- 4 files changed, 29 insertions(+), 15 deletions(-) diff --git a/components/sidebar.html b/components/sidebar.html index a6f02778..76be8484 100644 --- a/components/sidebar.html +++ b/components/sidebar.html @@ -54,15 +54,6 @@ /> For You - - - Recently Added - Trending + + + Recently Added + ({ ...m, preserveOrder: true }); break; } case FEED_TYPES.KIDS: runtime = this.buildKidsFeedRuntime(); metadataModifier = (m) => { - if (runtime?.ageGroup && !m.ageGroup) - m.ageGroup = runtime.ageGroup; - return m; + const next = { ...m, preserveOrder: true }; + if (runtime?.ageGroup && !next.ageGroup) + next.ageGroup = runtime.ageGroup; + return next; }; break; case FEED_TYPES.EXPLORE: @@ -869,6 +873,8 @@ export function createFeedCoordinator(deps) { break; case FEED_TYPES.TRENDING: runtime = buildTrendingFeedRuntime(this); + // Preserve the view-count ranking (otherwise re-sorted by date). + metadataModifier = (m) => ({ ...m, preserveOrder: true }); break; case "recent": runtime = this.buildRecentFeedRuntime(); diff --git a/js/hashChangeHandler.js b/js/hashChangeHandler.js index 705d0a57..7ccb36ec 100644 --- a/js/hashChangeHandler.js +++ b/js/hashChangeHandler.js @@ -1,5 +1,5 @@ import { devLogger as defaultDevLogger, userLogger as defaultUserLogger } from "./utils/logger.js"; -import { FEED_TYPES } from "./constants.js"; +import { FEED_TYPES, FEATURE_TRENDING_FEED } from "./constants.js"; const LEGACY_DOCS_VIEWS = { about: "about", @@ -90,8 +90,12 @@ export function createHashChangeHandler({ try { if (!match || !match[1]) { + // Logged in → personalized For You; logged out → Trending (the best + // not-personalized landing), falling back to Recent if Trending is off. const defaultViewName = resolveIsLoggedIn() ? FEED_TYPES.FOR_YOU + : FEATURE_TRENDING_FEED + ? FEED_TYPES.TRENDING : FEED_TYPES.RECENT; if (defaultViewName === currentViewName) {