notedeck

One damus client to rule them all
git clone git://jb55.com/notedeck
Log | Files | Refs | README | LICENSE

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 }