diff --git a/js/services/hashtagPreferencesService.js b/js/services/hashtagPreferencesService.js index 49e50fb1..8ec9cc85 100644 --- a/js/services/hashtagPreferencesService.js +++ b/js/services/hashtagPreferencesService.js @@ -344,6 +344,11 @@ class HashtagPreferencesService { async load(pubkey) { const normalized = normalizeHexPubkey(pubkey); + const wasLoadedForUser = + this.activePubkey && + this.activePubkey === normalized && + (this.interests.size > 0 || this.disinterests.size > 0 || this.loaded); + this.activePubkey = normalized; if (!normalized) { @@ -360,6 +365,13 @@ class HashtagPreferencesService { userLogger.warn( `${LOG_PREFIX} nostrClient.pool.list unavailable; treating preferences as empty.`, ); + // If we already have data for this user, do not reset on transient client issues. + if (wasLoadedForUser) { + userLogger.warn( + `${LOG_PREFIX} Keeping existing preferences despite client unavailability.`, + ); + return; + } this.reset(); this.loaded = true; return; @@ -371,6 +383,12 @@ class HashtagPreferencesService { : nostrClient.writeRelays, ); if (!relays.length) { + if (wasLoadedForUser) { + userLogger.warn( + `${LOG_PREFIX} Keeping existing preferences; no relays available for refresh.`, + ); + return; + } this.reset(); this.loaded = true; return; @@ -393,12 +411,15 @@ class HashtagPreferencesService { }; let events = []; + let fetchError = null; + try { const result = await nostrClient.pool.list(relays, [filter]); if (Array.isArray(result)) { events = result.filter((event) => event && event.pubkey === normalized); } } catch (error) { + fetchError = error; userLogger.warn( `${LOG_PREFIX} Failed to load hashtag preferences from relays`, error, @@ -407,6 +428,15 @@ class HashtagPreferencesService { } if (!events.length) { + // If we failed to fetch (network error) but already have data for this user, + // preserve the existing state instead of wiping it. + if (fetchError && wasLoadedForUser) { + userLogger.warn( + `${LOG_PREFIX} Keeping existing preferences after fetch error.`, + ); + return; + } + this.reset(); this.loaded = true; return; @@ -440,6 +470,9 @@ class HashtagPreferencesService { }, null); if (!latest) { + if (fetchError && wasLoadedForUser) { + return; + } this.reset(); this.loaded = true; return; @@ -451,6 +484,9 @@ class HashtagPreferencesService { `${LOG_PREFIX} Failed to decrypt hashtag preferences`, decryptResult.error, ); + // If decryption fails on a reload, we might want to keep old data? + // But typically decryption failure means key mismatch or bad payload. + // Resetting is safer here to avoid stuck state, unless we want to be very conservative. this.reset(); this.loaded = true; return; @@ -795,4 +831,3 @@ const hashtagPreferences = new HashtagPreferencesService(); export default hashtagPreferences; export { HashtagPreferencesService, hashtagPreferences, EVENTS as HASHTAG_PREFERENCES_EVENTS }; -