notedeck

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

commit 98a61c0aa78c2dbf378bbb4be69cad8198009a8f
parent 1458498131e384e50d2628de5219c02cffecf66b
Author: kernelkind <kernelkind@gmail.com>
Date:   Tue, 18 Jun 2024 19:11:24 -0400

reintroduce account switcher

Signed-off-by: kernelkind <kernelkind@gmail.com>

Diffstat:
Msrc/app.rs | 14+++++++++-----
Msrc/ui/account_switcher.rs | 84+++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------------------
Msrc/ui/side_panel.rs | 48+++++++++++++++++++++++++++++++++++-------------
3 files changed, 105 insertions(+), 41 deletions(-)

diff --git a/src/app.rs b/src/app.rs @@ -10,8 +10,8 @@ use crate::relay_pool_manager::RelayPoolManager; use crate::route::Route; use crate::timeline; use crate::timeline::{MergeKind, NoteRef, Timeline, ViewFilter}; -use crate::ui; -use crate::ui::{DesktopSidePanel, RelayView, SidePanelAction, View}; +use crate::ui::{self, AccountSelectionWidget}; +use crate::ui::{DesktopSidePanel, RelayView, View}; use crate::Result; use egui_nav::{Nav, NavAction}; use enostr::RelayPool; @@ -58,6 +58,7 @@ pub struct Damus { pub account_manager: AccountManager, frame_history: crate::frame_history::FrameHistory, + pub show_account_switcher: bool, } fn relay_setup(pool: &mut RelayPool, ctx: &egui::Context) { @@ -726,6 +727,7 @@ impl Damus { ), //compose: "".to_string(), frame_history: FrameHistory::default(), + show_account_switcher: false, } } @@ -752,6 +754,7 @@ impl Damus { ndb: Ndb::new(data_path.as_ref().to_str().expect("db path ok"), &config).expect("ndb"), account_manager: AccountManager::new(None, crate::key_storage::KeyStorage::None), frame_history: FrameHistory::default(), + show_account_switcher: false, } } @@ -983,6 +986,9 @@ fn render_damus_desktop(ctx: &egui::Context, app: &mut Damus) { main_panel(&ctx.style(), app.is_mobile()).show(ctx, |ui| { ui.spacing_mut().item_spacing.x = 0.0; + if app.show_account_switcher { + AccountSelectionWidget::ui(app, ui); + } if need_scroll { egui::ScrollArea::horizontal().show(ui, |ui| { timelines_view(ui, panel_sizes, app, app.timelines.len()); @@ -1004,10 +1010,8 @@ fn timelines_view(ui: &mut egui::Ui, sizes: Size, app: &mut Damus, timelines: us if side_panel.response.clicked() { info!("clicked {:?}", side_panel.action); - if let SidePanelAction::Account = side_panel.action { - app.timelines[0].routes.push(Route::ManageAccount); - } } + DesktopSidePanel::perform_action(app, side_panel.action); }); for timeline_ind in 0..timelines { diff --git a/src/ui/account_switcher.rs b/src/ui/account_switcher.rs @@ -30,39 +30,67 @@ impl AccountSelectionWidget { if app.is_mobile() { Self::show_mobile(ui); } else { - Self::show(app, ui); + account_switcher_window(&mut app.show_account_switcher.clone()).show( + ui.ctx(), + |ui: &mut egui::Ui| { + let (account_selection_response, response) = Self::show(app, ui); + if let Some(action) = account_selection_response.action { + Self::perform_action(app, action); + } + response + }, + ); + } + } + + fn perform_action(app: &mut Damus, action: AccountSelectAction) { + match action { + AccountSelectAction::RemoveAccount { _index } => { + app.account_manager.remove_account(_index) + } + AccountSelectAction::SelectAccount { _index } => { + app.show_account_switcher = false; + app.account_manager.select_account(_index); + } + AccountSelectAction::OpenAccountManagement => { + app.show_account_switcher = false; + // TODO: push account management to global popup router + } } } - fn show(app: &mut Damus, ui: &mut egui::Ui) -> AccountSelectResponse { + fn show(app: &mut Damus, ui: &mut egui::Ui) -> (AccountSelectResponse, egui::Response) { let mut res = AccountSelectResponse::default(); let mut selected_index = app.account_manager.get_selected_account_index(); - Frame::none().outer_margin(8.0).show(ui, |ui| { - res = top_section_widget(ui); + let response = Frame::none() + .outer_margin(8.0) + .show(ui, |ui| { + res = top_section_widget(ui); - scroll_area().show(ui, |ui| { - if let Some(_index) = Self::show_accounts(app, ui) { - selected_index = Some(_index); - res.action = Some(AccountSelectAction::SelectAccount { _index }); - } - }); - ui.add_space(8.0); - ui.add(add_account_button()); - - if let Some(_index) = selected_index { - if let Some(account) = app.account_manager.get_account(_index) { - ui.add_space(8.0); - if Self::handle_sign_out(&app.ndb, ui, account) { - res.action = Some(AccountSelectAction::RemoveAccount { _index }) + scroll_area().show(ui, |ui| { + if let Some(_index) = Self::show_accounts(app, ui) { + selected_index = Some(_index); + res.action = Some(AccountSelectAction::SelectAccount { _index }); + } + }); + ui.add_space(8.0); + ui.add(add_account_button()); + + if let Some(_index) = selected_index { + if let Some(account) = app.account_manager.get_account(_index) { + ui.add_space(8.0); + if Self::handle_sign_out(&app.ndb, ui, account) { + res.action = Some(AccountSelectAction::RemoveAccount { _index }) + } } } - } - ui.add_space(8.0); - }); + ui.add_space(8.0); + }) + .response; - res + (res, response) } fn handle_sign_out(ndb: &Ndb, ui: &mut egui::Ui, account: &UserAccount) -> bool { @@ -144,6 +172,16 @@ fn account_switcher_card_ui( .clicked() } +fn account_switcher_window(open: &'_ mut bool) -> egui::Window<'_> { + egui::Window::new("account switcher") + .title_bar(false) + .collapsible(false) + .anchor(egui::Align2::LEFT_BOTTOM, Vec2::new(4.0, -44.0)) + .fixed_size(Vec2::new(360.0, 406.0)) + .open(open) + .movable(false) +} + fn selection_widget() -> impl egui::Widget { |ui: &mut egui::Ui| { let img_data: egui::ImageSource = @@ -221,7 +259,7 @@ mod previews { impl View for AccountSelectionPreview { fn ui(&mut self, ui: &mut egui::Ui) { - AccountSelectionWidget::show(&mut self.app, ui); + AccountSelectionWidget::ui(&mut self.app, ui); } } diff --git a/src/ui/side_panel.rs b/src/ui/side_panel.rs @@ -55,7 +55,7 @@ impl<'a> DesktopSidePanel<'a> { let settings_resp = ui.add(settings_button(dark_mode)); let column_resp = ui.add(add_column_button(dark_mode)); - if pfp_resp.clicked() || pfp_resp.hovered() { + if pfp_resp.clicked() { egui::InnerResponse::new(SidePanelAction::Account, pfp_resp) } else if settings_resp.clicked() || settings_resp.hovered() { egui::InnerResponse::new(SidePanelAction::Settings, settings_resp) @@ -71,8 +71,22 @@ impl<'a> DesktopSidePanel<'a> { } fn pfp_button(&mut self, ui: &mut egui::Ui) -> egui::Response { - profile_preview_controller::show_with_selected_pfp(self.app, ui, show_pfp()); - add_button_to_ui(ui, no_account_pfp()) + if let Some(resp) = + profile_preview_controller::show_with_selected_pfp(self.app, ui, show_pfp()) + { + resp + } else { + add_button_to_ui(ui, no_account_pfp()) + } + } + + pub fn perform_action(app: &mut Damus, action: SidePanelAction) { + match action { + SidePanelAction::Panel => {} // TODO + SidePanelAction::Account => app.show_account_switcher = !app.show_account_switcher, + SidePanelAction::Settings => {} // TODO + SidePanelAction::Columns => (), // TODO + } } } @@ -109,9 +123,11 @@ fn add_column_button(dark_mode: bool) -> egui::Button<'static> { mod preview { + use egui_extras::{Size, StripBuilder}; + use crate::{ test_data, - ui::{Preview, PreviewConfig}, + ui::{AccountSelectionWidget, Preview, PreviewConfig}, }; use super::*; @@ -129,15 +145,21 @@ mod preview { impl View for DesktopSidePanelPreview { fn ui(&mut self, ui: &mut egui::Ui) { - let _selected_account = self - .app - .account_manager - .get_selected_account() - .map(|x| x.pubkey.bytes()); - - let mut panel = DesktopSidePanel::new(&mut self.app); - - DesktopSidePanel::panel().show(ui.ctx(), |ui| panel.ui(ui)); + StripBuilder::new(ui) + .size(Size::exact(40.0)) + .sizes(Size::remainder(), 0) + .clip(true) + .horizontal(|mut strip| { + strip.cell(|ui| { + let mut panel = DesktopSidePanel::new(&mut self.app); + let response = panel.show(ui); + DesktopSidePanel::perform_action(&mut self.app, response.action); + }); + }); + + if self.app.show_account_switcher { + AccountSelectionWidget::ui(&mut self.app, ui); + } } }