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