notedeck

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

commit 929c5c8b3355b33b8621f10d202f13b3445a80a6
parent e831539d23abb198139631cdb1a95b98a276f510
Author: kernelkind <kernelkind@gmail.com>
Date:   Thu, 26 Feb 2026 14:07:28 -0500

refactor: move legacy RelayPool usage exclusively to dave

Signed-off-by: kernelkind <kernelkind@gmail.com>

Diffstat:
Mcrates/notedeck/src/app.rs | 26++------------------------
Mcrates/notedeck/src/context.rs | 3+--
Mcrates/notedeck/src/note/mod.rs | 3+--
Mcrates/notedeck_clndash/src/ui.rs | 1-
Mcrates/notedeck_columns/src/nav.rs | 1-
Mcrates/notedeck_columns/src/ui/note/post.rs | 1-
Mcrates/notedeck_dave/src/events.rs | 35++++++++++++++++++++---------------
Mcrates/notedeck_dave/src/lib.rs | 18+++++++++++-------
Mcrates/notedeck_dave/src/ui/dave.rs | 1-
9 files changed, 35 insertions(+), 54 deletions(-)

diff --git a/crates/notedeck/src/app.rs b/crates/notedeck/src/app.rs @@ -7,7 +7,7 @@ use crate::wallet::GlobalWallet; use crate::zaps::Zaps; use crate::{ frame_history::FrameHistory, AccountStorage, Accounts, AppContext, Args, DataPath, - DataPathType, Directory, Images, NoteAction, NoteCache, RelayDebugView, UnknownIds, + DataPathType, Directory, Images, NoteAction, NoteCache, UnknownIds, }; use crate::{EguiWakeup, Error, JobCache, RemoteApi}; use crate::{JobPool, MediaJobs}; @@ -15,7 +15,7 @@ use crate::{NotedeckOptions, ScopedSubsState}; use egui::Margin; use egui::ThemePreference; use egui_winit::clipboard::Clipboard; -use enostr::{OutboxPool, OutboxSession, OutboxSessionHandler, RelayPool}; +use enostr::{OutboxPool, OutboxSession, OutboxSessionHandler}; use nostrdb::{Config, Ndb, Transaction}; use std::cell::RefCell; use std::collections::BTreeSet; @@ -65,7 +65,6 @@ pub struct Notedeck { ndb: Ndb, img_cache: Images, unknown_ids: UnknownIds, - legacy_pool: RelayPool, pool: OutboxPool, scoped_sub_state: ScopedSubsState, note_cache: NoteCache, @@ -180,16 +179,6 @@ impl eframe::App for Notedeck { }); self.app_size.try_save_app_size(ctx); - if self.args.options.contains(NotedeckOptions::RelayDebug) { - if self.legacy_pool.debug.is_none() { - self.legacy_pool.use_debug(); - } - - if let Some(debug) = &mut self.legacy_pool.debug { - RelayDebugView::window(ctx, debug); - } - } - #[cfg(feature = "puffin")] puffin_egui::profiler_window(ctx); } @@ -262,15 +251,6 @@ impl Notedeck { None }; - // AccountManager will setup the pool on first update - let mut legacy_pool = RelayPool::new(); - { - let ctx = ctx.clone(); - if let Err(err) = legacy_pool.add_multicast_relay(move || ctx.request_repaint()) { - error!("error setting up multicast relay: {err}"); - } - } - let mut unknown_ids = UnknownIds::default(); try_swap_compacted_db(&dbpath_str); let mut ndb = Ndb::new(&dbpath_str, &config).expect("ndb"); @@ -350,7 +330,6 @@ impl Notedeck { ndb, img_cache, unknown_ids, - legacy_pool, pool, scoped_sub_state, note_cache, @@ -426,7 +405,6 @@ impl Notedeck { ndb: &mut self.ndb, img_cache: &mut self.img_cache, unknown_ids: &mut self.unknown_ids, - legacy_pool: &mut self.legacy_pool, remote: RemoteApi::new(outbox, &mut self.scoped_sub_state), note_cache: &mut self.note_cache, accounts: &mut self.accounts, diff --git a/crates/notedeck/src/context.rs b/crates/notedeck/src/context.rs @@ -4,8 +4,8 @@ use crate::{ MediaJobs, NoteCache, RemoteApi, SettingsHandler, UnknownIds, }; use egui_winit::clipboard::Clipboard; +use enostr::Pubkey; -use enostr::{Pubkey, RelayPool}; use nostrdb::{Ndb, Transaction}; #[cfg(target_os = "android")] @@ -17,7 +17,6 @@ pub struct AppContext<'a> { pub ndb: &'a mut Ndb, pub img_cache: &'a mut Images, pub unknown_ids: &'a mut UnknownIds, - pub legacy_pool: &'a mut RelayPool, /// Relay/outbox transport APIs (scoped subs, oneshot, publish, relay inspect). pub remote: RemoteApi<'a>, pub note_cache: &'a mut NoteCache, diff --git a/crates/notedeck/src/note/mod.rs b/crates/notedeck/src/note/mod.rs @@ -16,7 +16,7 @@ use crate::GlobalWallet; use crate::Localization; use crate::UnknownIds; use crate::{notecache::NoteCache, zaps::Zaps, Images}; -use enostr::{NoteId, RelayPool}; +use enostr::NoteId; use nostrdb::{Ndb, Note, NoteKey, QueryResult, Transaction}; use std::borrow::Borrow; use std::cmp::Ordering; @@ -32,7 +32,6 @@ pub struct NoteContext<'d> { pub img_cache: &'d mut Images, pub note_cache: &'d mut NoteCache, pub zaps: &'d mut Zaps, - pub pool: &'d mut RelayPool, pub jobs: &'d MediaJobSender, pub unknown_ids: &'d mut UnknownIds, pub nip05_cache: &'d mut Nip05Cache, diff --git a/crates/notedeck_clndash/src/ui.rs b/crates/notedeck_clndash/src/ui.rs @@ -48,7 +48,6 @@ pub fn note_hover_ui( img_cache: ctx.img_cache, note_cache: ctx.note_cache, zaps: ctx.zaps, - pool: ctx.legacy_pool, jobs: ctx.media_jobs.sender(), unknown_ids: ctx.unknown_ids, nip05_cache: ctx.nip05_cache, diff --git a/crates/notedeck_columns/src/nav.rs b/crates/notedeck_columns/src/nav.rs @@ -651,7 +651,6 @@ fn render_nav_body( img_cache: ctx.img_cache, note_cache: ctx.note_cache, zaps: ctx.zaps, - pool: ctx.legacy_pool, jobs: ctx.media_jobs.sender(), unknown_ids: ctx.unknown_ids, nip05_cache: ctx.nip05_cache, diff --git a/crates/notedeck_columns/src/ui/note/post.rs b/crates/notedeck_columns/src/ui/note/post.rs @@ -900,7 +900,6 @@ mod preview { img_cache: app.img_cache, note_cache: app.note_cache, zaps: app.zaps, - pool: app.legacy_pool, jobs: app.media_jobs.sender(), unknown_ids: app.unknown_ids, nip05_cache: app.nip05_cache, diff --git a/crates/notedeck_dave/src/events.rs b/crates/notedeck_dave/src/events.rs @@ -1,23 +1,24 @@ -use enostr::{PoolEventBuf, PoolRelay, RelayEvent, RelayMessage}; +use enostr::{PoolEventBuf, PoolRelay, RelayEvent, RelayMessage, RelayPool}; use notedeck::{AppContext, UnknownIds}; use tracing::{error, info}; pub fn try_process_events_core( app_ctx: &mut AppContext<'_>, + pool: &mut enostr::RelayPool, ctx: &egui::Context, - mut receive: impl FnMut(&mut AppContext, PoolEventBuf), + mut receive: impl FnMut(&mut AppContext, &mut RelayPool, PoolEventBuf), ) { let ctx2 = ctx.clone(); let wakeup = move || { ctx2.request_repaint(); }; - app_ctx.legacy_pool.keepalive_ping(wakeup); + pool.keepalive_ping(wakeup); // NOTE: we don't use the while let loop due to borrow issues #[allow(clippy::while_let_loop)] loop { - let ev = if let Some(ev) = app_ctx.legacy_pool.try_recv() { + let ev = if let Some(ev) = pool.try_recv() { ev.into_owned() } else { break; @@ -33,28 +34,32 @@ pub fn try_process_events_core( } RelayEvent::Error(error) => error!("relay {} had error: {error:?}", &ev.relay), RelayEvent::Message(msg) => { - process_message_core(app_ctx, &ev.relay, &msg); + process_message_core(app_ctx, pool, &ev.relay, &msg); } } - receive(app_ctx, ev); + receive(app_ctx, pool, ev); } if app_ctx.unknown_ids.ready_to_send() { - pool_unknown_id_send(app_ctx.unknown_ids, app_ctx.legacy_pool); + pool_unknown_id_send(app_ctx.unknown_ids, pool); } } -fn process_message_core(ctx: &mut AppContext<'_>, relay: &str, msg: &RelayMessage) { +fn process_message_core( + ctx: &mut AppContext<'_>, + pool: &mut enostr::RelayPool, + relay: &str, + msg: &RelayMessage, +) { match msg { RelayMessage::Event(_subid, ev) => { - let relay = - if let Some(relay) = ctx.legacy_pool.relays.iter().find(|r| r.url() == relay) { - relay - } else { - error!("couldn't find relay {} for note processing!?", relay); - return; - }; + let relay = if let Some(relay) = pool.relays.iter().find(|r| r.url() == relay) { + relay + } else { + error!("couldn't find relay {} for note processing!?", relay); + return; + }; match relay { PoolRelay::Websocket(_) => { diff --git a/crates/notedeck_dave/src/lib.rs b/crates/notedeck_dave/src/lib.rs @@ -31,7 +31,7 @@ use backend::{ }; use chrono::{Duration, Local}; use egui_wgpu::RenderState; -use enostr::KeypairUnowned; +use enostr::{KeypairUnowned, RelayPool}; use focus_queue::FocusQueue; use nostrdb::{Subscription, Transaction}; use notedeck::{ @@ -120,6 +120,7 @@ pub enum DaveOverlay { } pub struct Dave { + pool: RelayPool, /// AI interaction mode (Chat vs Agentic) ai_mode: AiMode, /// Manages multiple chat sessions @@ -473,7 +474,10 @@ You are an AI agent for the nostr protocol called Dave, created by Damus. nostr AiMode::Agentic => (SessionManager::new(), DaveOverlay::DirectoryPicker), }; + let pool = RelayPool::new(); + Dave { + pool, ai_mode, backends, available_backends, @@ -2494,7 +2498,7 @@ You are an AI agent for the nostr protocol called Dave, created by Damus. nostr let pns_sub_id = self.pns_relay_sub.clone(); let pns_relay = self.pns_relay_url.clone(); let mut neg_events: Vec<enostr::negentropy::NegEvent> = Vec::new(); - try_process_events_core(ctx, ui.ctx(), |app_ctx, ev| { + try_process_events_core(ctx, &mut self.pool, ui.ctx(), |app_ctx, pool, ev| { if ev.relay == pns_relay { if let enostr::RelayEvent::Opened = (&ev.event).into() { neg_events.push(enostr::negentropy::NegEvent::RelayOpened); @@ -2509,7 +2513,7 @@ You are an AI agent for the nostr protocol called Dave, created by Damus. nostr .limit(500) .build(); let req = enostr::ClientMessage::req(sub_id.clone(), vec![pns_filter]); - app_ctx.legacy_pool.send_to(&req, &pns_relay); + pool.send_to(&req, &pns_relay); tracing::info!("re-subscribed for PNS events after relay reconnect"); } } @@ -2538,7 +2542,7 @@ You are an AI agent for the nostr protocol called Dave, created by Damus. nostr let result = self.neg_sync.process( neg_events, ctx.ndb, - ctx.legacy_pool, + &mut self.pool, &filter, &self.pns_relay_url, ); @@ -2593,7 +2597,7 @@ You are an AI agent for the nostr protocol called Dave, created by Damus. nostr // Ensure the PNS relay is in the pool let egui_ctx = ui.ctx().clone(); let wakeup = move || egui_ctx.request_repaint(); - if let Err(e) = ctx.legacy_pool.add_url(self.pns_relay_url.clone(), wakeup) { + if let Err(e) = self.pool.add_url(self.pns_relay_url.clone(), wakeup) { tracing::warn!("failed to add PNS relay {}: {:?}", self.pns_relay_url, e); } @@ -2605,7 +2609,7 @@ You are an AI agent for the nostr protocol called Dave, created by Damus. nostr .build(); let sub_id = uuid::Uuid::new_v4().to_string(); let req = enostr::ClientMessage::req(sub_id.clone(), vec![pns_filter]); - ctx.legacy_pool.send_to(&req, &self.pns_relay_url); + self.pool.send_to(&req, &self.pns_relay_url); self.pns_relay_sub = Some(sub_id); tracing::info!("subscribed for PNS events on {}", self.pns_relay_url); @@ -2754,7 +2758,7 @@ impl notedeck::App for Dave { for event in all_events { match session_events::wrap_pns(&event.note_json, &pns_keys) { Ok(pns_json) => match enostr::ClientMessage::event_json(pns_json) { - Ok(msg) => ctx.legacy_pool.send_to(&msg, &self.pns_relay_url), + Ok(msg) => self.pool.send_to(&msg, &self.pns_relay_url), Err(e) => tracing::warn!("failed to build relay message: {:?}", e), }, Err(e) => tracing::warn!("failed to PNS-wrap event: {}", e), diff --git a/crates/notedeck_dave/src/ui/dave.rs b/crates/notedeck_dave/src/ui/dave.rs @@ -1142,7 +1142,6 @@ impl<'a> DaveUi<'a> { img_cache: ctx.img_cache, note_cache: ctx.note_cache, zaps: ctx.zaps, - pool: ctx.legacy_pool, jobs: ctx.media_jobs.sender(), unknown_ids: ctx.unknown_ids, nip05_cache: ctx.nip05_cache,