From 9d365bf65ea223907490c337d448715285fef479 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Wed, 7 Jan 2026 18:44:43 +0000 Subject: [PATCH 1/2] Fix profile watch history and subscription lists syncing issues. --- js/historyView.js | 4 ++++ js/subscriptions.js | 18 +++++++++++++++--- js/ui/profileModalController.js | 14 ++++++++++++++ 3 files changed, 33 insertions(+), 3 deletions(-) diff --git a/js/historyView.js b/js/historyView.js index 5ef319dd..4d2e9bbe 100644 --- a/js/historyView.js +++ b/js/historyView.js @@ -2409,6 +2409,10 @@ export function createWatchHistoryRenderer(config = {}) { await this.init(options); return; } + if (options.actor !== state.actor) { + await this.refresh(options); + return; + } refreshElements(); updateFeatureBanner(); if (!state.featureEnabled) { diff --git a/js/subscriptions.js b/js/subscriptions.js index 1cc1be18..a7385d96 100644 --- a/js/subscriptions.js +++ b/js/subscriptions.js @@ -224,6 +224,7 @@ class SubscriptionsManager { constructor() { this.subscribedPubkeys = new Set(); this.subsEventId = null; + this.currentUserPubkey = null; this.loaded = false; this.loadingPromise = null; this.subscriptionListView = null; @@ -379,19 +380,30 @@ class SubscriptionsManager { const normalized = parseSubscriptionPlaintext(decryptedStr); this.subscribedPubkeys = new Set(normalized); + this.currentUserPubkey = normalizedUserPubkey; this.loaded = true; } catch (err) { userLogger.error("[SubscriptionsManager] Failed to load subs:", err); } } + reset() { + this.subscribedPubkeys.clear(); + this.subsEventId = null; + this.currentUserPubkey = null; + this.loaded = false; + this.lastRunOptions = null; + this.lastResult = null; + this.hasRenderedOnce = false; + } + async ensureLoaded(actorHex) { - if (this.loaded) { + const normalizedActor = normalizeHexPubkey(actorHex) || actorHex; + if (!normalizedActor) { return; } - const normalizedActor = normalizeHexPubkey(actorHex) || actorHex; - if (!normalizedActor) { + if (this.loaded && this.currentUserPubkey === normalizedActor) { return; } diff --git a/js/ui/profileModalController.js b/js/ui/profileModalController.js index 404330fa..4c48e79c 100644 --- a/js/ui/profileModalController.js +++ b/js/ui/profileModalController.js @@ -8828,6 +8828,20 @@ export class ProfileModalController { userLogger.warn("Failed to refresh admin pane after logout:", error); } + if ( + this.subscriptionsService && + typeof this.subscriptionsService.reset === "function" + ) { + try { + this.subscriptionsService.reset(); + } catch (error) { + devLogger.warn( + "[profileModal] Failed to reset subscriptions service on logout:", + error, + ); + } + } + this.populateBlockedList(); this.clearSubscriptionsList(); this.clearFriendsList(); From 19dd57060712f06f0bcfe9912ad3ba1f3f1f32e6 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Wed, 7 Jan 2026 19:22:23 +0000 Subject: [PATCH 2/2] Fix profile watch history and subscription lists syncing issues. --- js/historyView.js | 45 ++++++++++++++++++--------------- js/ui/profileModalController.js | 19 +++++++++++++- 2 files changed, 42 insertions(+), 22 deletions(-) diff --git a/js/historyView.js b/js/historyView.js index 4d2e9bbe..be961a5c 100644 --- a/js/historyView.js +++ b/js/historyView.js @@ -51,12 +51,13 @@ function escapeSelector(value) { return value.replace(/([^a-zA-Z0-9_-])/g, "\\$1"); } -function resolveElement(selector) { +function resolveElement(selector, root = document) { if (!selector || typeof selector !== "string") { return null; } + const scope = root && typeof root.querySelector === "function" ? root : document; try { - return document.querySelector(selector); + return scope.querySelector(selector); } catch (error) { userLogger.warn("[historyView] Failed to query selector:", selector, error); return null; @@ -1373,6 +1374,7 @@ export function buildHistoryCard({ item, video, profile }) { export function createWatchHistoryRenderer(config = {}) { const { + container = typeof document !== "undefined" ? document : null, fetchHistory = async ( actorInput, { cursor = 0, forceRefresh = false } = {} @@ -1500,26 +1502,27 @@ export function createWatchHistoryRenderer(config = {}) { const subscriptions = new Set(); function refreshElements() { + const scope = container || document; elements = { - view: resolveElement(viewSelector), - grid: resolveElement(gridSelector), - loading: resolveElement(loadingSelector), - status: resolveElement(statusSelector), - empty: resolveElement(emptySelector), - sentinel: resolveElement(sentinelSelector), - loadMore: resolveElement(loadMoreSelector), - clearButton: resolveElement(clearButtonSelector), - republishButton: resolveElement(republishButtonSelector), - refreshButton: resolveElement(refreshButtonSelector), - privacyBanner: resolveElement(privacyBannerSelector), - privacyMessage: resolveElement(privacyMessageSelector), - privacyToggle: resolveElement(privacyToggleSelector), - privacyDismiss: resolveElement(privacyDismissSelector), - info: resolveElement(infoSelector), - errorBanner: resolveElement(errorBannerSelector), - scrollContainer: resolveElement(scrollContainerSelector), - featureBanner: resolveElement(featureBannerSelector), - sessionWarning: resolveElement(sessionWarningSelector) + view: resolveElement(viewSelector, scope), + grid: resolveElement(gridSelector, scope), + loading: resolveElement(loadingSelector, scope), + status: resolveElement(statusSelector, scope), + empty: resolveElement(emptySelector, scope), + sentinel: resolveElement(sentinelSelector, scope), + loadMore: resolveElement(loadMoreSelector, scope), + clearButton: resolveElement(clearButtonSelector, scope), + republishButton: resolveElement(republishButtonSelector, scope), + refreshButton: resolveElement(refreshButtonSelector, scope), + privacyBanner: resolveElement(privacyBannerSelector, scope), + privacyMessage: resolveElement(privacyMessageSelector, scope), + privacyToggle: resolveElement(privacyToggleSelector, scope), + privacyDismiss: resolveElement(privacyDismissSelector, scope), + info: resolveElement(infoSelector, scope), + errorBanner: resolveElement(errorBannerSelector, scope), + scrollContainer: resolveElement(scrollContainerSelector, scope), + featureBanner: resolveElement(featureBannerSelector, scope), + sessionWarning: resolveElement(sessionWarningSelector, scope) }; } diff --git a/js/ui/profileModalController.js b/js/ui/profileModalController.js index 4c48e79c..1d7ffa00 100644 --- a/js/ui/profileModalController.js +++ b/js/ui/profileModalController.js @@ -1156,6 +1156,20 @@ export class ProfileModalController { throw new Error("profile modal container missing"); } + // Invalidate any stale renderer reference so it is recreated + // with the freshly loaded DOM elements. + if (this.profileHistoryRenderer) { + try { + if (typeof this.profileHistoryRenderer.destroy === "function") { + this.profileHistoryRenderer.destroy(); + } + } catch (err) { + devLogger.warn("[profileModal] Failed to destroy stale history renderer:", err); + } + this.profileHistoryRenderer = null; + this.profileHistoryRendererConfig = null; + } + const response = await fetch("components/profile-modal.html"); if (!response.ok) { throw new Error(`Failed to load profile modal HTML (${response.status})`); @@ -1460,7 +1474,10 @@ export class ProfileModalController { const config = this.getProfileHistoryRendererConfig(); try { - this.profileHistoryRenderer = this.createWatchHistoryRenderer(config); + this.profileHistoryRenderer = this.createWatchHistoryRenderer({ + ...config, + container: this.profileModalPanel || this.profileModalRoot, + }); } catch (error) { userLogger.error( "[profileModal] Failed to create watch history renderer:",