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, ¬e) 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, ¬e) 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 }