diff --git a/js/historyView.js b/js/historyView.js index 2b31b5e2..4be1b227 100644 --- a/js/historyView.js +++ b/js/historyView.js @@ -1521,9 +1521,12 @@ export function createWatchHistoryRenderer(config = {}) { ); } } + // The History view shows the user's FULL history (all months), unlike the + // feed's automatic load which only decrypts recent months for speed. const items = await watchHistoryService.loadLatest(actorInput, { allowStale: !forceRefresh, forceRefresh, + recentMonthsLimit: 0, }); const normalized = normalizeHistoryItems(items); return { items: normalized, metadata: { engine: "service-fallback" } }; diff --git a/js/nostr/watchHistory.js b/js/nostr/watchHistory.js index b1680326..035b2760 100644 --- a/js/nostr/watchHistory.js +++ b/js/nostr/watchHistory.js @@ -41,6 +41,10 @@ import { export { normalizePointerInput, pointerKey }; +// Recent monthly watch-history snapshots to decrypt on load (1 nip-07 call each). +// Override per-call with recentMonthsLimit (0 = all, e.g. the History view). +const RECENT_MONTHS_DECRYPT_LIMIT = 6; + /** * Domain utilities for watch-history interactions. This module owns pointer * normalization/serialization, chunking, fingerprint hashing, persistence, @@ -1989,6 +1993,17 @@ class WatchHistoryManager { return await loadFromStorage(); } + // Decrypt only the most recent months by default (see constant above). + const recentMonthsLimit = Number.isFinite(options?.recentMonthsLimit) + ? Math.floor(options.recentMonthsLimit) + : RECENT_MONTHS_DECRYPT_LIMIT; + if (recentMonthsLimit > 0 && pointerEvents.length > recentMonthsLimit) { + pointerEvents = [...pointerEvents] + .sort((a, b) => (b?.created_at || 0) - (a?.created_at || 0)) + .slice(0, recentMonthsLimit); + eventToProcess = pointerEvents; + } + // Determine snapshotId from the latest event (prioritizing monthly) const latestEvent = selectNewestListEvent(eventToProcess); @@ -2217,6 +2232,7 @@ class WatchHistoryManager { const fetchResult = await this.fetch(resolvedActor, { forceRefresh: options.forceRefresh || false, + recentMonthsLimit: options.recentMonthsLimit, }); const merged = mergeWatchHistoryItemsWithFallback( { diff --git a/js/watchHistoryService.js b/js/watchHistoryService.js index f093c24e..acf75615 100644 --- a/js/watchHistoryService.js +++ b/js/watchHistoryService.js @@ -1015,7 +1015,10 @@ function scheduleWatchHistoryRefresh(actorKey, cacheEntry = {}, options = {}) { if (!permissionResult.ok) { throw permissionResult.error; } - return nostrClient.resolveWatchHistory(actorKey, { forceRefresh: true }); + return nostrClient.resolveWatchHistory(actorKey, { + forceRefresh: true, + recentMonthsLimit: options?.recentMonthsLimit, + }); })() .then((resolvedItems) => updateFingerprintCache(actorKey, resolvedItems)) .then(() => { diff --git a/scripts/check-file-size.mjs b/scripts/check-file-size.mjs index 00c197d7..41996431 100644 --- a/scripts/check-file-size.mjs +++ b/scripts/check-file-size.mjs @@ -39,7 +39,7 @@ const GRANDFATHERED = { "js/subscriptions.js": 2426, "js/userBlocks.js": 2353, "js/services/nostrService.js": 2227, - "js/nostr/watchHistory.js": 2335, + "js/nostr/watchHistory.js": 2360, "js/nostr/nip46Client.js": 2102, "js/state/cache.js": 1827, "js/app/feedCoordinator.js": 1767,