notedeck

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

commit adc74dd7c91ca884d6cdae390fb72666df7e4d64
parent d7607c82974fc5b1a1afc4a818095e818d2152dc
Author: William Casarin <jb55@jb55.com>
Date:   Sat, 10 Feb 2024 14:46:17 -0800

home: move subscriptions to timeline

Diffstat:
MCargo.lock | 11-----------
MCargo.toml | 3+--
Msrc/app.rs | 76++++++++++++++++++++++++++++++++++++++++++++++++----------------------------
Msrc/error.rs | 24++++++++++++++++--------
4 files changed, 65 insertions(+), 49 deletions(-)

diff --git a/Cargo.lock b/Cargo.lock @@ -876,7 +876,6 @@ dependencies = [ "serde", "serde_derive", "serde_json", - "shatter", "tokio", "tracing", "tracing-subscriber", @@ -978,7 +977,6 @@ dependencies = [ "objc", "parking_lot", "percent-encoding", - "pollster", "puffin", "raw-window-handle 0.5.2", "raw-window-handle 0.6.0", @@ -988,7 +986,6 @@ dependencies = [ "wasm-bindgen-futures", "web-sys", "web-time", - "wgpu", "winapi", "winit", ] @@ -2667,12 +2664,6 @@ dependencies = [ ] [[package]] -name = "pollster" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22686f4785f02a4fcc856d3b3bb19bf6c8160d103f7a99cc258bddd0251dc7f2" - -[[package]] name = "powerfmt" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -4268,7 +4259,6 @@ dependencies = [ "cfg_aliases", "js-sys", "log", - "naga", "parking_lot", "profiling", "raw-window-handle 0.6.0", @@ -4318,7 +4308,6 @@ dependencies = [ "arrayvec", "ash", "bitflags 2.4.2", - "block", "cfg_aliases", "core-graphics-types", "glow", diff --git a/Cargo.toml b/Cargo.toml @@ -13,7 +13,7 @@ crate-type = ["lib", "cdylib"] [dependencies] #egui-android = { git = "https://github.com/jb55/egui-android.git" } egui = "0.26.0" -eframe = { version = "0.26.0", default-features = false, features = [ "glow", "wgpu", "android-native-activity" ] } +eframe = { version = "0.26.0", default-features = false, features = [ "glow", "android-native-activity" ] } #eframe = "0.22.0" egui_extras = { version = "0.26.0", features = ["image", "svg"] } ehttp = "0.2.0" @@ -27,7 +27,6 @@ tracing = "0.1.40" enostr = { path = "enostr" } serde_json = "1.0.89" env_logger = "0.10.0" -shatter = "0.1.1" puffin_egui = { version = "0.25.0", optional = true } puffin = { version = "0.19.0", optional = true } nostrdb = { git = "https://github.com/damus-io/nostrdb-rs", rev = "e513b6ed516a9adf757c1f7ac26cd3d544c391b2" } diff --git a/src/app.rs b/src/app.rs @@ -1,5 +1,6 @@ use crate::abbrev; use crate::contacts::Contacts; +use crate::error::Error; use crate::fonts::{setup_fonts, setup_gossip_fonts}; use crate::frame_history::FrameHistory; use crate::images::fetch_img; @@ -71,14 +72,19 @@ impl Ord for NoteRef { struct Timeline { pub notes: Vec<NoteRef>, + pub subscription: Option<Subscription>, } impl Timeline { pub fn new() -> Self { let mut notes: Vec<NoteRef> = vec![]; notes.reserve(1000); + let subscription: Option<Subscription> = None; - Timeline { notes } + Timeline { + notes, + subscription, + } } } @@ -90,7 +96,6 @@ pub struct Damus { compose: String, pool: RelayPool, - home_sub: Option<Subscription>, timelines: Vec<Timeline>, @@ -174,34 +179,50 @@ fn try_process_event(damus: &mut Damus, ctx: &egui::Context) { } } - // do we have any new processed events? - if let Some(ref sub) = damus.home_sub { - let new_note_ids = damus.ndb.poll_for_notes(sub, 100); - if new_note_ids.len() > 0 { - info!("{} new notes! {:?}", new_note_ids.len(), new_note_ids); + for timeline in 0..damus.timelines.len() { + if let Err(err) = poll_notes_for_timeline(damus, timeline) { + error!("{}", err); } + } +} - if let Ok(txn) = Transaction::new(&damus.ndb) { - let new_refs = new_note_ids - .iter() - .map(|key| { - let note = damus - .ndb - .get_note_by_key(&txn, NoteKey::new(*key)) - .expect("no note??"); - NoteRef { - key: NoteKey::new(*key), - created_at: note.created_at(), - } - }) - .collect(); +fn poll_notes_for_timeline(damus: &mut Damus, timeline: usize) -> Result<()> { + let sub = if let Some(sub) = &damus.timelines[timeline].subscription { + sub + } else { + return Err(Error::NoActiveSubscription); + }; - damus.timelines[0].notes = - timeline::merge_sorted_vecs(&damus.timelines[0].notes, &new_refs); - } else { - error!("Transaction error when polling") - } + let new_note_ids = damus.ndb.poll_for_notes(&sub, 100); + if new_note_ids.len() > 0 { + info!("{} new notes! {:?}", new_note_ids.len(), new_note_ids); } + + let txn = Transaction::new(&damus.ndb)?; + + let mut pubkeys: HashSet<&[u8; 32]> = HashSet::new(); + + let new_refs = new_note_ids + .iter() + .map(|key| { + let note = damus + .ndb + .get_note_by_key(&txn, NoteKey::new(*key)) + .expect("no note??"); + + pubkeys.insert(note.pubkey()); + + NoteRef { + key: NoteKey::new(*key), + created_at: note.created_at(), + } + }) + .collect(); + + damus.timelines[timeline].notes = + timeline::merge_sorted_vecs(&damus.timelines[timeline].notes, &new_refs); + + Ok(()) } #[cfg(feature = "profiling")] @@ -212,7 +233,7 @@ fn setup_profiling() { fn setup_initial_nostrdb_subs(damus: &mut Damus) -> Result<()> { let filter: nostrdb::Filter = crate::filter::convert_enostr_filter(&get_home_filter()); let filters = vec![filter]; - damus.home_sub = Some(damus.ndb.subscribe(filters.clone())?); + damus.timelines[0].subscription = Some(damus.ndb.subscribe(filters.clone())?); let txn = Transaction::new(&damus.ndb)?; let res = damus.ndb.query(&txn, filters, 100)?; damus.timelines[0].notes = res @@ -353,7 +374,6 @@ impl Damus { state: DamusState::Initializing, contacts: Contacts::new(), pool: RelayPool::new(), - home_sub: None, img_cache: HashMap::new(), n_panels: 1, timelines: vec![Timeline::new()], diff --git a/src/error.rs b/src/error.rs @@ -1,23 +1,31 @@ -use shatter::parser; +use std::fmt; #[derive(Debug)] pub enum Error { + NoActiveSubscription, Nostr(enostr::Error), Ndb(nostrdb::Error), - Shatter(parser::Error), Image(image::error::ImageError), Generic(String), } -impl From<String> for Error { - fn from(s: String) -> Self { - Error::Generic(s) +impl fmt::Display for Error { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + Self::NoActiveSubscription => { + write!(f, "subscription not active in timeline") + } + Self::Nostr(e) => write!(f, "{e}"), + Self::Ndb(e) => write!(f, "{e}"), + Self::Image(e) => write!(f, "{e}"), + Self::Generic(e) => write!(f, "{e}"), + } } } -impl From<parser::Error> for Error { - fn from(s: parser::Error) -> Self { - Error::Shatter(s) +impl From<String> for Error { + fn from(s: String) -> Self { + Error::Generic(s) } }