implement stateful account management view

`./preview StatefulAccountManagementView`

Signed-off-by: kernelkind <kernelkind@gmail.com>
This commit is contained in:
kernelkind
2024-09-09 18:31:05 -04:00
committed by William Casarin
parent 3a9c7607f3
commit 950a47119e
5 changed files with 166 additions and 10 deletions

View File

@@ -1,11 +1,13 @@
use std::cmp::Ordering; use std::cmp::Ordering;
use enostr::{FilledKeypair, Keypair}; use enostr::{FilledKeypair, FullKeypair, Keypair};
pub use crate::user_account::UserAccount; pub use crate::user_account::UserAccount;
use crate::{ use crate::{
key_storage::{KeyStorage, KeyStorageResponse, KeyStorageType}, key_storage::{KeyStorage, KeyStorageResponse, KeyStorageType},
ui::account_management::AccountManagementViewResponse, ui::{
account_login_view::AccountLoginResponse, account_management::AccountManagementViewResponse,
},
}; };
use tracing::info; use tracing::info;
@@ -120,7 +122,7 @@ impl AccountManager {
} }
} }
pub fn process_view_response( pub fn process_management_view_response_stateless(
manager: &mut AccountManager, manager: &mut AccountManager,
response: AccountManagementViewResponse, response: AccountManagementViewResponse,
) { ) {
@@ -131,5 +133,17 @@ pub fn process_view_response(
AccountManagementViewResponse::SelectAccount(index) => { AccountManagementViewResponse::SelectAccount(index) => {
manager.select_account(index); manager.select_account(index);
} }
AccountManagementViewResponse::RouteToLogin => {}
}
}
pub fn process_login_view_response(manager: &mut AccountManager, response: AccountLoginResponse) {
match response {
AccountLoginResponse::CreateNew => {
manager.add_account(FullKeypair::generate().to_keypair());
}
AccountLoginResponse::LoginWith(keypair) => {
manager.add_account(keypair);
}
} }
} }

View File

