Migrate to new AccountManagementView conception
Signed-off-by: kernelkind <kernelkind@gmail.com>
This commit is contained in:
committed by
William Casarin
parent
2ca47edf4d
commit
f489ed3b9e
BIN
assets/icons/add_account_icon_4x.png
Normal file
BIN
assets/icons/add_account_icon_4x.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.0 KiB |
BIN
assets/icons/select_icon_3x.png
Normal file
BIN
assets/icons/select_icon_3x.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.4 KiB |
BIN
assets/icons/signout_icon_4x.png
Normal file
BIN
assets/icons/signout_icon_4x.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.4 KiB |
@@ -1,3 +1,5 @@
|
|||||||
|
use std::cmp::Ordering;
|
||||||
|
|
||||||
use enostr::FullKeypair;
|
use enostr::FullKeypair;
|
||||||
|
|
||||||
pub use crate::user_account::UserAccount;
|
pub use crate::user_account::UserAccount;
|
||||||
@@ -51,9 +53,19 @@ impl AccountManager {
|
|||||||
pub fn remove_account(&mut self, index: usize) {
|
pub fn remove_account(&mut self, index: usize) {
|
||||||
if let Some(account) = self.accounts.get(index) {
|
if let Some(account) = self.accounts.get(index) {
|
||||||
let _ = self.key_store.remove_key(&account.key);
|
let _ = self.key_store.remove_key(&account.key);
|
||||||
}
|
|
||||||
if index < self.accounts.len() {
|
|
||||||
self.accounts.remove(index);
|
self.accounts.remove(index);
|
||||||
|
|
||||||
|
if let Some(selected_index) = self.currently_selected_account {
|
||||||
|
match selected_index.cmp(&index) {
|
||||||
|
Ordering::Greater => {
|
||||||
|
self.select_account(selected_index - 1);
|
||||||
|
}
|
||||||
|
Ordering::Equal => {
|
||||||
|
self.clear_selected_account();
|
||||||
|
}
|
||||||
|
Ordering::Less => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -84,4 +96,8 @@ impl AccountManager {
|
|||||||
self.currently_selected_account = Some(index)
|
self.currently_selected_account = Some(index)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn clear_selected_account(&mut self) {
|
||||||
|
self.currently_selected_account = None
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,12 +4,13 @@ use crate::{
|
|||||||
app_style::NotedeckTextStyle,
|
app_style::NotedeckTextStyle,
|
||||||
ui::{self, Preview, View},
|
ui::{self, Preview, View},
|
||||||
};
|
};
|
||||||
use egui::{Align, Button, Frame, Id, Layout, Margin, RichText, ScrollArea, Sense, Vec2};
|
use egui::{
|
||||||
|
Align, Button, Color32, Frame, Id, Image, Layout, Margin, RichText, ScrollArea, Sense, Vec2,
|
||||||
|
};
|
||||||
|
|
||||||
use super::global_popup::GlobalPopupType;
|
use super::global_popup::GlobalPopupType;
|
||||||
use super::profile::preview::SimpleProfilePreview;
|
use super::profile::preview::SimpleProfilePreview;
|
||||||
use super::profile::SimpleProfilePreviewController;
|
use super::profile::{ProfilePreviewOp, SimpleProfilePreviewController};
|
||||||
use super::state_in_memory::STATE_ACCOUNT_MANAGEMENT;
|
|
||||||
|
|
||||||
pub struct AccountManagementView<'a> {
|
pub struct AccountManagementView<'a> {
|
||||||
account_manager: &'a mut AccountManager,
|
account_manager: &'a mut AccountManager,
|
||||||
@@ -38,24 +39,23 @@ impl<'a> AccountManagementView<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn show(&mut self, ui: &mut egui::Ui) {
|
fn show(&mut self, ui: &mut egui::Ui) {
|
||||||
ui.add(self.buttons_widget());
|
Frame::none().outer_margin(24.0).show(ui, |ui| {
|
||||||
ui.add_space(8.0);
|
ui.add(self.top_section_buttons_widget());
|
||||||
scroll_area().show(ui, |ui| {
|
ui.add_space(8.0);
|
||||||
self.show_accounts(ui);
|
scroll_area().show(ui, |ui| {
|
||||||
|
self.show_accounts(ui);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn show_accounts(&mut self, ui: &mut egui::Ui) {
|
fn show_accounts(&mut self, ui: &mut egui::Ui) {
|
||||||
ui.horizontal_wrapped(|ui| {
|
let maybe_remove = self.simple_preview_controller.set_profile_previews(
|
||||||
let maybe_remove = self.simple_preview_controller.set_profile_previews(
|
self.account_manager,
|
||||||
self.account_manager,
|
ui,
|
||||||
ui,
|
account_card_ui(),
|
||||||
STATE_ACCOUNT_MANAGEMENT.get_state(ui.ctx()),
|
);
|
||||||
desktop_account_card_ui(),
|
|
||||||
);
|
|
||||||
|
|
||||||
self.maybe_remove_accounts(maybe_remove);
|
self.maybe_remove_accounts(maybe_remove);
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn show_accounts_mobile(&mut self, ui: &mut egui::Ui) {
|
fn show_accounts_mobile(&mut self, ui: &mut egui::Ui) {
|
||||||
@@ -67,8 +67,7 @@ impl<'a> AccountManagementView<'a> {
|
|||||||
let maybe_remove = self.simple_preview_controller.set_profile_previews(
|
let maybe_remove = self.simple_preview_controller.set_profile_previews(
|
||||||
self.account_manager,
|
self.account_manager,
|
||||||
ui,
|
ui,
|
||||||
STATE_ACCOUNT_MANAGEMENT.get_state(ui.ctx()),
|
account_card_ui(), // closure for creating an account 'card'
|
||||||
mobile_account_card_ui(), // closure for creating an account 'card'
|
|
||||||
);
|
);
|
||||||
|
|
||||||
// remove all account indicies user requested
|
// remove all account indicies user requested
|
||||||
@@ -89,7 +88,7 @@ impl<'a> AccountManagementView<'a> {
|
|||||||
egui::CentralPanel::default()
|
egui::CentralPanel::default()
|
||||||
.show(ui.ctx(), |ui| {
|
.show(ui.ctx(), |ui| {
|
||||||
ui.add(mobile_title());
|
ui.add(mobile_title());
|
||||||
ui.add(self.buttons_widget());
|
ui.add(self.top_section_buttons_widget());
|
||||||
ui.add_space(8.0);
|
ui.add_space(8.0);
|
||||||
scroll_area().show(ui, |ui| {
|
scroll_area().show(ui, |ui| {
|
||||||
self.show_accounts_mobile(ui);
|
self.show_accounts_mobile(ui);
|
||||||
@@ -98,84 +97,73 @@ impl<'a> AccountManagementView<'a> {
|
|||||||
.response
|
.response
|
||||||
}
|
}
|
||||||
|
|
||||||
fn buttons_widget(&mut self) -> impl egui::Widget + '_ {
|
fn top_section_buttons_widget(&mut self) -> impl egui::Widget + '_ {
|
||||||
|ui: &mut egui::Ui| {
|
|ui: &mut egui::Ui| {
|
||||||
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| {
|
|
||||||
if STATE_ACCOUNT_MANAGEMENT.get_state(ui.ctx()) {
|
|
||||||
if ui.add(done_account_button()).clicked() {
|
|
||||||
STATE_ACCOUNT_MANAGEMENT.set_state(ui.ctx(), false);
|
|
||||||
}
|
|
||||||
} else if ui.add(edit_account_button()).clicked() {
|
|
||||||
STATE_ACCOUNT_MANAGEMENT.set_state(ui.ctx(), true);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
ui.allocate_ui_with_layout(
|
|
||||||
Vec2::new(ui.available_size_before_wrap().x, 32.0),
|
|
||||||
Layout::right_to_left(egui::Align::Center),
|
|
||||||
|ui| {
|
|ui| {
|
||||||
if ui.add(add_account_button()).clicked() {
|
if ui.add(add_account_button()).clicked() {
|
||||||
// TODO: route to AccountLoginView
|
// TODO: route to AccountLoginView
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// UNCOMMENT FOR LOGOUTALL BUTTON
|
||||||
|
// ui.allocate_ui_with_layout(
|
||||||
|
// Vec2::new(ui.available_size_before_wrap().x, 32.0),
|
||||||
|
// Layout::right_to_left(egui::Align::Center),
|
||||||
|
// |ui| {
|
||||||
|
// if ui.add(logout_all_button()).clicked() {
|
||||||
|
// for index in (0..self.account_manager.num_accounts()).rev() {
|
||||||
|
// self.account_manager.remove_account(index);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// },
|
||||||
|
// );
|
||||||
})
|
})
|
||||||
.response
|
.response
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn mobile_account_card_ui(
|
fn account_card_ui() -> fn(
|
||||||
) -> fn(ui: &mut egui::Ui, preview: SimpleProfilePreview, edit_mode: bool) -> bool {
|
ui: &mut egui::Ui,
|
||||||
|ui, preview, edit_mode| {
|
preview: SimpleProfilePreview,
|
||||||
let mut should_remove = false;
|
width: f32,
|
||||||
|
is_selected: bool,
|
||||||
|
) -> Option<ProfilePreviewOp> {
|
||||||
|
|ui, preview, width, is_selected| {
|
||||||
|
let mut op: Option<ProfilePreviewOp> = None;
|
||||||
|
|
||||||
ui.add_sized(
|
ui.add_sized(Vec2::new(width, 50.0), |ui: &mut egui::Ui| {
|
||||||
Vec2::new(ui.available_width(), 50.0),
|
Frame::none()
|
||||||
|ui: &mut egui::Ui| {
|
.show(ui, |ui| {
|
||||||
Frame::none()
|
ui.horizontal(|ui| {
|
||||||
.show(ui, |ui| {
|
ui.add(preview);
|
||||||
ui.horizontal(|ui| {
|
|
||||||
ui.add(preview);
|
ui.with_layout(Layout::right_to_left(Align::Center), |ui| {
|
||||||
if edit_mode {
|
if is_selected {
|
||||||
ui.with_layout(Layout::right_to_left(Align::Center), |ui| {
|
ui.add(selected_widget());
|
||||||
should_remove =
|
} else {
|
||||||
ui.add(delete_button(ui.visuals().dark_mode)).clicked();
|
if ui
|
||||||
});
|
.add(switch_button(ui.style().visuals.dark_mode))
|
||||||
|
.clicked()
|
||||||
|
{
|
||||||
|
op = Some(ProfilePreviewOp::SwitchTo);
|
||||||
|
}
|
||||||
|
if ui.add(sign_out_button(ui)).clicked() {
|
||||||
|
op = Some(ProfilePreviewOp::RemoveAccount)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
})
|
|
||||||
.response
|
|
||||||
},
|
|
||||||
);
|
|
||||||
ui.add_space(16.0);
|
|
||||||
should_remove
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn desktop_account_card_ui(
|
|
||||||
) -> fn(ui: &mut egui::Ui, preview: SimpleProfilePreview, edit_mode: bool) -> bool {
|
|
||||||
|ui: &mut egui::Ui, preview, edit_mode| {
|
|
||||||
let mut should_remove = false;
|
|
||||||
|
|
||||||
ui.add_sized(preview.dimensions(), |ui: &mut egui::Ui| {
|
|
||||||
simple_preview_frame(ui)
|
|
||||||
.show(ui, |ui| {
|
|
||||||
ui.vertical_centered(|ui| {
|
|
||||||
ui.add(preview);
|
|
||||||
if edit_mode {
|
|
||||||
should_remove = ui.add(delete_button(ui.visuals().dark_mode)).clicked();
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
.response
|
.response
|
||||||
});
|
});
|
||||||
should_remove
|
ui.add_space(16.0);
|
||||||
|
op
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -216,24 +204,55 @@ fn scroll_area() -> ScrollArea {
|
|||||||
.auto_shrink([false; 2])
|
.auto_shrink([false; 2])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static PINK: Color32 = Color32::from_rgb(0xE4, 0x5A, 0xC9);
|
||||||
|
|
||||||
fn add_account_button() -> Button<'static> {
|
fn add_account_button() -> Button<'static> {
|
||||||
Button::new("Add Account").min_size(Vec2::new(0.0, 32.0))
|
let img_data = egui::include_image!("../../assets/icons/add_account_icon_4x.png");
|
||||||
|
let img = Image::new(img_data).fit_to_exact_size(Vec2::new(48.0, 48.0));
|
||||||
|
Button::image_and_text(
|
||||||
|
img,
|
||||||
|
RichText::new(" Add account")
|
||||||
|
.size(16.0)
|
||||||
|
// TODO: this color should not be hard coded. Find some way to add it to the visuals
|
||||||
|
.color(PINK),
|
||||||
|
)
|
||||||
|
.frame(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn edit_account_button() -> Button<'static> {
|
fn sign_out_button(ui: &egui::Ui) -> egui::Button<'static> {
|
||||||
Button::new("Edit").min_size(Vec2::new(0.0, 32.0))
|
let img_data = egui::include_image!("../../assets/icons/signout_icon_4x.png");
|
||||||
|
let img = Image::new(img_data).fit_to_exact_size(Vec2::new(16.0, 16.0));
|
||||||
|
|
||||||
|
egui::Button::image_and_text(
|
||||||
|
img,
|
||||||
|
RichText::new("Sign out").color(ui.visuals().noninteractive().fg_stroke.color),
|
||||||
|
)
|
||||||
|
.frame(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn done_account_button() -> Button<'static> {
|
fn switch_button(dark_mode: bool) -> egui::Button<'static> {
|
||||||
Button::new("Done").min_size(Vec2::new(0.0, 32.0))
|
let _ = dark_mode;
|
||||||
|
|
||||||
|
egui::Button::new("Switch").min_size(Vec2::new(76.0, 32.0))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn delete_button(_dark_mode: bool) -> egui::Button<'static> {
|
fn selected_widget() -> impl egui::Widget {
|
||||||
let img_data = egui::include_image!("../../assets/icons/delete_icon_4x.png");
|
|ui: &mut egui::Ui| {
|
||||||
|
Frame::none()
|
||||||
egui::Button::image(egui::Image::new(img_data).max_width(30.0)).frame(true)
|
.show(ui, |ui| {
|
||||||
|
ui.label(RichText::new("Selected").size(13.0).color(PINK));
|
||||||
|
let img_data = egui::include_image!("../../assets/icons/select_icon_3x.png");
|
||||||
|
let img = Image::new(img_data).max_size(Vec2::new(16.0, 16.0));
|
||||||
|
ui.add(img);
|
||||||
|
})
|
||||||
|
.response
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// fn logout_all_button() -> egui::Button<'static> {
|
||||||
|
// egui::Button::new("Logout all")
|
||||||
|
// }
|
||||||
|
|
||||||
pub struct AccountSelectionWidget<'a> {
|
pub struct AccountSelectionWidget<'a> {
|
||||||
account_manager: &'a mut AccountManager,
|
account_manager: &'a mut AccountManager,
|
||||||
simple_preview_controller: SimpleProfilePreviewController<'a>,
|
simple_preview_controller: SimpleProfilePreviewController<'a>,
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ pub enum GlobalPopupType {
|
|||||||
AccountManagement,
|
AccountManagement,
|
||||||
}
|
}
|
||||||
|
|
||||||
static ACCOUNT_MANAGEMENT_TITLE: &str = "Account Management";
|
static ACCOUNT_MANAGEMENT_TITLE: &str = "Manage accounts";
|
||||||
|
|
||||||
impl GlobalPopupType {
|
impl GlobalPopupType {
|
||||||
pub fn title(&self) -> &'static str {
|
pub fn title(&self) -> &'static str {
|
||||||
|
|||||||
@@ -4,4 +4,4 @@ mod profile_preview_controller;
|
|||||||
|
|
||||||
pub use picture::ProfilePic;
|
pub use picture::ProfilePic;
|
||||||
pub use preview::ProfilePreview;
|
pub use preview::ProfilePreview;
|
||||||
pub use profile_preview_controller::SimpleProfilePreviewController;
|
pub use profile_preview_controller::{ProfilePreviewOp, SimpleProfilePreviewController};
|
||||||
|
|||||||
@@ -9,6 +9,12 @@ pub struct SimpleProfilePreviewController<'a> {
|
|||||||
img_cache: &'a mut ImageCache,
|
img_cache: &'a mut ImageCache,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum ProfilePreviewOp {
|
||||||
|
RemoveAccount,
|
||||||
|
SwitchTo,
|
||||||
|
}
|
||||||
|
|
||||||
impl<'a> SimpleProfilePreviewController<'a> {
|
impl<'a> SimpleProfilePreviewController<'a> {
|
||||||
pub fn new(ndb: &'a Ndb, img_cache: &'a mut ImageCache) -> Self {
|
pub fn new(ndb: &'a Ndb, img_cache: &'a mut ImageCache) -> Self {
|
||||||
SimpleProfilePreviewController { ndb, img_cache }
|
SimpleProfilePreviewController { ndb, img_cache }
|
||||||
@@ -16,17 +22,19 @@ impl<'a> SimpleProfilePreviewController<'a> {
|
|||||||
|
|
||||||
pub fn set_profile_previews(
|
pub fn set_profile_previews(
|
||||||
&mut self,
|
&mut self,
|
||||||
account_manager: &AccountManager,
|
account_manager: &mut AccountManager,
|
||||||
ui: &mut egui::Ui,
|
ui: &mut egui::Ui,
|
||||||
edit_mode: bool,
|
|
||||||
add_preview_ui: fn(
|
add_preview_ui: fn(
|
||||||
ui: &mut egui::Ui,
|
ui: &mut egui::Ui,
|
||||||
preview: SimpleProfilePreview,
|
preview: SimpleProfilePreview,
|
||||||
edit_mode: bool,
|
width: f32,
|
||||||
) -> bool,
|
is_selected: bool,
|
||||||
|
) -> Option<ProfilePreviewOp>,
|
||||||
) -> Option<Vec<usize>> {
|
) -> Option<Vec<usize>> {
|
||||||
let mut to_remove: Option<Vec<usize>> = None;
|
let mut to_remove: Option<Vec<usize>> = None;
|
||||||
|
|
||||||
|
let width = ui.available_width();
|
||||||
|
|
||||||
for i in 0..account_manager.num_accounts() {
|
for i in 0..account_manager.num_accounts() {
|
||||||
if let Some(account) = account_manager.get_account(i) {
|
if let Some(account) = account_manager.get_account(i) {
|
||||||
if let Ok(txn) = Transaction::new(self.ndb) {
|
if let Ok(txn) = Transaction::new(self.ndb) {
|
||||||
@@ -37,11 +45,24 @@ impl<'a> SimpleProfilePreviewController<'a> {
|
|||||||
if let Ok(profile) = profile {
|
if let Ok(profile) = profile {
|
||||||
let preview = SimpleProfilePreview::new(&profile, self.img_cache);
|
let preview = SimpleProfilePreview::new(&profile, self.img_cache);
|
||||||
|
|
||||||
if add_preview_ui(ui, preview, edit_mode) {
|
let is_selected = if let Some(selected) =
|
||||||
if to_remove.is_none() {
|
account_manager.get_currently_selected_account()
|
||||||
to_remove = Some(Vec::new());
|
{
|
||||||
|
i == selected
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
};
|
||||||
|
|
||||||
|
if let Some(op) = add_preview_ui(ui, preview, width, is_selected) {
|
||||||
|
match op {
|
||||||
|
ProfilePreviewOp::RemoveAccount => {
|
||||||
|
if to_remove.is_none() {
|
||||||
|
to_remove = Some(Vec::new());
|
||||||
|
}
|
||||||
|
to_remove.as_mut().unwrap().push(i);
|
||||||
|
}
|
||||||
|
ProfilePreviewOp::SwitchTo => account_manager.select_account(i),
|
||||||
}
|
}
|
||||||
to_remove.as_mut().unwrap().push(i);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user