From ec90f9c65f79d3969b4a6527b377c66bc645d86f Mon Sep 17 00:00:00 2001 From: Yeastplume Date: Wed, 24 Apr 2024 11:45:03 +0100 Subject: [PATCH] tab order, add seed phrase --- Cargo.toml | 4 +- crates/core/Cargo.toml | 2 +- crates/core/src/config/mod.rs | 1 + crates/core/src/fs/save.rs | 2 +- crates/core/src/theme/mod.rs | 4 + crates/core/src/theme/text_editor.rs | 88 ++++++++++++++++++++ locale/de.json | 1 + locale/en.json | 1 + src/gui/element/wallet/setup/wallet_setup.rs | 54 +++++++----- src/gui/update.rs | 40 +++++---- 10 files changed, 154 insertions(+), 43 deletions(-) create mode 100644 crates/core/src/theme/text_editor.rs diff --git a/Cargo.toml b/Cargo.toml index 31509fa..054cf89 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -51,8 +51,8 @@ json-gettext = "3.2.8" strfmt = "0.1.6" once_cell = "1.6.0" lazy_static = "1" -serde = { version = "1.0", features=['derive'] } -serde_json = "1.0.59" +serde = { version = "1", features=['derive'] } +serde_json = "1" reqwest = { version = "0.11", features = ["json", "blocking"] } uuid = "0.8.2" diff --git a/crates/core/Cargo.toml b/crates/core/Cargo.toml index 85da0ac..9f8fd05 100644 --- a/crates/core/Cargo.toml +++ b/crates/core/Cargo.toml @@ -66,7 +66,7 @@ regex = "1.4.3" fancy-regex = "0.5.0" # Regex with backtracking async-std = { version = "1.9.0", features = ["unstable"] } dirs-next = "2.0.0" -serde = { version = "1.0.123", features = ['derive'] } +serde = { version = "1", features = ['derive'] } serde_yaml = "0.8.17" serde_json = "1.0.62" serde_urlencoded = "0.7" diff --git a/crates/core/src/config/mod.rs b/crates/core/src/config/mod.rs index 965fabf..7fee14b 100644 --- a/crates/core/src/config/mod.rs +++ b/crates/core/src/config/mod.rs @@ -44,6 +44,7 @@ pub struct Config { #[serde(default = "default_true")] pub alternating_row_colors: bool, + //TODO: These default values aren't working #[serde(default = "default_true")] pub is_keybindings_enabled: bool, diff --git a/crates/core/src/fs/save.rs b/crates/core/src/fs/save.rs index e71d839..db785a1 100644 --- a/crates/core/src/fs/save.rs +++ b/crates/core/src/fs/save.rs @@ -25,6 +25,7 @@ pub trait PersistentData: DeserializeOwned + Serialize { /// Load from `PersistentData::path()`. fn load() -> Result { let path = Self::path()?; + println!("{:?}", path); if path.exists() { let file = fs::File::open(&path)?; @@ -39,7 +40,6 @@ pub trait PersistentData: DeserializeOwned + Serialize { /// and return that object. fn load_or_default() -> Result { let load_result = ::load(); - match load_result { Ok(deser) => Ok(deser), _ => Ok(get_default_and_save()?), diff --git a/crates/core/src/theme/mod.rs b/crates/core/src/theme/mod.rs index 88b2c63..66af2cd 100644 --- a/crates/core/src/theme/mod.rs +++ b/crates/core/src/theme/mod.rs @@ -23,6 +23,7 @@ pub mod scrollable; pub mod table_header; pub mod table_row; pub mod text; +pub mod text_editor; pub mod text_input; pub use button::ButtonStyle; @@ -35,6 +36,7 @@ pub use radio::RadioStyle; pub use scrollable::ScrollableStyle; pub use table_header::TableHeaderStyle; pub use table_row::TableRowStyle; +pub use text_editor::TextEditorStyle; pub use text_input::TextInputStyle; pub async fn load_user_themes() -> Vec { @@ -56,6 +58,8 @@ pub type Column<'a, Message> = iced::widget::Column<'a, Message, Theme, Renderer pub type Row<'a, Message> = iced::widget::Row<'a, Message, Theme, Renderer>; pub type Text<'a> = iced::widget::Text<'a, Theme, Renderer>; pub type TextInput<'a, Message> = iced::widget::TextInput<'a, Message, Theme, Renderer>; +pub type TextEditor<'a, Message, Theme, Renderer> = + iced::widget::TextEditor<'a, Message, Theme, Renderer>; pub type Button<'a, Message> = iced::widget::Button<'a, Message, Theme, Renderer>; pub type Scrollable<'a, Message> = iced::widget::Scrollable<'a, Message, Theme, Renderer>; pub type PickList<'a, T, L, V, Message> = diff --git a/crates/core/src/theme/text_editor.rs b/crates/core/src/theme/text_editor.rs new file mode 100644 index 0000000..4c00d71 --- /dev/null +++ b/crates/core/src/theme/text_editor.rs @@ -0,0 +1,88 @@ +use super::Theme; +use iced::widget::text_editor; +use iced::{Background, Color}; +use iced_core::Border; + +#[derive(Debug, Clone, Copy, Default)] +pub enum TextEditorStyle { + #[default] + Default, +} + +impl text_editor::StyleSheet for Theme { + type Style = TextEditorStyle; + + /// Produces the style of an active text input. + fn active(&self, style: &Self::Style) -> text_editor::Appearance { + match style { + TextEditorStyle::Default => text_editor::Appearance { + background: Background::Color(self.palette.base.foreground), + border: Border { + color: self.palette.normal.primary, + width: 1.0, + radius: 2.0.into(), + }, + }, + } + } + + /// Produces the style of a focused text input. + fn focused(&self, style: &Self::Style) -> text_editor::Appearance { + match style { + TextEditorStyle::Default => text_editor::Appearance { + background: Background::Color(self.palette.base.foreground), + border: Border { + color: self.palette.bright.primary, + width: 1.0, + radius: 2.0.into(), + }, + }, + } + } + + fn disabled(&self, style: &Self::Style) -> text_editor::Appearance { + match style { + TextEditorStyle::Default => text_editor::Appearance { + background: Background::Color(self.palette.base.foreground), + border: Border { + color: self.palette.normal.primary, + width: 1.0, + radius: 2.0.into(), + }, + }, + } + } + + fn placeholder_color(&self, style: &Self::Style) -> Color { + match style { + TextEditorStyle::Default => self.palette.normal.surface, + _ => todo!("default"), + } + } + + fn value_color(&self, style: &Self::Style) -> Color { + match style { + TextEditorStyle::Default => self.palette.bright.primary, + _ => todo!("default"), + } + } + + fn selection_color(&self, style: &Self::Style) -> Color { + match style { + TextEditorStyle::Default => self.palette.bright.secondary, + _ => todo!("default"), + } + } + + fn disabled_color(&self, style: &Self::Style) -> Color { + match style { + TextEditorStyle::Default => self.palette.normal.secondary, + _ => todo!("default"), + } + } + + /// Produces the style of an hovered text editor. + fn hovered(&self, style: &Self::Style) -> text_editor::Appearance { + self.focused(style) + } +} diff --git a/locale/de.json b/locale/de.json index 43f37f3..961d953 100644 --- a/locale/de.json +++ b/locale/de.json @@ -78,6 +78,7 @@ "remote-release-channel": "Veröffentlichungskanal", "reset-columns": "Spalten zurücksetzen", "restore-from-seed": "Restore this wallet from an existing seed phrase", + "enter-seed-phrase": "Enter Seed Phrase", "retry": "Erneut versuchen", "scale": "Skalierung", "search-for-addon": "Suche nach einem Addon", diff --git a/locale/en.json b/locale/en.json index e064cd7..b2ab5a5 100644 --- a/locale/en.json +++ b/locale/en.json @@ -78,6 +78,7 @@ "remote-release-channel": "Release channel", "reset-columns": "Reset Columns", "restore-from-seed": "Restore this wallet from an existing seed phrase (TBD)", + "enter-seed-phrase": "Enter Seed Phrase:", "retry": "Retry", "scale": "Scale", "search-for-addon": "Search for an addon...", diff --git a/src/gui/element/wallet/setup/wallet_setup.rs b/src/gui/element/wallet/setup/wallet_setup.rs index 278bbdd..05ed27a 100644 --- a/src/gui/element/wallet/setup/wallet_setup.rs +++ b/src/gui/element/wallet/setup/wallet_setup.rs @@ -14,7 +14,7 @@ use { anyhow::Context, grin_gui_core::theme::ColorPalette, grin_gui_core::theme::{ - Button, Column, Container, Element, PickList, Row, Scrollable, Text, TextInput, + Button, Column, Container, Element, PickList, Row, Scrollable, Text, TextEditor, TextInput, }, grin_gui_core::{ config::Wallet, @@ -23,7 +23,7 @@ use { wallet::create_grin_wallet_path, wallet::WalletInterface, }, - iced::widget::{button, pick_list, scrollable, text_input, Checkbox, Space}, + iced::widget::{button, pick_list, scrollable, text_editor, text_input, Checkbox, Space}, iced::{alignment, Alignment, Command, Length}, std::sync::{Arc, RwLock}, }; @@ -31,7 +31,7 @@ use { pub struct StateContainer { pub password_state: PasswordState, pub restore_from_seed: bool, - pub seed_input_value: String, + pub seed_input_content: text_editor::Content, pub show_advanced_options: bool, pub is_testnet: bool, pub advanced_options_state: AdvancedOptionsState, @@ -44,7 +44,7 @@ impl Default for StateContainer { show_advanced_options: false, is_testnet: false, restore_from_seed: false, - seed_input_value: Default::default(), + seed_input_content: text_editor::Content::new(), advanced_options_state: Default::default(), } } @@ -94,7 +94,7 @@ pub enum LocalViewInteraction { CreateWallet(String, PathBuf), WalletCreatedOk((String, String, String, ChainTypes)), WalletCreateError(Arc>>), - SeedInput(String), + SeedValueAction(text_editor::Action), ShowFolderPicker, } @@ -191,8 +191,8 @@ pub fn handle_message<'a>( let password = state.password_state.input_value.clone(); let w = grin_gui.wallet_interface.clone(); let chain_type = if state.is_testnet { Testnet } else { Mainnet }; - let recovery_phrase = if !state.seed_input_value.is_empty() { - Some(state.seed_input_value.clone()) + let recovery_phrase = if !state.seed_input_content.text().is_empty() { + Some(state.seed_input_content.text().clone()) } else { None }; @@ -251,8 +251,9 @@ pub fn handle_message<'a>( log_error(e); } } - LocalViewInteraction::SeedInput(seed) => { - state.seed_input_value = seed; + LocalViewInteraction::SeedValueAction(action) => { + //state.seed_input_value = seed; + state.seed_input_content.perform(action); } } @@ -432,22 +433,33 @@ pub fn data_container<'a>( }; // ** start hideable restore from seed section - let seed_input: Element = TextInput::new( - "seed", - &state.seed_input_value, /*, |s| { - Interaction::WalletSetupWalletViewInteraction(LocalViewInteraction::SeedInput(s)) - }*/ - ) - .size(DEFAULT_FONT_SIZE) - .padding(6) - .width(Length::Fixed(200.0)) - .style(grin_gui_core::theme::TextInputStyle::AddonsQuery) - .into(); + let seed_input: Element = TextEditor::new(&state.seed_input_content) + /* .size(DEFAULT_FONT_SIZE)*/ + //.padding(6) + .height(Length::Fill) + .style(grin_gui_core::theme::TextEditorStyle::Default) + .on_action(|a| { + Interaction::WalletSetupWalletViewInteraction(LocalViewInteraction::SeedValueAction(a)) + }) + .into(); - let seed_column = Column::with_children(vec![seed_input.map(Message::Interaction)]); + let seed_input_wrapper = Container::new(seed_input.map(Message::Interaction)) + .height(Length::Fixed(200.0)) + .width(Length::Fixed(500.0)) + .style(grin_gui_core::theme::ContainerStyle::NormalBackground); + + let seed_column = Column::with_children(vec![seed_input_wrapper.into()]); + + let seed_description = Text::new(localized_string("enter-seed-phrase")) + .size(DEFAULT_SUB_HEADER_FONT_SIZE) + .horizontal_alignment(alignment::Horizontal::Center); + let seed_description_container = Container::new(seed_description) + .style(grin_gui_core::theme::ContainerStyle::NormalBackground); if state.restore_from_seed { restore_from_seed_column = restore_from_seed_column + .push(Space::with_height(Length::Fixed(DEFAULT_PADDING))) + .push(seed_description_container) .push(Space::with_height(Length::Fixed(DEFAULT_PADDING))) .push(seed_column); } diff --git a/src/gui/update.rs b/src/gui/update.rs index 2aef1da..47b603e 100644 --- a/src/gui/update.rs +++ b/src/gui/update.rs @@ -10,7 +10,11 @@ use { std::path::PathBuf, }; -use iced::window; +use iced::{ + widget::{focus_next, focus_previous}, + window, +}; +use iced_core::SmolStr; #[cfg(target_os = "windows")] use crate::tray::{TrayMessage, SHOULD_EXIT, TRAY_SENDER}; @@ -319,33 +323,33 @@ pub fn handle_message(grin_gui: &mut GrinGui, message: Message) -> Result { + /*debug!( + "Event::Keyboard::KeyReleased({:?}, {:?}, {:?})", + key, location, modifiers + );*/ // Bail out of keybindings if keybindings is diabled, or we are // pressing any modifiers. - if !grin_gui.config.is_keybindings_enabled - || modifiers != iced::keyboard::Modifiers::default() - { + /*if !grin_gui.config.is_keybindings_enabled { return Ok(Command::none()); - } + }*/ - match key { - iced::keyboard::Key::Character(A) => {} - iced::keyboard::Key::Character(C) => { - grin_gui.mode = Mode::Catalog; - } - iced::keyboard::Key::Character(R) => {} - iced::keyboard::Key::Character(S) => { - grin_gui.mode = Mode::Settings; - } - iced::keyboard::Key::Character(U) => {} - iced::keyboard::Key::Character(W) => {} - iced::keyboard::Key::Character(I) => { - grin_gui.mode = Mode::Install; + match key.as_ref() { + iced::keyboard::Key::Character("w") => { + // Just testing for now + debug!("w pressed"); } iced::keyboard::Key::Named(iced::keyboard::key::Named::Escape) => { match grin_gui.mode { _ => (), } } + iced::keyboard::Key::Named(iced::keyboard::key::Named::Tab) => { + if modifiers.shift() { + return Ok(focus_previous::()); + } else { + return Ok(focus_next::()); + } + } _ => (), } }