playlists(#37): playlist view resolves from cache first (no needless relay fetch)

The view always re-fetched the creator's videos from relays, so arriving from
the channel (where they're already loaded) or re-visiting a playlist lagged on a
round-trip. Now it resolves from the active cache first and only fetches when
some playlist coordinates are still missing (a cold deep-link). Channel→playlist
navigation is instant; deep-links still fetch just what they need.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
This commit is contained in:
thePR0M3TH3ANandClaude Opus 4.8 committed 2026-07-06 15:48:17 -04:00
1 parent 73a99358a2
commit 791296266a
1 file changed
+37 -22
+37 -22
View File
@@ -54,29 +54,13 @@ function resolveOrderedVideos(playlist, videoPool) {
return ordered;
}
// The videos to resolve against: the referenced creators' videos (fetched from
// relays so a DIRECT load / cold cache still works) plus whatever's already
// active. Without the fetch, a deep-linked playlist resolves nothing and the
// shared grid shows the default feed instead.
// The videos to resolve against. Resolve from the ALREADY-active cache first —
// when you arrive from the creator's channel (or re-visit), the videos are
// already loaded, so this is instant with no relay round-trip. Only when some
// playlist coordinates are still missing (a cold deep-link) do we fetch the
// referenced creators' videos. Without any fetch, a cold deep-link resolves
// nothing and the shared grid shows the default feed instead.
async function gatherVideoPool(playlist, app) {
const authors = [
...new Set(
playlist.items
.filter((item) => item.type === "a")
.map((item) => item.value.split(":")[1])
.filter(Boolean),
),
];
let fetched = [];
if (authors.length && typeof app?.nostrService?.fetchVideosByAuthors === "function") {
try {
fetched = (await app.nostrService.fetchVideosByAuthors(authors)) || [];
} catch (error) {
devLogger.warn("[playlistView] Failed to fetch playlist videos:", error);
}
}
let active = [];
try {
active = nostrClient.getActiveVideos() || [];
@@ -84,6 +68,37 @@ async function gatherVideoPool(playlist, app) {
active = [];
}
const covered = new Set();
for (const video of active) {
const coordinate = buildVideoAddressPointer(video);
if (coordinate) {
covered.add(coordinate);
}
}
const neededCoords = playlist.items
.filter((item) => item.type === "a")
.map((item) => item.value);
const allCovered = neededCoords.every((coord) => covered.has(coord));
if (allCovered) {
return active;
}
const authors = [
...new Set(neededCoords.map((coord) => coord.split(":")[1]).filter(Boolean)),
];
let fetched = [];
if (
authors.length &&
typeof app?.nostrService?.fetchVideosByAuthors === "function"
) {
try {
fetched = (await app.nostrService.fetchVideosByAuthors(authors)) || [];
} catch (error) {
devLogger.warn("[playlistView] Failed to fetch playlist videos:", error);
}
}
return [...fetched, ...active];
}