@@ -14,9 +14,11 @@ use super::profile_preview_controller::profile_preview_view;
pub struct AccountManagementView {} pub struct AccountManagementView {}
#[derive(Clone, Debug)]
pub enum AccountManagementViewResponse { pub enum AccountManagementViewResponse {
SelectAccount(usize), SelectAccount(usize),
RemoveAccount(usize), RemoveAccount(usize),
RouteToLogin,
} }
impl AccountManagementView { impl AccountManagementView {
@@ -27,7 +29,9 @@ impl AccountManagementView {
img_cache: &mut ImageCache, img_cache: &mut ImageCache,
) -> InnerResponse<Option<AccountManagementViewResponse>> { ) -> InnerResponse<Option<AccountManagementViewResponse>> {
Frame::none().outer_margin(12.0).show(ui, |ui| { Frame::none().outer_margin(12.0).show(ui, |ui| {
Self::top_section_buttons_widget(ui); if let Some(resp) = Self::top_section_buttons_widget(ui).inner {
return Some(resp);
}
ui.add_space(8.0); ui.add_space(8.0);
scroll_area() scroll_area()
@@ -88,19 +92,23 @@ impl AccountManagementView {
.inner .inner
} }
fn top_section_buttons_widget(ui: &mut egui::Ui) -> egui::Response { fn top_section_buttons_widget(
ui: &mut egui::Ui,
) -> InnerResponse<Option<AccountManagementViewResponse>> {
ui.horizontal(|ui| { ui.horizontal(|ui| {
ui.allocate_ui_with_layout( ui.allocate_ui_with_layout(
Vec2::new(ui.available_size_before_wrap().x, 32.0), Vec2::new(ui.available_size_before_wrap().x, 32.0),
Layout::left_to_right(egui::Align::Center), Layout::left_to_right(egui::Align::Center),
|ui| { |ui| {
if ui.add(add_account_button()).clicked() { if ui.add(add_account_button()).clicked() {
// TODO: route to AccountLoginView Some(AccountManagementViewResponse::RouteToLogin)
} else {
None
} }
}, },
); )
.inner
}) })
.response
} }
} }
@@ -194,7 +202,7 @@ fn selected_widget() -> impl egui::Widget {
mod preview { mod preview {
use super::*; use super::*;
use crate::{account_manager::process_view_response, test_data}; use crate::{account_manager::process_management_view_response_stateless, test_data};
pub struct AccountManagementPreview { pub struct AccountManagementPreview {
app: Damus, app: Damus,
@@ -219,7 +227,7 @@ mod preview {
) )
.inner .inner
{ {
process_view_response(&mut self.app.account_manager, response) process_management_view_response_stateless(&mut self.app.account_manager, response)
} }
} }
} }

View File

@@ -8,6 +8,7 @@ pub mod preview;
pub mod profile; pub mod profile;
pub mod relay; pub mod relay;
pub mod side_panel; pub mod side_panel;
pub mod stateful_account_management;
pub mod thread; pub mod thread;
pub mod timeline; pub mod timeline;
pub mod username; pub mod username;

View File

@@ -0,0 +1,131 @@
use egui::Ui;
use egui_nav::{Nav, NavAction};
use nostrdb::Ndb;
use crate::{
account_manager::{process_login_view_response, AccountManager},
imgcache::ImageCache,
login_manager::LoginState,
routable_widget_state::RoutableWidgetState,
route::{ManageAccountRoute, ManageAcountRouteResponse},
Damus,
};
use super::{
account_login_view::AccountLoginView, account_management::AccountManagementViewResponse,
AccountManagementView,
};
pub struct StatefulAccountManagementView {}
impl StatefulAccountManagementView {
pub fn show(
ui: &mut Ui,
account_management_state: &mut RoutableWidgetState<ManageAccountRoute>,
account_manager: &mut AccountManager,
img_cache: &mut ImageCache,
login_state: &mut LoginState,
ndb: &Ndb,
) {
let routes = account_management_state.get_routes();
let nav_response =
Nav::new(routes)
.title(false)
.navigating(false)
.show_mut(ui, |ui, nav| match nav.top() {
ManageAccountRoute::AccountManagement => {
AccountManagementView::ui(ui, account_manager, ndb, img_cache)
.inner
.map(ManageAcountRouteResponse::AccountManagement)
}
ManageAccountRoute::AddAccount => AccountLoginView::new(login_state)
.ui(ui)
.inner
.map(ManageAcountRouteResponse::AddAccount),
});
if let Some(resp) = nav_response.inner {
match resp {
ManageAcountRouteResponse::AccountManagement(response) => {
process_management_view_response_stateful(
response,
account_manager,
account_management_state,
);
}
ManageAcountRouteResponse::AddAccount(response) => {
process_login_view_response(account_manager, response);
*login_state = Default::default();
account_management_state.go_back();
}
}
}
if let Some(NavAction::Returned) = nav_response.action {
account_management_state.go_back();
}
}
}
pub fn process_management_view_response_stateful(
response: AccountManagementViewResponse,
manager: &mut AccountManager,
state: &mut RoutableWidgetState<ManageAccountRoute>,
) {
match response {
AccountManagementViewResponse::RemoveAccount(index) => {
manager.remove_account(index);
}
AccountManagementViewResponse::SelectAccount(index) => {
manager.select_account(index);
}
AccountManagementViewResponse::RouteToLogin => {
state.route_to(ManageAccountRoute::AddAccount);
}
}
}
mod preview {
use crate::{
test_data,
ui::{Preview, PreviewConfig, View},
};
use super::*;
pub struct StatefulAccountManagementPreview {
app: Damus,
}
impl StatefulAccountManagementPreview {
fn new() -> Self {
let mut app = test_data::test_app();
app.account_management_view_state
.route_to(ManageAccountRoute::AccountManagement);
StatefulAccountManagementPreview { app }
}
}
impl View for StatefulAccountManagementPreview {
fn ui(&mut self, ui: &mut egui::Ui) {
StatefulAccountManagementView::show(
ui,
&mut self.app.account_management_view_state,
&mut self.app.account_manager,
&mut self.app.img_cache,
&mut self.app.login_state,
&self.app.ndb,
);
}
}
impl Preview for StatefulAccountManagementView {
type Prev = StatefulAccountManagementPreview;
fn preview(cfg: PreviewConfig) -> Self::Prev {
let _ = cfg;
StatefulAccountManagementPreview::new()
}
}
}

View File

@@ -2,6 +2,7 @@ use notedeck::app_creation::{
generate_mobile_emulator_native_options, generate_native_options, setup_cc, generate_mobile_emulator_native_options, generate_native_options, setup_cc,
}; };
use notedeck::ui::account_login_view::AccountLoginView; use notedeck::ui::account_login_view::AccountLoginView;
use notedeck::ui::stateful_account_management::StatefulAccountManagementView;
use notedeck::ui::{ use notedeck::ui::{
AccountManagementView, AccountSelectionWidget, DesktopSidePanel, PostView, Preview, PreviewApp, AccountManagementView, AccountSelectionWidget, DesktopSidePanel, PostView, Preview, PreviewApp,
PreviewConfig, ProfilePic, ProfilePreview, RelayView, PreviewConfig, ProfilePic, ProfilePreview, RelayView,
@@ -104,5 +105,6 @@ async fn main() {
AccountSelectionWidget, AccountSelectionWidget,
DesktopSidePanel, DesktopSidePanel,
PostView, PostView,
StatefulAccountManagementView,
); );
} }