mention.rs (2685B)
1 use crate::ui; 2 use crate::{actionbar::NoteAction, profile::get_display_name, timeline::TimelineKind}; 3 use egui::Sense; 4 use enostr::Pubkey; 5 use nostrdb::{Ndb, Transaction}; 6 use notedeck::Images; 7 8 pub struct Mention<'a> { 9 ndb: &'a Ndb, 10 img_cache: &'a mut Images, 11 txn: &'a Transaction, 12 pk: &'a [u8; 32], 13 selectable: bool, 14 size: f32, 15 } 16 17 impl<'a> Mention<'a> { 18 pub fn new( 19 ndb: &'a Ndb, 20 img_cache: &'a mut Images, 21 txn: &'a Transaction, 22 pk: &'a [u8; 32], 23 ) -> Self { 24 let size = 16.0; 25 let selectable = true; 26 Mention { 27 ndb, 28 img_cache, 29 txn, 30 pk, 31 selectable, 32 size, 33 } 34 } 35 36 pub fn selectable(mut self, selectable: bool) -> Self { 37 self.selectable = selectable; 38 self 39 } 40 41 pub fn size(mut self, size: f32) -> Self { 42 self.size = size; 43 self 44 } 45 46 pub fn show(self, ui: &mut egui::Ui) -> egui::InnerResponse<Option<NoteAction>> { 47 mention_ui( 48 self.ndb, 49 self.img_cache, 50 self.txn, 51 self.pk, 52 ui, 53 self.size, 54 self.selectable, 55 ) 56 } 57 } 58 59 impl egui::Widget for Mention<'_> { 60 fn ui(self, ui: &mut egui::Ui) -> egui::Response { 61 self.show(ui).response 62 } 63 } 64 65 #[allow(clippy::too_many_arguments)] 66 fn mention_ui( 67 ndb: &Ndb, 68 img_cache: &mut Images, 69 txn: &Transaction, 70 pk: &[u8; 32], 71 ui: &mut egui::Ui, 72 size: f32, 73 selectable: bool, 74 ) -> egui::InnerResponse<Option<NoteAction>> { 75 #[cfg(feature = "profiling")] 76 puffin::profile_function!(); 77 78 let link_color = ui.visuals().hyperlink_color; 79 80 ui.horizontal(|ui| { 81 let profile = ndb.get_profile_by_pubkey(txn, pk).ok(); 82 83 let name: String = format!("@{}", get_display_name(profile.as_ref()).name()); 84 85 let resp = ui.add( 86 egui::Label::new(egui::RichText::new(name).color(link_color).size(size)) 87 .sense(Sense::click()) 88 .selectable(selectable), 89 ); 90 91 let note_action = if resp.clicked() { 92 ui::show_pointer(ui); 93 Some(NoteAction::OpenTimeline(TimelineKind::profile( 94 Pubkey::new(*pk), 95 ))) 96 } else if resp.hovered() { 97 ui::show_pointer(ui); 98 None 99 } else { 100 None 101 }; 102 103 if let Some(rec) = profile.as_ref() { 104 resp.on_hover_ui_at_pointer(|ui| { 105 ui.set_max_width(300.0); 106 ui.add(ui::ProfilePreview::new(rec, img_cache)); 107 }); 108 } 109 110 note_action 111 }) 112 }