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 enostr::{FilledKeypair, Keypair};
use enostr::{FilledKeypair, FullKeypair, Keypair};
pub use crate::user_account::UserAccount;
use crate::{
key_storage::{KeyStorage, KeyStorageResponse, KeyStorageType},
ui::account_management::AccountManagementViewResponse,
ui::{
account_login_view::AccountLoginResponse, account_management::AccountManagementViewResponse,
},
};
use tracing::info;
@ -120,7 +122,7 @@ impl AccountManager {
}
}
pub fn process_view_response(
pub fn process_management_view_response_stateless(
manager: &mut AccountManager,
response: AccountManagementViewResponse,
) {
@ -131,5 +133,17 @@ pub fn process_view_response(
AccountManagementViewResponse::SelectAccount(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 {}
#[derive(Clone, Debug)]
pub enum AccountManagementViewResponse {
SelectAccount(usize),
RemoveAccount(usize),
RouteToLogin,
}
impl AccountManagementView {
@ -27,7 +29,9 @@ impl AccountManagementView {
img_cache: &mut ImageCache,
) -> InnerResponse<Option<AccountManagementViewResponse>> {
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);
scroll_area()
@ -88,19 +92,23 @@ impl AccountManagementView {
.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.allocate_ui_with_layout(
Vec2::new(ui.available_size_before_wrap().x, 32.0),
Layout::left_to_right(egui::Align::Center),
|ui| {
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 {
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 {
app: Damus,
@ -219,7 +227,7 @@ mod preview {
)
.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 relay;
pub mod side_panel;
pub mod stateful_account_management;
pub mod thread;
pub mod timeline;
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,
};
use notedeck::ui::account_login_view::AccountLoginView;
use notedeck::ui::stateful_account_management::StatefulAccountManagementView;
use notedeck::ui::{
AccountManagementView, AccountSelectionWidget, DesktopSidePanel, PostView, Preview, PreviewApp,
PreviewConfig, ProfilePic, ProfilePreview, RelayView,
@ -104,5 +105,6 @@ async fn main() {
AccountSelectionWidget,
DesktopSidePanel,
PostView,
StatefulAccountManagementView,
);
}