-
Notifications
You must be signed in to change notification settings - Fork 16
Commit
Signed-off-by: William Casarin <[email protected]>
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,37 @@ | ||
use nostrdb::{NoteKey, QueryResult}; | ||
use std::cmp::Ordering; | ||
|
||
#[derive(Debug, Eq, PartialEq, Copy, Clone)] | ||
pub struct NoteRef { | ||
pub key: NoteKey, | ||
pub created_at: u64, | ||
} | ||
|
||
impl NoteRef { | ||
pub fn new(key: NoteKey, created_at: u64) -> Self { | ||
NoteRef { key, created_at } | ||
} | ||
|
||
pub fn from_query_result<'a>(qr: QueryResult<'a>) -> Self { | ||
NoteRef { | ||
key: qr.key, | ||
created_at: qr.created_at, | ||
} | ||
} | ||
} | ||
|
||
impl Ord for NoteRef { | ||
fn cmp(&self, other: &Self) -> Ordering { | ||
match self.created_at.cmp(&other.created_at) { | ||
Ordering::Equal => self.key.cmp(&other.key), | ||
Ordering::Less => Ordering::Greater, | ||
Ordering::Greater => Ordering::Less, | ||
} | ||
} | ||
} | ||
|
||
impl PartialOrd for NoteRef { | ||
fn partial_cmp(&self, other: &Self) -> Option<Ordering> { | ||
Some(self.cmp(other)) | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
use crate::note::NoteRef; | ||
use crate::timeline::{NotesAndReplies, TimelineView}; | ||
Check failure on line 2 in src/thread.rs GitHub Actions / Clippy
Check failure on line 2 in src/thread.rs GitHub Actions / Check
|
||
use nostrdb::{Ndb, NoteKey}; | ||
use std::collections::hash_map::Entry; | ||
use std::collections::HashMap; | ||
|
||
#[derive(Default)] | ||
pub struct Thread { | ||
pub view: TimelineView, | ||
} | ||
|
||
impl Thread { | ||
fn new(notes: Vec<NoteRef>) -> Self { | ||
let mut cap = ((notes.len() as f32) * 1.5) as usize; | ||
if cap == 0 { | ||
cap = 25; | ||
} | ||
let mut view = TimelineView::new_with_capacity(ViewFilter::NotesAndReplies, cap); | ||
Check failure on line 18 in src/thread.rs GitHub Actions / Clippy
Check failure on line 18 in src/thread.rs GitHub Actions / Check
|
||
view.notes = notes; | ||
|
||
Thread { view } | ||
} | ||
} | ||
|
||
#[derive(Default)] | ||
pub struct Threads { | ||
pub threads: HashMap<NoteKey, Thread>, | ||
} | ||
|
||
impl Threads { | ||
fn thread_mut(&self, ndb: &Ndb, key: NoteKey) -> &mut Thread { | ||
let thread = self.threads.entry(key).or_default(); | ||
|
||
match self.threads.entry(key) { | ||
Entry::Occupied(o) => o.get_mut(), | ||
|
||
Entry::Vacant(v) => { | ||
// looks like we don't have this thread yet, populate it | ||
// TODO: should we do this in the caller? | ||
|
||
let root = if let Some(root) = ndb.get_note_by_key(key) { | ||
root | ||
} else { | ||
// can't find the root note!? :( | ||
return v.insert(Thread::new(vec![])); | ||
}; | ||
|
||
// we don't have the thread, query for it! | ||
let filter = nostrdb::FilterBuilder::new() | ||
Check failure on line 49 in src/thread.rs GitHub Actions / Clippy
Check failure on line 49 in src/thread.rs GitHub Actions / Check
|
||
.start_tag_field('e') | ||
.add_id_element(root.id) | ||
.end_field() | ||
.build(); | ||
|
||
// TODO: what should be the max results ? | ||
let notes = if let Ok(results) = ndb.query(txn, vec![filter], 10000) { | ||
Check failure on line 56 in src/thread.rs GitHub Actions / Clippy
Check failure on line 56 in src/thread.rs GitHub Actions / Check
|
||
results.map(NoteRef::from_query_result) | ||
} else { | ||
vec![] | ||
}; | ||
|
||
v.insert(Thread::new(notes)) | ||
} | ||
} | ||
} | ||
|
||
fn thread(&self, ndb: &Ndb, key: NoteKey) -> &Thread { | ||
self.thread_mut(ndb, key) | ||
} | ||
|
||
//fn thread_by_id(&self, ndb: &Ndb, id: &[u8; 32]) -> &mut Thread { | ||
//} | ||
} |