commit 99405378972e9e3c6f42cb9f3278cbe301650118
parent 497c102af123e7f7c2230d42758a46dd99fdf2ff
Author: kernelkind <kernelkind@gmail.com>
Date: Mon, 7 Jul 2025 17:53:13 -0400
Unify sub for contacts in accounts & timeline
Signed-off-by: kernelkind <kernelkind@gmail.com>
Diffstat:
4 files changed, 62 insertions(+), 68 deletions(-)
diff --git a/crates/notedeck_columns/src/app.rs b/crates/notedeck_columns/src/app.rs
@@ -8,14 +8,16 @@ use crate::{
storage,
subscriptions::{SubKind, Subscriptions},
support::Support,
- timeline::{self, thread::Threads, TimelineCache},
+ timeline::{
+ self, fetch_contact_list, kind::ListKind, thread::Threads, TimelineCache, TimelineKind,
+ },
ui::{self, DesktopSidePanel},
view_state::ViewState,
Result,
};
use notedeck::{
- ui::is_narrow, Accounts, AppAction, AppContext, DataPath, DataPathType, FilterState, UnknownIds,
+ ui::is_narrow, Accounts, AppAction, AppContext, DataPath, DataPathType, UnknownIds,
};
use notedeck_ui::{jobs::JobsCache, NoteOptions};
@@ -116,13 +118,21 @@ fn try_process_event(
.accounts
.send_initial_filters(app_ctx.pool, &ev.relay);
+ let data = app_ctx.accounts.get_subs();
+ damus.subscriptions.subs.insert(
+ data.contacts.remote.clone(),
+ SubKind::FetchingContactList(TimelineKind::List(ListKind::Contact(
+ *app_ctx.accounts.selected_account_pubkey(),
+ ))),
+ );
+
timeline::send_initial_timeline_filters(
- app_ctx.ndb,
damus.since_optimize,
&mut damus.timeline_cache,
&mut damus.subscriptions,
app_ctx.pool,
&ev.relay,
+ app_ctx.accounts,
);
}
// TODO: handle reconnects
@@ -248,44 +258,11 @@ fn handle_eose(
}
SubKind::FetchingContactList(timeline_uid) => {
- let timeline = if let Some(tl) = timeline_cache.timelines.get_mut(timeline_uid) {
- tl
- } else {
- error!(
- "timeline uid:{} not found for FetchingContactList",
- timeline_uid
- );
+ let Some(timeline) = timeline_cache.timelines.get_mut(timeline_uid) else {
return Ok(());
};
- let filter_state = timeline.filter.get_mut(relay_url);
-
- // If this request was fetching a contact list, our filter
- // state should be "FetchingRemote". We look at the local
- // subscription for that filter state and get the subscription id
- let local_sub = if let FilterState::FetchingRemote(unisub) = filter_state {
- unisub.local
- } else {
- // TODO: we could have multiple contact list results, we need
- // to check to see if this one is newer and use that instead
- warn!(
- "Expected timeline to have FetchingRemote state but was {:?}",
- timeline.filter
- );
- return Ok(());
- };
-
- info!(
- "got contact list from {}, updating filter_state to got_remote",
- relay_url
- );
-
- // We take the subscription id and pass it to the new state of
- // "GotRemote". This will let future frames know that it can try
- // to look for the contact list in nostrdb.
- timeline
- .filter
- .set_relay_state(relay_url.to_string(), FilterState::got_remote(local_sub));
+ fetch_contact_list(relay_url, timeline, ctx.accounts);
}
}
@@ -704,7 +681,13 @@ fn timelines_view(
let mut save_cols = false;
if let Some(action) = side_panel_action {
save_cols = save_cols
- || action.process(&mut app.timeline_cache, &mut app.decks_cache, ctx, ui.ctx());
+ || action.process(
+ &mut app.timeline_cache,
+ &mut app.decks_cache,
+ &mut app.subscriptions,
+ ctx,
+ ui.ctx(),
+ );
}
let mut app_action: Option<AppAction> = None;
diff --git a/crates/notedeck_columns/src/nav.rs b/crates/notedeck_columns/src/nav.rs
@@ -7,9 +7,11 @@ use crate::{
profile::{ProfileAction, SaveProfileChanges},
profile_state::ProfileState,
route::{Route, Router, SingletonRouter},
+ subscriptions::{SubKind, Subscriptions},
timeline::{
+ kind::ListKind,
route::{render_thread_route, render_timeline_route},
- TimelineCache,
+ TimelineCache, TimelineKind,
},
ui::{
self,
@@ -72,6 +74,7 @@ impl SwitchingAction {
&self,
timeline_cache: &mut TimelineCache,
decks_cache: &mut DecksCache,
+ subs: &mut Subscriptions,
ctx: &mut AppContext<'_>,
ui_ctx: &egui::Context,
) -> bool {
@@ -86,6 +89,16 @@ impl SwitchingAction {
ctx.pool,
ui_ctx,
);
+
+ let new_subs = ctx.accounts.get_subs();
+
+ subs.subs.insert(
+ new_subs.contacts.remote.clone(),
+ SubKind::FetchingContactList(TimelineKind::List(ListKind::Contact(
+ *ctx.accounts.selected_account_pubkey(),
+ ))),
+ );
+
// pop nav after switch
get_active_columns_mut(ctx.accounts, decks_cache)
.column_mut(switch_action.source_column)
@@ -380,6 +393,7 @@ fn process_render_nav_action(
if switching_action.process(
&mut app.timeline_cache,
&mut app.decks_cache,
+ &mut app.subscriptions,
ctx,
ui.ctx(),
) {
diff --git a/crates/notedeck_columns/src/timeline/mod.rs b/crates/notedeck_columns/src/timeline/mod.rs
@@ -7,7 +7,8 @@ use crate::{
};
use notedeck::{
- filter, CachedNote, FilterError, FilterState, FilterStates, NoteCache, NoteRef, UnknownIds,
+ filter, Accounts, CachedNote, FilterError, FilterState, FilterStates, NoteCache, NoteRef,
+ UnknownIds,
};
use egui_virtual_list::VirtualList;
@@ -474,6 +475,7 @@ pub fn setup_new_timeline(
pool: &mut RelayPool,
note_cache: &mut NoteCache,
since_optimize: bool,
+ accounts: &Accounts,
) {
// if we're ready, setup local subs
if is_timeline_ready(ndb, pool, note_cache, timeline) {
@@ -483,7 +485,7 @@ pub fn setup_new_timeline(
}
for relay in &mut pool.relays {
- send_initial_timeline_filter(ndb, since_optimize, subs, relay, timeline);
+ send_initial_timeline_filter(since_optimize, subs, relay, timeline, accounts);
}
}
@@ -492,29 +494,29 @@ pub fn setup_new_timeline(
/// situations where you are adding a new timeline, use
/// setup_new_timeline.
pub fn send_initial_timeline_filters(
- ndb: &Ndb,
since_optimize: bool,
timeline_cache: &mut TimelineCache,
subs: &mut Subscriptions,
pool: &mut RelayPool,
relay_id: &str,
+ accounts: &Accounts,
) -> Option<()> {
info!("Sending initial filters to {}", relay_id);
let relay = &mut pool.relays.iter_mut().find(|r| r.url() == relay_id)?;
for (_kind, timeline) in timeline_cache.timelines.iter_mut() {
- send_initial_timeline_filter(ndb, since_optimize, subs, relay, timeline);
+ send_initial_timeline_filter(since_optimize, subs, relay, timeline, accounts);
}
Some(())
}
pub fn send_initial_timeline_filter(
- ndb: &Ndb,
can_since_optimize: bool,
subs: &mut Subscriptions,
relay: &mut PoolRelay,
timeline: &mut Timeline,
+ accounts: &Accounts,
) {
let filter_state = timeline.filter.get_mut(relay.url());
@@ -572,34 +574,27 @@ pub fn send_initial_timeline_filter(
}
// we need some data first
- FilterState::NeedsRemote(filter) => {
- fetch_contact_list(filter.to_owned(), ndb, subs, relay, timeline)
- }
+ FilterState::NeedsRemote(_filter) => fetch_contact_list(relay.url(), timeline, accounts),
}
}
-fn fetch_contact_list(
- filter: Vec<Filter>,
- ndb: &Ndb,
- subs: &mut Subscriptions,
- relay: &mut PoolRelay,
- timeline: &mut Timeline,
-) {
- let sub_kind = SubKind::FetchingContactList(timeline.kind.clone());
- let sub_id = subscriptions::new_sub_id();
- let local_sub = ndb.subscribe(&filter).expect("sub");
-
- timeline.filter.set_relay_state(
- relay.url().to_string(),
- FilterState::fetching_remote(sub_id.clone(), local_sub),
- );
+pub fn fetch_contact_list(relay_url: &str, timeline: &mut Timeline, accounts: &Accounts) {
+ let account_subs = accounts.get_subs();
+ let local = account_subs.contacts.local;
- subs.subs.insert(sub_id.clone(), sub_kind);
+ let filter_state = match accounts.get_selected_account().data.contacts.get_state() {
+ notedeck::ContactState::Unreceived => {
+ FilterState::fetching_remote(account_subs.contacts.remote.clone(), local)
+ }
+ notedeck::ContactState::Received {
+ contacts: _,
+ note_key: _,
+ } => FilterState::GotRemote(local),
+ };
- info!("fetching contact list from {}", relay.url());
- if let Err(err) = relay.subscribe(sub_id, filter) {
- error!("error subscribing: {err}");
- }
+ timeline
+ .filter
+ .set_relay_state(relay_url.to_owned(), filter_state);
}
fn setup_initial_timeline(
diff --git a/crates/notedeck_columns/src/ui/add_column.rs b/crates/notedeck_columns/src/ui/add_column.rs
@@ -626,6 +626,7 @@ pub fn render_add_column_routes(
ctx.pool,
ctx.note_cache,
app.since_optimize,
+ ctx.accounts,
);
app.columns_mut(ctx.accounts)
@@ -667,6 +668,7 @@ pub fn render_add_column_routes(
ctx.pool,
ctx.note_cache,
app.since_optimize,
+ ctx.accounts,
);
app.columns_mut(ctx.accounts)