From c56ffdfee6f35b27769393a6636e7fd90a124cac Mon Sep 17 00:00:00 2001 From: thePR0M3TH3AN <53631862+PR0M3TH3AN@users.noreply.github.com> Date: Thu, 25 Sep 2025 12:20:29 -0400 Subject: [PATCH] Reduce video list thrash and skip modal tracking --- js/app.js | 31 +++++++++++++++++++++++++++++++ js/index.js | 7 ++++++- 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/js/app.js b/js/app.js index 61fd68df..040c2c38 100644 --- a/js/app.js +++ b/js/app.js @@ -27,6 +27,7 @@ const UNSUPPORTED_BTITH_MESSAGE = "This magnet link is missing a compatible BitTorrent v1 info hash."; const FALLBACK_THUMBNAIL_SRC = "assets/jpg/video-thumbnail-fallback.jpg"; +const EMPTY_VIDEO_LIST_SIGNATURE = "__EMPTY__"; // We probe hosted URLs often enough that a naive implementation would spam // remote CDNs. A medium-lived cache (roughly 45 minutes) keeps us from // hammering dead hosts while still giving the UI timely updates when a CDN @@ -481,6 +482,8 @@ class bitvidApp { this.videosMap = new Map(); // Simple cache for user profiles this.profileCache = new Map(); + this.lastRenderedVideoSignature = null; + this._lastRenderedVideoListElement = null; // NEW: reference to the login modal's close button this.closeLoginModalBtn = @@ -1803,6 +1806,7 @@ class bitvidApp { // The rest of your existing logic: if (!this.videoSubscription) { if (this.videoList) { + this.lastRenderedVideoSignature = null; this.videoList.innerHTML = `
Loading videos as they arrive... @@ -2077,10 +2081,19 @@ class bitvidApp { async renderVideoList(videos) { if (!this.videoList) return; + if (this._lastRenderedVideoListElement !== this.videoList) { + this.lastRenderedVideoSignature = null; + this._lastRenderedVideoListElement = this.videoList; + } + const dedupedVideos = this.dedupeVideosByRoot(videos); // 1) If no videos if (!dedupedVideos.length) { + if (this.lastRenderedVideoSignature === EMPTY_VIDEO_LIST_SIGNATURE) { + return; + } + this.lastRenderedVideoSignature = EMPTY_VIDEO_LIST_SIGNATURE; this.videoList.innerHTML = `
No public videos available yet. Be the first to upload one! @@ -2091,6 +2104,24 @@ class bitvidApp { // 2) Sort newest first dedupedVideos.sort((a, b) => b.created_at - a.created_at); + const signaturePayload = dedupedVideos.map((video) => ({ + id: typeof video.id === "string" ? video.id : "", + createdAt: Number.isFinite(video.created_at) + ? video.created_at + : Number(video.created_at) || 0, + deleted: Boolean(video.deleted), + isPrivate: Boolean(video.isPrivate), + thumbnail: typeof video.thumbnail === "string" ? video.thumbnail : "", + url: typeof video.url === "string" ? video.url : "", + magnet: typeof video.magnet === "string" ? video.magnet : "", + })); + const signature = JSON.stringify(signaturePayload); + + if (signature === this.lastRenderedVideoSignature) { + return; + } + this.lastRenderedVideoSignature = signature; + const fullAllEventsArray = Array.from(nostrClient.allEvents.values()); const fragment = document.createDocumentFragment(); const authorSet = new Set(); diff --git a/js/index.js b/js/index.js index 12e3726b..a26695be 100644 --- a/js/index.js +++ b/js/index.js @@ -10,9 +10,14 @@ async function loadModal(url) { throw new Error("Failed to load " + url); } const html = await response.text(); + // Remove analytics loader tags from modal partials to avoid duplicate pageview events. + const sanitizedHtml = html.replace( + /