diff --git a/src/bridge.rs b/src/bridge.rs index b9959d5..b2f68a8 100644 --- a/src/bridge.rs +++ b/src/bridge.rs @@ -15,6 +15,7 @@ pub enum UICoreMsg { GetFederationInfo(InviteCode), AddFederation(InviteCode), Unlock(String), + GetSeedWords, } #[derive(Debug, Clone, PartialEq)] @@ -49,6 +50,7 @@ pub enum CoreUIMsg { Unlocking, UnlockSuccess, UnlockFailed(String), + SeedWords(String), } #[derive(Debug)] @@ -99,6 +101,10 @@ impl UIHandle { pub async fn peek_federation(&self, invite: InviteCode) { self.msg_send(UICoreMsg::GetFederationInfo(invite)).await; } + + pub async fn get_seed_words(&self) { + self.msg_send(UICoreMsg::GetSeedWords).await; + } } impl CoreHandle { diff --git a/src/core.rs b/src/core.rs index 231e83f..d329b15 100644 --- a/src/core.rs +++ b/src/core.rs @@ -307,6 +307,10 @@ impl HarborCore { }) .collect::>() } + + async fn get_seed_words(&self) -> String { + self.mnemonic.to_string() + } } pub fn run_core() -> Subscription { @@ -485,6 +489,10 @@ async fn process_core(core_handle: &mut bridge::CoreHandle, core: &HarborCore) { UICoreMsg::Unlock(_password) => { unreachable!("should already be unlocked") } + UICoreMsg::GetSeedWords => { + let seed_words = core.get_seed_words().await; + core.msg(CoreUIMsg::SeedWords(seed_words)).await; + } } } } diff --git a/src/main.rs b/src/main.rs index 4ffd7f8..a2853d6 100644 --- a/src/main.rs +++ b/src/main.rs @@ -92,6 +92,7 @@ pub enum Message { DonateAmountChanged(String), CopyToClipboard(String), ReceiveMethodChanged(ReceiveMethod), + ShowSeedWords(bool), // Async commands we fire from the UI to core Noop, Send(String), @@ -110,16 +111,22 @@ pub enum Message { #[derive(Default, Debug)] pub struct HarborWallet { ui_handle: Option>, - balance_sats: u64, active_route: Route, + // Globals + balance_sats: u64, + transaction_history: Vec, + federation_list: Vec, + // Lock screen + password_input_str: String, + unlock_status: UnlockStatus, + unlock_failure_reason: Option, + // Send send_status: SendStatus, send_failure_reason: Option, send_success_msg: Option, send_dest_input_str: String, send_amount_input_str: String, - password_input_str: String, - unlock_status: UnlockStatus, - unlock_failure_reason: Option, + // Receive receive_failure_reason: Option, receive_success_msg: Option, receive_status: ReceiveStatus, @@ -128,13 +135,16 @@ pub struct HarborWallet { receive_address: Option
, receive_qr_data: Option, receive_method: ReceiveMethod, - mint_invite_code_str: String, - add_federation_failure_reason: Option, - federation_list: Vec, + // Mints peek_federation_failure_reason: Option, peek_federation_item: Option, + mint_invite_code_str: String, + add_federation_failure_reason: Option, + // Donate donate_amount_str: String, - transaction_history: Vec, + // Settings + settings_show_seed_words: bool, + seed_words: Option, } impl HarborWallet { @@ -207,6 +217,14 @@ impl HarborWallet { } } + async fn async_get_seed_words(ui_handle: Option>) { + if let Some(ui_handle) = ui_handle { + ui_handle.clone().get_seed_words().await; + } else { + panic!("UI handle is None"); + } + } + fn update(&mut self, message: Message) -> Command { match message { // Setup @@ -221,7 +239,14 @@ impl HarborWallet { } // Internal app state stuff like navigation and text inputs Message::Navigate(route) => { - self.active_route = route; + match self.active_route { + // Reset the seed words state when we leave the settings screen + Route::Settings => { + self.settings_show_seed_words = false; + self.active_route = route; + } + _ => self.active_route = route, + } Command::none() } Message::ReceiveAmountChanged(amount) => { @@ -373,6 +398,16 @@ impl HarborWallet { println!("Copying to clipboard: {s}"); clipboard::write(s) } + Message::ShowSeedWords(show) => { + if show { + Command::perform(Self::async_get_seed_words(self.ui_handle.clone()), |_| { + Message::Noop + }) + } else { + self.settings_show_seed_words = false; + Command::none() + } + } // Handle any messages we get from core Message::CoreMessage(msg) => match msg { CoreUIMsg::Sending => { @@ -480,6 +515,11 @@ impl HarborWallet { self.unlock_failure_reason = Some(reason); Command::none() } + CoreUIMsg::SeedWords(words) => { + self.seed_words = Some(words); + self.settings_show_seed_words = true; + Command::none() + } }, } } @@ -496,8 +536,7 @@ impl HarborWallet { Route::Donate => row![sidebar, crate::routes::donate(self)].into(), Route::History => row![sidebar, crate::routes::history(self)].into(), Route::Transfer => row![sidebar, crate::routes::transfer(self)].into(), - // TODO: just add settings route and we can remove this - _ => row![sidebar, crate::routes::home(self)].into(), + Route::Settings => row![sidebar, crate::routes::settings(self)].into(), }; active_route diff --git a/src/routes/mod.rs b/src/routes/mod.rs index bce980d..54ccc31 100644 --- a/src/routes/mod.rs +++ b/src/routes/mod.rs @@ -22,6 +22,9 @@ pub use donate::*; pub mod history; pub use history::*; +pub mod settings; +pub use settings::*; + #[derive(Default, PartialEq, Debug, Clone, Copy)] pub enum Route { #[default] diff --git a/src/routes/settings.rs b/src/routes/settings.rs new file mode 100644 index 0000000..17d7ebd --- /dev/null +++ b/src/routes/settings.rs @@ -0,0 +1,31 @@ +use iced::widget::{column, text}; +use iced::Element; + +use crate::components::{basic_layout, h_button, h_header, SvgIcon}; +use crate::{HarborWallet, Message}; + +pub fn settings(harbor: &HarborWallet) -> Element { + let header = h_header("Settings", "The fun stuff."); + + let column = match (harbor.settings_show_seed_words, &harbor.seed_words) { + (true, Some(s)) => { + let button = h_button("Hide Seed Words", SvgIcon::Squirrel, false) + .on_press(Message::ShowSeedWords(false)); + + let words = text(s).size(24); + + let copy_button = h_button("Copy Seed Words", SvgIcon::Copy, false) + .on_press(Message::CopyToClipboard(s.clone())); + + column![header, button, words, copy_button] + } + _ => { + let button = h_button("Show Seed Words", SvgIcon::Squirrel, false) + .on_press(Message::ShowSeedWords(true)); + + column![header, button] + } + }; + + basic_layout(column.spacing(48)) +}