notedeck

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

preview.rs (5658B)


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