From df0377cb891c44797df29ec950c2e019d5fff178 Mon Sep 17 00:00:00 2001 From: kernelkind Date: Sun, 26 May 2024 22:05:45 -0400 Subject: [PATCH] Pfp integration to side panel Signed-off-by: kernelkind --- src/app.rs | 15 +++- src/ui/global_popup.rs | 7 +- src/ui/profile/preview.rs | 2 +- src/ui/profile/profile_preview_controller.rs | 24 ++++-- src/ui/side_panel.rs | 91 +++++++++++++++----- 5 files changed, 109 insertions(+), 30 deletions(-) diff --git a/src/app.rs b/src/app.rs index 52993ee..891d75d 100644 --- a/src/app.rs +++ b/src/app.rs @@ -8,6 +8,7 @@ use crate::notecache::{CachedNote, NoteCache}; use crate::relay_pool_manager::create_wakeup; use crate::timeline; use crate::timeline::{NoteRef, Timeline, ViewFilter}; +use crate::ui::profile::SimpleProfilePreviewController; use crate::ui::{is_mobile, DesktopGlobalPopup, DesktopSidePanel, View}; use crate::Result; @@ -853,7 +854,11 @@ fn render_damus_desktop(ctx: &egui::Context, app: &mut Damus) { if app.timelines.len() == 1 { DesktopSidePanel::panel().show(ctx, |ui| { - DesktopSidePanel::inner(ui); + DesktopSidePanel::new( + &mut app.account_manager, + SimpleProfilePreviewController::new(&app.ndb, &mut app.img_cache), + ) + .inner(ui); }); main_panel(&ctx.style()).show(ctx, |ui| { DesktopGlobalPopup::new(app).ui(ui); @@ -882,7 +887,13 @@ fn timelines_view(ui: &mut egui::Ui, sizes: Size, app: &mut Damus, timelines: us .sizes(sizes, timelines) .clip(true) .horizontal(|mut strip| { - strip.cell(crate::ui::DesktopSidePanel::inner); + strip.cell(|ui| { + DesktopSidePanel::new( + &mut app.account_manager, + SimpleProfilePreviewController::new(&app.ndb, &mut app.img_cache), + ) + .inner(ui) + }); for timeline_ind in 0..timelines { strip.cell(|ui| timeline::timeline_view(ui, app, timeline_ind)); diff --git a/src/ui/global_popup.rs b/src/ui/global_popup.rs index 2619187..f1bd505 100644 --- a/src/ui/global_popup.rs +++ b/src/ui/global_popup.rs @@ -126,7 +126,7 @@ impl<'a> DesktopGlobalPopup<'a> { mod preview { use crate::{ test_data, - ui::{DesktopSidePanel, Preview, View}, + ui::{profile::SimpleProfilePreviewController, DesktopSidePanel, Preview, View}, Damus, }; @@ -157,7 +157,10 @@ mod preview { impl View for GlobalPopupPreview { fn ui(&mut self, ui: &mut egui::Ui) { - let mut panel = DesktopSidePanel::new(); + let mut panel = DesktopSidePanel::new( + &mut self.app.account_manager, + SimpleProfilePreviewController::new(&self.app.ndb, &mut self.app.img_cache), + ); DesktopSidePanel::panel().show(ui.ctx(), |ui| panel.ui(ui)); DesktopGlobalPopup::new(&mut self.app).ui(ui); } diff --git a/src/ui/profile/preview.rs b/src/ui/profile/preview.rs index 3d851ae..806c39c 100644 --- a/src/ui/profile/preview.rs +++ b/src/ui/profile/preview.rs @@ -156,7 +156,7 @@ pub fn get_display_name<'a>(profile: &'a ProfileRecord<'a>) -> DisplayName<'a> { } } -fn get_profile_url<'a>(profile: &'a ProfileRecord<'a>) -> &'a str { +pub fn get_profile_url<'a>(profile: &'a ProfileRecord<'a>) -> &'a str { if let Some(url) = profile.record().profile().and_then(|p| p.picture()) { url } else { diff --git a/src/ui/profile/profile_preview_controller.rs b/src/ui/profile/profile_preview_controller.rs index 5786d31..f154bad 100644 --- a/src/ui/profile/profile_preview_controller.rs +++ b/src/ui/profile/profile_preview_controller.rs @@ -6,7 +6,10 @@ use crate::{ ui::state_in_memory::STATE_ACCOUNT_SWITCHER, DisplayName, }; -use super::preview::{get_display_name, SimpleProfilePreview}; +use super::{ + preview::{get_display_name, get_profile_url, SimpleProfilePreview}, + ProfilePic, +}; pub struct SimpleProfilePreviewController<'a> { ndb: &'a Ndb, @@ -117,7 +120,7 @@ impl<'a> SimpleProfilePreviewController<'a> { } pub fn show_with_nickname( - &'a self, + &self, ui: &mut egui::Ui, key: &Pubkey, ui_element: fn(ui: &mut egui::Ui, username: &DisplayName) -> egui::Response, @@ -133,10 +136,21 @@ impl<'a> SimpleProfilePreviewController<'a> { } pub fn show_with_pfp( - &'a self, + &mut self, ui: &mut egui::Ui, key: &Pubkey, - ui_element: fn(ui: &mut egui::Ui, preview: SimpleProfilePreview) -> egui::Response, - ) { + ui_element: fn(ui: &mut egui::Ui, pfp: ProfilePic) -> egui::Response, + ) -> Option { + if let Ok(txn) = Transaction::new(self.ndb) { + let profile = self.ndb.get_profile_by_pubkey(&txn, key.bytes()); + + if let Ok(profile) = profile { + return Some(ui_element( + ui, + ProfilePic::new(self.img_cache, get_profile_url(&profile)), + )); + } + } + None } } diff --git a/src/ui/side_panel.rs b/src/ui/side_panel.rs index b705b44..a81b808 100644 --- a/src/ui/side_panel.rs +++ b/src/ui/side_panel.rs @@ -1,37 +1,43 @@ -use egui::{Button, Layout, SidePanel, Vec2}; +use egui::{Button, Layout, SidePanel, Vec2, Widget}; -use crate::ui::global_popup::GlobalPopupType; +use crate::{account_manager::AccountManager, ui::global_popup::GlobalPopupType}; use super::{ + profile::SimpleProfilePreviewController, state_in_memory::{STATE_ACCOUNT_SWITCHER, STATE_SIDE_PANEL}, - View, + ProfilePic, View, }; -#[derive(Default)] -pub struct DesktopSidePanel {} +pub struct DesktopSidePanel<'a> { + account_manager: &'a mut AccountManager, + simple_preview_controller: SimpleProfilePreviewController<'a>, +} static ID: &str = "left panel"; -impl View for DesktopSidePanel { +impl<'a> View for DesktopSidePanel<'a> { fn ui(&mut self, ui: &mut egui::Ui) { - DesktopSidePanel::inner(ui); + self.inner(ui); } } -impl DesktopSidePanel { - pub fn new() -> Self { - DesktopSidePanel::default() +impl<'a> DesktopSidePanel<'a> { + pub fn new( + account_manager: &'a mut AccountManager, + simple_preview_controller: SimpleProfilePreviewController<'a>, + ) -> Self { + DesktopSidePanel { + account_manager, + simple_preview_controller, + } } - pub fn inner(ui: &mut egui::Ui) { + pub fn inner(&mut self, ui: &mut egui::Ui) { let dark_mode = ui.ctx().style().visuals.dark_mode; let spacing_amt = 16.0; ui.with_layout(Layout::bottom_up(egui::Align::Center), |ui| { ui.add_space(spacing_amt); - if ui - .add_sized(Vec2::new(32.0, 32.0), Button::new("A")) - .clicked() - { + if self.pfp_button(ui).clicked() { STATE_SIDE_PANEL.set_state(ui.ctx(), Some(GlobalPopupType::AccountSwitcher)); let previous_val = STATE_ACCOUNT_SWITCHER.get_state(ui.ctx()); STATE_ACCOUNT_SWITCHER.set_state(ui.ctx(), !previous_val); @@ -44,11 +50,32 @@ impl DesktopSidePanel { }); } + fn pfp_button(&mut self, ui: &mut egui::Ui) -> egui::Response { + if let Some(selected_account) = self.account_manager.get_selected_account() { + if let Some(response) = self.simple_preview_controller.show_with_pfp( + ui, + &selected_account.key.pubkey, + show_pfp(), + ) { + return response; + } + } + + add_button_to_ui(ui, no_account_pfp()) + } + pub fn panel() -> SidePanel { egui::SidePanel::left(ID).resizable(false).exact_width(40.0) } } +fn show_pfp() -> fn(ui: &mut egui::Ui, pfp: ProfilePic) -> egui::Response { + |ui, pfp| { + let response = pfp.ui(ui); + ui.allocate_rect(response.rect, egui::Sense::click()) + } +} + fn settings_button(dark_mode: bool) -> egui::Button<'static> { let _ = dark_mode; let img_data = egui::include_image!("../../assets/icons/settings_dark_4x.png"); @@ -56,6 +83,16 @@ fn settings_button(dark_mode: bool) -> egui::Button<'static> { egui::Button::image(egui::Image::new(img_data).max_width(32.0)).frame(false) } +fn add_button_to_ui(ui: &mut egui::Ui, button: Button) -> egui::Response { + ui.add_sized(Vec2::new(32.0, 32.0), button) +} + +fn no_account_pfp() -> Button<'static> { + Button::new("A") + .rounding(20.0) + .min_size(Vec2::new(38.0, 38.0)) +} + fn add_column_button(dark_mode: bool) -> egui::Button<'static> { let _ = dark_mode; let img_data = egui::include_image!("../../assets/icons/add_column_dark_4x.png"); @@ -64,26 +101,40 @@ fn add_column_button(dark_mode: bool) -> egui::Button<'static> { } mod preview { - use crate::ui::Preview; + use nostrdb::Ndb; + + use crate::{imgcache::ImageCache, test_data, ui::Preview}; use super::*; - pub struct DesktopSidePanelPreview {} + pub struct DesktopSidePanelPreview { + account_manager: AccountManager, + ndb: Ndb, + img_cache: ImageCache, + } impl DesktopSidePanelPreview { fn new() -> Self { - DesktopSidePanelPreview {} + let (account_manager, ndb, img_cache) = test_data::get_accmgr_and_ndb_and_imgcache(); + DesktopSidePanelPreview { + account_manager, + ndb, + img_cache, + } } } impl View for DesktopSidePanelPreview { fn ui(&mut self, ui: &mut egui::Ui) { - let mut panel = DesktopSidePanel::new(); + let mut panel = DesktopSidePanel::new( + &mut self.account_manager, + SimpleProfilePreviewController::new(&self.ndb, &mut self.img_cache), + ); DesktopSidePanel::panel().show(ui.ctx(), |ui| panel.ui(ui)); } } - impl Preview for DesktopSidePanel { + impl<'a> Preview for DesktopSidePanel<'a> { type Prev = DesktopSidePanelPreview; fn preview() -> Self::Prev {