contents.rs (3666B)
1 use crate::{colors, Damus}; 2 use egui::{Hyperlink, Image, RichText}; 3 use nostrdb::{BlockType, Mention, Note, NoteKey, Transaction}; 4 use tracing::warn; 5 6 pub struct NoteContents<'a> { 7 damus: &'a mut Damus, 8 txn: &'a Transaction, 9 note: &'a Note<'a>, 10 note_key: NoteKey, 11 } 12 13 impl<'a> NoteContents<'a> { 14 pub fn new( 15 damus: &'a mut Damus, 16 txn: &'a Transaction, 17 note: &'a Note, 18 note_key: NoteKey, 19 ) -> Self { 20 NoteContents { 21 damus, 22 txn, 23 note, 24 note_key, 25 } 26 } 27 } 28 29 impl egui::Widget for NoteContents<'_> { 30 fn ui(self, ui: &mut egui::Ui) -> egui::Response { 31 render_note_contents(ui, self.damus, self.txn, self.note, self.note_key).response 32 } 33 } 34 35 fn render_note_contents( 36 ui: &mut egui::Ui, 37 damus: &mut Damus, 38 txn: &Transaction, 39 note: &Note, 40 note_key: NoteKey, 41 ) -> egui::InnerResponse<()> { 42 #[cfg(feature = "profiling")] 43 puffin::profile_function!(); 44 45 let images: Vec<String> = vec![]; 46 47 let resp = ui.horizontal_wrapped(|ui| { 48 let blocks = if let Ok(blocks) = damus.ndb.get_blocks_by_key(txn, note_key) { 49 blocks 50 } else { 51 warn!("missing note content blocks? '{}'", note.content()); 52 ui.weak(note.content()); 53 return; 54 }; 55 56 ui.spacing_mut().item_spacing.x = 0.0; 57 58 for block in blocks.iter(note) { 59 match block.blocktype() { 60 BlockType::MentionBech32 => { 61 ui.colored_label(colors::PURPLE, "@"); 62 match block.as_mention().unwrap() { 63 Mention::Pubkey(npub) => { 64 let profile = damus.ndb.get_profile_by_pubkey(txn, npub.pubkey()).ok(); 65 if let Some(name) = profile 66 .as_ref() 67 .and_then(|p| crate::profile::get_profile_name(p)) 68 { 69 ui.colored_label(colors::PURPLE, name); 70 } else { 71 ui.colored_label(colors::PURPLE, "nostrich"); 72 } 73 } 74 _ => { 75 ui.colored_label(colors::PURPLE, block.as_str()); 76 } 77 } 78 } 79 80 BlockType::Hashtag => { 81 ui.colored_label(colors::PURPLE, "#"); 82 ui.colored_label(colors::PURPLE, block.as_str()); 83 } 84 85 BlockType::Url => { 86 /* 87 let url = block.as_str().to_lowercase(); 88 if url.ends_with("png") || url.ends_with("jpg") { 89 images.push(url); 90 } else { 91 */ 92 ui.add(Hyperlink::from_label_and_url( 93 RichText::new(block.as_str()).color(colors::PURPLE), 94 block.as_str(), 95 )); 96 //} 97 } 98 99 BlockType::Text => { 100 ui.label(block.as_str()); 101 } 102 103 _ => { 104 ui.colored_label(colors::PURPLE, block.as_str()); 105 } 106 } 107 } 108 }); 109 110 for image in images { 111 let img_resp = ui.add(Image::new(image.clone())); 112 img_resp.context_menu(|ui| { 113 if ui.button("Copy Link").clicked() { 114 ui.ctx().copy_text(image); 115 ui.close_menu(); 116 } 117 }); 118 } 119 120 resp 121 }