notedeck

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

commit 6c951d1a2973884c0bd2ef89cb09780ff00ad318
parent e4beb954db534c7b07bfde466476fc9b01b51c4c
Author: kernelkind <kernelkind@gmail.com>
Date:   Thu,  3 Jul 2025 15:18:30 -0400

move polling responsibility to `AccountData`

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

Diffstat:
Mcrates/notedeck/src/account/accounts.rs | 91++++++++++++++++++++++++++++++++++++++++---------------------------------------
Mcrates/notedeck/src/account/mute.rs | 14+++++++++++++-
Mcrates/notedeck/src/account/relay.rs | 22++++++++++++++++++----
3 files changed, 77 insertions(+), 50 deletions(-)

diff --git a/crates/notedeck/src/account/accounts.rs b/crates/notedeck/src/account/accounts.rs @@ -1,4 +1,3 @@ -use tracing::debug; use uuid::Uuid; use crate::account::cache::AccountCache; @@ -263,51 +262,31 @@ impl Accounts { ); } - fn poll_for_updates(&mut self, ndb: &Ndb) -> bool { - let mut changed = false; - let relay_sub = self.subs.relay.local; - let mute_sub = self.subs.mute.local; - let acc = self.get_selected_account_mut(); - - let nks = ndb.poll_for_notes(relay_sub, 1); - if !nks.is_empty() { - let txn = Transaction::new(ndb).expect("txn"); - let relays = AccountRelayData::harvest_nip65_relays(ndb, &txn, &nks); - debug!( - "pubkey {}: updated relays {:?}", - acc.key.pubkey.hex(), - relays - ); - acc.data.relay.advertised = relays.into_iter().collect(); - changed = true; - } - - let nks = ndb.poll_for_notes(mute_sub, 1); - if !nks.is_empty() { - let txn = Transaction::new(ndb).expect("txn"); - let muted = AccountMutedData::harvest_nip51_muted(ndb, &txn, &nks); - debug!("pubkey {}: updated muted {:?}", acc.key.pubkey.hex(), muted); - acc.data.muted.muted = Arc::new(muted); - changed = true; - } - - changed - } - pub fn update(&mut self, ndb: &mut Ndb, pool: &mut RelayPool, ctx: &egui::Context) { // IMPORTANT - This function is called in the UI update loop, // make sure it is fast when idle - // If needed, update the relay configuration - if self.poll_for_updates(ndb) { - let acc = self.cache.selected(); - update_relay_configuration( - pool, - &self.relay_defaults, - &acc.key.pubkey, - &acc.data, - create_wakeup(ctx), - ); + let Some(update) = self + .cache + .selected_mut() + .data + .poll_for_updates(ndb, &self.subs) + else { + return; + }; + + match update { + // If needed, update the relay configuration + AccountDataUpdate::Relay => { + let acc = self.cache.selected(); + update_relay_configuration( + pool, + &self.relay_defaults, + &acc.key.pubkey, + &acc.data.relay, + create_wakeup(ctx), + ); + } } } @@ -328,7 +307,7 @@ impl Accounts { pool, &self.relay_defaults, &acc.key.pubkey, - &acc.data, + &acc.data.relay, create_wakeup(ctx), ); } @@ -405,12 +384,34 @@ pub struct AccountData { pub(crate) muted: AccountMutedData, } +impl AccountData { + pub(super) fn poll_for_updates( + &mut self, + ndb: &Ndb, + subs: &AccountSubs, + ) -> Option<AccountDataUpdate> { + let txn = Transaction::new(ndb).expect("txn"); + let mut resp = None; + if self.relay.poll_for_updates(ndb, &txn, subs.relay.local) { + resp = Some(AccountDataUpdate::Relay); + } + + self.muted.poll_for_updates(ndb, &txn, subs.mute.local); + + resp + } +} + +pub(super) enum AccountDataUpdate { + Relay, +} + pub struct AddAccountResponse { pub switch_to: Pubkey, pub unk_id_action: SingleUnkIdAction, } -struct AccountSubs { +pub(super) struct AccountSubs { relay: UnifiedSubscription, mute: UnifiedSubscription, } @@ -426,7 +427,7 @@ impl AccountSubs { ) -> Self { let relay = subscribe(ndb, pool, &data.relay.filter); let mute = subscribe(ndb, pool, &data.muted.filter); - update_relay_configuration(pool, relay_defaults, pk, data, wakeup); + update_relay_configuration(pool, relay_defaults, pk, &data.relay, wakeup); Self { relay, mute } } diff --git a/crates/notedeck/src/account/mute.rs b/crates/notedeck/src/account/mute.rs @@ -1,6 +1,6 @@ use std::sync::Arc; -use nostrdb::{Filter, Ndb, NoteKey, Transaction}; +use nostrdb::{Filter, Ndb, NoteKey, Subscription, Transaction}; use tracing::{debug, error}; use crate::Muted; @@ -76,4 +76,16 @@ impl AccountMutedData { } muted } + + pub(super) fn poll_for_updates(&mut self, ndb: &Ndb, txn: &Transaction, sub: Subscription) { + let nks = ndb.poll_for_notes(sub, 1); + + if nks.is_empty() { + return; + } + + let muted = AccountMutedData::harvest_nip51_muted(ndb, txn, &nks); + debug!("updated muted {:?}", muted); + self.muted = Arc::new(muted); + } } diff --git a/crates/notedeck/src/account/relay.rs b/crates/notedeck/src/account/relay.rs @@ -1,7 +1,7 @@ use std::collections::BTreeSet; use enostr::{Keypair, Pubkey, RelayPool}; -use nostrdb::{Filter, Ndb, NoteBuilder, NoteKey, Transaction}; +use nostrdb::{Filter, Ndb, NoteBuilder, NoteKey, Subscription, Transaction}; use tracing::{debug, error, info}; use url::Url; @@ -106,6 +106,20 @@ impl AccountRelayData { let note = builder.sign(seckey).build().expect("note build"); pool.send(&enostr::ClientMessage::event(&note).expect("note client message")); } + + pub fn poll_for_updates(&mut self, ndb: &Ndb, txn: &Transaction, sub: Subscription) -> bool { + let nks = ndb.poll_for_notes(sub, 1); + + if nks.is_empty() { + return false; + } + + let relays = AccountRelayData::harvest_nip65_relays(ndb, txn, &nks); + debug!("updated relays {:?}", relays); + self.advertised = relays.into_iter().collect(); + + true + } } pub(crate) struct RelayDefaults { @@ -142,7 +156,7 @@ pub(super) fn update_relay_configuration( pool: &mut RelayPool, relay_defaults: &RelayDefaults, pk: &Pubkey, - data: &AccountData, + data: &AccountRelayData, wakeup: impl Fn() + Send + Sync + Clone + 'static, ) { debug!( @@ -155,8 +169,8 @@ pub(super) fn update_relay_configuration( // Compose the desired relay lists from the selected account if desired_relays.is_empty() { - desired_relays.extend(data.relay.local.iter().cloned()); - desired_relays.extend(data.relay.advertised.iter().cloned()); + desired_relays.extend(data.local.iter().cloned()); + desired_relays.extend(data.advertised.iter().cloned()); } // If no relays are specified at this point use the bootstrap list