diff --git a/src/account_manager.rs b/src/account_manager.rs index c8bbc9f..c0d8284 100644 --- a/src/account_manager.rs +++ b/src/account_manager.rs @@ -19,7 +19,7 @@ impl<'a> SimpleProfilePreviewController<'a> { pub fn set_profile_previews( &mut self, - account_manager: &AccountManager<'a>, + account_manager: &AccountManager, ui: &mut egui::Ui, edit_mode: bool, add_preview_ui: fn( @@ -56,7 +56,7 @@ impl<'a> SimpleProfilePreviewController<'a> { pub fn view_profile_previews( &mut self, - account_manager: &'a AccountManager<'a>, + account_manager: &'a AccountManager, ui: &mut egui::Ui, add_preview_ui: fn(ui: &mut egui::Ui, preview: SimpleProfilePreview, index: usize) -> bool, ) -> Option { @@ -86,18 +86,31 @@ impl<'a> SimpleProfilePreviewController<'a> { /// The interface for managing the user's accounts. /// Represents all user-facing operations related to account management. -pub struct AccountManager<'a> { - accounts: &'a mut Vec, +pub struct AccountManager { + accounts: Vec, key_store: KeyStorage, relay_generator: RelayGenerator, } -impl<'a> AccountManager<'a> { +impl AccountManager { pub fn new( - accounts: &'a mut Vec, key_store: KeyStorage, + // TODO: right now, there is only one way of generating relays for all accounts. In the future + // each account should have the option of generating relays differently relay_generator: RelayGenerator, + wakeup: impl Fn() + Send + Sync + Clone + 'static, ) -> Self { + let accounts = if let Ok(keys) = key_store.get_keys() { + keys.into_iter() + .map(|key| { + let relays = relay_generator.generate_relays_for(&key.pubkey, wakeup.clone()); + UserAccount { key, relays } + }) + .collect() + } else { + Vec::new() + }; + AccountManager { accounts, key_store, @@ -105,11 +118,11 @@ impl<'a> AccountManager<'a> { } } - pub fn get_accounts(&'a self) -> &'a Vec { - self.accounts + pub fn get_accounts(&self) -> &Vec { + &self.accounts } - pub fn get_account(&'a self, index: usize) -> Option<&'a UserAccount> { + pub fn get_account(&self, index: usize) -> Option<&UserAccount> { self.accounts.get(index) } @@ -122,9 +135,15 @@ impl<'a> AccountManager<'a> { } } - pub fn add_account(&'a mut self, key: FullKeypair, ctx: &egui::Context) { + pub fn add_account( + &mut self, + key: FullKeypair, + wakeup: impl Fn() + Send + Sync + Clone + 'static, + ) { let _ = self.key_store.add_key(&key); - let relays = self.relay_generator.generate_relays_for(&key.pubkey, ctx); + let relays = self + .relay_generator + .generate_relays_for(&key.pubkey, wakeup); let account = UserAccount { key, relays }; self.accounts.push(account) diff --git a/src/app.rs b/src/app.rs index 30770e5..db73eb9 100644 --- a/src/app.rs +++ b/src/app.rs @@ -1,10 +1,11 @@ -use crate::account_manager::UserAccount; +use crate::account_manager::AccountManager; use crate::app_creation::setup_cc; use crate::app_style::user_requested_visuals_change; use crate::error::Error; use crate::frame_history::FrameHistory; use crate::imgcache::ImageCache; use crate::notecache::{CachedNote, NoteCache}; +use crate::relay_pool_manager::create_wakeup; use crate::timeline; use crate::timeline::{NoteRef, Timeline, ViewFilter}; use crate::ui::{is_mobile, DesktopGlobalPopup, DesktopSidePanel, View}; @@ -44,7 +45,7 @@ pub struct Damus { pub img_cache: ImageCache, pub ndb: Ndb, - pub accounts: Vec, + pub account_manager: AccountManager, frame_history: crate::frame_history::FrameHistory, } @@ -646,7 +647,13 @@ impl Damus { timelines, textmode: false, ndb: Ndb::new(data_path.as_ref().to_str().expect("db path ok"), &config).expect("ndb"), - accounts: Vec::new(), + account_manager: AccountManager::new( + // TODO: use correct KeyStorage mechanism for current OS arch + crate::key_storage::KeyStorage::None, + // TODO: setting for relay generator + crate::relay_generation::RelayGenerator::Constant, + create_wakeup(&cc.egui_ctx), + ), //compose: "".to_string(), frame_history: FrameHistory::default(), } @@ -672,7 +679,11 @@ impl Damus { timelines, textmode: false, ndb: Ndb::new(data_path.as_ref().to_str().expect("db path ok"), &config).expect("ndb"), - accounts: Vec::new(), + account_manager: AccountManager::new( + crate::key_storage::KeyStorage::None, + crate::relay_generation::RelayGenerator::Constant, + || {}, + ), frame_history: FrameHistory::default(), } } diff --git a/src/relay_generation.rs b/src/relay_generation.rs index 20df1be..8bd33a6 100644 --- a/src/relay_generation.rs +++ b/src/relay_generation.rs @@ -1,4 +1,3 @@ -use crate::relay_pool_manager::create_wakeup; use enostr::{Pubkey, RelayPool}; use tracing::error; @@ -9,30 +8,39 @@ pub enum RelayGenerator { } impl RelayGenerator { - pub fn generate_relays_for(&self, key: &Pubkey, ctx: &egui::Context) -> RelayPool { + pub fn generate_relays_for( + &self, + key: &Pubkey, + wakeup: impl Fn() + Send + Sync + Clone + 'static, + ) -> RelayPool { match self { - Self::GossipModel => generate_relays_gossip(key, ctx), - Self::Nip65 => generate_relays_nip65(key, ctx), - Self::Constant => generate_constant_relays(ctx), + Self::GossipModel => generate_relays_gossip(key, wakeup), + Self::Nip65 => generate_relays_nip65(key, wakeup), + Self::Constant => generate_constant_relays(wakeup), } } } -fn generate_relays_gossip(key: &Pubkey, ctx: &egui::Context) -> RelayPool { - let _ = ctx; +fn generate_relays_gossip( + key: &Pubkey, + wakeup: impl Fn() + Send + Sync + Clone + 'static, +) -> RelayPool { + let _ = wakeup; let _ = key; todo!() } -fn generate_relays_nip65(key: &Pubkey, ctx: &egui::Context) -> RelayPool { - let _ = ctx; +fn generate_relays_nip65( + key: &Pubkey, + wakeup: impl Fn() + Send + Sync + Clone + 'static, +) -> RelayPool { + let _ = wakeup; let _ = key; todo!() } -fn generate_constant_relays(ctx: &egui::Context) -> RelayPool { +fn generate_constant_relays(wakeup: impl Fn() + Send + Sync + Clone + 'static) -> RelayPool { let mut pool = RelayPool::new(); - let wakeup = create_wakeup(ctx); if let Err(e) = pool.add_url("ws://localhost:8080".to_string(), wakeup.clone()) { error!("{:?}", e) diff --git a/src/ui/account_management.rs b/src/ui/account_management.rs index 98dba2e..4b2e001 100644 --- a/src/ui/account_management.rs +++ b/src/ui/account_management.rs @@ -11,7 +11,7 @@ use super::profile::preview::SimpleProfilePreview; use super::state_in_memory::STATE_ACCOUNT_MANAGEMENT; pub struct AccountManagementView<'a> { - account_manager: AccountManager<'a>, + account_manager: &'a mut AccountManager, simple_preview_controller: SimpleProfilePreviewController<'a>, } @@ -27,7 +27,7 @@ impl<'a> View for AccountManagementView<'a> { impl<'a> AccountManagementView<'a> { pub fn new( - account_manager: AccountManager<'a>, + account_manager: &'a mut AccountManager, simple_preview_controller: SimpleProfilePreviewController<'a>, ) -> Self { AccountManagementView { @@ -47,7 +47,7 @@ impl<'a> AccountManagementView<'a> { 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, + self.account_manager, ui, STATE_ACCOUNT_MANAGEMENT.get_state(ui.ctx()), desktop_account_card_ui(), @@ -64,7 +64,7 @@ impl<'a> AccountManagementView<'a> { |ui| { // create all account 'cards' and get the indicies the user requested to remove let maybe_remove = self.simple_preview_controller.set_profile_previews( - &self.account_manager, + self.account_manager, ui, STATE_ACCOUNT_MANAGEMENT.get_state(ui.ctx()), mobile_account_card_ui(), // closure for creating an account 'card' @@ -180,13 +180,8 @@ fn desktop_account_card_ui( impl<'a> FromApp<'a> for AccountManagementView<'a> { fn from_app(app: &'a mut crate::Damus) -> Self { - // TODO: don't hard-code key store & relay generator AccountManagementView::new( - AccountManager::new( - &mut app.accounts, - crate::key_storage::KeyStorage::None, - crate::relay_generation::RelayGenerator::Constant, - ), + &mut app.account_manager, SimpleProfilePreviewController::new(&app.ndb, &mut app.img_cache), ) } @@ -239,7 +234,7 @@ fn delete_button(_dark_mode: bool) -> egui::Button<'static> { } pub struct AccountSelectionWidget<'a> { - account_manager: AccountManager<'a>, + account_manager: &'a mut AccountManager, simple_preview_controller: SimpleProfilePreviewController<'a>, } @@ -249,7 +244,7 @@ impl<'a> AccountSelectionWidget<'a> { scroll_area().show(ui, |ui| { ui.horizontal_wrapped(|ui| { let clicked_at = self.simple_preview_controller.view_profile_previews( - &self.account_manager, + self.account_manager, ui, |ui, preview, index| { let resp = ui.add_sized(preview.dimensions(), |ui: &mut egui::Ui| { @@ -278,7 +273,7 @@ impl<'a> AccountSelectionWidget<'a> { impl<'a> AccountSelectionWidget<'a> { pub fn new( - account_manager: AccountManager<'a>, + account_manager: &'a mut AccountManager, simple_preview_controller: SimpleProfilePreviewController<'a>, ) -> Self { AccountSelectionWidget { @@ -301,7 +296,7 @@ mod preview { use std::path::Path; pub struct AccountManagementPreview { - accounts: Vec, + account_manager: AccountManager, ndb: Ndb, img_cache: ImageCache, } @@ -320,11 +315,16 @@ mod preview { impl AccountManagementPreview { fn new() -> Self { + let mut account_manager = + AccountManager::new(KeyStorage::None, RelayGenerator::Constant, || {}); let accounts = test_data::get_test_accounts(); + accounts + .into_iter() + .for_each(|acc| account_manager.add_account(acc.key, || {})); let (ndb, img_cache) = get_ndb_and_img_cache(); AccountManagementPreview { - accounts, + account_manager, ndb, img_cache, } @@ -333,15 +333,9 @@ mod preview { impl View for AccountManagementPreview { fn ui(&mut self, ui: &mut egui::Ui) { - let account_manager = AccountManager::new( - &mut self.accounts, - KeyStorage::None, - RelayGenerator::Constant, - ); - ui.add_space(24.0); AccountManagementView::new( - account_manager, + &mut self.account_manager, SimpleProfilePreviewController::new(&self.ndb, &mut self.img_cache), ) .ui(ui); @@ -357,17 +351,22 @@ mod preview { } pub struct AccountSelectionPreview { - accounts: Vec, + account_manager: AccountManager, ndb: Ndb, img_cache: ImageCache, } impl AccountSelectionPreview { fn new() -> Self { + let mut account_manager = + AccountManager::new(KeyStorage::None, RelayGenerator::Constant, || {}); let accounts = test_data::get_test_accounts(); + accounts + .into_iter() + .for_each(|acc| account_manager.add_account(acc.key, || {})); let (ndb, img_cache) = get_ndb_and_img_cache(); AccountSelectionPreview { - accounts, + account_manager, ndb, img_cache, } @@ -376,14 +375,8 @@ mod preview { impl View for AccountSelectionPreview { fn ui(&mut self, ui: &mut egui::Ui) { - let account_manager = AccountManager::new( - &mut self.accounts, - KeyStorage::None, - RelayGenerator::Constant, - ); - let mut widget = AccountSelectionWidget::new( - account_manager, + &mut self.account_manager, SimpleProfilePreviewController::new(&self.ndb, &mut self.img_cache), ); diff --git a/src/ui/global_popup.rs b/src/ui/global_popup.rs index 2901796..b0355d8 100644 --- a/src/ui/global_popup.rs +++ b/src/ui/global_popup.rs @@ -91,7 +91,7 @@ impl<'a> DesktopGlobalPopup<'a> { mod preview { use crate::{ - test_data::get_test_accounts, + test_data, ui::{DesktopSidePanel, Preview, View}, Damus, }; @@ -113,7 +113,10 @@ mod preview { impl GlobalPopupPreview { fn new() -> Self { let mut app = Damus::mock("."); - app.accounts = get_test_accounts(); + let accounts = test_data::get_test_accounts(); + accounts + .into_iter() + .for_each(|acc| app.account_manager.add_account(acc.key, || {})); GlobalPopupPreview { app } } }