mention.rs (2710B)
1 use crate::actionbar::NoteAction; 2 use crate::ui; 3 use egui::Sense; 4 use enostr::Pubkey; 5 use nostrdb::{Ndb, Transaction}; 6 use notedeck::ImageCache; 7 8 pub struct Mention<'a> { 9 ndb: &'a Ndb, 10 img_cache: &'a mut ImageCache, 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 ImageCache, 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 fn mention_ui( 66 ndb: &Ndb, 67 img_cache: &mut ImageCache, 68 txn: &Transaction, 69 pk: &[u8; 32], 70 ui: &mut egui::Ui, 71 size: f32, 72 selectable: bool, 73 ) -> egui::InnerResponse<Option<NoteAction>> { 74 #[cfg(feature = "profiling")] 75 puffin::profile_function!(); 76 77 let link_color = ui.visuals().hyperlink_color; 78 79 ui.horizontal(|ui| { 80 let profile = ndb.get_profile_by_pubkey(txn, pk).ok(); 81 82 let name: String = 83 if let Some(name) = profile.as_ref().and_then(crate::profile::get_profile_name) { 84 format!("@{}", name.username()) 85 } else { 86 "@???".to_string() 87 }; 88 89 let resp = ui.add( 90 egui::Label::new(egui::RichText::new(name).color(link_color).size(size)) 91 .sense(Sense::click()) 92 .selectable(selectable), 93 ); 94 95 let note_action = if resp.clicked() { 96 ui::show_pointer(ui); 97 Some(NoteAction::OpenProfile(Pubkey::new(*pk))) 98 } else if resp.hovered() { 99 ui::show_pointer(ui); 100 None 101 } else { 102 None 103 }; 104 105 if let Some(rec) = profile.as_ref() { 106 resp.on_hover_ui_at_pointer(|ui| { 107 ui.set_max_width(300.0); 108 ui.add(ui::ProfilePreview::new(rec, img_cache)); 109 }); 110 } 111 112 note_action 113 }) 114 }