thread: fix ordering and duplication bugs
Signed-off-by: William Casarin <jb55@jb55.com>
This commit is contained in:
2
Cargo.lock
generated
2
Cargo.lock
generated
@@ -2296,7 +2296,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "nostrdb"
|
name = "nostrdb"
|
||||||
version = "0.3.4"
|
version = "0.3.4"
|
||||||
source = "git+https://github.com/damus-io/nostrdb-rs?branch=threads#27e7c19c8941fe996490a82512fd2660e5da1900"
|
source = "git+https://github.com/damus-io/nostrdb-rs?rev=86ff69438221932a1b6d26a349b9c65c80d51989#86ff69438221932a1b6d26a349b9c65c80d51989"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bindgen",
|
"bindgen",
|
||||||
"cc",
|
"cc",
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ serde_json = "1.0.89"
|
|||||||
env_logger = "0.10.0"
|
env_logger = "0.10.0"
|
||||||
puffin_egui = { version = "0.27.0", optional = true }
|
puffin_egui = { version = "0.27.0", optional = true }
|
||||||
puffin = { version = "0.19.0", optional = true }
|
puffin = { version = "0.19.0", optional = true }
|
||||||
nostrdb = { git = "https://github.com/damus-io/nostrdb-rs", branch = "threads" }
|
nostrdb = { git = "https://github.com/damus-io/nostrdb-rs", rev = "86ff69438221932a1b6d26a349b9c65c80d51989" }
|
||||||
#nostrdb = { path = "/Users/jb55/dev/github/damus-io/nostrdb-rs" }
|
#nostrdb = { path = "/Users/jb55/dev/github/damus-io/nostrdb-rs" }
|
||||||
#nostrdb = "0.3.4"
|
#nostrdb = "0.3.4"
|
||||||
hex = "0.4.3"
|
hex = "0.4.3"
|
||||||
|
|||||||
@@ -29,43 +29,43 @@ pub fn convert_enostr_filter(filter: &enostr::Filter) -> nostrdb::Filter {
|
|||||||
let mut nfilter = nostrdb::Filter::new();
|
let mut nfilter = nostrdb::Filter::new();
|
||||||
|
|
||||||
if let Some(ref ids) = filter.ids {
|
if let Some(ref ids) = filter.ids {
|
||||||
nfilter.ids(ids.iter().map(|a| *a.bytes()).collect());
|
nfilter = nfilter.ids(ids.iter().map(|a| *a.bytes()).collect());
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(ref authors) = filter.authors {
|
if let Some(ref authors) = filter.authors {
|
||||||
let authors: Vec<[u8; 32]> = authors.iter().map(|a| *a.bytes()).collect();
|
let authors: Vec<[u8; 32]> = authors.iter().map(|a| *a.bytes()).collect();
|
||||||
nfilter.authors(authors);
|
nfilter = nfilter.authors(authors);
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(ref kinds) = filter.kinds {
|
if let Some(ref kinds) = filter.kinds {
|
||||||
nfilter.kinds(kinds.clone());
|
nfilter = nfilter.kinds(kinds.clone());
|
||||||
}
|
}
|
||||||
|
|
||||||
// #e
|
// #e
|
||||||
if let Some(ref events) = filter.events {
|
if let Some(ref events) = filter.events {
|
||||||
nfilter.events(events.iter().map(|a| *a.bytes()).collect());
|
nfilter = nfilter.events(events.iter().map(|a| *a.bytes()).collect());
|
||||||
}
|
}
|
||||||
|
|
||||||
// #p
|
// #p
|
||||||
if let Some(ref pubkeys) = filter.pubkeys {
|
if let Some(ref pubkeys) = filter.pubkeys {
|
||||||
nfilter.pubkeys(pubkeys.iter().map(|a| *a.bytes()).collect());
|
nfilter = nfilter.pubkeys(pubkeys.iter().map(|a| *a.bytes()).collect());
|
||||||
}
|
}
|
||||||
|
|
||||||
// #t
|
// #t
|
||||||
if let Some(ref hashtags) = filter.hashtags {
|
if let Some(ref hashtags) = filter.hashtags {
|
||||||
nfilter.tags(hashtags.clone(), 't');
|
nfilter = nfilter.tags(hashtags.clone(), 't');
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(since) = filter.since {
|
if let Some(since) = filter.since {
|
||||||
nfilter.since(since);
|
nfilter = nfilter.since(since);
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(until) = filter.until {
|
if let Some(until) = filter.until {
|
||||||
nfilter.until(until);
|
nfilter = nfilter.until(until);
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(limit) = filter.limit {
|
if let Some(limit) = filter.limit {
|
||||||
nfilter.limit(limit.into());
|
nfilter = nfilter.limit(limit.into());
|
||||||
}
|
}
|
||||||
|
|
||||||
nfilter.build()
|
nfilter.build()
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
use crate::note::NoteRef;
|
use crate::note::NoteRef;
|
||||||
use crate::timeline::{TimelineTab, ViewFilter};
|
use crate::timeline::{TimelineTab, ViewFilter};
|
||||||
use crate::Error;
|
use crate::Error;
|
||||||
use nostrdb::{Filter, Ndb, Subscription, Transaction};
|
use nostrdb::{Filter, FilterBuilder, Ndb, Subscription, Transaction};
|
||||||
use std::cmp::Ordering;
|
use std::cmp::Ordering;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use tracing::debug;
|
use tracing::debug;
|
||||||
@@ -49,7 +49,7 @@ impl Thread {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let last_note = notes[0];
|
let last_note = notes[0];
|
||||||
let filters = Thread::filters_since(root_id, last_note.created_at - 60);
|
let filters = Thread::filters_since(root_id, last_note.created_at + 1);
|
||||||
|
|
||||||
if let Ok(results) = ndb.query(txn, filters, 1000) {
|
if let Ok(results) = ndb.query(txn, filters, 1000) {
|
||||||
debug!("got {} results from thread update", results.len());
|
debug!("got {} results from thread update", results.len());
|
||||||
@@ -64,7 +64,6 @@ impl Thread {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn decrement_sub(&mut self) -> Result<DecrementResult, Error> {
|
pub fn decrement_sub(&mut self) -> Result<DecrementResult, Error> {
|
||||||
debug!("decrementing sub {:?}", self.subscription().map(|s| s.id));
|
|
||||||
self.subscribers -= 1;
|
self.subscribers -= 1;
|
||||||
|
|
||||||
match self.subscribers.cmp(&0) {
|
match self.subscribers.cmp(&0) {
|
||||||
@@ -88,29 +87,25 @@ impl Thread {
|
|||||||
&mut self.sub
|
&mut self.sub
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn filters_since(root: &[u8; 32], since: u64) -> Vec<Filter> {
|
fn filters_raw(root: &[u8; 32]) -> Vec<FilterBuilder> {
|
||||||
vec![
|
vec![
|
||||||
nostrdb::Filter::new()
|
nostrdb::Filter::new().kinds(vec![1]).event(root),
|
||||||
.since(since)
|
nostrdb::Filter::new().ids(vec![*root]).limit(1),
|
||||||
.kinds(vec![1])
|
|
||||||
.event(root)
|
|
||||||
.build(),
|
|
||||||
nostrdb::Filter::new()
|
|
||||||
.kinds(vec![1])
|
|
||||||
.ids(vec![*root])
|
|
||||||
.since(since)
|
|
||||||
.build(),
|
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn filters_since(root: &[u8; 32], since: u64) -> Vec<Filter> {
|
||||||
|
Self::filters_raw(root)
|
||||||
|
.into_iter()
|
||||||
|
.map(|fb| fb.since(since).build())
|
||||||
|
.collect()
|
||||||
|
}
|
||||||
|
|
||||||
pub fn filters(root: &[u8; 32]) -> Vec<Filter> {
|
pub fn filters(root: &[u8; 32]) -> Vec<Filter> {
|
||||||
vec![
|
Self::filters_raw(root)
|
||||||
nostrdb::Filter::new().kinds(vec![1]).event(root).build(),
|
.into_iter()
|
||||||
nostrdb::Filter::new()
|
.map(|mut fb| fb.build())
|
||||||
.kinds(vec![1])
|
.collect()
|
||||||
.ids(vec![*root])
|
|
||||||
.build(),
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -162,17 +157,6 @@ impl Threads {
|
|||||||
return ThreadResult::Stale(self.root_id_to_thread.get_mut(root_id).unwrap());
|
return ThreadResult::Stale(self.root_id_to_thread.get_mut(root_id).unwrap());
|
||||||
}
|
}
|
||||||
|
|
||||||
// looks like we don't have this thread yet, populate it
|
|
||||||
// TODO: should we do this in the caller?
|
|
||||||
let root = if let Ok(root) = ndb.get_note_by_id(txn, root_id) {
|
|
||||||
root
|
|
||||||
} else {
|
|
||||||
debug!("couldnt find root note root_id:{}", hex::encode(root_id));
|
|
||||||
self.root_id_to_thread
|
|
||||||
.insert(root_id.to_owned(), Thread::new(vec![]));
|
|
||||||
return ThreadResult::Fresh(self.root_id_to_thread.get_mut(root_id).unwrap());
|
|
||||||
};
|
|
||||||
|
|
||||||
// we don't have the thread, query for it!
|
// we don't have the thread, query for it!
|
||||||
let filters = Thread::filters(root_id);
|
let filters = Thread::filters(root_id);
|
||||||
|
|
||||||
@@ -184,7 +168,7 @@ impl Threads {
|
|||||||
} else {
|
} else {
|
||||||
debug!(
|
debug!(
|
||||||
"got no results from thread lookup for {}",
|
"got no results from thread lookup for {}",
|
||||||
hex::encode(root.id())
|
hex::encode(root_id)
|
||||||
);
|
);
|
||||||
vec![]
|
vec![]
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -96,13 +96,14 @@ impl<'a> ThreadView<'a> {
|
|||||||
ui.spacing_mut().item_spacing.y = 0.0;
|
ui.spacing_mut().item_spacing.y = 0.0;
|
||||||
ui.spacing_mut().item_spacing.x = 4.0;
|
ui.spacing_mut().item_spacing.x = 4.0;
|
||||||
|
|
||||||
|
let ind = len - 1 - start_index;
|
||||||
let note_key = {
|
let note_key = {
|
||||||
let thread = self
|
let thread = self
|
||||||
.app
|
.app
|
||||||
.threads
|
.threads
|
||||||
.thread_mut(&self.app.ndb, &txn, root_id)
|
.thread_mut(&self.app.ndb, &txn, root_id)
|
||||||
.get_ptr();
|
.get_ptr();
|
||||||
thread.view.notes[start_index].key
|
thread.view.notes[ind].key
|
||||||
};
|
};
|
||||||
|
|
||||||
let note = if let Ok(note) = self.app.ndb.get_note_by_key(&txn, note_key) {
|
let note = if let Ok(note) = self.app.ndb.get_note_by_key(&txn, note_key) {
|
||||||
|
|||||||
Reference in New Issue
Block a user