notedeck

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

route.rs (4988B)


      1 use crate::{
      2     accounts::Accounts,
      3     column::Columns,
      4     draft::Drafts,
      5     imgcache::ImageCache,
      6     muted::MuteFun,
      7     nav::RenderNavAction,
      8     notecache::NoteCache,
      9     notes_holder::NotesHolderStorage,
     10     profile::Profile,
     11     thread::Thread,
     12     timeline::{TimelineId, TimelineKind},
     13     ui::{
     14         self,
     15         note::{NoteOptions, QuoteRepostView},
     16         profile::ProfileView,
     17     },
     18     unknowns::UnknownIds,
     19 };
     20 
     21 use enostr::{NoteId, Pubkey};
     22 use nostrdb::{Ndb, Transaction};
     23 
     24 #[derive(Debug, Eq, PartialEq, Clone, Copy, serde::Serialize, serde::Deserialize)]
     25 pub enum TimelineRoute {
     26     Timeline(TimelineId),
     27     Thread(NoteId),
     28     Profile(Pubkey),
     29     Reply(NoteId),
     30     Quote(NoteId),
     31 }
     32 
     33 #[allow(clippy::too_many_arguments)]
     34 pub fn render_timeline_route(
     35     ndb: &Ndb,
     36     columns: &mut Columns,
     37     drafts: &mut Drafts,
     38     img_cache: &mut ImageCache,
     39     unknown_ids: &mut UnknownIds,
     40     note_cache: &mut NoteCache,
     41     threads: &mut NotesHolderStorage<Thread>,
     42     profiles: &mut NotesHolderStorage<Profile>,
     43     accounts: &mut Accounts,
     44     route: TimelineRoute,
     45     col: usize,
     46     textmode: bool,
     47     ui: &mut egui::Ui,
     48 ) -> Option<RenderNavAction> {
     49     match route {
     50         TimelineRoute::Timeline(timeline_id) => {
     51             let note_options = {
     52                 let is_universe = if let Some(timeline) = columns.find_timeline(timeline_id) {
     53                     timeline.kind == TimelineKind::Universe
     54                 } else {
     55                     false
     56                 };
     57 
     58                 let mut options = NoteOptions::new(is_universe);
     59                 options.set_textmode(textmode);
     60                 options
     61             };
     62 
     63             let note_action = ui::TimelineView::new(
     64                 timeline_id,
     65                 columns,
     66                 ndb,
     67                 note_cache,
     68                 img_cache,
     69                 note_options,
     70             )
     71             .ui(ui);
     72 
     73             note_action.map(RenderNavAction::NoteAction)
     74         }
     75 
     76         TimelineRoute::Thread(id) => ui::ThreadView::new(
     77             threads,
     78             ndb,
     79             note_cache,
     80             unknown_ids,
     81             img_cache,
     82             id.bytes(),
     83             textmode,
     84         )
     85         .id_source(egui::Id::new(("threadscroll", col)))
     86         .ui(ui, &accounts.mutefun())
     87         .map(Into::into),
     88 
     89         TimelineRoute::Reply(id) => {
     90             let txn = if let Ok(txn) = Transaction::new(ndb) {
     91                 txn
     92             } else {
     93                 ui.label("Reply to unknown note");
     94                 return None;
     95             };
     96 
     97             let note = if let Ok(note) = ndb.get_note_by_id(&txn, id.bytes()) {
     98                 note
     99             } else {
    100                 ui.label("Reply to unknown note");
    101                 return None;
    102             };
    103 
    104             let id = egui::Id::new(("post", col, note.key().unwrap()));
    105             let poster = accounts.selected_or_first_nsec()?;
    106 
    107             let action = {
    108                 let draft = drafts.reply_mut(note.id());
    109 
    110                 let response = egui::ScrollArea::vertical().show(ui, |ui| {
    111                     ui::PostReplyView::new(ndb, poster, draft, note_cache, img_cache, &note)
    112                         .id_source(id)
    113                         .show(ui)
    114                 });
    115 
    116                 response.inner.action
    117             };
    118 
    119             action.map(Into::into)
    120         }
    121 
    122         TimelineRoute::Profile(pubkey) => render_profile_route(
    123             &pubkey,
    124             ndb,
    125             profiles,
    126             img_cache,
    127             note_cache,
    128             col,
    129             ui,
    130             &accounts.mutefun(),
    131         ),
    132 
    133         TimelineRoute::Quote(id) => {
    134             let txn = Transaction::new(ndb).expect("txn");
    135 
    136             let note = if let Ok(note) = ndb.get_note_by_id(&txn, id.bytes()) {
    137                 note
    138             } else {
    139                 ui.label("Quote of unknown note");
    140                 return None;
    141             };
    142 
    143             let id = egui::Id::new(("post", col, note.key().unwrap()));
    144 
    145             let poster = accounts.selected_or_first_nsec()?;
    146             let draft = drafts.quote_mut(note.id());
    147 
    148             let response = egui::ScrollArea::vertical().show(ui, |ui| {
    149                 QuoteRepostView::new(ndb, poster, note_cache, img_cache, draft, &note)
    150                     .id_source(id)
    151                     .show(ui)
    152             });
    153 
    154             response.inner.action.map(Into::into)
    155         }
    156     }
    157 }
    158 
    159 #[allow(clippy::too_many_arguments)]
    160 pub fn render_profile_route(
    161     pubkey: &Pubkey,
    162     ndb: &Ndb,
    163     profiles: &mut NotesHolderStorage<Profile>,
    164     img_cache: &mut ImageCache,
    165     note_cache: &mut NoteCache,
    166     col: usize,
    167     ui: &mut egui::Ui,
    168     is_muted: &MuteFun,
    169 ) -> Option<RenderNavAction> {
    170     let note_action = ProfileView::new(
    171         pubkey,
    172         col,
    173         profiles,
    174         ndb,
    175         note_cache,
    176         img_cache,
    177         NoteOptions::default(),
    178     )
    179     .ui(ui, is_muted);
    180 
    181     note_action.map(RenderNavAction::NoteAction)
    182 }