notedeck

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

route.rs (5414B)


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