diff --git a/src/app.rs b/src/app.rs index eb9b616..b0d0cfd 100644 --- a/src/app.rs +++ b/src/app.rs @@ -481,7 +481,7 @@ impl Damus { timelines.push(Timeline::new(filter)); }; - let imgcache_dir = data_path.as_ref().join("cache/img"); + let imgcache_dir = data_path.as_ref().join(ImageCache::rel_datadir()); let _ = std::fs::create_dir_all(imgcache_dir.clone()); let mut config = Config::new(); diff --git a/src/app_creation.rs b/src/app_creation.rs index 42ec8a3..0e9a945 100644 --- a/src/app_creation.rs +++ b/src/app_creation.rs @@ -3,7 +3,7 @@ use crate::fonts::setup_fonts; use crate::ui::is_mobile; use eframe::NativeOptions; -pub const UI_SCALE_FACTOR: f32 = 0.2; +//pub const UI_SCALE_FACTOR: f32 = 0.2; pub fn generate_native_options() -> NativeOptions { generate_native_options_with_builder_modifiers(|builder| { @@ -40,7 +40,7 @@ pub fn setup_cc(cc: &eframe::CreationContext<'_>) { let ctx = &cc.egui_ctx; setup_fonts(ctx); - ctx.set_pixels_per_point(ctx.pixels_per_point() + UI_SCALE_FACTOR); + //ctx.set_pixels_per_point(ctx.pixels_per_point() + UI_SCALE_FACTOR); egui_extras::install_image_loaders(ctx); diff --git a/src/app_style.rs b/src/app_style.rs index efc4dfb..4873775 100644 --- a/src/app_style.rs +++ b/src/app_style.rs @@ -75,7 +75,7 @@ pub fn desktop_font_size(text_style: &NotedeckTextStyle) -> f32 { NotedeckTextStyle::Heading => 48.0, NotedeckTextStyle::Heading2 => 24.0, NotedeckTextStyle::Heading3 => 20.0, - NotedeckTextStyle::Body => 13.0, + NotedeckTextStyle::Body => 16.0, NotedeckTextStyle::Monospace => 13.0, NotedeckTextStyle::Button => 13.0, NotedeckTextStyle::Small => 12.0, diff --git a/src/imgcache.rs b/src/imgcache.rs index 9c2b668..6377f97 100644 --- a/src/imgcache.rs +++ b/src/imgcache.rs @@ -25,6 +25,10 @@ impl ImageCache { } } + pub fn rel_datadir() -> &'static str { + "cache/img" + } + pub fn write(cache_dir: &path::Path, url: &str, data: ColorImage) -> Result<()> { let file_path = cache_dir.join(Self::key(url)); let file = File::options() diff --git a/src/ui/note/contents.rs b/src/ui/note/contents.rs index 994da97..535611a 100644 --- a/src/ui/note/contents.rs +++ b/src/ui/note/contents.rs @@ -139,7 +139,7 @@ fn render_note_contents( if let Some(rec) = profile.as_ref() { resp.on_hover_ui_at_pointer(|ui| { ui.set_max_width(300.0); - ui.add(ui::ProfilePreview::new(rec)); + ui.add(ui::ProfilePreview::new(rec, &mut damus.img_cache)); }); } }); diff --git a/src/ui/note/mod.rs b/src/ui/note/mod.rs index cba860b..c0edc85 100644 --- a/src/ui/note/mod.rs +++ b/src/ui/note/mod.rs @@ -90,10 +90,12 @@ impl<'a> Note<'a> { let note_key = self.note.key().expect("todo: support non-db notes"); let txn = self.note.txn().expect("todo: support non-db notes"); - ui.with_layout(egui::Layout::left_to_right(egui::Align::TOP), |ui| { - let profile = self.app.ndb.get_profile_by_pubkey(txn, self.note.pubkey()); + crate::ui::padding(12.0, ui, |ui| { + ui.with_layout(egui::Layout::left_to_right(egui::Align::TOP), |ui| { + ui.spacing_mut().item_spacing.x = 16.0; + + let profile = self.app.ndb.get_profile_by_pubkey(txn, self.note.pubkey()); - crate::ui::padding(6.0, ui, |ui| { match profile .as_ref() .ok() diff --git a/src/ui/profile/picture.rs b/src/ui/profile/picture.rs index 2d7c7da..0bc18e1 100644 --- a/src/ui/profile/picture.rs +++ b/src/ui/profile/picture.rs @@ -5,32 +5,42 @@ use egui::{vec2, Sense, TextureHandle}; pub struct ProfilePic<'cache, 'url> { cache: &'cache mut ImageCache, url: &'url str, + size: f32, } impl<'cache, 'url> egui::Widget for ProfilePic<'cache, 'url> { fn ui(self, ui: &mut egui::Ui) -> egui::Response { - render_pfp(ui, self.cache, self.url) + render_pfp(ui, self.cache, self.url, self.size) } } impl<'cache, 'url> ProfilePic<'cache, 'url> { pub fn new(cache: &'cache mut ImageCache, url: &'url str) -> Self { - ProfilePic { cache, url } + let size = 32.0; + ProfilePic { cache, url, size } } pub fn no_pfp_url() -> &'static str { "https://damus.io/img/no-profile.svg" } + + pub fn size(mut self, size: f32) -> Self { + self.size = size; + self + } } -fn render_pfp(ui: &mut egui::Ui, img_cache: &mut ImageCache, url: &str) -> egui::Response { +fn render_pfp( + ui: &mut egui::Ui, + img_cache: &mut ImageCache, + url: &str, + ui_size: f32, +) -> egui::Response { #[cfg(feature = "profiling")] puffin::profile_function!(); - let ui_size = 30.0; - // We will want to downsample these so it's not blurry on hi res displays - let img_size = (ui_size * 2.0) as u32; + let img_size = 128u32; let m_cached_promise = img_cache.map().get(url); if m_cached_promise.is_none() { diff --git a/src/ui/profile/preview.rs b/src/ui/profile/preview.rs index 1127c06..4335481 100644 --- a/src/ui/profile/preview.rs +++ b/src/ui/profile/preview.rs @@ -1,20 +1,24 @@ use crate::app_style::NotedeckTextStyle; +use crate::imgcache::ImageCache; +use crate::ui::ProfilePic; use crate::{colors, images, DisplayName}; use egui::load::TexturePoll; use egui::{RichText, Sense}; use egui_extras::Size; use nostrdb::ProfileRecord; -pub struct ProfilePreview<'a> { +pub struct ProfilePreview<'a, 'cache> { profile: &'a ProfileRecord<'a>, + cache: &'cache mut ImageCache, banner_height: Size, } -impl<'a> ProfilePreview<'a> { - pub fn new(profile: &'a ProfileRecord<'a>) -> Self { +impl<'a, 'cache> ProfilePreview<'a, 'cache> { + pub fn new(profile: &'a ProfileRecord<'a>, cache: &'cache mut ImageCache) -> Self { let banner_height = Size::exact(80.0); ProfilePreview { profile, + cache, banner_height, } } @@ -58,14 +62,22 @@ impl<'a> ProfilePreview<'a> { } } - fn body(ui: &mut egui::Ui, profile: &ProfileRecord<'_>) { - let name = if let Some(name) = crate::profile::get_profile_name(profile) { + fn body(self, ui: &mut egui::Ui) { + let name = if let Some(name) = crate::profile::get_profile_name(self.profile) { name } else { DisplayName::One("??") }; crate::ui::padding(12.0, ui, |ui| { + let url = if let Some(url) = self.profile.record().profile().and_then(|p| p.picture()) { + url + } else { + ProfilePic::no_pfp_url() + }; + + ui.add(ProfilePic::new(self.cache, url).size(80.0)); + match name { DisplayName::One(n) => { ui.label(RichText::new(n).text_style(NotedeckTextStyle::Heading3.text_style())); @@ -88,21 +100,21 @@ impl<'a> ProfilePreview<'a> { } } - if let Some(about) = profile.record().profile().and_then(|p| p.about()) { + if let Some(about) = self.profile.record().profile().and_then(|p| p.about()) { ui.label(about); } }); } } -impl<'a> egui::Widget for ProfilePreview<'a> { +impl<'a, 'cache> egui::Widget for ProfilePreview<'a, 'cache> { fn ui(self, ui: &mut egui::Ui) -> egui::Response { ui.vertical(|ui| { ui.add_sized([ui.available_size().x, 80.0], |ui: &mut egui::Ui| { ProfilePreview::banner(ui, self.profile) }); - ProfilePreview::body(ui, self.profile); + self.body(ui); }) .response } @@ -116,12 +128,14 @@ mod previews { pub struct ProfilePreviewPreview<'a> { profile: ProfileRecord<'a>, + cache: ImageCache, } impl<'a> ProfilePreviewPreview<'a> { pub fn new() -> Self { let profile = test_profile_record(); - ProfilePreviewPreview { profile } + let cache = ImageCache::new(ImageCache::rel_datadir().into()); + ProfilePreviewPreview { profile, cache } } } @@ -133,11 +147,11 @@ mod previews { impl<'a> View for ProfilePreviewPreview<'a> { fn ui(&mut self, ui: &mut egui::Ui) { - ProfilePreview::new(&self.profile).ui(ui); + ProfilePreview::new(&self.profile, &mut self.cache).ui(ui); } } - impl<'a> Preview for ProfilePreview<'a> { + impl<'a, 'cache> Preview for ProfilePreview<'a, 'cache> { /// A preview of the profile preview :D type Prev = ProfilePreviewPreview<'a>;