proper timelineTabs

Signed-off-by: kernelkind <kernelkind@gmail.com>
This commit is contained in:
kernelkind
2024-10-14 17:39:10 -04:00
parent 6ffe33e924
commit dcb6620ddd
8 changed files with 97 additions and 38 deletions

View File

@@ -47,7 +47,7 @@ fn open_thread(
router.route_to(Route::thread(NoteId::new(selected_note.to_owned()))); 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); 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 { impl BarAction {
@@ -91,7 +91,7 @@ impl BarAction {
txn: &Transaction, txn: &Transaction,
) { ) {
if let Some(br) = self.execute(ndb, router, threads, note_cache, pool, txn) { 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<N: NotesHolder>( pub fn process<N: NotesHolder>(
&self, &self,
ndb: &Ndb, ndb: &Ndb,
note_cache: &mut NoteCache,
txn: &Transaction, txn: &Transaction,
storage: &mut NotesHolderStorage<N>, storage: &mut NotesHolderStorage<N>,
) { ) {
@@ -111,7 +112,7 @@ impl NotesHolderResult {
// update the thread for next render if we have new notes // update the thread for next render if we have new notes
NotesHolderResult::NewNotes(new_notes) => { NotesHolderResult::NewNotes(new_notes) => {
let holder = storage let holder = storage
.notes_holder_mutated(ndb, txn, &new_notes.id) .notes_holder_mutated(ndb, note_cache, txn, &new_notes.id)
.get_ptr(); .get_ptr();
new_notes.process(holder); new_notes.process(holder);
} }

View File

@@ -364,8 +364,24 @@ fn setup_initial_timeline(
timeline.subscription, timeline.filter timeline.subscription, timeline.filter
); );
let lim = filters[0].limit().unwrap_or(crate::filter::default_limit()) as i32; 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<NoteRef>,
) {
let filters = { let filters = {
let views = &timeline.views; let views = &timeline.views;
let filters: Vec<fn(&CachedNote, &Note) -> bool> = let filters: Vec<fn(&CachedNote, &Note) -> bool> =
@@ -373,21 +389,18 @@ fn setup_initial_timeline(
filters filters
}; };
for result in results { for note_ref in notes {
for (view, filter) in filters.iter().enumerate() { for (view, filter) in filters.iter().enumerate() {
if filter( if let Ok(note) = ndb.get_note_by_key(txn, note_ref.key) {
note_cache.cached_note_or_insert_mut(result.note_key, &result.note), if filter(
&result.note, note_cache.cached_note_or_insert_mut(note_ref.key, &note),
) { &note,
timeline.views[view].notes.push(NoteRef { ) {
key: result.note_key, timeline.views[view].notes.push(note_ref)
created_at: result.note.created_at(), }
})
} }
} }
} }
Ok(())
} }
fn setup_initial_nostrdb_subs( fn setup_initial_nostrdb_subs(

View File

@@ -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"); let txn = Transaction::new(&app.ndb).expect("txn");
if let Some(res) = Profile::open( if let Some(res) = Profile::open(
&app.ndb, &app.ndb,
&mut app.note_cache,
&txn, &txn,
&mut app.pool, &mut app.pool,
&mut app.profiles, &mut app.profiles,
pubkey.bytes(), 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(), 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 { if let Some(Route::Profile(pubkey)) = r {
Profile::unsubscribe_locally( Profile::unsubscribe_locally(
&txn, &txn,
&app.ndb, &app.ndb,
&mut app.note_cache,
&mut app.profiles, &mut app.profiles,
&mut app.pool, &mut app.pool,
pubkey.bytes(), pubkey.bytes(),

View File

@@ -2,11 +2,11 @@ use std::collections::HashMap;
use enostr::{Filter, RelayPool}; use enostr::{Filter, RelayPool};
use nostrdb::{Ndb, Transaction}; use nostrdb::{Ndb, Transaction};
use tracing::{debug, warn}; use tracing::{debug, info, warn};
use crate::{ use crate::{
actionbar::NotesHolderResult, multi_subscriber::MultiSubscriber, note::NoteRef, actionbar::NotesHolderResult, multi_subscriber::MultiSubscriber, note::NoteRef,
timeline::TimelineTab, Error, Result, notecache::NoteCache, timeline::TimelineTab, Error, Result,
}; };
pub struct NotesHolderStorage<M: NotesHolder> { pub struct NotesHolderStorage<M: NotesHolder> {
@@ -52,6 +52,7 @@ impl<M: NotesHolder> NotesHolderStorage<M> {
pub fn notes_holder_mutated<'a>( pub fn notes_holder_mutated<'a>(
&'a mut self, &'a mut self,
ndb: &Ndb, ndb: &Ndb,
note_cache: &mut NoteCache,
txn: &Transaction, txn: &Transaction,
id: &[u8; 32], id: &[u8; 32],
) -> Vitality<'a, M> { ) -> Vitality<'a, M> {
@@ -79,12 +80,12 @@ impl<M: NotesHolder> NotesHolderStorage<M> {
if notes.is_empty() { if notes.is_empty() {
warn!("thread query returned 0 notes? ") warn!("thread query returned 0 notes? ")
} else { } else {
debug!("found thread with {} notes", notes.len()); info!("found thread with {} notes", notes.len());
} }
self.id_to_object.insert( self.id_to_object.insert(
id.to_owned(), 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()) 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 get_view(&mut self) -> &mut TimelineTab;
fn filters(for_id: &[u8; 32]) -> Vec<Filter>; fn filters(for_id: &[u8; 32]) -> Vec<Filter>;
fn filters_since(for_id: &[u8; 32], since: u64) -> Vec<Filter>; fn filters_since(for_id: &[u8; 32], since: u64) -> Vec<Filter>;
fn new_notes_holder(id: &[u8; 32], filters: Vec<Filter>, notes: Vec<NoteRef>) -> Self; fn new_notes_holder(
txn: &Transaction,
ndb: &Ndb,
note_cache: &mut NoteCache,
id: &[u8; 32],
filters: Vec<Filter>,
notes: Vec<NoteRef>,
) -> Self;
#[must_use = "UnknownIds::update_from_note_refs should be used on this result"] #[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<()> { fn poll_notes_into_view(&mut self, txn: &Transaction, ndb: &Ndb) -> Result<()> {
@@ -138,12 +146,13 @@ pub trait NotesHolder {
fn unsubscribe_locally<M: NotesHolder>( fn unsubscribe_locally<M: NotesHolder>(
txn: &Transaction, txn: &Transaction,
ndb: &Ndb, ndb: &Ndb,
note_cache: &mut NoteCache,
notes_holder_storage: &mut NotesHolderStorage<M>, notes_holder_storage: &mut NotesHolderStorage<M>,
pool: &mut RelayPool, pool: &mut RelayPool,
id: &[u8; 32], id: &[u8; 32],
) { ) {
let notes_holder = notes_holder_storage let notes_holder = notes_holder_storage
.notes_holder_mutated(ndb, txn, id) .notes_holder_mutated(ndb, note_cache, txn, id)
.get_ptr(); .get_ptr();
if let Some(multi_subscriber) = notes_holder.get_multi_subscriber() { if let Some(multi_subscriber) = notes_holder.get_multi_subscriber() {
@@ -153,12 +162,13 @@ pub trait NotesHolder {
fn open<M: NotesHolder>( fn open<M: NotesHolder>(
ndb: &Ndb, ndb: &Ndb,
note_cache: &mut NoteCache,
txn: &Transaction, txn: &Transaction,
pool: &mut RelayPool, pool: &mut RelayPool,
storage: &mut NotesHolderStorage<M>, storage: &mut NotesHolderStorage<M>,
id: &[u8; 32], id: &[u8; 32],
) -> Option<NotesHolderResult> { ) -> Option<NotesHolderResult> {
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 { let (holder, result) = match vitality {
Vitality::Stale(holder) => { Vitality::Stale(holder) => {

View File

@@ -1,12 +1,8 @@
use enostr::{Filter, Pubkey}; use enostr::{Filter, Pubkey};
use nostrdb::{FilterBuilder, ProfileRecord}; use nostrdb::{FilterBuilder, Ndb, ProfileRecord, Transaction};
use crate::{ use crate::{
filter::{self, FilterState}, app::copy_notes_into_timeline, filter::{self, FilterState}, multi_subscriber::MultiSubscriber, note::NoteRef, notecache::NoteCache, notes_holder::NotesHolder, timeline::{PubkeySource, Timeline, TimelineKind}
multi_subscriber::MultiSubscriber,
note::NoteRef,
notes_holder::NotesHolder,
timeline::{PubkeySource, Timeline, TimelineKind},
}; };
pub enum DisplayName<'a> { pub enum DisplayName<'a> {
@@ -53,10 +49,18 @@ pub struct Profile {
} }
impl Profile { impl Profile {
pub fn new(source: PubkeySource, filters: Vec<Filter>, notes: Vec<NoteRef>) -> Self { pub fn new(
txn: &Transaction,
ndb: &Ndb,
note_cache: &mut NoteCache,
source: PubkeySource,
filters: Vec<Filter>,
notes: Vec<NoteRef>,
) -> Self {
let mut timeline = let mut timeline =
Timeline::new(TimelineKind::profile(source), FilterState::ready(filters)); 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 { Profile {
timeline, timeline,
@@ -95,8 +99,22 @@ impl NotesHolder for Profile {
.collect() .collect()
} }
fn new_notes_holder(id: &[u8; 32], filters: Vec<Filter>, notes: Vec<NoteRef>) -> Self { fn new_notes_holder(
Profile::new(PubkeySource::Explicit(Pubkey::new(*id)), filters, notes) txn: &Transaction,
ndb: &Ndb,
note_cache: &mut NoteCache,
id: &[u8; 32],
filters: Vec<Filter>,
notes: Vec<NoteRef>,
) -> Self {
Profile::new(
txn,
ndb,
note_cache,
PubkeySource::Explicit(Pubkey::new(*id)),
filters,
notes,
)
} }
fn set_multi_subscriber(&mut self, subscriber: MultiSubscriber) { fn set_multi_subscriber(&mut self, subscriber: MultiSubscriber) {

View File

@@ -1,10 +1,11 @@
use crate::{ use crate::{
multi_subscriber::MultiSubscriber, multi_subscriber::MultiSubscriber,
note::NoteRef, note::NoteRef,
notecache::NoteCache,
notes_holder::NotesHolder, notes_holder::NotesHolder,
timeline::{TimelineTab, ViewFilter}, timeline::{TimelineTab, ViewFilter},
}; };
use nostrdb::{Filter, FilterBuilder}; use nostrdb::{Filter, FilterBuilder, Ndb, Transaction};
#[derive(Default)] #[derive(Default)]
pub struct Thread { pub struct Thread {
@@ -66,7 +67,14 @@ impl NotesHolder for Thread {
Thread::filters(for_id) Thread::filters(for_id)
} }
fn new_notes_holder(_: &[u8; 32], _: Vec<Filter>, notes: Vec<NoteRef>) -> Self { fn new_notes_holder(
_: &Transaction,
_: &Ndb,
_: &mut NoteCache,
_: &[u8; 32],
_: Vec<Filter>,
notes: Vec<NoteRef>,
) -> Self {
Thread::new(notes) Thread::new(notes)
} }

View File

@@ -54,7 +54,7 @@ impl<'a> ProfileView<'a> {
} }
let profile = self let profile = self
.profiles .profiles
.notes_holder_mutated(self.ndb, &txn, self.pubkey.bytes()) .notes_holder_mutated(self.ndb, self.note_cache, &txn, self.pubkey.bytes())
.get_ptr(); .get_ptr();
profile.timeline.selected_view = tabs_ui(ui); profile.timeline.selected_view = tabs_ui(ui);

View File

@@ -89,7 +89,7 @@ impl<'a> ThreadView<'a> {
let thread = self let thread = self
.threads .threads
.notes_holder_mutated(self.ndb, &txn, root_id) .notes_holder_mutated(self.ndb, self.note_cache, &txn, root_id)
.get_ptr(); .get_ptr();
// TODO(jb55): skip poll if ThreadResult is fresh? // TODO(jb55): skip poll if ThreadResult is fresh?