notedeck

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

thread.rs (4710B)


      1 use crate::{actionbar::BarResult, timeline::TimelineSource, ui, Damus};
      2 use nostrdb::{NoteKey, Transaction};
      3 use tracing::{error, warn};
      4 
      5 pub struct ThreadView<'a> {
      6     app: &'a mut Damus,
      7     timeline: usize,
      8     selected_note_id: &'a [u8; 32],
      9 }
     10 
     11 impl<'a> ThreadView<'a> {
     12     pub fn new(app: &'a mut Damus, timeline: usize, selected_note_id: &'a [u8; 32]) -> Self {
     13         ThreadView {
     14             app,
     15             timeline,
     16             selected_note_id,
     17         }
     18     }
     19 
     20     pub fn ui(&mut self, ui: &mut egui::Ui) -> Option<BarResult> {
     21         let txn = Transaction::new(&self.app.ndb).expect("txn");
     22         let mut result: Option<BarResult> = None;
     23 
     24         let selected_note_key = if let Ok(key) = self
     25             .app
     26             .ndb
     27             .get_notekey_by_id(&txn, self.selected_note_id)
     28             .map(NoteKey::new)
     29         {
     30             key
     31         } else {
     32             // TODO: render 404 ?
     33             return None;
     34         };
     35 
     36         let scroll_id = egui::Id::new((
     37             "threadscroll",
     38             self.app.timelines[self.timeline].selected_view,
     39             self.timeline,
     40             selected_note_key,
     41         ));
     42 
     43         ui.label(
     44             egui::RichText::new("Threads ALPHA! It's not done. Things will be broken.")
     45                 .color(egui::Color32::RED),
     46         );
     47 
     48         egui::ScrollArea::vertical()
     49             .id_source(scroll_id)
     50             .animated(false)
     51             .auto_shrink([false, false])
     52             .scroll_bar_visibility(egui::scroll_area::ScrollBarVisibility::AlwaysVisible)
     53             .show(ui, |ui| {
     54                 let note = if let Ok(note) = self.app.ndb.get_note_by_key(&txn, selected_note_key) {
     55                     note
     56                 } else {
     57                     return;
     58                 };
     59 
     60                 let root_id = {
     61                     let cached_note = self
     62                         .app
     63                         .note_cache_mut()
     64                         .cached_note_or_insert(selected_note_key, &note);
     65 
     66                     cached_note
     67                         .reply
     68                         .borrow(note.tags())
     69                         .root()
     70                         .map_or_else(|| self.selected_note_id, |nr| nr.id)
     71                 };
     72 
     73                 // poll for new notes and insert them into our existing notes
     74                 if let Err(e) = TimelineSource::Thread(root_id).poll_notes_into_view(&txn, self.app)
     75                 {
     76                     error!("Thread::poll_notes_into_view: {e}");
     77                 }
     78 
     79                 let (len, list) = {
     80                     let thread = self
     81                         .app
     82                         .threads
     83                         .thread_mut(&self.app.ndb, &txn, root_id)
     84                         .get_ptr();
     85 
     86                     let len = thread.view.notes.len();
     87                     (len, &mut thread.view.list)
     88                 };
     89 
     90                 list.clone()
     91                     .borrow_mut()
     92                     .ui_custom_layout(ui, len, |ui, start_index| {
     93                         ui.spacing_mut().item_spacing.y = 0.0;
     94                         ui.spacing_mut().item_spacing.x = 4.0;
     95 
     96                         let ind = len - 1 - start_index;
     97                         let note_key = {
     98                             let thread = self
     99                                 .app
    100                                 .threads
    101                                 .thread_mut(&self.app.ndb, &txn, root_id)
    102                                 .get_ptr();
    103                             thread.view.notes[ind].key
    104                         };
    105 
    106                         let note = if let Ok(note) = self.app.ndb.get_note_by_key(&txn, note_key) {
    107                             note
    108                         } else {
    109                             warn!("failed to query note {:?}", note_key);
    110                             return 0;
    111                         };
    112 
    113                         ui::padding(8.0, ui, |ui| {
    114                             let textmode = self.app.textmode;
    115                             let resp = ui::NoteView::new(self.app, &note)
    116                                 .note_previews(!textmode)
    117                                 .show(ui);
    118 
    119                             if let Some(action) = resp.action {
    120                                 let br = action.execute(self.app, self.timeline, note.id(), &txn);
    121                                 if br.is_some() {
    122                                     result = br;
    123                                 }
    124                             }
    125                         });
    126 
    127                         ui::hline(ui);
    128                         //ui.add(egui::Separator::default().spacing(0.0));
    129 
    130                         1
    131                     });
    132             });
    133 
    134         result
    135     }
    136 }