preview.rs (5598B)
1 use crate::ui::ProfilePic; 2 use crate::NostrName; 3 use egui::{Frame, Label, RichText, Widget}; 4 use egui_extras::Size; 5 use nostrdb::ProfileRecord; 6 7 use notedeck::{ImageCache, NotedeckTextStyle, UserAccount}; 8 9 use super::{about_section_widget, banner, display_name_widget, get_display_name, get_profile_url}; 10 11 pub struct ProfilePreview<'a, 'cache> { 12 profile: &'a ProfileRecord<'a>, 13 cache: &'cache mut ImageCache, 14 banner_height: Size, 15 } 16 17 impl<'a, 'cache> ProfilePreview<'a, 'cache> { 18 pub fn new(profile: &'a ProfileRecord<'a>, cache: &'cache mut ImageCache) -> Self { 19 let banner_height = Size::exact(80.0); 20 ProfilePreview { 21 profile, 22 cache, 23 banner_height, 24 } 25 } 26 27 pub fn banner_height(&mut self, size: Size) { 28 self.banner_height = size; 29 } 30 31 fn body(self, ui: &mut egui::Ui) { 32 let padding = 12.0; 33 crate::ui::padding(padding, ui, |ui| { 34 let mut pfp_rect = ui.available_rect_before_wrap(); 35 let size = 80.0; 36 pfp_rect.set_width(size); 37 pfp_rect.set_height(size); 38 let pfp_rect = pfp_rect.translate(egui::vec2(0.0, -(padding + 2.0 + (size / 2.0)))); 39 40 ui.put( 41 pfp_rect, 42 ProfilePic::new(self.cache, get_profile_url(Some(self.profile))).size(size), 43 ); 44 ui.add(display_name_widget( 45 get_display_name(Some(self.profile)), 46 false, 47 )); 48 ui.add(about_section_widget(self.profile)); 49 }); 50 } 51 } 52 53 impl egui::Widget for ProfilePreview<'_, '_> { 54 fn ui(self, ui: &mut egui::Ui) -> egui::Response { 55 ui.vertical(|ui| { 56 banner( 57 ui, 58 self.profile.record().profile().and_then(|p| p.banner()), 59 80.0, 60 ); 61 62 self.body(ui); 63 }) 64 .response 65 } 66 } 67 68 pub struct SimpleProfilePreview<'a, 'cache> { 69 profile: Option<&'a ProfileRecord<'a>>, 70 cache: &'cache mut ImageCache, 71 is_nsec: bool, 72 } 73 74 impl<'a, 'cache> SimpleProfilePreview<'a, 'cache> { 75 pub fn new( 76 profile: Option<&'a ProfileRecord<'a>>, 77 cache: &'cache mut ImageCache, 78 is_nsec: bool, 79 ) -> Self { 80 SimpleProfilePreview { 81 profile, 82 cache, 83 is_nsec, 84 } 85 } 86 } 87 88 impl egui::Widget for SimpleProfilePreview<'_, '_> { 89 fn ui(self, ui: &mut egui::Ui) -> egui::Response { 90 Frame::none() 91 .show(ui, |ui| { 92 ui.add(ProfilePic::new(self.cache, get_profile_url(self.profile)).size(48.0)); 93 ui.vertical(|ui| { 94 ui.add(display_name_widget(get_display_name(self.profile), true)); 95 if !self.is_nsec { 96 ui.add( 97 Label::new( 98 RichText::new("Read only") 99 .size(notedeck::fonts::get_font_size( 100 ui.ctx(), 101 &NotedeckTextStyle::Tiny, 102 )) 103 .color(ui.visuals().warn_fg_color), 104 ) 105 .selectable(false), 106 ); 107 } 108 }); 109 }) 110 .response 111 } 112 } 113 114 mod previews { 115 use super::*; 116 use crate::test_data::test_profile_record; 117 use crate::ui::{Preview, PreviewConfig}; 118 use notedeck::{App, AppContext}; 119 120 pub struct ProfilePreviewPreview<'a> { 121 profile: ProfileRecord<'a>, 122 } 123 124 impl ProfilePreviewPreview<'_> { 125 pub fn new() -> Self { 126 let profile = test_profile_record(); 127 ProfilePreviewPreview { profile } 128 } 129 } 130 131 impl Default for ProfilePreviewPreview<'_> { 132 fn default() -> Self { 133 ProfilePreviewPreview::new() 134 } 135 } 136 137 impl App for ProfilePreviewPreview<'_> { 138 fn update(&mut self, app: &mut AppContext<'_>, ui: &mut egui::Ui) { 139 ProfilePreview::new(&self.profile, app.img_cache).ui(ui); 140 } 141 } 142 143 impl<'a> Preview for ProfilePreview<'a, '_> { 144 /// A preview of the profile preview :D 145 type Prev = ProfilePreviewPreview<'a>; 146 147 fn preview(_cfg: PreviewConfig) -> Self::Prev { 148 ProfilePreviewPreview::new() 149 } 150 } 151 } 152 153 pub fn get_profile_url_owned(profile: Option<ProfileRecord<'_>>) -> &str { 154 if let Some(url) = profile.and_then(|pr| pr.record().profile().and_then(|p| p.picture())) { 155 url 156 } else { 157 ProfilePic::no_pfp_url() 158 } 159 } 160 161 pub fn get_account_url<'a>( 162 txn: &'a nostrdb::Transaction, 163 ndb: &nostrdb::Ndb, 164 account: Option<&UserAccount>, 165 ) -> &'a str { 166 if let Some(selected_account) = account { 167 if let Ok(profile) = ndb.get_profile_by_pubkey(txn, selected_account.pubkey.bytes()) { 168 get_profile_url_owned(Some(profile)) 169 } else { 170 get_profile_url_owned(None) 171 } 172 } else { 173 get_profile_url(None) 174 } 175 } 176 177 pub fn one_line_display_name_widget<'a>( 178 visuals: &egui::Visuals, 179 display_name: NostrName<'a>, 180 style: NotedeckTextStyle, 181 ) -> impl egui::Widget + 'a { 182 let text_style = style.text_style(); 183 let color = visuals.noninteractive().fg_stroke.color; 184 185 move |ui: &mut egui::Ui| -> egui::Response { 186 ui.label( 187 RichText::new(display_name.name()) 188 .text_style(text_style) 189 .color(color), 190 ) 191 } 192 }