commit 21f21eaa60b7c07c1d5e48c6d955ae7f7aaaa22d
parent 1c3bec5a2402c6365c2423dc06fd910c4ae2a9f4
Author: William Casarin <jb55@jb55.com>
Date: Fri, 27 Feb 2026 07:06:09 -0800
fix: clear async load tracking when popping timeline routes
When navigating back from a profile (or any timeline route), the
timeline was removed from the cache but its entry in
loaded_timeline_loads was kept. This prevented the async loader
from re-populating the timeline on subsequent visits, resulting
in an empty note list.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Diffstat:
4 files changed, 13 insertions(+), 2 deletions(-)
diff --git a/crates/notedeck_columns/src/app.rs b/crates/notedeck_columns/src/app.rs
@@ -54,9 +54,9 @@ pub struct Damus {
/// Background loader for initial timeline scans.
timeline_loader: TimelineLoader,
/// Timelines currently loading initial notes.
- inflight_timeline_loads: HashSet<TimelineKind>,
+ pub inflight_timeline_loads: HashSet<TimelineKind>,
/// Timelines that have completed their initial load.
- loaded_timeline_loads: HashSet<TimelineKind>,
+ pub loaded_timeline_loads: HashSet<TimelineKind>,
//frame_history: crate::frame_history::FrameHistory,
diff --git a/crates/notedeck_columns/src/nav.rs b/crates/notedeck_columns/src/nav.rs
@@ -285,6 +285,8 @@ fn process_nav_resp(
&mut app.view_state,
ctx.ndb,
&mut ctx.remote.scoped_subs(ctx.accounts),
+ &mut app.loaded_timeline_loads,
+ &mut app.inflight_timeline_loads,
return_type,
col,
);
diff --git a/crates/notedeck_columns/src/route.rs b/crates/notedeck_columns/src/route.rs
@@ -5,6 +5,7 @@ use notedeck::{
tr, Localization, NoteZapTargetOwned, ReplacementType, ReportTarget, RootNoteIdBuf, Router,
ScopedSubApi, WalletType,
};
+use std::collections::HashSet;
use std::ops::Range;
use crate::{
@@ -803,6 +804,8 @@ pub fn cleanup_popped_route(
view_state: &mut ViewState,
ndb: &mut Ndb,
scoped_subs: &mut ScopedSubApi,
+ loaded_timeline_loads: &mut HashSet<TimelineKind>,
+ inflight_timeline_loads: &mut HashSet<TimelineKind>,
return_type: ReturnType,
col_index: usize,
) {
@@ -811,6 +814,10 @@ pub fn cleanup_popped_route(
if let Err(err) = timeline_cache.pop(kind, ndb, scoped_subs) {
tracing::error!("popping timeline had an error: {err} for {:?}", kind);
}
+ // Allow the async loader to re-populate this timeline if
+ // it is opened again later.
+ loaded_timeline_loads.remove(kind);
+ inflight_timeline_loads.remove(kind);
}
Route::Thread(selection) => {
threads.close(ndb, scoped_subs, selection, return_type, col_index);
diff --git a/crates/notedeck_columns/src/toolbar.rs b/crates/notedeck_columns/src/toolbar.rs
@@ -104,6 +104,8 @@ fn pop_to_root(app: &mut Damus, ctx: &mut AppContext, col_index: usize) {
&mut app.view_state,
ctx.ndb,
&mut ctx.remote.scoped_subs(ctx.accounts),
+ &mut app.loaded_timeline_loads,
+ &mut app.inflight_timeline_loads,
ReturnType::Click,
col_index,
);