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;
|
||||
|
||||
pub use crate::user_account::UserAccount;
|
||||
@@ -51,9 +53,19 @@ impl AccountManager {
|
||||
pub fn remove_account(&mut self, index: usize) {
|
||||
if let Some(account) = self.accounts.get(index) {
|
||||
let _ = self.key_store.remove_key(&account.key);
|
||||
}
|
||||
if index < self.accounts.len() {
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn clear_selected_account(&mut self) {
|
||||
self.currently_selected_account = None
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,12 +4,13 @@ use crate::{
|
||||
app_style::NotedeckTextStyle,
|
||||
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::profile::preview::SimpleProfilePreview;
|
||||
use super::profile::SimpleProfilePreviewController;
|
||||
use super::state_in_memory::STATE_ACCOUNT_MANAGEMENT;
|
||||
use super::profile::{ProfilePreviewOp, SimpleProfilePreviewController};
|
||||
|
||||
pub struct AccountManagementView<'a> {
|
||||
account_manager: &'a mut AccountManager,
|
||||
@@ -38,24 +39,23 @@ impl<'a> AccountManagementView<'a> {
|
||||
}
|
||||
|
||||
fn show(&mut self, ui: &mut egui::Ui) {
|
||||
ui.add(self.buttons_widget());
|
||||
ui.add_space(8.0);
|
||||
scroll_area().show(ui, |ui| {
|
||||
self.show_accounts(ui);
|
||||
Frame::none().outer_margin(24.0).show(ui, |ui| {
|
||||
ui.add(self.top_section_buttons_widget());
|
||||
ui.add_space(8.0);
|
||||
scroll_area().show(ui, |ui| {
|
||||
self.show_accounts(ui);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
fn show_accounts(&mut self, ui: &mut egui::Ui) {
|
||||
ui.horizontal_wrapped(|ui| {
|
||||
let maybe_remove = self.simple_preview_controller.set_profile_previews(
|
||||
self.account_manager,
|
||||
ui,
|
||||
STATE_ACCOUNT_MANAGEMENT.get_state(ui.ctx()),
|
||||
desktop_account_card_ui(),
|
||||
);
|
||||
let maybe_remove = self.simple_preview_controller.set_profile_previews(
|
||||
self.account_manager,
|
||||
ui,
|
||||
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) {
|
||||
@@ -67,8 +67,7 @@ impl<'a> AccountManagementView<'a> {
|
||||
let maybe_remove = self.simple_preview_controller.set_profile_previews(
|
||||
self.account_manager,
|
||||
ui,
|
||||
STATE_ACCOUNT_MANAGEMENT.get_state(ui.ctx()),
|
||||
mobile_account_card_ui(), // closure for creating an account 'card'
|
||||
account_card_ui(), // closure for creating an account 'card'
|
||||
);
|
||||
|
||||
// remove all account indicies user requested
|
||||
@@ -89,7 +88,7 @@ impl<'a> AccountManagementView<'a> {
|
||||
egui::CentralPanel::default()
|
||||
.show(ui.ctx(), |ui| {
|
||||
ui.add(mobile_title());
|
||||
ui.add(self.buttons_widget());
|
||||
ui.add(self.top_section_buttons_widget());
|
||||
ui.add_space(8.0);
|
||||
scroll_area().show(ui, |ui| {
|
||||
self.show_accounts_mobile(ui);
|
||||
@@ -98,84 +97,73 @@ impl<'a> AccountManagementView<'a> {
|
||||
.response
|
||||
}
|
||||
|
||||
fn buttons_widget(&mut self) -> impl egui::Widget + '_ {
|
||||
fn top_section_buttons_widget(&mut self) -> impl egui::Widget + '_ {
|
||||
|ui: &mut egui::Ui| {
|
||||
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 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| {
|
||||
if ui.add(add_account_button()).clicked() {
|
||||
// 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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn mobile_account_card_ui(
|
||||
) -> fn(ui: &mut egui::Ui, preview: SimpleProfilePreview, edit_mode: bool) -> bool {
|
||||
|ui, preview, edit_mode| {
|
||||
let mut should_remove = false;
|
||||
fn account_card_ui() -> fn(
|
||||
ui: &mut egui::Ui,
|
||||
preview: SimpleProfilePreview,
|
||||
width: f32,
|
||||
is_selected: bool,
|
||||
) -> Option<ProfilePreviewOp> {
|
||||
|ui, preview, width, is_selected| {
|
||||
let mut op: Option<ProfilePreviewOp> = None;
|
||||
|
||||
ui.add_sized(
|
||||
Vec2::new(ui.available_width(), 50.0),
|
||||
|ui: &mut egui::Ui| {
|
||||
Frame::none()
|
||||
.show(ui, |ui| {
|
||||
ui.horizontal(|ui| {
|
||||
ui.add(preview);
|
||||
if edit_mode {
|
||||
ui.with_layout(Layout::right_to_left(Align::Center), |ui| {
|
||||
should_remove =
|
||||
ui.add(delete_button(ui.visuals().dark_mode)).clicked();
|
||||
});
|
||||
ui.add_sized(Vec2::new(width, 50.0), |ui: &mut egui::Ui| {
|
||||
Frame::none()
|
||||
.show(ui, |ui| {
|
||||
ui.horizontal(|ui| {
|
||||
ui.add(preview);
|
||||
|
||||
ui.with_layout(Layout::right_to_left(Align::Center), |ui| {
|
||||
if is_selected {
|
||||
ui.add(selected_widget());
|
||||
} else {
|
||||
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
|
||||
});
|
||||
should_remove
|
||||
ui.add_space(16.0);
|
||||
op
|
||||
}
|
||||
}
|
||||
|
||||
@@ -216,24 +204,55 @@ fn scroll_area() -> ScrollArea {
|
||||
.auto_shrink([false; 2])
|
||||
}
|
||||
|
||||
static PINK: Color32 = Color32::from_rgb(0xE4, 0x5A, 0xC9);
|
||||
|
||||
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> {
|
||||
Button::new("Edit").min_size(Vec2::new(0.0, 32.0))
|
||||
fn sign_out_button(ui: &egui::Ui) -> egui::Button<'static> {
|
||||
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> {
|
||||
Button::new("Done").min_size(Vec2::new(0.0, 32.0))
|
||||
fn switch_button(dark_mode: bool) -> egui::Button<'static> {
|
||||
let _ = dark_mode;
|
||||
|
||||
egui::Button::new("Switch").min_size(Vec2::new(76.0, 32.0))
|
||||
}
|
||||
|
||||
fn delete_button(_dark_mode: bool) -> egui::Button<'static> {
|
||||
let img_data = egui::include_image!("../../assets/icons/delete_icon_4x.png");
|
||||
|
||||
egui::Button::image(egui::Image::new(img_data).max_width(30.0)).frame(true)
|
||||
fn selected_widget() -> impl egui::Widget {
|
||||
|ui: &mut egui::Ui| {
|
||||
Frame::none()
|
||||
.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> {
|
||||
account_manager: &'a mut AccountManager,
|
||||
simple_preview_controller: SimpleProfilePreviewController<'a>,
|
||||
|
||||
@@ -12,7 +12,7 @@ pub enum GlobalPopupType {
|
||||
AccountManagement,
|
||||
}
|
||||
|
||||
static ACCOUNT_MANAGEMENT_TITLE: &str = "Account Management";
|
||||
static ACCOUNT_MANAGEMENT_TITLE: &str = "Manage accounts";
|
||||
|
||||
impl GlobalPopupType {
|
||||
pub fn title(&self) -> &'static str {
|
||||
|
||||
@@ -4,4 +4,4 @@ mod profile_preview_controller;
|
||||
|
||||
pub use picture::ProfilePic;
|
||||
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,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum ProfilePreviewOp {
|
||||
RemoveAccount,
|
||||
SwitchTo,
|
||||
}
|
||||
|
||||
impl<'a> SimpleProfilePreviewController<'a> {
|
||||
pub fn new(ndb: &'a Ndb, img_cache: &'a mut ImageCache) -> Self {
|
||||
SimpleProfilePreviewController { ndb, img_cache }
|
||||
@@ -16,17 +22,19 @@ impl<'a> SimpleProfilePreviewController<'a> {
|
||||
|
||||
pub fn set_profile_previews(
|
||||
&mut self,
|
||||
account_manager: &AccountManager,
|
||||
account_manager: &mut AccountManager,
|
||||
ui: &mut egui::Ui,
|
||||
edit_mode: bool,
|
||||
add_preview_ui: fn(
|
||||
ui: &mut egui::Ui,
|
||||
preview: SimpleProfilePreview,
|
||||
edit_mode: bool,
|
||||
) -> bool,
|
||||
width: f32,
|
||||
is_selected: bool,
|
||||
) -> Option<ProfilePreviewOp>,
|
||||
) -> Option<Vec<usize>> {
|
||||
let mut to_remove: Option<Vec<usize>> = None;
|
||||
|
||||
let width = ui.available_width();
|
||||
|
||||
for i in 0..account_manager.num_accounts() {
|
||||
if let Some(account) = account_manager.get_account(i) {
|
||||
if let Ok(txn) = Transaction::new(self.ndb) {
|
||||
@@ -37,11 +45,24 @@ impl<'a> SimpleProfilePreviewController<'a> {
|
||||
if let Ok(profile) = profile {
|
||||
let preview = SimpleProfilePreview::new(&profile, self.img_cache);
|
||||
|
||||
if add_preview_ui(ui, preview, edit_mode) {
|
||||
if to_remove.is_none() {
|
||||
to_remove = Some(Vec::new());
|
||||
let is_selected = if let Some(selected) =
|
||||
account_manager.get_currently_selected_account()
|
||||
{
|
||||
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