feed: stop the grid re-sorting ranked feeds chronologically; Trending defaults

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 <[email protected]>
This commit is contained in:
thePR0M3TH3ANandClaude Opus 4.8 committed 2026-06-24 13:13:45 -04:00
1 parent 02854d4fb5
commit 04621efc52
4 files changed
+29 -15

No files matched your search

+9 -9
View File
@@ -54,15 +54,6 @@
/>
<span class="sidebar-text">For You</span>
</a>
<a href="#view=most-recent-videos" class="sidebar-nav-link" title="Recently Added">
<img
src="assets/svg/globe-icon.svg"
alt=""
aria-hidden="true"
class="sidebar-icon"
/>
<span class="sidebar-text">Recently Added</span>
</a>
<a
id="trendingLink"
href="#view=trending"
@@ -85,6 +76,15 @@
</svg>
<span class="sidebar-text">Trending</span>
</a>
<a href="#view=most-recent-videos" class="sidebar-nav-link" title="Recently Added">
<img
src="assets/svg/globe-icon.svg"
alt=""
aria-hidden="true"
class="sidebar-icon"
/>
<span class="sidebar-text">Recently Added</span>
</a>
<a href="#view=kids" class="sidebar-nav-link" title="For Kids">
<svg
xmlns="http://www.w3.org/2000/svg"
+6 -2
View File
@@ -12,7 +12,7 @@
import { clearDecryptionSchemeCache } from "../nostr/decryptionSchemeCache.js";
import { clearWatchHistoryConversationKeyCache } from "../nostr/watchHistory.js";
import { clearWatchHistoryDecryptedChunkCache } from "../nostr/watchHistoryDecryptCache.js";
import { FEED_TYPES } from "../constants.js";
import { FEED_TYPES, FEATURE_TRENDING_FEED } from "../constants.js";
/**
* Kick a background watch-history refresh after login, once the feed-driving
@@ -988,7 +988,11 @@ export function createAuthSessionCoordinator(deps) {
typeof logoutView === "string" &&
logoutView.trim().toLowerCase() === FEED_TYPES.FOR_YOU
) {
setHashView(FEED_TYPES.RECENT);
// For You is logged-in only; send logged-out users to the same landing
// as the default homepage — Trending (or Recent if Trending is off).
setHashView(
FEATURE_TRENDING_FEED ? FEED_TYPES.TRENDING : FEED_TYPES.RECENT
);
}
const activeModalVideo =
+9 -3
View File
@@ -848,14 +848,18 @@ export function createFeedCoordinator(deps) {
);
}
runtime = this.buildForYouFeedRuntime({ watchHistoryItems });
// Keep the scorer/sorter's "your people first" order — without this
// VideoListView re-sorts chronologically and For You looks like Recent.
metadataModifier = (m) => ({ ...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();
+5 -1
View File
@@ -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) {