notedeck

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

thread.rs (3998B)


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