From 24d400d5aa327a27ef50efd9a4d62784c4e1d1cc Mon Sep 17 00:00:00 2001 From: William Casarin Date: Tue, 11 Jun 2024 17:44:35 -0700 Subject: [PATCH] small inline preview pfps Signed-off-by: William Casarin --- src/app.rs | 4 +- src/ui/account_management.rs | 1 - src/ui/note/contents.rs | 10 +-- src/ui/note/mod.rs | 141 +++++++++++++++++++++-------------- src/ui/note/options.rs | 20 +++++ src/ui/side_panel.rs | 1 - 6 files changed, 110 insertions(+), 67 deletions(-) diff --git a/src/app.rs b/src/app.rs index bd12152..667b97f 100644 --- a/src/app.rs +++ b/src/app.rs @@ -651,7 +651,7 @@ impl Damus { is_mobile = Some(true); } else if arg == "--filter" { let next_args = &args[1 + i + 1..]; - if next_args.len() == 0 { + if next_args.is_empty() { continue; } let filter = &next_args[0]; @@ -663,7 +663,7 @@ impl Damus { } } else if arg == "--filter-file" || arg == "-f" { let next_args = &args[1 + i + 1..]; - if next_args.len() == 0 { + if next_args.is_empty() { continue; } let filter_file = &next_args[0]; diff --git a/src/ui/account_management.rs b/src/ui/account_management.rs index 8cf3cd1..8e61fc1 100644 --- a/src/ui/account_management.rs +++ b/src/ui/account_management.rs @@ -199,7 +199,6 @@ fn selected_widget() -> impl egui::Widget { // PREVIEWS mod preview { - use super::*; use crate::test_data::get_account_manager_test_app; diff --git a/src/ui/note/contents.rs b/src/ui/note/contents.rs index 7b2b8bf..e64ca2f 100644 --- a/src/ui/note/contents.rs +++ b/src/ui/note/contents.rs @@ -89,11 +89,11 @@ fn render_note_preview( ui.visuals().noninteractive().bg_stroke.color, )) .show(ui, |ui| { - ui.add( - ui::Note::new(app, ¬e) - .actionbar(false) - .note_previews(false), - ) + ui::Note::new(app, ¬e) + .actionbar(false) + .small_pfp(true) + .note_previews(false) + .show(ui); }) .response } diff --git a/src/ui/note/mod.rs b/src/ui/note/mod.rs index dd2f67e..f4c49a0 100644 --- a/src/ui/note/mod.rs +++ b/src/ui/note/mod.rs @@ -4,7 +4,7 @@ pub mod options; pub use contents::NoteContents; pub use options::NoteOptions; -use crate::{colors, notecache::CachedNote, ui, Damus}; +use crate::{colors, notecache::CachedNote, ui, ui::View, Damus}; use egui::{Label, RichText, Sense}; use nostrdb::{NoteKey, Transaction}; use std::hash::{Hash, Hasher}; @@ -20,12 +20,12 @@ pub struct NoteResponse { pub action: Option, } -impl<'a> egui::Widget for Note<'a> { - fn ui(self, ui: &mut egui::Ui) -> egui::Response { +impl<'a> View for Note<'a> { + fn ui(&mut self, ui: &mut egui::Ui) { if self.app.textmode { - self.textmode_ui(ui) + self.textmode_ui(ui); } else { - self.show(ui).response + self.show(ui); } } } @@ -140,6 +140,11 @@ impl<'a> Note<'a> { self } + pub fn small_pfp(mut self, enable: bool) -> Self { + self.options_mut().set_small_pfp(enable); + self + } + pub fn note_previews(mut self, enable: bool) -> Self { self.options_mut().set_note_previews(enable); self @@ -153,7 +158,7 @@ impl<'a> Note<'a> { &mut self.flags } - fn textmode_ui(self, ui: &mut egui::Ui) -> egui::Response { + fn textmode_ui(&mut self, ui: &mut egui::Ui) -> egui::Response { let note_key = self.note.key().expect("todo: implement non-db notes"); let txn = self.note.txn().expect("todo: implement non-db notes"); @@ -191,66 +196,86 @@ impl<'a> Note<'a> { .response } - pub fn show(self, ui: &mut egui::Ui) -> NoteResponse { + fn pfp( + &mut self, + note_key: NoteKey, + profile: &Result, nostrdb::Error>, + ui: &mut egui::Ui, + ) { + ui.spacing_mut().item_spacing.x = 16.0; + + let pfp_size = if self.options().has_small_pfp() { + 24.0 + } else { + ui::ProfilePic::default_size() + }; + + match profile + .as_ref() + .ok() + .and_then(|p| p.record().profile()?.picture()) + { + // these have different lifetimes and types, + // so the calls must be separate + Some(pic) => { + let expand_size = 5.0; + let anim_speed = 0.05; + let profile_key = profile.as_ref().unwrap().record().note_key(); + let note_key = note_key.as_u64(); + + if self.app.is_mobile() { + ui.add(ui::ProfilePic::new(&mut self.app.img_cache, pic)); + } else { + let (rect, size) = ui::anim::hover_expand( + ui, + egui::Id::new(ProfileAnimId { + profile_key, + note_key, + }), + pfp_size, + expand_size, + anim_speed, + ); + + ui.put( + rect, + ui::ProfilePic::new(&mut self.app.img_cache, pic).size(size), + ) + .on_hover_ui_at_pointer(|ui| { + ui.set_max_width(300.0); + ui.add(ui::ProfilePreview::new( + profile.as_ref().unwrap(), + &mut self.app.img_cache, + )); + }); + } + } + None => { + ui.add( + ui::ProfilePic::new(&mut self.app.img_cache, ui::ProfilePic::no_pfp_url()) + .size(pfp_size), + ); + } + } + } + + pub fn show(&mut self, ui: &mut egui::Ui) -> NoteResponse { #[cfg(feature = "profiling")] puffin::profile_function!(); let note_key = self.note.key().expect("todo: support non-db notes"); let txn = self.note.txn().expect("todo: support non-db notes"); let mut note_action: Option = None; + let profile = self.app.ndb.get_profile_by_pubkey(txn, self.note.pubkey()); + + if self.options().has_wide() { + ui.horizontal_centered(|ui| { + self.pfp(note_key, &profile, ui); + }); + } let response = 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()); - - match profile - .as_ref() - .ok() - .and_then(|p| p.record().profile()?.picture()) - { - // these have different lifetimes and types, - // so the calls must be separate - Some(pic) => { - let expand_size = 5.0; - let anim_speed = 0.05; - let profile_key = profile.as_ref().unwrap().record().note_key(); - let note_key = note_key.as_u64(); - - if self.app.is_mobile() { - ui.add(ui::ProfilePic::new(&mut self.app.img_cache, pic)); - } else { - let (rect, size) = ui::anim::hover_expand( - ui, - egui::Id::new(ProfileAnimId { - profile_key, - note_key, - }), - ui::ProfilePic::default_size(), - expand_size, - anim_speed, - ); - - ui.put( - rect, - ui::ProfilePic::new(&mut self.app.img_cache, pic).size(size), - ) - .on_hover_ui_at_pointer(|ui| { - ui.set_max_width(300.0); - ui.add(ui::ProfilePreview::new( - profile.as_ref().unwrap(), - &mut self.app.img_cache, - )); - }); - } - } - None => { - ui.add(ui::ProfilePic::new( - &mut self.app.img_cache, - ui::ProfilePic::no_pfp_url(), - )); - } - } + self.pfp(note_key, &profile, ui); ui.with_layout(egui::Layout::top_down(egui::Align::LEFT), |ui| { ui.horizontal(|ui| { diff --git a/src/ui/note/options.rs b/src/ui/note/options.rs index d0ebc32..b33bce2 100644 --- a/src/ui/note/options.rs +++ b/src/ui/note/options.rs @@ -7,6 +7,8 @@ bitflags! { pub struct NoteOptions: u32 { const actionbar = 0b00000001; const note_previews = 0b00000010; + const small_pfp = 0b00000100; + const wide = 0b00001000; } } @@ -21,6 +23,24 @@ impl NoteOptions { (self & NoteOptions::note_previews) == NoteOptions::note_previews } + #[inline] + pub fn has_small_pfp(self) -> bool { + (self & NoteOptions::small_pfp) == NoteOptions::small_pfp + } + + #[inline] + pub fn has_wide(self) -> bool { + (self & NoteOptions::wide) == NoteOptions::wide + } + + #[inline] + pub fn set_small_pfp(&mut self, enable: bool) { + if enable { + *self |= NoteOptions::small_pfp; + } else { + *self &= !NoteOptions::small_pfp; + } + } #[inline] pub fn set_note_previews(&mut self, enable: bool) { if enable { diff --git a/src/ui/side_panel.rs b/src/ui/side_panel.rs index 9960751..b424780 100644 --- a/src/ui/side_panel.rs +++ b/src/ui/side_panel.rs @@ -119,7 +119,6 @@ fn add_column_button(dark_mode: bool) -> egui::Button<'static> { } mod preview { - use crate::{ test_data,