thread.rs (4077B)
1 use crate::{ 2 actionbar::NoteActionResponse, 3 imgcache::ImageCache, 4 notecache::NoteCache, 5 notes_holder::{NotesHolder, NotesHolderStorage}, 6 thread::Thread, 7 ui::note::NoteOptions, 8 unknowns::UnknownIds, 9 }; 10 use nostrdb::{Ndb, NoteKey, Transaction}; 11 use tracing::error; 12 13 use super::timeline::TimelineTabView; 14 15 pub struct ThreadView<'a> { 16 threads: &'a mut NotesHolderStorage<Thread>, 17 ndb: &'a Ndb, 18 note_cache: &'a mut NoteCache, 19 unknown_ids: &'a mut UnknownIds, 20 img_cache: &'a mut ImageCache, 21 selected_note_id: &'a [u8; 32], 22 textmode: bool, 23 id_source: egui::Id, 24 } 25 26 impl<'a> ThreadView<'a> { 27 #[allow(clippy::too_many_arguments)] 28 pub fn new( 29 threads: &'a mut NotesHolderStorage<Thread>, 30 ndb: &'a Ndb, 31 note_cache: &'a mut NoteCache, 32 unknown_ids: &'a mut UnknownIds, 33 img_cache: &'a mut ImageCache, 34 selected_note_id: &'a [u8; 32], 35 textmode: bool, 36 ) -> Self { 37 let id_source = egui::Id::new("threadscroll_threadview"); 38 ThreadView { 39 threads, 40 ndb, 41 note_cache, 42 unknown_ids, 43 img_cache, 44 selected_note_id, 45 textmode, 46 id_source, 47 } 48 } 49 50 pub fn id_source(mut self, id: egui::Id) -> Self { 51 self.id_source = id; 52 self 53 } 54 55 pub fn ui(&mut self, ui: &mut egui::Ui) -> NoteActionResponse { 56 let txn = Transaction::new(self.ndb).expect("txn"); 57 58 let selected_note_key = if let Ok(key) = self 59 .ndb 60 .get_notekey_by_id(&txn, self.selected_note_id) 61 .map(NoteKey::new) 62 { 63 key 64 } else { 65 // TODO: render 404 ? 66 return NoteActionResponse::default(); 67 }; 68 69 ui.label( 70 egui::RichText::new("Threads ALPHA! It's not done. Things will be broken.") 71 .color(egui::Color32::RED), 72 ); 73 74 egui::ScrollArea::vertical() 75 .id_source(self.id_source) 76 .animated(false) 77 .auto_shrink([false, false]) 78 .scroll_bar_visibility(egui::scroll_area::ScrollBarVisibility::AlwaysVisible) 79 .show(ui, |ui| { 80 let note = if let Ok(note) = self.ndb.get_note_by_key(&txn, selected_note_key) { 81 note 82 } else { 83 return NoteActionResponse::default(); 84 }; 85 86 let root_id = { 87 let cached_note = self 88 .note_cache 89 .cached_note_or_insert(selected_note_key, ¬e); 90 91 cached_note 92 .reply 93 .borrow(note.tags()) 94 .root() 95 .map_or_else(|| self.selected_note_id, |nr| nr.id) 96 }; 97 98 let thread = self 99 .threads 100 .notes_holder_mutated(self.ndb, self.note_cache, &txn, root_id) 101 .get_ptr(); 102 103 // TODO(jb55): skip poll if ThreadResult is fresh? 104 105 // poll for new notes and insert them into our existing notes 106 match thread.poll_notes_into_view(&txn, self.ndb) { 107 Ok(action) => { 108 action.process_action(&txn, self.ndb, self.unknown_ids, self.note_cache) 109 } 110 Err(err) => error!("{err}"), 111 }; 112 113 // This is threadview. We are not the universe view... 114 let is_universe = false; 115 let mut note_options = NoteOptions::new(is_universe); 116 note_options.set_textmode(self.textmode); 117 118 TimelineTabView::new( 119 thread.view(), 120 true, 121 note_options, 122 &txn, 123 self.ndb, 124 self.note_cache, 125 self.img_cache, 126 ) 127 .show(ui) 128 }) 129 .inner 130 } 131 }