notedeck

One damus client to rule them all
git clone git://jb55.com/notedeck
Log | Files | Refs | README | LICENSE

commit e8444f10b37cbd93f00469a76bec264ac2342768
parent 8752a49485a3fa18a78e5887f629c2e5510af0d7
Author: William Casarin <jb55@jb55.com>
Date:   Fri, 11 Jul 2025 13:49:47 -0700

Revert "Unify sub for contacts in accounts & timeline"

Since its causing contact timelines to not load

eg: ./target/release/notedeck --datapath new3 -c contacts

This reverts commit 99405378972e9e3c6f42cb9f3278cbe301650118.

Diffstat:
Mcrates/notedeck_columns/src/app.rs | 61+++++++++++++++++++++++++++++++++++++++----------------------
Mcrates/notedeck_columns/src/nav.rs | 16+---------------
Mcrates/notedeck_columns/src/timeline/mod.rs | 51++++++++++++++++++++++++++++-----------------------
Mcrates/notedeck_columns/src/ui/add_column.rs | 2--
4 files changed, 68 insertions(+), 62 deletions(-)

diff --git a/crates/notedeck_columns/src/app.rs b/crates/notedeck_columns/src/app.rs @@ -8,16 +8,14 @@ use crate::{ storage, subscriptions::{SubKind, Subscriptions}, support::Support, - timeline::{ - self, fetch_contact_list, kind::ListKind, thread::Threads, TimelineCache, TimelineKind, - }, + timeline::{self, kind::ListKind, thread::Threads, TimelineCache, TimelineKind}, ui::{self, DesktopSidePanel, SidePanelAction}, view_state::ViewState, Result, }; use notedeck::{ - ui::is_narrow, Accounts, AppAction, AppContext, DataPath, DataPathType, UnknownIds, + ui::is_narrow, Accounts, AppAction, AppContext, DataPath, DataPathType, FilterState, UnknownIds, }; use notedeck_ui::{jobs::JobsCache, NoteOptions}; @@ -118,21 +116,13 @@ 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 @@ -258,11 +248,44 @@ fn handle_eose( } SubKind::FetchingContactList(timeline_uid) => { - let Some(timeline) = timeline_cache.timelines.get_mut(timeline_uid) else { + let timeline = if let Some(tl) = timeline_cache.timelines.get_mut(timeline_uid) { + tl + } else { + error!( + "timeline uid:{} not found for FetchingContactList", + timeline_uid + ); + 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(()); }; - fetch_contact_list(relay_url, timeline, ctx.accounts); + 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)); } } @@ -724,13 +747,7 @@ 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, - &mut app.subscriptions, - ctx, - ui.ctx(), - ); + || action.process(&mut app.timeline_cache, &mut app.decks_cache, 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,11 +7,9 @@ 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, TimelineKind, + TimelineCache, }, ui::{ self, @@ -74,7 +72,6 @@ impl SwitchingAction { &self, timeline_cache: &mut TimelineCache, decks_cache: &mut DecksCache, - subs: &mut Subscriptions, ctx: &mut AppContext<'_>, ui_ctx: &egui::Context, ) -> bool { @@ -89,16 +86,6 @@ 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) @@ -393,7 +380,6 @@ 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,8 +7,7 @@ use crate::{ }; use notedeck::{ - filter, Accounts, CachedNote, FilterError, FilterState, FilterStates, NoteCache, NoteRef, - UnknownIds, + filter, CachedNote, FilterError, FilterState, FilterStates, NoteCache, NoteRef, UnknownIds, }; use egui_virtual_list::VirtualList; @@ -475,7 +474,6 @@ 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) { @@ -485,7 +483,7 @@ pub fn setup_new_timeline( } for relay in &mut pool.relays { - send_initial_timeline_filter(since_optimize, subs, relay, timeline, accounts); + send_initial_timeline_filter(ndb, since_optimize, subs, relay, timeline); } } @@ -494,29 +492,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(since_optimize, subs, relay, timeline, accounts); + send_initial_timeline_filter(ndb, since_optimize, subs, relay, timeline); } 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()); @@ -574,27 +572,34 @@ pub fn send_initial_timeline_filter( } // we need some data first - FilterState::NeedsRemote(_filter) => fetch_contact_list(relay.url(), timeline, accounts), + FilterState::NeedsRemote(filter) => { + fetch_contact_list(filter.to_owned(), ndb, subs, relay, timeline) + } } } -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; +pub 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), + ); - 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), - }; + subs.subs.insert(sub_id.clone(), sub_kind); - timeline - .filter - .set_relay_state(relay_url.to_owned(), filter_state); + info!("fetching contact list from {}", relay.url()); + if let Err(err) = relay.subscribe(sub_id, filter) { + error!("error subscribing: {err}"); + } } fn setup_initial_timeline( diff --git a/crates/notedeck_columns/src/ui/add_column.rs b/crates/notedeck_columns/src/ui/add_column.rs @@ -623,7 +623,6 @@ pub fn render_add_column_routes( ctx.pool, ctx.note_cache, app.since_optimize, - ctx.accounts, ); app.columns_mut(ctx.accounts) @@ -665,7 +664,6 @@ pub fn render_add_column_routes( ctx.pool, ctx.note_cache, app.since_optimize, - ctx.accounts, ); app.columns_mut(ctx.accounts)