fix: keep lastNotes intact on CardFeedContentState.trimToSize()

Clearing lastNotes caused the next additive update to call
refreshSuspended(), reloading the full filter limit (~500 notes) from
LocalCache and immediately undoing the trim.

With lastNotes intact the fast additive path stays active: only
genuinely new notifications are appended, so the card list remains near
maxItems until the next full feed key change or navigation event.

The Note refs in lastNotes are the same object instances already held
by LocalCache. They are freed when MemoryTrimmingService prunes
LocalCache and the following refreshSuspended() replaces lastNotes with
the pruned set.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019h2c44rAwexuUEP3kky2F3
This commit is contained in:
Claude
2026-06-24 21:42:14 +00:00
parent e17c95eda1
commit ea2dbd9a77
@@ -411,13 +411,14 @@ class CardFeedContentState(
val loaded = current.feed.value
if (loaded.list.size > maxItems) {
current.feed.tryEmit(LoadedFeedState(loaded.list.take(maxItems).toImmutableList(), loaded.showHidden))
// lastNotes holds strong refs to every raw Note that was ever included in this
// feed (used for additive-dedup). Clearing it releases those refs so the Notes
// are no longer pinned in memory independently of LocalCache.
// The next additive update will find lastNotes == null, skip the fast path, and
// call refreshSuspended() — a single controlled rebuild from LocalCache.
lastNotes = null
lastAccount = null
// lastNotes is intentionally kept intact. Clearing it would cause the next
// additive update to fall through to refreshSuspended(), reloading up to
// limit() notes from LocalCache and undoing the trim immediately. With
// lastNotes intact, the fast additive path stays active: only genuinely
// new notifications are appended, so the card list stays near maxItems.
// The Note refs in lastNotes are the same objects already held by LocalCache;
// they are freed when pruneRepliesAndReactions() prunes LocalCache and the
// next full refreshSuspended() replaces lastNotes with the pruned set.
}
}
}