notedeck

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

route.rs (6729B)


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