Add popular tag strip support to recent videos

This commit is contained in:
thePR0M3TH3AN committed 2025-10-23 15:13:05 -04:00
1 parent 62e9ff54fc
commit 876020b90f
5 files changed
+202

No files matched your search

+21
View File
@@ -887,6 +887,7 @@ class Application {
this.currentVideoPointerKey = null;
this.videoSubscription = this.nostrService.getVideoSubscription() || null;
this.videoList = null;
this.videoListPopularTags = null;
this.modalViewCountUnsub = null;
this.modalReactionUnsub = null;
this.modalReactionPointerKey = null;
@@ -1197,6 +1198,11 @@ class Application {
}
this.videoList = null;
if (this.videoListPopularTags) {
this.videoListPopularTags.textContent = "";
this.videoListPopularTags.hidden = true;
}
this.videoListPopularTags = null;
if (this.mediaLoader && typeof this.mediaLoader.disconnect === "function") {
this.mediaLoader.disconnect();
@@ -2902,6 +2908,11 @@ class Application {
const target = container || document.getElementById("videoList");
this.videoList = target || null;
const tagsRoot = document.getElementById("recentVideoTags");
this.videoListPopularTags = tagsRoot || null;
if (typeof this.videoListView.setPopularTagsContainer === "function") {
this.videoListView.setPopularTagsContainer(this.videoListPopularTags);
}
this.videoListView.mount(this.videoList || null);
return this.videoList;
}
@@ -2933,6 +2944,11 @@ class Application {
: "Refreshing videos…";
this.videoList = isElement(container) ? container : null;
const tagsRoot = document.getElementById("recentVideoTags");
this.videoListPopularTags = isElement(tagsRoot) ? tagsRoot : null;
if (typeof this.videoListView.setPopularTagsContainer === "function") {
this.videoListView.setPopularTagsContainer(this.videoListPopularTags);
}
if (this.videoList) {
this.videoList.innerHTML = getSidebarLoadingMarkup(messageContext);
@@ -8831,6 +8847,11 @@ class Application {
}
this.videoList = null;
if (this.videoListPopularTags) {
this.videoListPopularTags.textContent = "";
this.videoListPopularTags.hidden = true;
}
this.videoListPopularTags = null;
}
shareActiveVideo() {
+3
View File
@@ -1123,6 +1123,9 @@ class SubscriptionsManager {
};
const listView = new VideoListView(listViewConfig);
if (typeof listView.setPopularTagsContainer === "function") {
listView.setPopularTagsContainer(null);
}
listView.setPlaybackHandler((detail) => {
if (!detail) {
+97
View File
@@ -1,10 +1,12 @@
import { VideoCard } from "../components/VideoCard.js";
import { renderTagPillStrip } from "../components/tagPillList.js";
import {
subscribeToVideoViewCount,
unsubscribeFromVideoViewCount,
} from "../../viewCounter.js";
import { normalizeDesignSystemContext } from "../../designSystem.js";
import { userLogger } from "../../utils/logger.js";
import { collectVideoTags } from "../../utils/videoTags.js";
const EMPTY_VIDEO_LIST_SIGNATURE = "__EMPTY__";
@@ -174,6 +176,8 @@ export class VideoListView {
this.currentVideos = [];
this.lastRenderedVideoSignature = null;
this._lastRenderedVideoListElement = null;
this.popularTagsRoot = null;
this._popularTagStrip = null;
this.handlers = {
playback: null,
@@ -256,6 +260,12 @@ export class VideoListView {
this.currentVideos = [];
this.lastRenderedVideoSignature = null;
this._lastRenderedVideoListElement = null;
if (this.popularTagsRoot) {
this.popularTagsRoot.textContent = "";
this.popularTagsRoot.hidden = true;
}
this.popularTagsRoot = null;
this._popularTagStrip = null;
}
setPlaybackHandler(handler) {
@@ -282,6 +292,91 @@ export class VideoListView {
this.handlers.moderationOverride = typeof handler === "function" ? handler : null;
}
setPopularTagsContainer(container) {
if (this.popularTagsRoot && this.popularTagsRoot !== container) {
this.popularTagsRoot.textContent = "";
this.popularTagsRoot.hidden = true;
}
this.popularTagsRoot = container || null;
this._popularTagStrip = null;
if (this.popularTagsRoot) {
this.popularTagsRoot.textContent = "";
this.popularTagsRoot.hidden = true;
}
}
updatePopularTags(videos) {
const root = this.popularTagsRoot;
if (!root) {
return;
}
if (!Array.isArray(videos) || videos.length === 0) {
root.textContent = "";
root.hidden = true;
this._popularTagStrip = null;
return;
}
const counts = new Map();
const displayNames = new Map();
videos.forEach((video) => {
const tags = collectVideoTags(video);
tags.forEach((tag) => {
if (typeof tag !== "string" || !tag) {
return;
}
const lower = tag.toLowerCase();
counts.set(lower, (counts.get(lower) || 0) + 1);
if (!displayNames.has(lower)) {
displayNames.set(lower, tag);
}
});
});
if (!counts.size) {
root.textContent = "";
root.hidden = true;
this._popularTagStrip = null;
return;
}
const tagEntries = Array.from(counts.entries()).map(([lower, count]) => ({
count,
tag: displayNames.get(lower) || lower,
}));
tagEntries.sort((a, b) => {
if (b.count !== a.count) {
return b.count - a.count;
}
const lowerA = a.tag.toLowerCase();
const lowerB = b.tag.toLowerCase();
if (lowerA === lowerB) {
return a.tag.localeCompare(b.tag);
}
return lowerA.localeCompare(lowerB);
});
const tags = tagEntries.map((entry) => entry.tag);
const doc = this.document || root.ownerDocument || null;
if (!doc) {
root.textContent = "";
root.hidden = true;
this._popularTagStrip = null;
return;
}
const { root: strip } = renderTagPillStrip({ document: doc, tags });
root.textContent = "";
root.appendChild(strip);
root.hidden = false;
this._popularTagStrip = strip;
}
render(videos, metadata = null) {
if (!this.container) {
return [];
@@ -307,6 +402,8 @@ export class VideoListView {
return canEdit || !isPrivate;
});
this.updatePopularTags(displayVideos);
this.syncViewCountSubscriptions(displayVideos);
this.cleanupThumbnailCache(displayVideos);
this.cleanupHealthCache(displayVideos);