notedeck

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

commit 8adf22a7e978b5a9f4438391aa16dee7d223b99c
parent e9d25140d37b7ce7bb1c269bec07e1e3fe9d74c6
Author: kernelkind <kernelkind@gmail.com>
Date:   Tue, 24 Feb 2026 17:40:45 -0500

feat(outbox-int): integration outbox ingestion

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

Diffstat:
Mcrates/notedeck/src/app.rs | 61+++++++++++++++++++++++++++++++++++++++++++------------------
Mcrates/notedeck/src/context.rs | 4+++-
Mcrates/notedeck_chrome/src/chrome.rs | 2+-
Mcrates/notedeck_chrome/src/notedeck.rs | 11+++++++----
4 files changed, 54 insertions(+), 24 deletions(-)

diff --git a/crates/notedeck/src/app.rs b/crates/notedeck/src/app.rs @@ -9,13 +9,16 @@ use crate::{ frame_history::FrameHistory, AccountStorage, Accounts, AppContext, Args, DataPath, DataPathType, Directory, Images, NoteAction, NoteCache, RelayDebugView, UnknownIds, }; -use crate::{Error, JobCache}; +use crate::{EguiWakeup, Error, JobCache, RemoteApi}; use crate::{JobPool, MediaJobs}; use crate::{NotedeckOptions, ScopedSubsState}; use egui::Margin; use egui::ThemePreference; use egui_winit::clipboard::Clipboard; -use enostr::{OutboxPool, PoolEventBuf, PoolRelay, RelayEvent, RelayMessage, RelayPool}; +use enostr::{ + OutboxPool, OutboxSession, OutboxSessionHandler, PoolEventBuf, PoolRelay, RelayEvent, + RelayMessage, RelayPool, +}; use nostrdb::{Config, Ndb, Transaction}; use std::cell::RefCell; use std::collections::BTreeSet; @@ -98,15 +101,14 @@ fn main_panel(style: &egui::Style) -> egui::CentralPanel { }) } -fn render_notedeck(notedeck: &mut Notedeck, ctx: &egui::Context) { +#[profiling::function] +fn render_notedeck( + app: Rc<RefCell<dyn App + 'static>>, + app_ctx: &mut AppContext, + ctx: &egui::Context, +) { main_panel(&ctx.style()).show(ctx, |ui| { - // render app - let Some(app) = &notedeck.app else { - return; - }; - - let app = app.clone(); - app.borrow_mut().update(&mut notedeck.app_context(), ui); + app.borrow_mut().update(app_ctx, ui); // Move the screen up when we have a virtual keyboard // NOTE: actually, we only want to do this if the keyboard is covering the focused element? @@ -140,15 +142,27 @@ impl eframe::App for Notedeck { } self.nip05_cache.poll(); + let Some(app) = &self.app else { + return; + }; + let app = app.clone(); + let mut app_ctx = self.app_context(ctx); // handle account updates - self.accounts - .update(&mut self.ndb, &mut self.legacy_pool, ctx); + app_ctx + .accounts + .update(app_ctx.ndb, app_ctx.legacy_pool, ctx); - self.zaps - .process(&mut self.accounts, &mut self.global_wallet, &self.ndb); + app_ctx + .zaps + .process(app_ctx.accounts, app_ctx.global_wallet, app_ctx.ndb); - render_notedeck(self, ctx); + render_notedeck(app, &mut app_ctx, ctx); + + { + profiling::scope!("outbox ingestion"); + drop(app_ctx); + } self.settings.update_batch(|settings| { settings.zoom_factor = ctx.zoom_factor(); @@ -379,17 +393,28 @@ impl Notedeck { self } - pub fn app_context(&mut self) -> AppContext<'_> { - self.notedeck_ref().app_ctx + pub fn app_context(&mut self, ui_ctx: &egui::Context) -> AppContext<'_> { + self.notedeck_ref(ui_ctx, None).app_ctx } - pub fn notedeck_ref<'a>(&'a mut self) -> NotedeckRef<'a> { + pub fn notedeck_ref<'a>( + &'a mut self, + ui_ctx: &egui::Context, + session: Option<OutboxSession>, + ) -> NotedeckRef<'a> { + let outbox = if let Some(session) = session { + OutboxSessionHandler::import(&mut self.pool, session, EguiWakeup::new(ui_ctx.clone())) + } else { + OutboxSessionHandler::new(&mut self.pool, EguiWakeup::new(ui_ctx.clone())) + }; + NotedeckRef { app_ctx: AppContext { 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, global_wallet: &mut self.global_wallet, diff --git a/crates/notedeck/src/context.rs b/crates/notedeck/src/context.rs @@ -1,7 +1,7 @@ use crate::{ account::accounts::Accounts, frame_history::FrameHistory, i18n::Localization, nip05::Nip05Cache, wallet::GlobalWallet, zaps::Zaps, Args, DataPath, Images, JobPool, - MediaJobs, NoteCache, SettingsHandler, UnknownIds, + MediaJobs, NoteCache, RemoteApi, SettingsHandler, UnknownIds, }; use egui_winit::clipboard::Clipboard; @@ -18,6 +18,8 @@ pub struct AppContext<'a> { 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, pub accounts: &'a mut Accounts, pub global_wallet: &'a mut GlobalWallet, diff --git a/crates/notedeck_chrome/src/chrome.rs b/crates/notedeck_chrome/src/chrome.rs @@ -154,7 +154,7 @@ impl Chrome { ) -> Result<Self, Error> { stop_debug_mode(notedeck.options()); - let notedeck_ref = &mut notedeck.notedeck_ref(); + let notedeck_ref = &mut notedeck.notedeck_ref(&cc.egui_ctx, None); let dave = Dave::new( cc.wgpu_render_state.as_ref(), notedeck_ref.app_ctx.ndb.clone(), diff --git a/crates/notedeck_chrome/src/notedeck.rs b/crates/notedeck_chrome/src/notedeck.rs @@ -185,7 +185,7 @@ mod tests { let ctx = egui::Context::default(); let mut notedeck = Notedeck::new(&ctx, &tmpdir, &args); - let mut app_ctx = notedeck.app_context(); + let mut app_ctx = notedeck.app_context(&ctx); let app = Damus::new(&mut app_ctx, &args); assert_eq!(app.columns(app_ctx.accounts).columns().len(), 2); @@ -234,13 +234,16 @@ mod tests { let ctx = egui::Context::default(); let mut notedeck = Notedeck::new(&ctx, &tmpdir, &args); - let mut app_ctx = notedeck.app_context(); - let app = Damus::new(&mut app_ctx, &args); + let unrecognized_args = { + let mut app_ctx = notedeck.app_context(&ctx); + let app = Damus::new(&mut app_ctx, &args); + app.unrecognized_args().clone() + }; // ensure we recognized all the arguments let completely_unrecognized: Vec<String> = notedeck .unrecognized_args() - .intersection(app.unrecognized_args()) + .intersection(&unrecognized_args) .cloned() .collect(); assert_eq!(completely_unrecognized, ["--unknown-arg"]);