From dcb6620dddabd0644dbe37f34569a50ad577125e Mon Sep 17 00:00:00 2001 From: kernelkind Date: Mon, 14 Oct 2024 17:39:10 -0400 Subject: [PATCH] proper timelineTabs Signed-off-by: kernelkind --- src/actionbar.rs | 7 ++++--- src/app.rs | 37 +++++++++++++++++++++++++------------ src/nav.rs | 13 +++++++++++-- src/notes_holder.rs | 24 +++++++++++++++++------- src/profile.rs | 38 ++++++++++++++++++++++++++++---------- src/thread.rs | 12 ++++++++++-- src/ui/profile/mod.rs | 2 +- src/ui/thread.rs | 2 +- 8 files changed, 97 insertions(+), 38 deletions(-) diff --git a/src/actionbar.rs b/src/actionbar.rs index 71eebf4..1752305 100644 --- a/src/actionbar.rs +++ b/src/actionbar.rs @@ -47,7 +47,7 @@ fn open_thread( router.route_to(Route::thread(NoteId::new(selected_note.to_owned()))); let root_id = crate::note::root_note_id_from_selected_id(ndb, note_cache, txn, selected_note); - Thread::open(ndb, txn, pool, threads, root_id) + Thread::open(ndb, note_cache, txn, pool, threads, root_id) } impl BarAction { @@ -91,7 +91,7 @@ impl BarAction { txn: &Transaction, ) { if let Some(br) = self.execute(ndb, router, threads, note_cache, pool, txn) { - br.process(ndb, txn, threads); + br.process(ndb, note_cache, txn, threads); } } } @@ -104,6 +104,7 @@ impl NotesHolderResult { pub fn process( &self, ndb: &Ndb, + note_cache: &mut NoteCache, txn: &Transaction, storage: &mut NotesHolderStorage, ) { @@ -111,7 +112,7 @@ impl NotesHolderResult { // update the thread for next render if we have new notes NotesHolderResult::NewNotes(new_notes) => { let holder = storage - .notes_holder_mutated(ndb, txn, &new_notes.id) + .notes_holder_mutated(ndb, note_cache, txn, &new_notes.id) .get_ptr(); new_notes.process(holder); } diff --git a/src/app.rs b/src/app.rs index 3f07c83..e04b8ad 100644 --- a/src/app.rs +++ b/src/app.rs @@ -364,8 +364,24 @@ fn setup_initial_timeline( timeline.subscription, timeline.filter ); let lim = filters[0].limit().unwrap_or(crate::filter::default_limit()) as i32; - let results = ndb.query(&txn, filters, lim)?; + let notes = ndb + .query(&txn, filters, lim)? + .into_iter() + .map(NoteRef::from_query_result) + .collect(); + copy_notes_into_timeline(timeline, &txn, ndb, note_cache, notes); + + Ok(()) +} + +pub fn copy_notes_into_timeline( + timeline: &mut Timeline, + txn: &Transaction, + ndb: &Ndb, + note_cache: &mut NoteCache, + notes: Vec, +) { let filters = { let views = &timeline.views; let filters: Vec bool> = @@ -373,21 +389,18 @@ fn setup_initial_timeline( filters }; - for result in results { + for note_ref in notes { for (view, filter) in filters.iter().enumerate() { - if filter( - note_cache.cached_note_or_insert_mut(result.note_key, &result.note), - &result.note, - ) { - timeline.views[view].notes.push(NoteRef { - key: result.note_key, - created_at: result.note.created_at(), - }) + if let Ok(note) = ndb.get_note_by_key(txn, note_ref.key) { + if filter( + note_cache.cached_note_or_insert_mut(note_ref.key, ¬e), + ¬e, + ) { + timeline.views[view].notes.push(note_ref) + } } } } - - Ok(()) } fn setup_initial_nostrdb_subs( diff --git a/src/nav.rs b/src/nav.rs index d4c1f07..a3e62a3 100644 --- a/src/nav.rs +++ b/src/nav.rs @@ -152,12 +152,13 @@ pub fn render_nav(col: usize, app: &mut Damus, ui: &mut egui::Ui) { let txn = Transaction::new(&app.ndb).expect("txn"); if let Some(res) = Profile::open( &app.ndb, + &mut app.note_cache, &txn, &mut app.pool, &mut app.profiles, pubkey.bytes(), ) { - res.process(&app.ndb, &txn, &mut app.profiles); + res.process(&app.ndb, &mut app.note_cache, &txn, &mut app.profiles); } } } @@ -175,13 +176,21 @@ pub fn render_nav(col: usize, app: &mut Damus, ui: &mut egui::Ui) { id.bytes(), ) }; - Thread::unsubscribe_locally(&txn, &app.ndb, &mut app.threads, &mut app.pool, root_id); + Thread::unsubscribe_locally( + &txn, + &app.ndb, + &mut app.note_cache, + &mut app.threads, + &mut app.pool, + root_id, + ); } if let Some(Route::Profile(pubkey)) = r { Profile::unsubscribe_locally( &txn, &app.ndb, + &mut app.note_cache, &mut app.profiles, &mut app.pool, pubkey.bytes(), diff --git a/src/notes_holder.rs b/src/notes_holder.rs index 536a28c..a7c7019 100644 --- a/src/notes_holder.rs +++ b/src/notes_holder.rs @@ -2,11 +2,11 @@ use std::collections::HashMap; use enostr::{Filter, RelayPool}; use nostrdb::{Ndb, Transaction}; -use tracing::{debug, warn}; +use tracing::{debug, info, warn}; use crate::{ actionbar::NotesHolderResult, multi_subscriber::MultiSubscriber, note::NoteRef, - timeline::TimelineTab, Error, Result, + notecache::NoteCache, timeline::TimelineTab, Error, Result, }; pub struct NotesHolderStorage { @@ -52,6 +52,7 @@ impl NotesHolderStorage { pub fn notes_holder_mutated<'a>( &'a mut self, ndb: &Ndb, + note_cache: &mut NoteCache, txn: &Transaction, id: &[u8; 32], ) -> Vitality<'a, M> { @@ -79,12 +80,12 @@ impl NotesHolderStorage { if notes.is_empty() { warn!("thread query returned 0 notes? ") } else { - debug!("found thread with {} notes", notes.len()); + info!("found thread with {} notes", notes.len()); } self.id_to_object.insert( id.to_owned(), - M::new_notes_holder(id, M::filters(id), notes), + M::new_notes_holder(txn, ndb, note_cache, id, M::filters(id), notes), ); Vitality::Fresh(self.id_to_object.get_mut(id).unwrap()) } @@ -96,7 +97,14 @@ pub trait NotesHolder { fn get_view(&mut self) -> &mut TimelineTab; fn filters(for_id: &[u8; 32]) -> Vec; fn filters_since(for_id: &[u8; 32], since: u64) -> Vec; - fn new_notes_holder(id: &[u8; 32], filters: Vec, notes: Vec) -> Self; + fn new_notes_holder( + txn: &Transaction, + ndb: &Ndb, + note_cache: &mut NoteCache, + id: &[u8; 32], + filters: Vec, + notes: Vec, + ) -> Self; #[must_use = "UnknownIds::update_from_note_refs should be used on this result"] fn poll_notes_into_view(&mut self, txn: &Transaction, ndb: &Ndb) -> Result<()> { @@ -138,12 +146,13 @@ pub trait NotesHolder { fn unsubscribe_locally( txn: &Transaction, ndb: &Ndb, + note_cache: &mut NoteCache, notes_holder_storage: &mut NotesHolderStorage, pool: &mut RelayPool, id: &[u8; 32], ) { let notes_holder = notes_holder_storage - .notes_holder_mutated(ndb, txn, id) + .notes_holder_mutated(ndb, note_cache, txn, id) .get_ptr(); if let Some(multi_subscriber) = notes_holder.get_multi_subscriber() { @@ -153,12 +162,13 @@ pub trait NotesHolder { fn open( ndb: &Ndb, + note_cache: &mut NoteCache, txn: &Transaction, pool: &mut RelayPool, storage: &mut NotesHolderStorage, id: &[u8; 32], ) -> Option { - let vitality = storage.notes_holder_mutated(ndb, txn, id); + let vitality = storage.notes_holder_mutated(ndb, note_cache, txn, id); let (holder, result) = match vitality { Vitality::Stale(holder) => { diff --git a/src/profile.rs b/src/profile.rs index 28c9775..03fd397 100644 --- a/src/profile.rs +++ b/src/profile.rs @@ -1,12 +1,8 @@ use enostr::{Filter, Pubkey}; -use nostrdb::{FilterBuilder, ProfileRecord}; +use nostrdb::{FilterBuilder, Ndb, ProfileRecord, Transaction}; use crate::{ - filter::{self, FilterState}, - multi_subscriber::MultiSubscriber, - note::NoteRef, - notes_holder::NotesHolder, - timeline::{PubkeySource, Timeline, TimelineKind}, + app::copy_notes_into_timeline, filter::{self, FilterState}, multi_subscriber::MultiSubscriber, note::NoteRef, notecache::NoteCache, notes_holder::NotesHolder, timeline::{PubkeySource, Timeline, TimelineKind} }; pub enum DisplayName<'a> { @@ -53,10 +49,18 @@ pub struct Profile { } impl Profile { - pub fn new(source: PubkeySource, filters: Vec, notes: Vec) -> Self { + pub fn new( + txn: &Transaction, + ndb: &Ndb, + note_cache: &mut NoteCache, + source: PubkeySource, + filters: Vec, + notes: Vec, + ) -> Self { let mut timeline = Timeline::new(TimelineKind::profile(source), FilterState::ready(filters)); - timeline.current_view_mut().notes = notes; + + copy_notes_into_timeline(&mut timeline, txn, ndb, note_cache, notes); Profile { timeline, @@ -95,8 +99,22 @@ impl NotesHolder for Profile { .collect() } - fn new_notes_holder(id: &[u8; 32], filters: Vec, notes: Vec) -> Self { - Profile::new(PubkeySource::Explicit(Pubkey::new(*id)), filters, notes) + fn new_notes_holder( + txn: &Transaction, + ndb: &Ndb, + note_cache: &mut NoteCache, + id: &[u8; 32], + filters: Vec, + notes: Vec, + ) -> Self { + Profile::new( + txn, + ndb, + note_cache, + PubkeySource::Explicit(Pubkey::new(*id)), + filters, + notes, + ) } fn set_multi_subscriber(&mut self, subscriber: MultiSubscriber) { diff --git a/src/thread.rs b/src/thread.rs index 00159c5..4a883df 100644 --- a/src/thread.rs +++ b/src/thread.rs @@ -1,10 +1,11 @@ use crate::{ multi_subscriber::MultiSubscriber, note::NoteRef, + notecache::NoteCache, notes_holder::NotesHolder, timeline::{TimelineTab, ViewFilter}, }; -use nostrdb::{Filter, FilterBuilder}; +use nostrdb::{Filter, FilterBuilder, Ndb, Transaction}; #[derive(Default)] pub struct Thread { @@ -66,7 +67,14 @@ impl NotesHolder for Thread { Thread::filters(for_id) } - fn new_notes_holder(_: &[u8; 32], _: Vec, notes: Vec) -> Self { + fn new_notes_holder( + _: &Transaction, + _: &Ndb, + _: &mut NoteCache, + _: &[u8; 32], + _: Vec, + notes: Vec, + ) -> Self { Thread::new(notes) } diff --git a/src/ui/profile/mod.rs b/src/ui/profile/mod.rs index 03cbaf2..7a87402 100644 --- a/src/ui/profile/mod.rs +++ b/src/ui/profile/mod.rs @@ -54,7 +54,7 @@ impl<'a> ProfileView<'a> { } let profile = self .profiles - .notes_holder_mutated(self.ndb, &txn, self.pubkey.bytes()) + .notes_holder_mutated(self.ndb, self.note_cache, &txn, self.pubkey.bytes()) .get_ptr(); profile.timeline.selected_view = tabs_ui(ui); diff --git a/src/ui/thread.rs b/src/ui/thread.rs index 2651a9a..38a724b 100644 --- a/src/ui/thread.rs +++ b/src/ui/thread.rs @@ -89,7 +89,7 @@ impl<'a> ThreadView<'a> { let thread = self .threads - .notes_holder_mutated(self.ndb, &txn, root_id) + .notes_holder_mutated(self.ndb, self.note_cache, &txn, root_id) .get_ptr(); // TODO(jb55): skip poll if ThreadResult is fresh?