Fix filter states when adding columns
This fixes various issues with filter states when adding columns. We now maintain multiple states per relay so that we don't lose track of anything. Fixes: https://github.com/damus-io/notedeck/issues/431 Fixes: https://github.com/damus-io/notedeck/issues/359 Signed-off-by: William Casarin <jb55@jb55.com>
This commit is contained in:
@@ -2,6 +2,7 @@ use crate::error::{Error, FilterError};
|
||||
use crate::note::NoteRef;
|
||||
use crate::Result;
|
||||
use nostrdb::{Filter, FilterBuilder, Note, Subscription};
|
||||
use std::collections::HashMap;
|
||||
use tracing::{debug, warn};
|
||||
|
||||
/// A unified subscription has a local and remote component. The remote subid
|
||||
@@ -12,6 +13,74 @@ pub struct UnifiedSubscription {
|
||||
pub remote: String,
|
||||
}
|
||||
|
||||
/// Each relay can have a different filter state. For example, some
|
||||
/// relays may have the contact list, some may not. Let's capture all of
|
||||
/// these states so that some relays don't stop the states of other
|
||||
/// relays.
|
||||
#[derive(Debug)]
|
||||
pub struct FilterStates {
|
||||
pub initial_state: FilterState,
|
||||
pub states: HashMap<String, FilterState>,
|
||||
}
|
||||
|
||||
impl FilterStates {
|
||||
pub fn get(&mut self, relay: &str) -> &FilterState {
|
||||
// if our initial state is ready, then just use that
|
||||
if let FilterState::Ready(_) = self.initial_state {
|
||||
&self.initial_state
|
||||
} else {
|
||||
// otherwise we look at relay states
|
||||
if !self.states.contains_key(relay) {
|
||||
self.states
|
||||
.insert(relay.to_string(), self.initial_state.clone());
|
||||
}
|
||||
self.states.get(relay).unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_any_gotremote(&self) -> Option<(&str, Subscription)> {
|
||||
for (k, v) in self.states.iter() {
|
||||
if let FilterState::GotRemote(sub) = v {
|
||||
return Some((k, *sub));
|
||||
}
|
||||
}
|
||||
|
||||
None
|
||||
}
|
||||
|
||||
pub fn get_any_ready(&self) -> Option<&Vec<Filter>> {
|
||||
if let FilterState::Ready(fs) = &self.initial_state {
|
||||
Some(fs)
|
||||
} else {
|
||||
for (_k, v) in self.states.iter() {
|
||||
if let FilterState::Ready(ref fs) = v {
|
||||
return Some(fs);
|
||||
}
|
||||
}
|
||||
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
pub fn new(initial_state: FilterState) -> Self {
|
||||
Self {
|
||||
initial_state,
|
||||
states: HashMap::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_relay_state(&mut self, relay: String, state: FilterState) {
|
||||
if self.states.contains_key(&relay) {
|
||||
let current_state = self.states.get(&relay).unwrap();
|
||||
warn!(
|
||||
"set_relay_state: we already have the {:?} state set for {}. overriding with {:?}",
|
||||
current_state, &relay, state
|
||||
);
|
||||
}
|
||||
self.states.insert(relay, state);
|
||||
}
|
||||
}
|
||||
|
||||
/// We may need to fetch some data from relays before our filter is ready.
|
||||
/// [`FilterState`] tracks this.
|
||||
#[derive(Debug, Clone)]
|
||||
|
||||
Reference in New Issue
Block a user