diff --git a/js/services/hashtagPreferencesService.js b/js/services/hashtagPreferencesService.js index 94176763..b3afa4a1 100644 --- a/js/services/hashtagPreferencesService.js +++ b/js/services/hashtagPreferencesService.js @@ -325,6 +325,14 @@ class HashtagPreferencesService { } stopHashtagPreferencesSubscription() { + if (this.subscriptionHandle) { + try { + this.subscriptionHandle.close(); + } catch (error) { + devLogger.warn(`${LOG_PREFIX} Failed to close hashtag subscription handle`, error); + } + this.subscriptionHandle = null; + } if (this.subscriptionKey) { relaySubscriptionService.stopSubscription(this.subscriptionKey, "reset"); this.subscriptionKey = null; @@ -353,6 +361,23 @@ class HashtagPreferencesService { const key = `hashtags:${normalized}`; this.subscriptionKey = key; + // Route through the L1 SubscriptionManager when available (dedup + reconnect + // re-issue); fall back to relaySubscriptionService in manager-less envs. + const manager = + typeof nostrClient.getSubscriptionManager === "function" + ? nostrClient.getSubscriptionManager() + : null; + if (manager) { + this.subscriptionHandle = manager.subscribe({ + key, + relays, + filters, + label: "hashtag-preferences", + onEvent: (event) => this.handleHashtagPreferencesEvent(event), + }); + return this.subscriptionHandle; + } + return relaySubscriptionService.ensureSubscription({ key, pool: nostrClient.pool, diff --git a/js/subscriptions.js b/js/subscriptions.js index 28033165..5a2f2d10 100644 --- a/js/subscriptions.js +++ b/js/subscriptions.js @@ -851,6 +851,14 @@ class SubscriptionsManager { } stopSubscriptionListSubscription() { + if (this.subscriptionHandle) { + try { + this.subscriptionHandle.close(); + } catch (error) { + devLogger.warn("[SubscriptionsManager] Failed to close subscription handle", error); + } + this.subscriptionHandle = null; + } if (this.subscriptionKey) { relaySubscriptionService.stopSubscription(this.subscriptionKey, "reset"); this.subscriptionKey = null; @@ -874,6 +882,24 @@ class SubscriptionsManager { }, ]; + // Route through the L1 SubscriptionManager when available: centralized + // dedup + reconnect re-issue (so the follows list self-heals after a relay + // drop). Falls back to relaySubscriptionService in manager-less envs. + const manager = + typeof nostrClient.getSubscriptionManager === "function" + ? nostrClient.getSubscriptionManager() + : null; + if (manager) { + this.subscriptionHandle = manager.subscribe({ + key, + relays, + filters, + label: "subscription-list", + onEvent: (event) => this.handleSubscriptionListEvent(event), + }); + return this.subscriptionHandle; + } + return relaySubscriptionService.ensureSubscription({ key, pool: nostrClient.pool,