commit 3a9c7607f330e53eb6fa06b117742bc87f7edba2
parent dda7256f51426624fbaa486034d728de07f4c245
Author: kernelkind <kernelkind@gmail.com>
Date: Mon, 9 Sep 2024 13:55:33 -0400
make AccountManagementView stateless
Signed-off-by: kernelkind <kernelkind@gmail.com>
Diffstat:
3 files changed, 137 insertions(+), 122 deletions(-)
diff --git a/src/account_manager.rs b/src/account_manager.rs
@@ -2,8 +2,11 @@ use std::cmp::Ordering;
use enostr::{FilledKeypair, Keypair};
-use crate::key_storage::{KeyStorage, KeyStorageResponse, KeyStorageType};
pub use crate::user_account::UserAccount;
+use crate::{
+ key_storage::{KeyStorage, KeyStorageResponse, KeyStorageType},
+ ui::account_management::AccountManagementViewResponse,
+};
use tracing::info;
/// The interface for managing the user's accounts.
@@ -116,3 +119,17 @@ impl AccountManager {
self.currently_selected_account = None
}
}
+
+pub fn process_view_response(
+ manager: &mut AccountManager,
+ response: AccountManagementViewResponse,
+) {
+ match response {
+ AccountManagementViewResponse::RemoveAccount(index) => {
+ manager.remove_account(index);
+ }
+ AccountManagementViewResponse::SelectAccount(index) => {
+ manager.select_account(index);
+ }
+ }
+}
diff --git a/src/ui/account_management.rs b/src/ui/account_management.rs
@@ -1,55 +1,91 @@
use crate::colors::PINK;
+use crate::imgcache::ImageCache;
use crate::{
account_manager::AccountManager,
- app_style::NotedeckTextStyle,
- ui,
- ui::{profile_preview_controller, Preview, PreviewConfig, View},
+ ui::{Preview, PreviewConfig, View},
Damus,
};
-use egui::{Align, Button, Frame, Image, Layout, Response, RichText, ScrollArea, Vec2};
+use egui::{Align, Button, Frame, Image, InnerResponse, Layout, RichText, ScrollArea, Ui, Vec2};
+use nostrdb::{Ndb, Transaction};
use super::profile::preview::SimpleProfilePreview;
use super::profile::ProfilePreviewOp;
+use super::profile_preview_controller::profile_preview_view;
pub struct AccountManagementView {}
-impl AccountManagementView {
- pub fn ui(app: &mut Damus, ui: &mut egui::Ui) -> Response {
- Frame::none()
- .outer_margin(12.0)
- .show(ui, |ui| {
- Self::top_section_buttons_widget(ui);
+pub enum AccountManagementViewResponse {
+ SelectAccount(usize),
+ RemoveAccount(usize),
+}
- ui.add_space(8.0);
- scroll_area().show(ui, |ui| Self::show_accounts(app, ui));
- })
- .response
+impl AccountManagementView {
+ pub fn ui(
+ ui: &mut Ui,
+ account_manager: &AccountManager,
+ ndb: &Ndb,
+ img_cache: &mut ImageCache,
+ ) -> InnerResponse<Option<AccountManagementViewResponse>> {
+ Frame::none().outer_margin(12.0).show(ui, |ui| {
+ Self::top_section_buttons_widget(ui);
+
+ ui.add_space(8.0);
+ scroll_area()
+ .show(ui, |ui| {
+ Self::show_accounts(ui, account_manager, ndb, img_cache)
+ })
+ .inner
+ })
}
- fn show_accounts(app: &mut Damus, ui: &mut egui::Ui) {
+ fn show_accounts(
+ ui: &mut Ui,
+ account_manager: &AccountManager,
+ ndb: &Ndb,
+ img_cache: &mut ImageCache,
+ ) -> Option<AccountManagementViewResponse> {
ui.allocate_ui_with_layout(
Vec2::new(ui.available_size_before_wrap().x, 32.0),
Layout::top_down(egui::Align::Min),
|ui| {
- // create all account 'cards' and get the indicies the user requested to remove
- let maybe_remove = profile_preview_controller::set_profile_previews(
- app,
- ui,
- account_card_ui(), // closure for creating an account 'card'
- );
-
- // remove all account indicies user requested
- if let Some(indicies_to_remove) = maybe_remove {
- Self::remove_accounts(&mut app.account_manager, indicies_to_remove);
+ let txn = Transaction::new(ndb).ok()?;
+
+ for i in 0..account_manager.num_accounts() {
+ let account_pubkey = account_manager
+ .get_account(i)
+ .map(|account| account.pubkey.bytes());
+
+ let account_pubkey = if let Some(pubkey) = account_pubkey {
+ pubkey
+ } else {
+ continue;
+ };
+
+ let profile = ndb.get_profile_by_pubkey(&txn, account_pubkey).ok();
+ let is_selected =
+ if let Some(selected) = account_manager.get_selected_account_index() {
+ i == selected
+ } else {
+ false
+ };
+
+ if let Some(op) =
+ profile_preview_view(ui, profile.as_ref(), img_cache, is_selected)
+ {
+ return Some(match op {
+ ProfilePreviewOp::SwitchTo => {
+ AccountManagementViewResponse::SelectAccount(i)
+ }
+ ProfilePreviewOp::RemoveAccount => {
+ AccountManagementViewResponse::RemoveAccount(i)
+ }
+ });
+ }
}
+ None
},
- );
- }
-
- fn remove_accounts(manager: &mut AccountManager, account_indices: Vec<usize>) {
- account_indices
- .iter()
- .for_each(|index| manager.remove_account(*index));
+ )
+ .inner
}
fn top_section_buttons_widget(ui: &mut egui::Ui) -> egui::Response {
@@ -68,43 +104,41 @@ impl AccountManagementView {
}
}
-fn account_card_ui() -> fn(
+pub fn show_profile_card(
ui: &mut egui::Ui,
preview: SimpleProfilePreview,
width: f32,
is_selected: bool,
) -> Option<ProfilePreviewOp> {
- |ui, preview, width, is_selected| {
- let mut op: Option<ProfilePreviewOp> = None;
+ let mut op: Option<ProfilePreviewOp> = None;
- 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)
- }
+ 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);
- op
- }
+ });
+ })
+ .response
+ });
+ ui.add_space(16.0);
+ op
}
fn scroll_area() -> ScrollArea {
@@ -160,7 +194,7 @@ fn selected_widget() -> impl egui::Widget {
mod preview {
use super::*;
- use crate::test_data;
+ use crate::{account_manager::process_view_response, test_data};
pub struct AccountManagementPreview {
app: Damus,
@@ -177,7 +211,16 @@ mod preview {
impl View for AccountManagementPreview {
fn ui(&mut self, ui: &mut egui::Ui) {
ui.add_space(24.0);
- AccountManagementView::ui(&mut self.app, ui);
+ if let Some(response) = AccountManagementView::ui(
+ ui,
+ &self.app.account_manager,
+ &self.app.ndb,
+ &mut self.app.img_cache,
+ )
+ .inner
+ {
+ process_view_response(&mut self.app.account_manager, response)
+ }
}
}
diff --git a/src/ui/profile/profile_preview_controller.rs b/src/ui/profile/profile_preview_controller.rs
@@ -1,6 +1,9 @@
-use nostrdb::{Ndb, Transaction};
+use egui::Ui;
+use nostrdb::{Ndb, ProfileRecord, Transaction};
-use crate::{Damus, DisplayName, Result};
+use crate::{
+ imgcache::ImageCache, ui::account_management::show_profile_card, Damus, DisplayName, Result,
+};
use super::{
preview::{get_display_name, get_profile_url, SimpleProfilePreview},
@@ -13,64 +16,16 @@ pub enum ProfilePreviewOp {
SwitchTo,
}
-pub fn set_profile_previews(
- app: &mut Damus,
- ui: &mut egui::Ui,
- add_preview_ui: fn(
- ui: &mut egui::Ui,
- preview: SimpleProfilePreview,
- width: f32,
- is_selected: bool,
- ) -> Option<ProfilePreviewOp>,
-) -> Option<Vec<usize>> {
- let mut to_remove: Option<Vec<usize>> = None;
-
+pub fn profile_preview_view(
+ ui: &mut Ui,
+ profile: Option<&'_ ProfileRecord<'_>>,
+ img_cache: &mut ImageCache,
+ is_selected: bool,
+) -> Option<ProfilePreviewOp> {
let width = ui.available_width();
- let txn = if let Ok(txn) = Transaction::new(&app.ndb) {
- txn
- } else {
- return None;
- };
-
- for i in 0..app.accounts.num_accounts() {
- let account = if let Some(account) = app.accounts.get_account(i) {
- account
- } else {
- continue;
- };
-
- let profile = app
- .ndb
- .get_profile_by_pubkey(&txn, account.pubkey.bytes())
- .ok();
-
- let preview = SimpleProfilePreview::new(profile.as_ref(), &mut app.img_cache);
-
- let is_selected = if let Some(selected) = app.accounts.get_selected_account_index() {
- i == selected
- } else {
- false
- };
-
- let op = if let Some(op) = add_preview_ui(ui, preview, width, is_selected) {
- op
- } else {
- continue;
- };
-
- match op {
- ProfilePreviewOp::RemoveAccount => {
- if to_remove.is_none() {
- to_remove = Some(Vec::new());
- }
- to_remove.as_mut().unwrap().push(i);
- }
- ProfilePreviewOp::SwitchTo => app.accounts.select_account(i),
- }
- }
-
- to_remove
+ let preview = SimpleProfilePreview::new(profile, img_cache);
+ show_profile_card(ui, preview, width, is_selected)
}
pub fn view_profile_previews(