notedeck

One damus client to rule them all
git clone git://jb55.com/notedeck
Log | Files | Refs | README | LICENSE

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, &note);
     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 }