Merge explicitly activate and deactivate account relay/muted list #678
Ken Sedgwick (4):
drive-by compiler warning fixes
improve debug logging, comments, and variable names for clarity
explicitly activate and deactivate account relay list subs
explicitly activate and deactivate account muted list subs
This commit is contained in:
@@ -37,7 +37,7 @@ pub enum AccountsAction {
|
||||
|
||||
pub struct AccountRelayData {
|
||||
filter: Filter,
|
||||
subid: String,
|
||||
subid: Option<String>,
|
||||
sub: Option<Subscription>,
|
||||
local: BTreeSet<RelaySpec>, // used locally but not advertised
|
||||
advertised: BTreeSet<RelaySpec>, // advertised via NIP-65
|
||||
@@ -56,7 +56,7 @@ pub struct AddAccountAction {
|
||||
}
|
||||
|
||||
impl AccountRelayData {
|
||||
pub fn new(ndb: &Ndb, pool: &mut RelayPool, pubkey: &[u8; 32]) -> Self {
|
||||
pub fn new(ndb: &Ndb, pubkey: &[u8; 32]) -> Self {
|
||||
// Construct a filter for the user's NIP-65 relay list
|
||||
let filter = Filter::new()
|
||||
.authors([pubkey])
|
||||
@@ -64,11 +64,6 @@ impl AccountRelayData {
|
||||
.limit(1)
|
||||
.build();
|
||||
|
||||
// Local ndb subscription
|
||||
let ndbsub = ndb
|
||||
.subscribe(&[filter.clone()])
|
||||
.expect("ndb relay list subscription");
|
||||
|
||||
// Query the ndb immediately to see if the user list is already there
|
||||
let txn = Transaction::new(ndb).expect("transaction");
|
||||
let lim = filter.limit().unwrap_or(crate::filter::default_limit()) as i32;
|
||||
@@ -85,21 +80,51 @@ impl AccountRelayData {
|
||||
relays
|
||||
);
|
||||
|
||||
// Id for future remote relay subscriptions
|
||||
let subid = Uuid::new_v4().to_string();
|
||||
|
||||
// Add remote subscription to existing relays
|
||||
pool.subscribe(subid.clone(), vec![filter.clone()]);
|
||||
|
||||
AccountRelayData {
|
||||
filter,
|
||||
subid,
|
||||
sub: Some(ndbsub),
|
||||
subid: None,
|
||||
sub: None,
|
||||
local: BTreeSet::new(),
|
||||
advertised: relays.into_iter().collect(),
|
||||
}
|
||||
}
|
||||
|
||||
// make this account the current selected account
|
||||
pub fn activate(&mut self, ndb: &Ndb, pool: &mut RelayPool) {
|
||||
debug!("activating relay sub {}", self.filter.json().unwrap());
|
||||
assert_eq!(self.subid, None, "subid already exists");
|
||||
assert_eq!(self.sub, None, "sub already exists");
|
||||
|
||||
// local subscription
|
||||
let sub = ndb
|
||||
.subscribe(&[self.filter.clone()])
|
||||
.expect("ndb relay list subscription");
|
||||
|
||||
// remote subscription
|
||||
let subid = Uuid::new_v4().to_string();
|
||||
pool.subscribe(subid.clone(), vec![self.filter.clone()]);
|
||||
|
||||
self.sub = Some(sub);
|
||||
self.subid = Some(subid);
|
||||
}
|
||||
|
||||
// this account is no longer the selected account
|
||||
pub fn deactivate(&mut self, ndb: &mut Ndb, pool: &mut RelayPool) {
|
||||
debug!("deactivating relay sub {}", self.filter.json().unwrap());
|
||||
assert_ne!(self.subid, None, "subid doesn't exist");
|
||||
assert_ne!(self.sub, None, "sub doesn't exist");
|
||||
|
||||
// remote subscription
|
||||
pool.unsubscribe(self.subid.as_ref().unwrap().clone());
|
||||
|
||||
// local subscription
|
||||
ndb.unsubscribe(self.sub.unwrap())
|
||||
.expect("ndb relay list unsubscribe");
|
||||
|
||||
self.sub = None;
|
||||
self.subid = None;
|
||||
}
|
||||
|
||||
// standardize the format (ie, trailing slashes) to avoid dups
|
||||
pub fn canonicalize_url(url: &str) -> String {
|
||||
match Url::parse(url) {
|
||||
@@ -162,13 +187,13 @@ impl AccountRelayData {
|
||||
|
||||
pub struct AccountMutedData {
|
||||
filter: Filter,
|
||||
subid: String,
|
||||
subid: Option<String>,
|
||||
sub: Option<Subscription>,
|
||||
muted: Arc<Muted>,
|
||||
}
|
||||
|
||||
impl AccountMutedData {
|
||||
pub fn new(ndb: &Ndb, pool: &mut RelayPool, pubkey: &[u8; 32]) -> Self {
|
||||
pub fn new(ndb: &Ndb, pubkey: &[u8; 32]) -> Self {
|
||||
// Construct a filter for the user's NIP-51 muted list
|
||||
let filter = Filter::new()
|
||||
.authors([pubkey])
|
||||
@@ -176,11 +201,6 @@ impl AccountMutedData {
|
||||
.limit(1)
|
||||
.build();
|
||||
|
||||
// Local ndb subscription
|
||||
let ndbsub = ndb
|
||||
.subscribe(&[filter.clone()])
|
||||
.expect("ndb muted subscription");
|
||||
|
||||
// Query the ndb immediately to see if the user's muted list is already there
|
||||
let txn = Transaction::new(ndb).expect("transaction");
|
||||
let lim = filter.limit().unwrap_or(crate::filter::default_limit()) as i32;
|
||||
@@ -193,20 +213,50 @@ impl AccountMutedData {
|
||||
let muted = Self::harvest_nip51_muted(ndb, &txn, &nks);
|
||||
debug!("pubkey {}: initial muted {:?}", hex::encode(pubkey), muted);
|
||||
|
||||
// Id for future remote relay subscriptions
|
||||
let subid = Uuid::new_v4().to_string();
|
||||
|
||||
// Add remote subscription to existing relays
|
||||
pool.subscribe(subid.clone(), vec![filter.clone()]);
|
||||
|
||||
AccountMutedData {
|
||||
filter,
|
||||
subid,
|
||||
sub: Some(ndbsub),
|
||||
subid: None,
|
||||
sub: None,
|
||||
muted: Arc::new(muted),
|
||||
}
|
||||
}
|
||||
|
||||
// make this account the current selected account
|
||||
pub fn activate(&mut self, ndb: &Ndb, pool: &mut RelayPool) {
|
||||
debug!("activating muted sub {}", self.filter.json().unwrap());
|
||||
assert_eq!(self.subid, None, "subid already exists");
|
||||
assert_eq!(self.sub, None, "sub already exists");
|
||||
|
||||
// local subscription
|
||||
let sub = ndb
|
||||
.subscribe(&[self.filter.clone()])
|
||||
.expect("ndb muted subscription");
|
||||
|
||||
// remote subscription
|
||||
let subid = Uuid::new_v4().to_string();
|
||||
pool.subscribe(subid.clone(), vec![self.filter.clone()]);
|
||||
|
||||
self.sub = Some(sub);
|
||||
self.subid = Some(subid);
|
||||
}
|
||||
|
||||
// this account is no longer the selected account
|
||||
pub fn deactivate(&mut self, ndb: &mut Ndb, pool: &mut RelayPool) {
|
||||
debug!("deactivating muted sub {}", self.filter.json().unwrap());
|
||||
assert_ne!(self.subid, None, "subid doesn't exist");
|
||||
assert_ne!(self.sub, None, "sub doesn't exist");
|
||||
|
||||
// remote subscription
|
||||
pool.unsubscribe(self.subid.as_ref().unwrap().clone());
|
||||
|
||||
// local subscription
|
||||
ndb.unsubscribe(self.sub.unwrap())
|
||||
.expect("ndb muted unsubscribe");
|
||||
|
||||
self.sub = None;
|
||||
self.subid = None;
|
||||
}
|
||||
|
||||
fn harvest_nip51_muted(ndb: &Ndb, txn: &Transaction, nks: &[NoteKey]) -> Muted {
|
||||
let mut muted = Muted::default();
|
||||
for nk in nks.iter() {
|
||||
@@ -432,13 +482,12 @@ impl Accounts {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_selected_account_data(&self) -> Option<&AccountData> {
|
||||
if let Some(account) = self.get_selected_account() {
|
||||
if let Some(account_data) = self.account_data.get(account.pubkey.bytes()) {
|
||||
return Some(account_data);
|
||||
}
|
||||
}
|
||||
None
|
||||
pub fn get_selected_account_data(&mut self) -> Option<&mut AccountData> {
|
||||
let account_pubkey = {
|
||||
let account = self.get_selected_account()?;
|
||||
*account.pubkey.bytes()
|
||||
};
|
||||
self.account_data.get_mut(&account_pubkey)
|
||||
}
|
||||
|
||||
pub fn select_account(&mut self, index: usize) {
|
||||
@@ -470,18 +519,25 @@ impl Accounts {
|
||||
|
||||
pub fn send_initial_filters(&mut self, pool: &mut RelayPool, relay_url: &str) {
|
||||
for data in self.account_data.values() {
|
||||
pool.send_to(
|
||||
&ClientMessage::req(data.relay.subid.clone(), vec![data.relay.filter.clone()]),
|
||||
relay_url,
|
||||
);
|
||||
pool.send_to(
|
||||
&ClientMessage::req(data.muted.subid.clone(), vec![data.muted.filter.clone()]),
|
||||
relay_url,
|
||||
);
|
||||
// send the active account's relay list subscription
|
||||
if let Some(relay_subid) = &data.relay.subid {
|
||||
pool.send_to(
|
||||
&ClientMessage::req(relay_subid.clone(), vec![data.relay.filter.clone()]),
|
||||
relay_url,
|
||||
);
|
||||
}
|
||||
// send the active account's muted subscription
|
||||
if let Some(muted_subid) = &data.muted.subid {
|
||||
pool.send_to(
|
||||
&ClientMessage::req(muted_subid.clone(), vec![data.muted.filter.clone()]),
|
||||
relay_url,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Returns added and removed accounts
|
||||
// Return accounts which have no account_data yet (added) and accounts
|
||||
// which have still data but are no longer in our account list (removed).
|
||||
fn delta_accounts(&self) -> (Vec<[u8; 32]>, Vec<[u8; 32]>) {
|
||||
let mut added = Vec::new();
|
||||
for pubkey in self.accounts.iter().map(|a| a.pubkey.bytes()) {
|
||||
@@ -498,13 +554,13 @@ impl Accounts {
|
||||
(added, removed)
|
||||
}
|
||||
|
||||
fn handle_added_account(&mut self, ndb: &Ndb, pool: &mut RelayPool, pubkey: &[u8; 32]) {
|
||||
fn handle_added_account(&mut self, ndb: &Ndb, pubkey: &[u8; 32]) {
|
||||
debug!("handle_added_account {}", hex::encode(pubkey));
|
||||
|
||||
// Create the user account data
|
||||
let new_account_data = AccountData {
|
||||
relay: AccountRelayData::new(ndb, pool, pubkey),
|
||||
muted: AccountMutedData::new(ndb, pool, pubkey),
|
||||
relay: AccountRelayData::new(ndb, pubkey),
|
||||
muted: AccountMutedData::new(ndb, pubkey),
|
||||
};
|
||||
self.account_data.insert(*pubkey, new_account_data);
|
||||
}
|
||||
@@ -552,8 +608,9 @@ impl Accounts {
|
||||
wakeup: impl Fn() + Send + Sync + Clone + 'static,
|
||||
) {
|
||||
debug!(
|
||||
"updating relay configuration for currently selected account {:?}",
|
||||
"updating relay configuration for currently selected {:?}",
|
||||
self.currently_selected_account
|
||||
.map(|i| hex::encode(self.accounts.get(i).unwrap().pubkey.bytes()))
|
||||
);
|
||||
|
||||
// If forced relays are set use them only
|
||||
@@ -600,37 +657,66 @@ impl Accounts {
|
||||
debug!("current relays: {:?}", pool.urls());
|
||||
}
|
||||
|
||||
pub fn update(&mut self, ndb: &Ndb, pool: &mut RelayPool, ctx: &egui::Context) {
|
||||
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
|
||||
|
||||
// On the initial update the relays need config even if nothing changes below
|
||||
let mut relays_changed = self.needs_relay_config;
|
||||
let mut need_reconfig = self.needs_relay_config;
|
||||
|
||||
let ctx2 = ctx.clone();
|
||||
let wakeup = move || {
|
||||
ctx2.request_repaint();
|
||||
};
|
||||
|
||||
// Do we need to deactivate any existing account subs?
|
||||
for (ndx, account) in self.accounts.iter().enumerate() {
|
||||
if Some(ndx) != self.currently_selected_account {
|
||||
// this account is not currently selected
|
||||
if let Some(data) = self.account_data.get_mut(account.pubkey.bytes()) {
|
||||
if data.relay.sub.is_some() {
|
||||
// this account has relay subs, deactivate them
|
||||
data.relay.deactivate(ndb, pool);
|
||||
}
|
||||
if data.muted.sub.is_some() {
|
||||
// this account has muted subs, deactivate them
|
||||
data.muted.deactivate(ndb, pool);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Were any accounts added or removed?
|
||||
let (added, removed) = self.delta_accounts();
|
||||
for pk in added {
|
||||
self.handle_added_account(ndb, pool, &pk);
|
||||
relays_changed = true;
|
||||
self.handle_added_account(ndb, &pk);
|
||||
need_reconfig = true;
|
||||
}
|
||||
for pk in removed {
|
||||
self.handle_removed_account(&pk);
|
||||
relays_changed = true;
|
||||
need_reconfig = true;
|
||||
}
|
||||
|
||||
// Did any accounts receive updates (ie NIP-65 relay lists)
|
||||
relays_changed = self.poll_for_updates(ndb) || relays_changed;
|
||||
need_reconfig = self.poll_for_updates(ndb) || need_reconfig;
|
||||
|
||||
// If needed, update the relay configuration
|
||||
if relays_changed {
|
||||
if need_reconfig {
|
||||
self.update_relay_configuration(pool, wakeup);
|
||||
self.needs_relay_config = false;
|
||||
}
|
||||
|
||||
// Do we need to activate account subs?
|
||||
if let Some(data) = self.get_selected_account_data() {
|
||||
if data.relay.sub.is_none() {
|
||||
// the currently selected account doesn't have relay subs, activate them
|
||||
data.relay.activate(ndb, pool);
|
||||
}
|
||||
if data.muted.sub.is_none() {
|
||||
// the currently selected account doesn't have muted subs, activate them
|
||||
data.muted.activate(ndb, pool);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_full<'a>(&'a self, pubkey: &[u8; 32]) -> Option<FilledKeypair<'a>> {
|
||||
|
||||
@@ -69,7 +69,7 @@ impl eframe::App for Notedeck {
|
||||
puffin::GlobalProfiler::lock().new_frame();
|
||||
|
||||
// handle account updates
|
||||
self.accounts.update(&self.ndb, &mut self.pool, ctx);
|
||||
self.accounts.update(&mut self.ndb, &mut self.pool, ctx);
|
||||
|
||||
main_panel(&ctx.style(), crate::ui::is_narrow(ctx)).show(ctx, |ui| {
|
||||
// render app
|
||||
|
||||
Reference in New Issue
Block a user