From 4639a572fec61bce53e0f67279e8ca1082da7e3e Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Thu, 15 Jan 2026 02:21:57 +0000 Subject: [PATCH] fix: prevent hashtag preferences reset on empty or stale relay responses This commit updates `HashtagPreferencesService.load` to handle transient empty responses from relays more robustly. - It prevents `reset()` if `wasLoadedForUser` is true and the fetch returns empty, ensuring existing data isn't wiped during connectivity issues or relay switches. - It adds a staleness check to ignore incoming events that are older than the currently loaded data, protecting against out-of-sync relays returning obsolete preferences. This addresses the issue where hashtag interests would disappear ("turn gray") or revert to older states shortly after login when video grid filters were applied. --- js/services/hashtagPreferencesService.js | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/js/services/hashtagPreferencesService.js b/js/services/hashtagPreferencesService.js index 8ec9cc85..3ed72af4 100644 --- a/js/services/hashtagPreferencesService.js +++ b/js/services/hashtagPreferencesService.js @@ -430,9 +430,9 @@ 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) { + if (wasLoadedForUser) { userLogger.warn( - `${LOG_PREFIX} Keeping existing preferences after fetch error.`, + `${LOG_PREFIX} Keeping existing preferences despite empty relay response.`, ); return; } @@ -470,7 +470,7 @@ class HashtagPreferencesService { }, null); if (!latest) { - if (fetchError && wasLoadedForUser) { + if (wasLoadedForUser) { return; } this.reset(); @@ -478,6 +478,16 @@ class HashtagPreferencesService { return; } + const currentCreatedAt = Number(this.eventCreatedAt) || 0; + const latestCreatedAt = Number(latest.created_at) || 0; + + if (wasLoadedForUser && currentCreatedAt > latestCreatedAt) { + userLogger.warn( + `${LOG_PREFIX} Ignoring stale preferences event (remote: ${latestCreatedAt}, local: ${currentCreatedAt}).`, + ); + return; + } + const decryptResult = await this.decryptEvent(latest, normalized); if (!decryptResult.ok) { userLogger.warn(