From 202fb86205162edb3c2956988cf9910e119ccca4 Mon Sep 17 00:00:00 2001 From: Yeastplume Date: Wed, 17 Jan 2024 09:33:09 +0000 Subject: [PATCH 1/5] update about links --- locale/de.json | 4 ++-- locale/en.json | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/locale/de.json b/locale/de.json index b3e6a9f..3e0a95b 100644 --- a/locale/de.json +++ b/locale/de.json @@ -122,7 +122,7 @@ "weakaura-updates-queued": "Aktualisierung in Warteschlange. Aktualisierung im Spiel erforderlich.", "weakauras-loaded": "{number} geladen", "website": "Website", - "website-http": "https://getgrin.com", + "website-http": "https://grin.mw", "welcome-to-grin-gui-description": "Bitte wähle dein Verzeichnis", "woops": "Ups!", "wtf": "WTF", @@ -153,7 +153,7 @@ "auto-update": "Neue Updates automatisch anwenden, wenn sie verfügbar sind", "type": "Typ", "donate": "Unterstützen", - "donate-http": "https://www.getajour.com/donate", + "donate-http": "https://grin.mw/fund", "close-to-tray": "Schließen in der Systemablage", "toggle-autostart": "Grin automatisch nach der Anmeldung öffnen", "start-closed-to-tray": "Start Grin geschlossen in System Tray", diff --git a/locale/en.json b/locale/en.json index 7dd7270..6ec00bf 100644 --- a/locale/en.json +++ b/locale/en.json @@ -122,7 +122,7 @@ "weakaura-updates-queued": "Updates can now be applied in-game", "weakauras-loaded": "{number} loaded", "website": "Website", - "website-http": "https://getgrin.com", + "website-http": "https://grin.mw", "welcome-to-grin-gui-description": "Please select your directory", "woops": "Woops!", "wtf": "WTF", @@ -153,7 +153,7 @@ "auto-update": "Automatically apply new updates when available", "type": "Type", "donate": "Donate", - "donate-http": "https://www.getajour.com/donate", + "donate-http": "https://grin.mw/fund", "close-to-tray": "Close to System Tray", "toggle-autostart": "Open Grin automatically after you log in", "start-closed-to-tray": "Start Grin closed to System Tray", From 93d2540692deeabdbb347fe5e0e9070992b6ce99 Mon Sep 17 00:00:00 2001 From: Yeastplume Date: Wed, 17 Jan 2024 09:47:52 +0000 Subject: [PATCH 2/5] remove irrelevant command line ops --- src/cli.rs | 149 +++++++++----------------- src/main.rs | 303 ++++++++++++++++++++++++++-------------------------- 2 files changed, 203 insertions(+), 249 deletions(-) diff --git a/src/cli.rs b/src/cli.rs index 96312a7..7b99557 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -2,63 +2,63 @@ use crate::VERSION; use isahc::http::Uri; use structopt::{ - clap::{self, AppSettings}, - StructOpt, + clap::{self, AppSettings}, + StructOpt, }; use std::env; use std::path::PathBuf; pub fn get_opts() -> Result { - let args = env::args_os(); + let args = env::args_os(); - Opts::from_iter_safe(args) + Opts::from_iter_safe(args) } #[allow(unused_variables)] pub fn validate_opts_or_exit( - opts_result: Result, - is_cli: bool, - is_debug: bool, + opts_result: Result, + is_cli: bool, + is_debug: bool, ) -> Opts { - // If an error, we need to setup the AttachConsole fix for Windows release - // so we can exit and display the error message to the user. - let is_opts_error = opts_result.is_err(); + // If an error, we need to setup the AttachConsole fix for Windows release + // so we can exit and display the error message to the user. + let is_opts_error = opts_result.is_err(); - // Workaround to output to console even though we compile with windows_subsystem = "windows" - // in release mode - #[cfg(target_os = "windows")] - { - if (is_cli || is_opts_error) && !is_debug { - use winapi::um::wincon::{AttachConsole, ATTACH_PARENT_PROCESS}; + // Workaround to output to console even though we compile with windows_subsystem = "windows" + // in release mode + #[cfg(target_os = "windows")] + { + if (is_cli || is_opts_error) && !is_debug { + use winapi::um::wincon::{AttachConsole, ATTACH_PARENT_PROCESS}; - unsafe { - AttachConsole(ATTACH_PARENT_PROCESS); - } - } - } + unsafe { + AttachConsole(ATTACH_PARENT_PROCESS); + } + } + } - // Now that the windows fix is successfully setup, we can safely exit on the error - // and it will display properly to the user, or carry forward with the program - // and properly display our logging to the user. Since `e.exit()` returns a `!`, - // we can return the Ok(Opts) and carry forward with our program. - match opts_result { - Ok(opts) => opts, - Err(e) => { - // Apparently on `--version`, there is no "error message" that gets displayed - // like with `--help` and actual clap errors. It gets printed before we - // ever hit our console fix for windows, so let's manually print it - // before exiting - #[cfg(target_os = "windows")] - { - if !is_debug && e.kind == clap::ErrorKind::VersionDisplayed { - print!("Grin GUI {}", VERSION); - } - } + // Now that the windows fix is successfully setup, we can safely exit on the error + // and it will display properly to the user, or carry forward with the program + // and properly display our logging to the user. Since `e.exit()` returns a `!`, + // we can return the Ok(Opts) and carry forward with our program. + match opts_result { + Ok(opts) => opts, + Err(e) => { + // Apparently on `--version`, there is no "error message" that gets displayed + // like with `--help` and actual clap errors. It gets printed before we + // ever hit our console fix for windows, so let's manually print it + // before exiting + #[cfg(target_os = "windows")] + { + if !is_debug && e.kind == clap::ErrorKind::VersionDisplayed { + print!("Grin GUI {}", VERSION); + } + } - e.exit(); - } - } + e.exit(); + } + } } #[derive(Debug, StructOpt)] @@ -68,64 +68,15 @@ pub fn validate_opts_or_exit( author = env!("CARGO_PKG_AUTHORS"), setting = AppSettings::DisableHelpSubcommand)] pub struct Opts { - #[structopt(long = "data", help = "Path to a custom data directory for the app")] - pub data_directory: Option, - #[structopt(long = "aa", help = "Enable / Disable Anti-aliasing (true / false)")] - pub antialiasing: Option, - #[structopt(subcommand)] - pub command: Option, - #[structopt(long, hidden = true)] - pub self_update_temp: Option, + #[structopt(long = "data", help = "Path to a custom data directory for the app")] + pub data_directory: Option, + #[structopt(long = "aa", help = "Enable / Disable Anti-aliasing (true / false)")] + pub antialiasing: Option, + #[structopt(subcommand)] + pub command: Option, + #[structopt(long, hidden = true)] + pub self_update_temp: Option, } #[derive(Debug, StructOpt)] -pub enum Command { - /// Update all addons, WeakAura and Plater auras - Update, - /// Update all addons - UpdateAddons, - /// Update all WeakAura and Plater auras - UpdateAuras, - /// Install an addon - Install { - #[structopt()] - /// source url [Github & Gitlab currently supported] - url: Uri, - }, - /// Backup your WTF and/or AddOns folders - Backup { - #[structopt(short, long, default_value = "all", parse(try_from_str = str_to_backup_folder), possible_values = &["all","wtf","addons","config", "screenshots", "fonts"])] - /// folder to backup - backup_folder: BackupFolder, - #[structopt()] - /// folder to save backups to - destination: PathBuf, - }, - /// Add a World of Warcraft path - PathAdd { - /// path to the World of Warcraft directory - path: PathBuf, - }, -} - -#[derive(Debug, Clone, Copy)] -pub enum BackupFolder { - All, - AddOns, - Wtf, - Config, - Screenshots, - Fonts, -} - -fn str_to_backup_folder(s: &str) -> Result { - match s { - "all" => Ok(BackupFolder::All), - "wtf" => Ok(BackupFolder::Wtf), - "addons" => Ok(BackupFolder::AddOns), - "config" => Ok(BackupFolder::Config), - "screenshots" => Ok(BackupFolder::Screenshots), - "fonts" => Ok(BackupFolder::Fonts), - _ => Err("valid values are ['all','wtf','addons','config','screenshots','fonts']"), - } -} +pub enum Command {} diff --git a/src/main.rs b/src/main.rs index 88e73ca..4974cc4 100644 --- a/src/main.rs +++ b/src/main.rs @@ -21,7 +21,7 @@ extern crate log; use grin_gui_core::config::Config; use grin_gui_core::fs::{PersistentData, CONFIG_DIR}; use grin_gui_core::utility::{remove_file, rename}; -use grin_gui_core::{LoggingConfig, logger}; +use grin_gui_core::{logger, LoggingConfig}; #[cfg(target_os = "linux")] use anyhow::Context; @@ -35,165 +35,168 @@ pub const VERSION: &str = env!("CARGO_PKG_VERSION"); pub type Result = std::result::Result; pub fn main() { - let opts_result = cli::get_opts(); - - #[cfg(debug_assertions)] - let is_debug = true; - #[cfg(not(debug_assertions))] - let is_debug = false; - - // If this is a clap error, we map to None since we are going to exit and display - // an error message anyway and this value won't matter. If it's not an error, - // the underlying `command` will drive this variable. If a `command` is passed - // on the command line, Grin GUI functions as a CLI instead of launching the GUI. - let is_cli = opts_result - .as_ref() - .map(|o| &o.command) - .unwrap_or(&None) - .is_some(); - - // This function validates whether or not we need to exit and print any message - // due to arguments passed on the command line. If not, it will return a - // parsed `Opts` struct. This also handles setting up our windows release build - // fix that allows us to print to the console when not using the GUI. - let opts = cli::validate_opts_or_exit(opts_result, is_cli, is_debug); - - let config_dir_local = { - let mut config_dir = CONFIG_DIR.lock().unwrap(); - if let Some(data_dir) = &opts.data_directory { - *config_dir = data_dir.clone(); - } - config_dir.clone() - }; - - // Set up logging config for grin-gui code itself - let mut gui_logging_config = LoggingConfig::default(); - gui_logging_config.tui_running = Some(false); - gui_logging_config.stdout_log_level = log::Level::Debug; - gui_logging_config.file_log_level = log::Level::Debug; - let mut gui_log_dir = config_dir_local.clone(); - gui_log_dir.push("grin-gui.log"); - gui_logging_config.log_file_path = gui_log_dir.into_os_string().into_string().unwrap(); - - logger::update_logging_config(logger::LogArea::Gui, gui_logging_config); - - // Called when we launch from the temp (new release) binary during the self update - // process. We will rename the temp file (running process) to the original binary - if let Some(cleanup_path) = &opts.self_update_temp { - if let Err(e) = handle_self_update_temp(cleanup_path) { - log_error(&e); - std::process::exit(1); - } - } - - log_panics::init(); - - log::info!("Grin GUI {} has started.", VERSION); - - // Ensures another instance of Grin GUI isn't already running. - #[cfg(target_os = "windows")] - process::avoid_multiple_instances(); - - /*match opts.command { - Some(command) => { - // Process the command and exit - if let Err(e) = match command { - cli::Command::Backup { - backup_folder, - destination, - flavors, - compression_format, - level, - } => command::backup( - backup_folder, - destination, - flavors, - compression_format, - level, - ), - cli::Command::Update => command::update_both(), - cli::Command::UpdateAddons => command::update_all_addons(), - cli::Command::UpdateAuras => command::update_all_auras(), - cli::Command::Install { url, flavor } => command::install_from_source(url, flavor), - cli::Command::PathAdd { path, flavor } => command::path_add(path, flavor), - } { - log_error(&e); - } - } - None => {*/ - let config: Config = Config::load_or_default().expect("loading config on application startup"); - - #[cfg(target_os = "windows")] - tray::spawn_sys_tray(config.close_to_tray, config.start_closed_to_tray); - - // Start the GUI - gui::run(opts, config); - /* - }*/ + let opts_result = cli::get_opts(); + + #[cfg(debug_assertions)] + let is_debug = true; + #[cfg(not(debug_assertions))] + let is_debug = false; + + // If this is a clap error, we map to None since we are going to exit and display + // an error message anyway and this value won't matter. If it's not an error, + // the underlying `command` will drive this variable. If a `command` is passed + // on the command line, Grin GUI functions as a CLI instead of launching the GUI. + /*let is_cli = opts_result + .as_ref() + .map(|o| &o.command) + .unwrap_or(&None) + .is_some();*/ + + // disable command line for now + let is_cli = false; + + // This function validates whether or not we need to exit and print any message + // due to arguments passed on the command line. If not, it will return a + // parsed `Opts` struct. This also handles setting up our windows release build + // fix that allows us to print to the console when not using the GUI. + let opts = cli::validate_opts_or_exit(opts_result, is_cli, is_debug); + + let config_dir_local = { + let mut config_dir = CONFIG_DIR.lock().unwrap(); + if let Some(data_dir) = &opts.data_directory { + *config_dir = data_dir.clone(); + } + config_dir.clone() + }; + + // Set up logging config for grin-gui code itself + let mut gui_logging_config = LoggingConfig::default(); + gui_logging_config.tui_running = Some(false); + gui_logging_config.stdout_log_level = log::Level::Debug; + gui_logging_config.file_log_level = log::Level::Debug; + let mut gui_log_dir = config_dir_local.clone(); + gui_log_dir.push("grin-gui.log"); + gui_logging_config.log_file_path = gui_log_dir.into_os_string().into_string().unwrap(); + + logger::update_logging_config(logger::LogArea::Gui, gui_logging_config); + + // Called when we launch from the temp (new release) binary during the self update + // process. We will rename the temp file (running process) to the original binary + if let Some(cleanup_path) = &opts.self_update_temp { + if let Err(e) = handle_self_update_temp(cleanup_path) { + log_error(&e); + std::process::exit(1); + } + } + + log_panics::init(); + + log::info!("Grin GUI {} has started.", VERSION); + + // Ensures another instance of Grin GUI isn't already running. + #[cfg(target_os = "windows")] + process::avoid_multiple_instances(); + + /*match opts.command { + Some(command) => { + // Process the command and exit + if let Err(e) = match command { + cli::Command::Backup { + backup_folder, + destination, + flavors, + compression_format, + level, + } => command::backup( + backup_folder, + destination, + flavors, + compression_format, + level, + ), + cli::Command::Update => command::update_both(), + cli::Command::UpdateAddons => command::update_all_addons(), + cli::Command::UpdateAuras => command::update_all_auras(), + cli::Command::Install { url, flavor } => command::install_from_source(url, flavor), + cli::Command::PathAdd { path, flavor } => command::path_add(path, flavor), + } { + log_error(&e); + } + } + None => {*/ + let config: Config = Config::load_or_default().expect("loading config on application startup"); + + #[cfg(target_os = "windows")] + tray::spawn_sys_tray(config.close_to_tray, config.start_closed_to_tray); + + // Start the GUI + gui::run(opts, config); + /* + }*/ } /// Log any errors pub fn log_error(error: &anyhow::Error) { - log::error!("{}", error); + log::error!("{}", error); - let mut causes = error.chain(); - // Remove first entry since it's same as top level error - causes.next(); + let mut causes = error.chain(); + // Remove first entry since it's same as top level error + causes.next(); - for cause in causes { - log::error!("caused by: {}", cause); - } + for cause in causes { + log::error!("caused by: {}", cause); + } } pub fn error_cause_string(error: &anyhow::Error) -> String { - let mut ret_val = String::new(); - let mut causes = error.chain(); - - // Remove first entry since it's same as top level error - let top_level_cause = causes.next(); - if let Some(t) = top_level_cause { - ret_val.push_str(&format!("{}\n\n", t)); - } - - for cause in causes { - ret_val.push_str(&format!("{}\n\n", cause)); - } - ret_val + let mut ret_val = String::new(); + let mut causes = error.chain(); + + // Remove first entry since it's same as top level error + let top_level_cause = causes.next(); + if let Some(t) = top_level_cause { + ret_val.push_str(&format!("{}\n\n", t)); + } + + for cause in causes { + ret_val.push_str(&format!("{}\n\n", cause)); + } + ret_val } fn handle_self_update_temp(cleanup_path: &Path) -> Result<()> { - #[cfg(not(target_os = "linux"))] - let current_bin = env::current_exe()?; - - #[cfg(target_os = "linux")] - let current_bin = - PathBuf::from(env::var("APPIMAGE").context("error getting APPIMAGE env variable")?); - - // Fix for self updating pre 0.5.4 to >= 0.5.4 - // - // Pre 0.5.4, `cleanup_path` is actually the file name of the main bin name that - // got passed via the CLI in the self update process. We want to rename the - // current bin to that bin name. This was passed as a string of just the file - // name, so we want to make an actual full path out of it first. - if current_bin - .file_name() - .unwrap_or_default() - .to_str() - .unwrap_or_default() - .starts_with("tmp_") - { - let main_bin_name = cleanup_path; - - let parent_dir = current_bin.parent().unwrap(); - - let main_bin = parent_dir.join(&main_bin_name); - - rename(¤t_bin, &main_bin)?; - } else { - remove_file(cleanup_path)?; - } - - log::debug!("Grin GUI updated successfully"); - - Ok(()) + #[cfg(not(target_os = "linux"))] + let current_bin = env::current_exe()?; + + #[cfg(target_os = "linux")] + let current_bin = + PathBuf::from(env::var("APPIMAGE").context("error getting APPIMAGE env variable")?); + + // Fix for self updating pre 0.5.4 to >= 0.5.4 + // + // Pre 0.5.4, `cleanup_path` is actually the file name of the main bin name that + // got passed via the CLI in the self update process. We want to rename the + // current bin to that bin name. This was passed as a string of just the file + // name, so we want to make an actual full path out of it first. + if current_bin + .file_name() + .unwrap_or_default() + .to_str() + .unwrap_or_default() + .starts_with("tmp_") + { + let main_bin_name = cleanup_path; + + let parent_dir = current_bin.parent().unwrap(); + + let main_bin = parent_dir.join(&main_bin_name); + + rename(¤t_bin, &main_bin)?; + } else { + remove_file(cleanup_path)?; + } + + log::debug!("Grin GUI updated successfully"); + + Ok(()) } From 45b194c2b5b9d81cc0c164b15090b9c1dbe97524 Mon Sep 17 00:00:00 2001 From: Yeastplume Date: Wed, 17 Jan 2024 09:48:33 +0000 Subject: [PATCH 3/5] merge from master --- src/gui/element/about.rs | 157 +- src/gui/element/mod.rs | 8 +- src/gui/element/modal.rs | 213 +- src/gui/element/node/embedded/mod.rs | 90 +- src/gui/element/node/mod.rs | 65 +- src/gui/element/settings/general.rs | 1026 ++--- src/gui/element/settings/mod.rs | 304 +- src/gui/element/settings/node.rs | 104 +- src/gui/element/settings/wallet.rs | 449 ++- src/gui/element/wallet/mod.rs | 102 +- .../element/wallet/operation/action_menu.rs | 260 +- src/gui/element/wallet/operation/apply_tx.rs | 848 ++-- .../wallet/operation/apply_tx_confirm.rs | 884 ++-- src/gui/element/wallet/operation/chart.rs | 494 +-- src/gui/element/wallet/operation/create_tx.rs | 720 ++-- .../wallet/operation/create_tx_contracts.rs | 1126 +++--- src/gui/element/wallet/operation/home.rs | 1671 ++++---- src/gui/element/wallet/operation/mod.rs | 166 +- src/gui/element/wallet/operation/open.rs | 530 +-- .../wallet/operation/show_slatepack.rs | 383 +- src/gui/element/wallet/operation/tx_detail.rs | 765 ++-- src/gui/element/wallet/operation/tx_done.rs | 264 +- src/gui/element/wallet/operation/tx_list.rs | 3578 ++++++++--------- .../wallet/operation/tx_list_display.rs | 810 ++-- src/gui/element/wallet/operation/tx_proof.rs | 485 ++- src/gui/element/wallet/setup/init.rs | 308 +- src/gui/element/wallet/setup/mod.rs | 98 +- src/gui/element/wallet/setup/wallet_list.rs | 742 ++-- src/gui/element/wallet/setup/wallet_setup.rs | 1198 +++--- .../element/wallet/setup/wallet_success.rs | 208 +- src/gui/mod.rs | 1244 +++--- src/gui/time.rs | 40 +- src/gui/update.rs | 860 ++-- src/localization.rs | 56 +- src/process.rs | 132 +- src/tray/autostart.rs | 94 +- src/tray/mod.rs | 718 ++-- 37 files changed, 10618 insertions(+), 10582 deletions(-) diff --git a/src/gui/element/about.rs b/src/gui/element/about.rs index d5f8dee..e72e605 100644 --- a/src/gui/element/about.rs +++ b/src/gui/element/about.rs @@ -1,95 +1,104 @@ use { - super::{DEFAULT_FONT_SIZE, DEFAULT_HEADER_FONT_SIZE, DEFAULT_PADDING}, - crate::gui::{Interaction, Message}, - crate::localization::localized_string, - grin_gui_core::theme::{Button, Column, Container, Element, PickList, Row, Scrollable, Text}, - grin_gui_core::{theme::ColorPalette, utility::Release}, - iced::widget::{button, pick_list, scrollable, text_input, Checkbox, Space, TextInput}, - iced::{alignment, Alignment, Command, Length}, - std::collections::HashMap, - strfmt::strfmt, + super::{DEFAULT_FONT_SIZE, DEFAULT_HEADER_FONT_SIZE, DEFAULT_PADDING}, + crate::gui::{Interaction, Message}, + crate::localization::localized_string, + grin_gui_core::theme::{Button, Column, Container, Element, PickList, Row, Scrollable, Text}, + grin_gui_core::{theme::ColorPalette, utility::Release}, + iced::widget::{button, pick_list, scrollable, text_input, Checkbox, Space, TextInput}, + iced::{alignment, Alignment, Command, Length}, + std::collections::HashMap, + strfmt::strfmt, }; pub struct StateContainer {} impl Default for StateContainer { - fn default() -> Self { - Self {} - } + fn default() -> Self { + Self {} + } } pub fn data_container<'a>( - release: &Option, - state: &'a StateContainer, + release: &Option, + state: &'a StateContainer, ) -> Container<'a, Message> { - let grin_gui_title = Text::new(localized_string("grin")).size(DEFAULT_HEADER_FONT_SIZE); - let grin_gui_title_container = Container::new(grin_gui_title) - .style(grin_gui_core::theme::ContainerStyle::NormalBackground); + let grin_gui_title = Text::new(localized_string("grin")).size(DEFAULT_HEADER_FONT_SIZE); + let grin_gui_title_container = Container::new(grin_gui_title) + .style(grin_gui_core::theme::ContainerStyle::NormalBackground); - let changelog_title_text = Text::new(if let Some(release) = release { - let mut vars = HashMap::new(); - // TODO (casperstorm): change "addon" to "tag" or "version". - vars.insert("addon".to_string(), &release.tag_name); - let fmt = localized_string("changelog-for"); - strfmt(&fmt, &vars).unwrap() - } else { - localized_string("changelog") - }) - .size(DEFAULT_FONT_SIZE); + let changelog_title_text = Text::new(if let Some(release) = release { + let mut vars = HashMap::new(); + // TODO (casperstorm): change "addon" to "tag" or "version". + vars.insert("addon".to_string(), &release.tag_name); + let fmt = localized_string("changelog-for"); + strfmt(&fmt, &vars).unwrap() + } else { + localized_string("changelog") + }) + .size(DEFAULT_FONT_SIZE); - let changelog_text = Text::new(if let Some(release) = release { - release.body.clone() - } else { - localized_string("no-changelog") - }) - .size(DEFAULT_FONT_SIZE); + let changelog_text = Text::new(if let Some(release) = release { + release.body.clone() + } else { + localized_string("no-changelog") + }) + .size(DEFAULT_FONT_SIZE); - let website_button: Element = - Button::new(Text::new(localized_string("website")).size(DEFAULT_FONT_SIZE)) - .style(grin_gui_core::theme::ButtonStyle::Bordered) - .on_press(Interaction::OpenLink(localized_string("website-http"))) - .into(); + let website_button: Element = + Button::new(Text::new(localized_string("website")).size(DEFAULT_FONT_SIZE)) + .style(grin_gui_core::theme::ButtonStyle::Bordered) + .on_press(Interaction::OpenLink(localized_string("website-http"))) + .into(); - let donation_button: Element = - Button::new(Text::new(localized_string("donate")).size(DEFAULT_FONT_SIZE)) - .style(grin_gui_core::theme::ButtonStyle::Bordered) - .on_press(Interaction::OpenLink(localized_string("donate-http"))) - .into(); + let donation_button: Element = + Button::new(Text::new(localized_string("donate")).size(DEFAULT_FONT_SIZE)) + .style(grin_gui_core::theme::ButtonStyle::Bordered) + .on_press(Interaction::OpenLink(localized_string("donate-http"))) + .into(); - let button_row = Row::new() - .spacing(DEFAULT_PADDING) - .push(website_button.map(Message::Interaction)) - .push(donation_button.map(Message::Interaction)); + let button_row = Row::new() + .spacing(DEFAULT_PADDING) + .push(website_button.map(Message::Interaction)) + .push(donation_button.map(Message::Interaction)); - let changelog_text_container = Container::new(changelog_text) - .style(grin_gui_core::theme::ContainerStyle::NormalBackground); - let changelog_title_container = Container::new(changelog_title_text) - .style(grin_gui_core::theme::ContainerStyle::NormalBackground); + let changelog_text_container = Container::new(changelog_text) + .style(grin_gui_core::theme::ContainerStyle::NormalBackground); + let changelog_title_container = Container::new(changelog_title_text) + .style(grin_gui_core::theme::ContainerStyle::NormalBackground); - let column = Column::new() - .spacing(1) - .push(grin_gui_title_container) - .push(Space::new(Length::Fixed(0.0), Length::Fixed(DEFAULT_PADDING))) - .push(button_row) - .push(Space::new(Length::Fixed(0.0), Length::Fixed(DEFAULT_PADDING))) - .push(changelog_title_container) - .push(Space::new(Length::Fixed(0.0), Length::Fixed(5.0))) - .push(changelog_text_container); + let column = Column::new() + .spacing(1) + .push(grin_gui_title_container) + .push(Space::new( + Length::Fixed(0.0), + Length::Fixed(DEFAULT_PADDING), + )) + .push(button_row) + .push(Space::new( + Length::Fixed(0.0), + Length::Fixed(DEFAULT_PADDING), + )) + .push(changelog_title_container) + .push(Space::new(Length::Fixed(0.0), Length::Fixed(5.0))) + .push(changelog_text_container); - let mut scrollable = Scrollable::new(column) - .height(Length::FillPortion(1)) - .style(grin_gui_core::theme::ScrollableStyle::Primary); + let mut scrollable = Scrollable::new(column) + .height(Length::FillPortion(1)) + .style(grin_gui_core::theme::ScrollableStyle::Primary); - let col = Column::new().push(scrollable); - let row = Row::new() - .push(Space::new(Length::Fixed(DEFAULT_PADDING), Length::Fixed(0.0))) - .push(col); + let col = Column::new().push(scrollable); + let row = Row::new() + .push(Space::new( + Length::Fixed(DEFAULT_PADDING), + Length::Fixed(0.0), + )) + .push(col); - // Returns the final container. - Container::new(row) - .center_x() - .width(Length::Fill) - .height(Length::Shrink) - .style(grin_gui_core::theme::ContainerStyle::NormalBackground) - .padding(20) + // Returns the final container. + Container::new(row) + .center_x() + .width(Length::Fill) + .height(Length::Shrink) + .style(grin_gui_core::theme::ContainerStyle::NormalBackground) + .padding(20) } diff --git a/src/gui/element/mod.rs b/src/gui/element/mod.rs index 845d289..6069014 100644 --- a/src/gui/element/mod.rs +++ b/src/gui/element/mod.rs @@ -1,9 +1,9 @@ -pub mod menu; pub mod about; +pub mod menu; +pub mod modal; +pub mod node; pub mod settings; pub mod wallet; -pub mod node; -pub mod modal; // Default values used on multiple elements. pub static SMALLER_FONT_SIZE: u16 = 12; @@ -13,4 +13,4 @@ pub static DEFAULT_SUB_HEADER_FONT_SIZE: u16 = 18; pub static DEFAULT_PADDING: f32 = 10.0; pub static BUTTON_WIDTH: f32 = 84.0; -pub static BUTTON_HEIGHT: f32 = 16.0; \ No newline at end of file +pub static BUTTON_HEIGHT: f32 = 16.0; diff --git a/src/gui/element/modal.rs b/src/gui/element/modal.rs index a29ddc5..4a0ca1b 100644 --- a/src/gui/element/modal.rs +++ b/src/gui/element/modal.rs @@ -3,130 +3,125 @@ use iced::Renderer; use super::{BUTTON_HEIGHT, BUTTON_WIDTH}; use { - super::super::{DEFAULT_FONT_SIZE, DEFAULT_HEADER_FONT_SIZE, SMALLER_FONT_SIZE}, - crate::gui::{Interaction, Message}, - crate::localization::localized_string, - grin_gui_core::theme::ColorPalette, - grin_gui_core::theme::{Card, Container, Column, Button, Element, Scrollable, Text, PickList, Row}, - iced::{alignment, Alignment, Command, Length}, - iced::widget::{ - button, pick_list, scrollable, text_input, Checkbox, Space, TextInput, - }, - iced_aw::{modal, Modal}, + super::super::{DEFAULT_FONT_SIZE, DEFAULT_HEADER_FONT_SIZE, SMALLER_FONT_SIZE}, + crate::gui::{Interaction, Message}, + crate::localization::localized_string, + grin_gui_core::theme::ColorPalette, + grin_gui_core::theme::{ + Button, Card, Column, Container, Element, PickList, Row, Scrollable, Text, + }, + iced::widget::{button, pick_list, scrollable, text_input, Checkbox, Space, TextInput}, + iced::{alignment, Alignment, Command, Length}, + iced_aw::{modal, Modal}, }; -pub struct StateContainer { -} +pub struct StateContainer {} impl Default for StateContainer { - fn default() -> Self { - Self { - } - } + fn default() -> Self { + Self {} + } } pub fn exit_card() -> Card<'static, Message> { - let button_height = Length::Fixed(BUTTON_HEIGHT); - let button_width = Length::Fixed(BUTTON_WIDTH); + let button_height = Length::Fixed(BUTTON_HEIGHT); + let button_width = Length::Fixed(BUTTON_WIDTH); - let yes_button_label = - Container::new(Text::new(localized_string("yes")).size(DEFAULT_FONT_SIZE)) - .width(button_width) - .height(button_height) - .center_x() - .center_y() - .align_x(alignment::Horizontal::Center); + let yes_button_label = + Container::new(Text::new(localized_string("yes")).size(DEFAULT_FONT_SIZE)) + .width(button_width) + .height(button_height) + .center_x() + .center_y() + .align_x(alignment::Horizontal::Center); - let cancel_button_label = - Container::new(Text::new(localized_string("no")).size(DEFAULT_FONT_SIZE)) - .width(button_width) - .height(button_height) - .center_x() - .center_y() - .align_x(alignment::Horizontal::Center); + let cancel_button_label = + Container::new(Text::new(localized_string("no")).size(DEFAULT_FONT_SIZE)) + .width(button_width) + .height(button_height) + .center_x() + .center_y() + .align_x(alignment::Horizontal::Center); - let yes_button: Element = Button::new( yes_button_label) - .style(grin_gui_core::theme::ButtonStyle::Primary) - .on_press(Interaction::Exit) - .into(); + let yes_button: Element = Button::new(yes_button_label) + .style(grin_gui_core::theme::ButtonStyle::Primary) + .on_press(Interaction::Exit) + .into(); - let cancel_button: Element = - Button::new( cancel_button_label) - .style(grin_gui_core::theme::ButtonStyle::Primary) - .on_press(Interaction::ExitCancel) - .into(); + let cancel_button: Element = Button::new(cancel_button_label) + .style(grin_gui_core::theme::ButtonStyle::Primary) + .on_press(Interaction::ExitCancel) + .into(); - let unit_spacing = 15.0; + let unit_spacing = 15.0; - // button lipstick - let yes_container = Container::new(yes_button.map(Message::Interaction)).padding(1); - let yes_container = Container::new(yes_container) - .style(grin_gui_core::theme::ContainerStyle::Segmented) - .padding(1); - let cancel_container = Container::new(cancel_button.map(Message::Interaction)).padding(1); - let cancel_container = Container::new(cancel_container) - .style(grin_gui_core::theme::ContainerStyle::Segmented) - .padding(1); + // button lipstick + let yes_container = Container::new(yes_button.map(Message::Interaction)).padding(1); + let yes_container = Container::new(yes_container) + .style(grin_gui_core::theme::ContainerStyle::Segmented) + .padding(1); + let cancel_container = Container::new(cancel_button.map(Message::Interaction)).padding(1); + let cancel_container = Container::new(cancel_container) + .style(grin_gui_core::theme::ContainerStyle::Segmented) + .padding(1); - let button_row = Row::new() - .push(yes_container) - .push(Space::new(Length::Fixed(unit_spacing), Length::Fixed(0.0))) - .push(cancel_container); + let button_row = Row::new() + .push(yes_container) + .push(Space::new(Length::Fixed(unit_spacing), Length::Fixed(0.0))) + .push(cancel_container); - Card::new( - Text::new(localized_string("exit-confirm-title")) - .size(DEFAULT_HEADER_FONT_SIZE) - .horizontal_alignment(alignment::Horizontal::Center), - Text::new(localized_string("exit-confirm-msg")).size(DEFAULT_FONT_SIZE), - ) - .foot( - Column::new() - .spacing(10) - .padding(5) - .width(Length::Fill) - .align_items(Alignment::Center) - .push(button_row), - ) - .max_width(500.0) - .on_close(Message::Interaction(Interaction::ExitCancel)) - .style(grin_gui_core::theme::CardStyle::Normal) + Card::new( + Text::new(localized_string("exit-confirm-title")) + .size(DEFAULT_HEADER_FONT_SIZE) + .horizontal_alignment(alignment::Horizontal::Center), + Text::new(localized_string("exit-confirm-msg")).size(DEFAULT_FONT_SIZE), + ) + .foot( + Column::new() + .spacing(10) + .padding(5) + .width(Length::Fill) + .align_items(Alignment::Center) + .push(button_row), + ) + .max_width(500.0) + .on_close(Message::Interaction(Interaction::ExitCancel)) + .style(grin_gui_core::theme::CardStyle::Normal) } -pub fn error_card( - error_cause: String, -) -> Card<'static, Message> { - Card::new( - Text::new(localized_string("error-detail")).size(DEFAULT_HEADER_FONT_SIZE), - Text::new(error_cause.clone()).size(DEFAULT_FONT_SIZE), - ) - .foot( - Column::new() - .spacing(10) - .padding(5) - .width(Length::Fill) - .align_items(Alignment::Center) - .push( - Button::new( - Text::new(localized_string("ok-caps")) - .size(DEFAULT_FONT_SIZE) - .horizontal_alignment(alignment::Horizontal::Center), - ) - .style(grin_gui_core::theme::ButtonStyle::Primary) - .on_press(Message::Interaction(Interaction::CloseErrorModal)), - ) - .push( - Button::new( - Text::new(localized_string("copy-to-clipboard")) - .size(SMALLER_FONT_SIZE) - .horizontal_alignment(alignment::Horizontal::Center), - ) - .style(grin_gui_core::theme::ButtonStyle::NormalText) - .on_press(Message::Interaction(Interaction::WriteToClipboard( - error_cause, - ))), - ), - ) - .max_width(500.0) - .on_close(Message::Interaction(Interaction::CloseErrorModal)) - .style(grin_gui_core::theme::CardStyle::Normal) +pub fn error_card(error_cause: String) -> Card<'static, Message> { + Card::new( + Text::new(localized_string("error-detail")).size(DEFAULT_HEADER_FONT_SIZE), + Text::new(error_cause.clone()).size(DEFAULT_FONT_SIZE), + ) + .foot( + Column::new() + .spacing(10) + .padding(5) + .width(Length::Fill) + .align_items(Alignment::Center) + .push( + Button::new( + Text::new(localized_string("ok-caps")) + .size(DEFAULT_FONT_SIZE) + .horizontal_alignment(alignment::Horizontal::Center), + ) + .style(grin_gui_core::theme::ButtonStyle::Primary) + .on_press(Message::Interaction(Interaction::CloseErrorModal)), + ) + .push( + Button::new( + Text::new(localized_string("copy-to-clipboard")) + .size(SMALLER_FONT_SIZE) + .horizontal_alignment(alignment::Horizontal::Center), + ) + .style(grin_gui_core::theme::ButtonStyle::NormalText) + .on_press(Message::Interaction(Interaction::WriteToClipboard( + error_cause, + ))), + ), + ) + .max_width(500.0) + .on_close(Message::Interaction(Interaction::CloseErrorModal)) + .style(grin_gui_core::theme::CardStyle::Normal) } diff --git a/src/gui/element/node/embedded/mod.rs b/src/gui/element/node/embedded/mod.rs index e423d95..151b76f 100644 --- a/src/gui/element/node/embedded/mod.rs +++ b/src/gui/element/node/embedded/mod.rs @@ -3,73 +3,73 @@ use crate::gui::element::DEFAULT_PADDING; pub mod summary; use { - crate::gui::{GrinGui, Message}, - crate::Result, - grin_gui_core::node::ChainTypes, - grin_gui_core::node::ServerStats, - grin_gui_core::theme::ColorPalette, - grin_gui_core::theme::{Column, Container}, - iced::widget::container, - iced::{Command, Length}, + crate::gui::{GrinGui, Message}, + crate::Result, + grin_gui_core::node::ChainTypes, + grin_gui_core::node::ServerStats, + grin_gui_core::theme::ColorPalette, + grin_gui_core::theme::{Column, Container}, + iced::widget::container, + iced::{Command, Length}, }; pub struct StateContainer { - pub mode: Mode, - pub server_stats: Option, - pub summary_state: summary::StateContainer, + pub mode: Mode, + pub server_stats: Option, + pub summary_state: summary::StateContainer, } #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub enum Mode { - Summary, + Summary, - Peers, - // etc as in TUI + Peers, + // etc as in TUI } impl Default for StateContainer { - fn default() -> Self { - Self { - mode: Mode::Summary, - server_stats: None, - summary_state: Default::default(), - } - } + fn default() -> Self { + Self { + mode: Mode::Summary, + server_stats: None, + summary_state: Default::default(), + } + } } #[derive(Debug, Clone)] pub enum LocalViewInteraction {} pub fn handle_message( - grin_gui: &mut GrinGui, - message: LocalViewInteraction, + grin_gui: &mut GrinGui, + message: LocalViewInteraction, ) -> Result> { - Ok(Command::none()) + Ok(Command::none()) } pub fn data_container<'a>( - state: &'a StateContainer, - chain_type: ChainTypes, + state: &'a StateContainer, + chain_type: ChainTypes, ) -> Container<'a, Message> { - let content = match state.mode { - Mode::Summary => { - summary::data_container(&state.summary_state, &state.server_stats, chain_type) - } - _ => Container::new(Column::new()), - }; + let content = match state.mode { + Mode::Summary => { + summary::data_container(&state.summary_state, &state.server_stats, chain_type) + } + _ => Container::new(Column::new()), + }; - let column = Column::new().push(content); + let column = Column::new().push(content); - Container::new(column) - .center_y() - .center_x() - .width(Length::Fill) - .height(Length::Fill) - .style(grin_gui_core::theme::ContainerStyle::NormalBackground) - .padding(iced::Padding::from([ - DEFAULT_PADDING, // top - DEFAULT_PADDING, // right - DEFAULT_PADDING, // bottom - DEFAULT_PADDING, // left - ])) + Container::new(column) + .center_y() + .center_x() + .width(Length::Fill) + .height(Length::Fill) + .style(grin_gui_core::theme::ContainerStyle::NormalBackground) + .padding(iced::Padding::from([ + DEFAULT_PADDING, // top + DEFAULT_PADDING, // right + DEFAULT_PADDING, // bottom + DEFAULT_PADDING, // left + ])) } diff --git a/src/gui/element/node/mod.rs b/src/gui/element/node/mod.rs index 73434ff..f12bf18 100644 --- a/src/gui/element/node/mod.rs +++ b/src/gui/element/node/mod.rs @@ -1,52 +1,51 @@ pub mod embedded; use { - crate::gui::{Message}, - grin_gui_core::{theme::ColorPalette, node::ChainTypes}, - iced::Length, - grin_gui_core::theme::{Container, Column}, + crate::gui::Message, + grin_gui_core::theme::{Column, Container}, + grin_gui_core::{node::ChainTypes, theme::ColorPalette}, + iced::Length, }; #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub enum Mode { - Embedded, - // etc, as in TUI for now + Embedded, + // etc, as in TUI for now } pub struct StateContainer { - pub mode: Mode, - //pub external_state: external::StateContainer, - pub embedded_state: embedded::StateContainer, + pub mode: Mode, + //pub external_state: external::StateContainer, + pub embedded_state: embedded::StateContainer, } impl Default for StateContainer { - fn default() -> Self { - Self { - mode: Mode::Embedded, - embedded_state: Default::default(), - } - } + fn default() -> Self { + Self { + mode: Mode::Embedded, + embedded_state: Default::default(), + } + } } -impl StateContainer { -} +impl StateContainer {} pub fn data_container<'a>( - state: &'a StateContainer, - chain_type: ChainTypes, + state: &'a StateContainer, + chain_type: ChainTypes, ) -> Container<'a, Message> { - let content = match state.mode { - Mode::Embedded => embedded::data_container(&state.embedded_state, chain_type), - //_ => Container::new(Column::new()), - }; - - let column = Column::new() - //.push(Space::new(Length::Fixed(0.0), Length::Fixed(20))) - .push(content); - - Container::new(column) - .center_y() - .center_x() - .width(Length::Fill) - .style(grin_gui_core::theme::ContainerStyle::NormalBackground) + let content = match state.mode { + Mode::Embedded => embedded::data_container(&state.embedded_state, chain_type), + //_ => Container::new(Column::new()), + }; + + let column = Column::new() + //.push(Space::new(Length::Fixed(0.0), Length::Fixed(20))) + .push(content); + + Container::new(column) + .center_y() + .center_x() + .width(Length::Fill) + .style(grin_gui_core::theme::ContainerStyle::NormalBackground) } diff --git a/src/gui/element/settings/general.rs b/src/gui/element/settings/general.rs index 0decc44..00d4d24 100644 --- a/src/gui/element/settings/general.rs +++ b/src/gui/element/settings/general.rs @@ -2,555 +2,555 @@ use futures::future; use grin_gui_core::config::Currency; use { - super::{DEFAULT_FONT_SIZE, DEFAULT_PADDING}, - crate::gui::{GrinGui, Interaction, Message}, - crate::localization::{localized_string, LANG}, - crate::{log_error, Result}, - anyhow::Context, - grin_gui_core::{ - config::{Config, Language}, - error::ThemeError, - fs::{import_theme, PersistentData}, - theme::{ - Button, ColorPalette, Column, Container, Element, PickList, Row, Scrollable, Text, - TextInput, Theme, - }, - }, - iced::widget::{button, pick_list, scrollable, text_input, Checkbox, Space}, - iced::{Alignment, Command, Length}, - std::sync::{Arc, RwLock}, + super::{DEFAULT_FONT_SIZE, DEFAULT_PADDING}, + crate::gui::{GrinGui, Interaction, Message}, + crate::localization::{localized_string, LANG}, + crate::{log_error, Result}, + anyhow::Context, + grin_gui_core::{ + config::{Config, Language}, + error::ThemeError, + fs::{import_theme, PersistentData}, + theme::{ + Button, ColorPalette, Column, Container, Element, PickList, Row, Scrollable, Text, + TextInput, Theme, + }, + }, + iced::widget::{button, pick_list, scrollable, text_input, Checkbox, Space}, + iced::{Alignment, Command, Length}, + std::sync::{Arc, RwLock}, }; #[derive(Debug, Clone)] pub struct StateContainer { - pub theme_state: ThemeState, - pub scale_state: ScaleState, - //scrollable_state: scrollable::State, - //localization_picklist_state: pick_list::State, + pub theme_state: ThemeState, + pub scale_state: ScaleState, + //scrollable_state: scrollable::State, + //localization_picklist_state: pick_list::State, } impl Default for StateContainer { - fn default() -> Self { - Self { - theme_state: Default::default(), - //scrollable_state: Default::default(), - scale_state: Default::default(), - //localization_picklist_state: Default::default(), - } - } + fn default() -> Self { + Self { + theme_state: Default::default(), + //scrollable_state: Default::default(), + scale_state: Default::default(), + //localization_picklist_state: Default::default(), + } + } } #[derive(Debug, Clone)] pub struct ThemeState { - pub themes: Vec<(String, Theme)>, - pub current_theme_name: String, - //pick_list_state: pick_list::State, - //input_state: text_input::State, - input_url: String, - //import_button_state: button::State, - //open_builder_button_state: button::State, + pub themes: Vec<(String, Theme)>, + pub current_theme_name: String, + //pick_list_state: pick_list::State, + //input_state: text_input::State, + input_url: String, + //import_button_state: button::State, + //open_builder_button_state: button::State, } impl Default for ThemeState { - fn default() -> Self { - let themes = Theme::all(); - - ThemeState { - themes, - current_theme_name: "Dark".to_string(), - //pick_list_state: Default::default(), - //input_state: Default::default(), - input_url: Default::default(), - //import_button_state: Default::default(), - //open_builder_button_state: Default::default(), - } - } + fn default() -> Self { + let themes = Theme::all(); + + ThemeState { + themes, + current_theme_name: "Dark".to_string(), + //pick_list_state: Default::default(), + //input_state: Default::default(), + input_url: Default::default(), + //import_button_state: Default::default(), + //open_builder_button_state: Default::default(), + } + } } #[derive(Debug, Clone)] pub struct ScaleState { - pub scale: f64, - //up_btn_state: button::State, - //down_btn_state: button::State, + pub scale: f64, + //up_btn_state: button::State, + //down_btn_state: button::State, } impl Default for ScaleState { - fn default() -> Self { - ScaleState { - scale: 1.0, - //up_btn_state: Default::default(), - //down_btn_state: Default::default(), - } - } + fn default() -> Self { + ScaleState { + scale: 1.0, + //up_btn_state: Default::default(), + //down_btn_state: Default::default(), + } + } } #[derive(Debug, Clone)] pub enum LocalViewInteraction { - ThemeSelected(String), - CurrencySelected(Currency), - LanguageSelected(Language), - ScaleUp, - ScaleDown, - ThemeUrlInput(String), - ImportTheme, - ThemeImportedOk((String, Vec)), - ThemeImportedError(Arc>>), + ThemeSelected(String), + CurrencySelected(Currency), + LanguageSelected(Language), + ScaleUp, + ScaleDown, + ThemeUrlInput(String), + ImportTheme, + ThemeImportedOk((String, Vec)), + ThemeImportedError(Arc>>), } #[derive(Debug, Clone)] pub enum Mode { - Wallet, - Node, - General, + Wallet, + Node, + General, } pub fn handle_message( - grin_gui: &mut GrinGui, - message: LocalViewInteraction, + grin_gui: &mut GrinGui, + message: LocalViewInteraction, ) -> Result> { - let state = &mut grin_gui.general_settings_state; - match message { - LocalViewInteraction::CurrencySelected(currency) => { - log::debug!( - "settings::general::LocalViewInteraction::CurrencySelected({:?})", - ¤cy - ); - - grin_gui.config.currency = currency; - let _ = grin_gui.config.save(); - - return Ok(Command::perform(future::ready(()), |r| { - // update the prices - Message::Interaction(Interaction::WalletOperationHomeViewInteraction( + let state = &mut grin_gui.general_settings_state; + match message { + LocalViewInteraction::CurrencySelected(currency) => { + log::debug!( + "settings::general::LocalViewInteraction::CurrencySelected({:?})", + ¤cy + ); + + grin_gui.config.currency = currency; + let _ = grin_gui.config.save(); + + return Ok(Command::perform(future::ready(()), |r| { + // update the prices + Message::Interaction(Interaction::WalletOperationHomeViewInteraction( crate::gui::element::wallet::operation::home::LocalViewInteraction::UpdatePrices, )) - })); - } - LocalViewInteraction::ThemeSelected(theme_name) => { - log::debug!( - "settings::general::LocalViewInteraction::ThemeSelected({:?})", - &theme_name - ); - - // set theme for gui - let theme = &state - .theme_state - .themes - .iter() - .find(|x| theme_name == x.0) - .unwrap() - .1; - grin_gui.theme = theme.clone(); - - state.theme_state.current_theme_name = theme_name.clone(); - grin_gui.config.theme = Some(theme_name); - - let _ = grin_gui.config.save(); - } - LocalViewInteraction::LanguageSelected(lang) => { - log::debug!( - "settings::general::LocalViewInteraction::LanguageSelected({:?})", - &lang - ); - // Update config. - grin_gui.config.language = lang; - let _ = grin_gui.config.save(); - - // Update global LANG refcell. - *LANG.get().expect("LANG not set").write().unwrap() = lang.language_code(); - } - LocalViewInteraction::ScaleUp => { - let prev_scale = state.scale_state.scale; - - state.scale_state.scale = ((prev_scale + 0.1).min(2.0) * 10.0).round() / 10.0; - - grin_gui.config.scale = Some(state.scale_state.scale); - let _ = grin_gui.config.save(); - - log::debug!( - "settings::general::LocalViewInteraction::ScaleUp({} -> {})", - prev_scale, - state.scale_state.scale - ); - } - LocalViewInteraction::ScaleDown => { - let prev_scale = state.scale_state.scale; - - state.scale_state.scale = ((prev_scale - 0.1).max(0.5) * 10.0).round() / 10.0; - - grin_gui.config.scale = Some(state.scale_state.scale); - let _ = grin_gui.config.save(); - - log::debug!( - "settings::general::LocalViewInteraction::ScaleDown({} -> {})", - prev_scale, - state.scale_state.scale - ); - } - LocalViewInteraction::ThemeUrlInput(url) => { - state.theme_state.input_url = url; - } - LocalViewInteraction::ImportTheme => { - // Reset error - grin_gui.error.take(); - - let url = state.theme_state.input_url.clone(); - - log::debug!("Interaction::ImportTheme({})", &url); - - return Ok(Command::perform(import_theme(url), |r| { - match r.context("Failed to Import Theme") { - Ok(result) => { - Message::Interaction(Interaction::GeneralSettingsViewInteraction( - LocalViewInteraction::ThemeImportedOk(result), - )) - } - Err(mut e) => { - for cause in e.chain() { - if let Some(theme_error) = cause.downcast_ref::() { - if matches!(theme_error, ThemeError::NameCollision { .. }) { - e = e.context(localized_string( - "import-theme-error-name-collision", - )); - break; - } - } - } - Message::Interaction(Interaction::GeneralSettingsViewInteraction( - LocalViewInteraction::ThemeImportedError(Arc::new(RwLock::new(Some( - e, - )))), - )) - } - } - })); - } - LocalViewInteraction::ThemeImportedOk((new_theme_name, mut new_themes)) => { - log::debug!("Message::ThemeImported({})", &new_theme_name); - - state.theme_state = Default::default(); - - new_themes.sort(); - - for theme in new_themes { - state.theme_state.themes.push((theme.name.clone(), theme)); - } - - state.theme_state.current_theme_name = new_theme_name.clone(); - grin_gui.config.theme = Some(new_theme_name); - let _ = grin_gui.config.save(); - } - LocalViewInteraction::ThemeImportedError(err) => { - grin_gui.error = err.write().unwrap().take(); - if let Some(e) = grin_gui.error.as_ref() { - log_error(e); - } - // Reset text input - state.theme_state.input_url = Default::default(); - //state.theme_state.input_state = Default::default(); - } - } - Ok(Command::none()) + })); + } + LocalViewInteraction::ThemeSelected(theme_name) => { + log::debug!( + "settings::general::LocalViewInteraction::ThemeSelected({:?})", + &theme_name + ); + + // set theme for gui + let theme = &state + .theme_state + .themes + .iter() + .find(|x| theme_name == x.0) + .unwrap() + .1; + grin_gui.theme = theme.clone(); + + state.theme_state.current_theme_name = theme_name.clone(); + grin_gui.config.theme = Some(theme_name); + + let _ = grin_gui.config.save(); + } + LocalViewInteraction::LanguageSelected(lang) => { + log::debug!( + "settings::general::LocalViewInteraction::LanguageSelected({:?})", + &lang + ); + // Update config. + grin_gui.config.language = lang; + let _ = grin_gui.config.save(); + + // Update global LANG refcell. + *LANG.get().expect("LANG not set").write().unwrap() = lang.language_code(); + } + LocalViewInteraction::ScaleUp => { + let prev_scale = state.scale_state.scale; + + state.scale_state.scale = ((prev_scale + 0.1).min(2.0) * 10.0).round() / 10.0; + + grin_gui.config.scale = Some(state.scale_state.scale); + let _ = grin_gui.config.save(); + + log::debug!( + "settings::general::LocalViewInteraction::ScaleUp({} -> {})", + prev_scale, + state.scale_state.scale + ); + } + LocalViewInteraction::ScaleDown => { + let prev_scale = state.scale_state.scale; + + state.scale_state.scale = ((prev_scale - 0.1).max(0.5) * 10.0).round() / 10.0; + + grin_gui.config.scale = Some(state.scale_state.scale); + let _ = grin_gui.config.save(); + + log::debug!( + "settings::general::LocalViewInteraction::ScaleDown({} -> {})", + prev_scale, + state.scale_state.scale + ); + } + LocalViewInteraction::ThemeUrlInput(url) => { + state.theme_state.input_url = url; + } + LocalViewInteraction::ImportTheme => { + // Reset error + grin_gui.error.take(); + + let url = state.theme_state.input_url.clone(); + + log::debug!("Interaction::ImportTheme({})", &url); + + return Ok(Command::perform(import_theme(url), |r| { + match r.context("Failed to Import Theme") { + Ok(result) => { + Message::Interaction(Interaction::GeneralSettingsViewInteraction( + LocalViewInteraction::ThemeImportedOk(result), + )) + } + Err(mut e) => { + for cause in e.chain() { + if let Some(theme_error) = cause.downcast_ref::() { + if matches!(theme_error, ThemeError::NameCollision { .. }) { + e = e.context(localized_string( + "import-theme-error-name-collision", + )); + break; + } + } + } + Message::Interaction(Interaction::GeneralSettingsViewInteraction( + LocalViewInteraction::ThemeImportedError(Arc::new(RwLock::new(Some( + e, + )))), + )) + } + } + })); + } + LocalViewInteraction::ThemeImportedOk((new_theme_name, mut new_themes)) => { + log::debug!("Message::ThemeImported({})", &new_theme_name); + + state.theme_state = Default::default(); + + new_themes.sort(); + + for theme in new_themes { + state.theme_state.themes.push((theme.name.clone(), theme)); + } + + state.theme_state.current_theme_name = new_theme_name.clone(); + grin_gui.config.theme = Some(new_theme_name); + let _ = grin_gui.config.save(); + } + LocalViewInteraction::ThemeImportedError(err) => { + grin_gui.error = err.write().unwrap().take(); + if let Some(e) = grin_gui.error.as_ref() { + log_error(e); + } + // Reset text input + state.theme_state.input_url = Default::default(); + //state.theme_state.input_state = Default::default(); + } + } + Ok(Command::none()) } pub fn data_container<'a>(state: &'a StateContainer, config: &Config) -> Container<'a, Message> { - let language_container = { - let title = Container::new(Text::new(localized_string("language")).size(DEFAULT_FONT_SIZE)) - .style(grin_gui_core::theme::ContainerStyle::NormalBackground); - - let pick_list = PickList::new(&Language::ALL[..], Some(config.language), |l| { - Message::Interaction(Interaction::GeneralSettingsViewInteraction( - LocalViewInteraction::LanguageSelected(l), - )) - }) - .text_size(14) - .width(Length::Fixed(120.0)) - .style(grin_gui_core::theme::PickListStyle::Primary); - - let container = Container::new(pick_list) - .center_y() - .width(Length::Fixed(120.0)) - .style(grin_gui_core::theme::ContainerStyle::NormalBackground); - - Column::new() - .push(title) - .push(Space::new(Length::Fixed(0.0), Length::Fixed(5.0))) - .push(container) - }; - - let currency_container = { - let title = Container::new(Text::new(localized_string("currency")).size(DEFAULT_FONT_SIZE)) - .style(grin_gui_core::theme::ContainerStyle::NormalBackground); - - let pick_list = PickList::new(&Currency::ALL[..], Some(config.currency), |c| { - Message::Interaction(Interaction::GeneralSettingsViewInteraction( - LocalViewInteraction::CurrencySelected(c), - )) - }) - .text_size(14) - .width(Length::Fixed(120.0)) - .style(grin_gui_core::theme::PickListStyle::Primary); - - let container = Container::new(pick_list) - .center_y() - .width(Length::Fixed(120.0)) - .style(grin_gui_core::theme::ContainerStyle::NormalBackground); - - Column::new() - .push(title) - .push(Space::new(Length::Fixed(0.0), Length::Fixed(5.0))) - .push(container) - }; - - let theme_column = { - let title_container = - Container::new(Text::new(localized_string("theme")).size(DEFAULT_FONT_SIZE)) - .style(grin_gui_core::theme::ContainerStyle::NormalBackground); - - let theme_names = state - .theme_state - .themes - .iter() - .cloned() - .map(|(name, _)| name) - .collect::>(); - - let theme_pick_list = PickList::new( - theme_names, - Some(state.theme_state.current_theme_name.clone()), - |t| { - Message::Interaction(Interaction::GeneralSettingsViewInteraction( - LocalViewInteraction::ThemeSelected(t), - )) - }, - ) - .text_size(DEFAULT_FONT_SIZE) - .width(Length::Fixed(120.0)) - .style(grin_gui_core::theme::PickListStyle::Primary); - - // Data row for theme picker list. - let theme_data_row = Row::new() - .push(theme_pick_list) - .align_items(Alignment::Center) - .height(Length::Fixed(26.0)); - - Column::new() - .push(title_container) - .push(Space::new(Length::Fixed(0.0), Length::Fixed(5.0))) - .push(theme_data_row) - }; - - // Scale buttons for application scale factoring. - let scale_column = { - let title_container = - Container::new(Text::new(localized_string("scale")).size(DEFAULT_FONT_SIZE)) - .style(grin_gui_core::theme::ContainerStyle::NormalBackground); - let scale_title_row = Row::new().push(title_container); - - let scale_down_button: Element = Button::new( - // &mut state.scale_state.down_btn_state, - Text::new(" - ").size(DEFAULT_FONT_SIZE), - ) - .style(grin_gui_core::theme::ButtonStyle::Bordered) - .on_press(Interaction::GeneralSettingsViewInteraction( - LocalViewInteraction::ScaleDown, - )) - .into(); - - let scale_up_button: Element = Button::new( - // &mut state.scale_state.up_btn_state, - Text::new(" + ").size(DEFAULT_FONT_SIZE), - ) - .style(grin_gui_core::theme::ButtonStyle::Bordered) - .on_press(Interaction::GeneralSettingsViewInteraction( - LocalViewInteraction::ScaleUp, - )) - .into(); - - let current_scale_text = Text::new(format!(" {:.2} ", state.scale_state.scale)) - .size(DEFAULT_FONT_SIZE) - .vertical_alignment(iced_core::alignment::Vertical::Center); - let current_scale_container = Container::new(current_scale_text) - .height(Length::Fill) - .center_y() - .style(grin_gui_core::theme::ContainerStyle::NormalBackground); - - let scale_buttons_row = Row::new() - .push(scale_down_button.map(Message::Interaction)) - .push(current_scale_container) - .push(scale_up_button.map(Message::Interaction)) - .align_items(Alignment::Center) - .height(Length::Fixed(26.0)); - - Column::new() - .push(scale_title_row) - .push(Space::new(Length::Fixed(0.0), Length::Fixed(5.0))) - .push(scale_buttons_row) - }; - - let import_theme_column = { - let title_container = - Container::new(Text::new(localized_string("import-theme")).size(DEFAULT_FONT_SIZE)) - .style(grin_gui_core::theme::ContainerStyle::NormalBackground); - - let theme_input = TextInput::new( - &localized_string("paste-url")[..], - &state.theme_state.input_url, - //|s| Interaction::GeneralSettingsViewInteraction(LocalViewInteraction::ThemeUrlInput(s)), - ) - .size(DEFAULT_FONT_SIZE) - .padding(6) - .width(Length::Fixed(185.0)) - .style(grin_gui_core::theme::TextInputStyle::AddonsQuery); - - let theme_input: Element = theme_input.into(); - - let mut import_button = Button::new( - // &mut state.theme_state.import_button_state, - Text::new(localized_string("import-theme-button")).size(DEFAULT_FONT_SIZE), - ) - .style(grin_gui_core::theme::ButtonStyle::Bordered); - - if !state.theme_state.input_url.is_empty() { - import_button = import_button.on_press(Interaction::GeneralSettingsViewInteraction( - LocalViewInteraction::ImportTheme, - )); - } - - let import_button: Element = import_button.into(); - - let theme_input_row = Row::new() - .push(theme_input.map(Message::Interaction)) - .push(import_button.map(Message::Interaction)) - .spacing(DEFAULT_PADDING) - .align_items(Alignment::Center) - .height(Length::Fixed(26.0)); - - Column::new() - .push(title_container) - .push(Space::new(Length::Fixed(0.0), Length::Fixed(5.0))) - .push(theme_input_row) - }; - - let open_theme_row = { - let open_button = Button::new( - // &mut state.theme_state.open_builder_button_state, - Text::new(localized_string("open-theme-builder")).size(DEFAULT_FONT_SIZE), - ) - .on_press(Interaction::OpenLink(String::from( - "https://theme.getajour.com", - ))) - .style(grin_gui_core::theme::ButtonStyle::Bordered); - - let open_button: Element = open_button.into(); - - Row::new() - .push(open_button.map(Message::Interaction)) - .align_items(Alignment::Center) - .height(Length::Fixed(26.0)) - }; - - let theme_scale_row = Row::new() - .push(theme_column) - .push(scale_column) - .push(import_theme_column) - .spacing(DEFAULT_PADDING); - - #[cfg(target_os = "windows")] - let close_to_tray_column = { - let checkbox = Checkbox::new( - localized_string("close-to-tray"), - config.close_to_tray, - Interaction::ToggleCloseToTray, - ) - .style(grin_gui_core::theme::CheckboxStyle::Normal) - .text_size(DEFAULT_FONT_SIZE) - .spacing(5); - - let checkbox: Element = checkbox.into(); - - let checkbox_container = Container::new(checkbox.map(Message::Interaction)) - .style(grin_gui_core::theme::ContainerStyle::NormalBackground); - Column::new().push(checkbox_container) - }; - - #[cfg(target_os = "windows")] - let toggle_autostart_column = { - let checkbox = Checkbox::new( - localized_string("toggle-autostart"), - config.autostart, - Interaction::ToggleAutoStart, - ) - .style(grin_gui_core::theme::CheckboxStyle::Normal) - .text_size(DEFAULT_FONT_SIZE) - .spacing(5); - - let checkbox: Element = checkbox.into(); - - let checkbox_container = Container::new(checkbox.map(Message::Interaction)) - .style(grin_gui_core::theme::ContainerStyle::NormalBackground); - Column::new().push(checkbox_container) - }; - - #[cfg(target_os = "windows")] - let start_closed_to_tray_column = { - let checkbox = Checkbox::new( - localized_string("start-closed-to-tray"), - config.start_closed_to_tray, - Interaction::ToggleStartClosedToTray, - ) - .style(grin_gui_core::theme::CheckboxStyle::Normal) - .text_size(DEFAULT_FONT_SIZE) - .spacing(5); - - let checkbox: Element = checkbox.into(); - - let checkbox_container = Container::new(checkbox.map(Message::Interaction)) - .style(grin_gui_core::theme::ContainerStyle::NormalBackground); - Column::new().push(checkbox_container) - }; - - let mut column = Column::new() - .spacing(1) - .push(language_container) - .push(Space::new(Length::Fixed(0.0), Length::Fixed(10.0))) - .push(currency_container) - .push(Space::new(Length::Fixed(0.0), Length::Fixed(10.0))) - .push(theme_scale_row) - .push(Space::new(Length::Fixed(0.0), Length::Fixed(10.0))) - .push(open_theme_row) - .spacing(1); - - // Systray settings - #[cfg(target_os = "windows")] - { - column = column - .push(Space::new(Length::Fixed(0.0), Length::Fixed(10.0))) - .push(close_to_tray_column) - .push(Space::new(Length::Fixed(0.0), Length::Fixed(10.0))) - .push(start_closed_to_tray_column) - .push(Space::new(Length::Fixed(0.0), Length::Fixed(10.0))) - .push(toggle_autostart_column); - } - - let scrollable = Scrollable::new(column) - .height(Length::Fill) - .style(grin_gui_core::theme::ScrollableStyle::Primary); - - // Colum wrapping all the settings content. - //scrollable = scrollable.height(Length::Fill); - - let col = Column::new() - .push(Space::new(Length::Fixed(0.0), Length::Fixed(10.0))) - .push(scrollable) - .push(Space::new(Length::Fixed(0.0), Length::Fixed(20.0))); - let row = Row::new() - .push(Space::new(Length::Fixed(5.0), Length::Fixed(0.0))) - .push(col); - - // Returns the final container. - Container::new(row) - .width(Length::Fill) - .height(Length::Shrink) - .style(grin_gui_core::theme::ContainerStyle::NormalBackground) + let language_container = { + let title = Container::new(Text::new(localized_string("language")).size(DEFAULT_FONT_SIZE)) + .style(grin_gui_core::theme::ContainerStyle::NormalBackground); + + let pick_list = PickList::new(&Language::ALL[..], Some(config.language), |l| { + Message::Interaction(Interaction::GeneralSettingsViewInteraction( + LocalViewInteraction::LanguageSelected(l), + )) + }) + .text_size(14) + .width(Length::Fixed(120.0)) + .style(grin_gui_core::theme::PickListStyle::Primary); + + let container = Container::new(pick_list) + .center_y() + .width(Length::Fixed(120.0)) + .style(grin_gui_core::theme::ContainerStyle::NormalBackground); + + Column::new() + .push(title) + .push(Space::new(Length::Fixed(0.0), Length::Fixed(5.0))) + .push(container) + }; + + let currency_container = { + let title = Container::new(Text::new(localized_string("currency")).size(DEFAULT_FONT_SIZE)) + .style(grin_gui_core::theme::ContainerStyle::NormalBackground); + + let pick_list = PickList::new(&Currency::ALL[..], Some(config.currency), |c| { + Message::Interaction(Interaction::GeneralSettingsViewInteraction( + LocalViewInteraction::CurrencySelected(c), + )) + }) + .text_size(14) + .width(Length::Fixed(120.0)) + .style(grin_gui_core::theme::PickListStyle::Primary); + + let container = Container::new(pick_list) + .center_y() + .width(Length::Fixed(120.0)) + .style(grin_gui_core::theme::ContainerStyle::NormalBackground); + + Column::new() + .push(title) + .push(Space::new(Length::Fixed(0.0), Length::Fixed(5.0))) + .push(container) + }; + + let theme_column = { + let title_container = + Container::new(Text::new(localized_string("theme")).size(DEFAULT_FONT_SIZE)) + .style(grin_gui_core::theme::ContainerStyle::NormalBackground); + + let theme_names = state + .theme_state + .themes + .iter() + .cloned() + .map(|(name, _)| name) + .collect::>(); + + let theme_pick_list = PickList::new( + theme_names, + Some(state.theme_state.current_theme_name.clone()), + |t| { + Message::Interaction(Interaction::GeneralSettingsViewInteraction( + LocalViewInteraction::ThemeSelected(t), + )) + }, + ) + .text_size(DEFAULT_FONT_SIZE) + .width(Length::Fixed(120.0)) + .style(grin_gui_core::theme::PickListStyle::Primary); + + // Data row for theme picker list. + let theme_data_row = Row::new() + .push(theme_pick_list) + .align_items(Alignment::Center) + .height(Length::Fixed(26.0)); + + Column::new() + .push(title_container) + .push(Space::new(Length::Fixed(0.0), Length::Fixed(5.0))) + .push(theme_data_row) + }; + + // Scale buttons for application scale factoring. + let scale_column = { + let title_container = + Container::new(Text::new(localized_string("scale")).size(DEFAULT_FONT_SIZE)) + .style(grin_gui_core::theme::ContainerStyle::NormalBackground); + let scale_title_row = Row::new().push(title_container); + + let scale_down_button: Element = Button::new( + // &mut state.scale_state.down_btn_state, + Text::new(" - ").size(DEFAULT_FONT_SIZE), + ) + .style(grin_gui_core::theme::ButtonStyle::Bordered) + .on_press(Interaction::GeneralSettingsViewInteraction( + LocalViewInteraction::ScaleDown, + )) + .into(); + + let scale_up_button: Element = Button::new( + // &mut state.scale_state.up_btn_state, + Text::new(" + ").size(DEFAULT_FONT_SIZE), + ) + .style(grin_gui_core::theme::ButtonStyle::Bordered) + .on_press(Interaction::GeneralSettingsViewInteraction( + LocalViewInteraction::ScaleUp, + )) + .into(); + + let current_scale_text = Text::new(format!(" {:.2} ", state.scale_state.scale)) + .size(DEFAULT_FONT_SIZE) + .vertical_alignment(iced_core::alignment::Vertical::Center); + let current_scale_container = Container::new(current_scale_text) + .height(Length::Fill) + .center_y() + .style(grin_gui_core::theme::ContainerStyle::NormalBackground); + + let scale_buttons_row = Row::new() + .push(scale_down_button.map(Message::Interaction)) + .push(current_scale_container) + .push(scale_up_button.map(Message::Interaction)) + .align_items(Alignment::Center) + .height(Length::Fixed(26.0)); + + Column::new() + .push(scale_title_row) + .push(Space::new(Length::Fixed(0.0), Length::Fixed(5.0))) + .push(scale_buttons_row) + }; + + let import_theme_column = { + let title_container = + Container::new(Text::new(localized_string("import-theme")).size(DEFAULT_FONT_SIZE)) + .style(grin_gui_core::theme::ContainerStyle::NormalBackground); + + let theme_input = TextInput::new( + &localized_string("paste-url")[..], + &state.theme_state.input_url, + //|s| Interaction::GeneralSettingsViewInteraction(LocalViewInteraction::ThemeUrlInput(s)), + ) + .size(DEFAULT_FONT_SIZE) + .padding(6) + .width(Length::Fixed(185.0)) + .style(grin_gui_core::theme::TextInputStyle::AddonsQuery); + + let theme_input: Element = theme_input.into(); + + let mut import_button = Button::new( + // &mut state.theme_state.import_button_state, + Text::new(localized_string("import-theme-button")).size(DEFAULT_FONT_SIZE), + ) + .style(grin_gui_core::theme::ButtonStyle::Bordered); + + if !state.theme_state.input_url.is_empty() { + import_button = import_button.on_press(Interaction::GeneralSettingsViewInteraction( + LocalViewInteraction::ImportTheme, + )); + } + + let import_button: Element = import_button.into(); + + let theme_input_row = Row::new() + .push(theme_input.map(Message::Interaction)) + .push(import_button.map(Message::Interaction)) + .spacing(DEFAULT_PADDING) + .align_items(Alignment::Center) + .height(Length::Fixed(26.0)); + + Column::new() + .push(title_container) + .push(Space::new(Length::Fixed(0.0), Length::Fixed(5.0))) + .push(theme_input_row) + }; + + let open_theme_row = { + let open_button = Button::new( + // &mut state.theme_state.open_builder_button_state, + Text::new(localized_string("open-theme-builder")).size(DEFAULT_FONT_SIZE), + ) + .on_press(Interaction::OpenLink(String::from( + "https://theme.getajour.com", + ))) + .style(grin_gui_core::theme::ButtonStyle::Bordered); + + let open_button: Element = open_button.into(); + + Row::new() + .push(open_button.map(Message::Interaction)) + .align_items(Alignment::Center) + .height(Length::Fixed(26.0)) + }; + + let theme_scale_row = Row::new() + .push(theme_column) + .push(scale_column) + .push(import_theme_column) + .spacing(DEFAULT_PADDING); + + #[cfg(target_os = "windows")] + let close_to_tray_column = { + let checkbox = Checkbox::new( + localized_string("close-to-tray"), + config.close_to_tray, + Interaction::ToggleCloseToTray, + ) + .style(grin_gui_core::theme::CheckboxStyle::Normal) + .text_size(DEFAULT_FONT_SIZE) + .spacing(5); + + let checkbox: Element = checkbox.into(); + + let checkbox_container = Container::new(checkbox.map(Message::Interaction)) + .style(grin_gui_core::theme::ContainerStyle::NormalBackground); + Column::new().push(checkbox_container) + }; + + #[cfg(target_os = "windows")] + let toggle_autostart_column = { + let checkbox = Checkbox::new( + localized_string("toggle-autostart"), + config.autostart, + Interaction::ToggleAutoStart, + ) + .style(grin_gui_core::theme::CheckboxStyle::Normal) + .text_size(DEFAULT_FONT_SIZE) + .spacing(5); + + let checkbox: Element = checkbox.into(); + + let checkbox_container = Container::new(checkbox.map(Message::Interaction)) + .style(grin_gui_core::theme::ContainerStyle::NormalBackground); + Column::new().push(checkbox_container) + }; + + #[cfg(target_os = "windows")] + let start_closed_to_tray_column = { + let checkbox = Checkbox::new( + localized_string("start-closed-to-tray"), + config.start_closed_to_tray, + Interaction::ToggleStartClosedToTray, + ) + .style(grin_gui_core::theme::CheckboxStyle::Normal) + .text_size(DEFAULT_FONT_SIZE) + .spacing(5); + + let checkbox: Element = checkbox.into(); + + let checkbox_container = Container::new(checkbox.map(Message::Interaction)) + .style(grin_gui_core::theme::ContainerStyle::NormalBackground); + Column::new().push(checkbox_container) + }; + + let mut column = Column::new() + .spacing(1) + .push(language_container) + .push(Space::new(Length::Fixed(0.0), Length::Fixed(10.0))) + .push(currency_container) + .push(Space::new(Length::Fixed(0.0), Length::Fixed(10.0))) + .push(theme_scale_row) + .push(Space::new(Length::Fixed(0.0), Length::Fixed(10.0))) + .push(open_theme_row) + .spacing(1); + + // Systray settings + #[cfg(target_os = "windows")] + { + column = column + .push(Space::new(Length::Fixed(0.0), Length::Fixed(10.0))) + .push(close_to_tray_column) + .push(Space::new(Length::Fixed(0.0), Length::Fixed(10.0))) + .push(start_closed_to_tray_column) + .push(Space::new(Length::Fixed(0.0), Length::Fixed(10.0))) + .push(toggle_autostart_column); + } + + let scrollable = Scrollable::new(column) + .height(Length::Fill) + .style(grin_gui_core::theme::ScrollableStyle::Primary); + + // Colum wrapping all the settings content. + //scrollable = scrollable.height(Length::Fill); + + let col = Column::new() + .push(Space::new(Length::Fixed(0.0), Length::Fixed(10.0))) + .push(scrollable) + .push(Space::new(Length::Fixed(0.0), Length::Fixed(20.0))); + let row = Row::new() + .push(Space::new(Length::Fixed(5.0), Length::Fixed(0.0))) + .push(col); + + // Returns the final container. + Container::new(row) + .width(Length::Fill) + .height(Length::Shrink) + .style(grin_gui_core::theme::ContainerStyle::NormalBackground) } diff --git a/src/gui/element/settings/mod.rs b/src/gui/element/settings/mod.rs index efffb2e..6d529dc 100644 --- a/src/gui/element/settings/mod.rs +++ b/src/gui/element/settings/mod.rs @@ -5,183 +5,173 @@ pub mod node; pub mod wallet; use { - super::{DEFAULT_FONT_SIZE, DEFAULT_HEADER_FONT_SIZE, DEFAULT_PADDING}, - crate::gui::{GrinGui, Interaction, Message}, - crate::localization::localized_string, - grin_gui_core::theme::{ - Button, Column, Container, Element, PickList, Row, Scrollable, Text, TextInput, - }, - grin_gui_core::{config::Config, theme::ColorPalette}, - iced::widget::{button, Space}, - iced::{Alignment, Length}, - serde::{Deserialize, Serialize}, + super::{DEFAULT_FONT_SIZE, DEFAULT_HEADER_FONT_SIZE, DEFAULT_PADDING}, + crate::gui::{GrinGui, Interaction, Message}, + crate::localization::localized_string, + grin_gui_core::theme::{ + Button, Column, Container, Element, PickList, Row, Scrollable, Text, TextInput, + }, + grin_gui_core::{config::Config, theme::ColorPalette}, + iced::widget::{button, Space}, + iced::{Alignment, Length}, + serde::{Deserialize, Serialize}, }; #[derive(Debug, Clone)] pub struct StateContainer { - pub mode: Mode, - // wallet_btn: button::State, - // node_btn: button::State, - // general_btn: button::State, + pub mode: Mode, + // wallet_btn: button::State, + // node_btn: button::State, + // general_btn: button::State, } impl Default for StateContainer { - fn default() -> Self { - Self { - mode: Mode::Wallet, - // wallet_btn: Default::default(), - // node_btn: Default::default(), - // general_btn: Default::default(), - } - } + fn default() -> Self { + Self { + mode: Mode::Wallet, + // wallet_btn: Default::default(), + // node_btn: Default::default(), + // general_btn: Default::default(), + } + } } #[derive(Serialize, Deserialize, Debug, Clone)] pub enum LocalViewInteraction { - SelectMode(Mode), + SelectMode(Mode), } #[derive(Serialize, Deserialize, Debug, Clone)] pub enum Mode { - Wallet, - Node, - General, + Wallet, + Node, + General, } pub fn handle_message(grin_gui: &mut GrinGui, message: LocalViewInteraction) { - match message { - LocalViewInteraction::SelectMode(mode) => { - log::debug!("Interaction::ModeSelectedSettings({:?})", mode); - // Set Mode - grin_gui.settings_state.mode = mode; - } - } + match message { + LocalViewInteraction::SelectMode(mode) => { + log::debug!("Interaction::ModeSelectedSettings({:?})", mode); + // Set Mode + grin_gui.settings_state.mode = mode; + } + } } pub fn data_container<'a>( - state: &'a StateContainer, - config: &'a Config, - wallet_settings_state: &'a wallet::StateContainer, - node_settings_state: &'a node::StateContainer, - general_settings_state: &'a general::StateContainer, + state: &'a StateContainer, + config: &'a Config, + wallet_settings_state: &'a wallet::StateContainer, + node_settings_state: &'a node::StateContainer, + general_settings_state: &'a general::StateContainer, ) -> Container<'a, Message> { - let title_string = match state.mode { - Mode::Wallet => localized_string("settings-wallet"), - Mode::Node => localized_string("settings-node"), - Mode::General => localized_string("settings-general"), - }; - - // Submenu title to appear of left side of panel - let general_settings_title = Text::new(title_string).size(DEFAULT_HEADER_FONT_SIZE); - let general_settings_title_container = Container::new(general_settings_title) - .style(grin_gui_core::theme::ContainerStyle::BrightBackground) - .padding(iced::Padding::from([ - 0, // top - 0, // right - 0, // bottom - 5, // left - ])); - - let mut wallet_button: Button = Button::new( - // &mut state.wallet_btn, - Text::new(localized_string("wallet")).size(DEFAULT_FONT_SIZE), - ) - .on_press(Interaction::SettingsViewInteraction( - LocalViewInteraction::SelectMode(Mode::Wallet), - )); - - let mut node_button: Button = Button::new( - // &mut state.node_btn, - Text::new(localized_string("node")).size(DEFAULT_FONT_SIZE), - ) - .on_press(Interaction::SettingsViewInteraction( - LocalViewInteraction::SelectMode(Mode::Node), - )); - - let mut general_button: Button = Button::new( - // &mut state.general_btn, - Text::new(localized_string("general")).size(DEFAULT_FONT_SIZE), - ) - .on_press(Interaction::SettingsViewInteraction( - LocalViewInteraction::SelectMode(Mode::General), - )); - - match state.mode { - Mode::Wallet => { - wallet_button = wallet_button.style(grin_gui_core::theme::ButtonStyle::Selected); - node_button = - node_button.style(grin_gui_core::theme::ButtonStyle::Primary); - general_button = - general_button.style(grin_gui_core::theme::ButtonStyle::Primary); - } - Mode::Node => { - wallet_button = - wallet_button.style(grin_gui_core::theme::ButtonStyle::Primary); - node_button = node_button.style(grin_gui_core::theme::ButtonStyle::Selected); - general_button = - general_button.style(grin_gui_core::theme::ButtonStyle::Primary); - } - Mode::General => { - wallet_button = - wallet_button.style(grin_gui_core::theme::ButtonStyle::Primary); - node_button = - node_button.style(grin_gui_core::theme::ButtonStyle::Primary); - general_button = general_button.style(grin_gui_core::theme::ButtonStyle::Selected); - } - } - - let wallet_button: Element = wallet_button.into(); - let node_button: Element = node_button.into(); - let general_button: Element = general_button.into(); - - let segmented_mode_row = Row::new() - .push(wallet_button.map(Message::Interaction)) - .push(node_button.map(Message::Interaction)) - .push(general_button.map(Message::Interaction)) - .spacing(1); - - let segmented_mode_container = Container::new(segmented_mode_row).padding(1); - - let segmented_mode_control_container = - Container::new(segmented_mode_container).padding(1).style( - grin_gui_core::theme::ContainerStyle::Segmented, - ); - - let header_row = Row::new() - .push(general_settings_title_container) - .push(Space::with_width(Length::Fill)) - .push(segmented_mode_control_container) - .align_items(Alignment::Center); - - let header_container = Container::new(header_row); - - // Wrapper for submenu + actual content - let mut wrapper_column = - Column::with_children(vec![header_container.into()]).height(Length::Fill); - // Submenu Area + actual content - match state.mode { - Mode::Wallet => { - wrapper_column = - wrapper_column.push(wallet::data_container(wallet_settings_state, config)) - } - Mode::Node => { - wrapper_column = - wrapper_column.push(node::data_container(node_settings_state)) - } - Mode::General => { - wrapper_column = wrapper_column.push(general::data_container( - general_settings_state, - config, - )) - } - } - - Container::new(wrapper_column) - .style(grin_gui_core::theme::ContainerStyle::NormalBackground) - .padding(iced::Padding::from([ - DEFAULT_PADDING, // top - DEFAULT_PADDING, // right - DEFAULT_PADDING, // bottom - DEFAULT_PADDING, // left - ])) + let title_string = match state.mode { + Mode::Wallet => localized_string("settings-wallet"), + Mode::Node => localized_string("settings-node"), + Mode::General => localized_string("settings-general"), + }; + + // Submenu title to appear of left side of panel + let general_settings_title = Text::new(title_string).size(DEFAULT_HEADER_FONT_SIZE); + let general_settings_title_container = Container::new(general_settings_title) + .style(grin_gui_core::theme::ContainerStyle::BrightBackground) + .padding(iced::Padding::from([ + 0, // top + 0, // right + 0, // bottom + 5, // left + ])); + + let mut wallet_button: Button = Button::new( + // &mut state.wallet_btn, + Text::new(localized_string("wallet")).size(DEFAULT_FONT_SIZE), + ) + .on_press(Interaction::SettingsViewInteraction( + LocalViewInteraction::SelectMode(Mode::Wallet), + )); + + let mut node_button: Button = Button::new( + // &mut state.node_btn, + Text::new(localized_string("node")).size(DEFAULT_FONT_SIZE), + ) + .on_press(Interaction::SettingsViewInteraction( + LocalViewInteraction::SelectMode(Mode::Node), + )); + + let mut general_button: Button = Button::new( + // &mut state.general_btn, + Text::new(localized_string("general")).size(DEFAULT_FONT_SIZE), + ) + .on_press(Interaction::SettingsViewInteraction( + LocalViewInteraction::SelectMode(Mode::General), + )); + + match state.mode { + Mode::Wallet => { + wallet_button = wallet_button.style(grin_gui_core::theme::ButtonStyle::Selected); + node_button = node_button.style(grin_gui_core::theme::ButtonStyle::Primary); + general_button = general_button.style(grin_gui_core::theme::ButtonStyle::Primary); + } + Mode::Node => { + wallet_button = wallet_button.style(grin_gui_core::theme::ButtonStyle::Primary); + node_button = node_button.style(grin_gui_core::theme::ButtonStyle::Selected); + general_button = general_button.style(grin_gui_core::theme::ButtonStyle::Primary); + } + Mode::General => { + wallet_button = wallet_button.style(grin_gui_core::theme::ButtonStyle::Primary); + node_button = node_button.style(grin_gui_core::theme::ButtonStyle::Primary); + general_button = general_button.style(grin_gui_core::theme::ButtonStyle::Selected); + } + } + + let wallet_button: Element = wallet_button.into(); + let node_button: Element = node_button.into(); + let general_button: Element = general_button.into(); + + let segmented_mode_row = Row::new() + .push(wallet_button.map(Message::Interaction)) + .push(node_button.map(Message::Interaction)) + .push(general_button.map(Message::Interaction)) + .spacing(1); + + let segmented_mode_container = Container::new(segmented_mode_row).padding(1); + + let segmented_mode_control_container = Container::new(segmented_mode_container) + .padding(1) + .style(grin_gui_core::theme::ContainerStyle::Segmented); + + let header_row = Row::new() + .push(general_settings_title_container) + .push(Space::with_width(Length::Fill)) + .push(segmented_mode_control_container) + .align_items(Alignment::Center); + + let header_container = Container::new(header_row); + + // Wrapper for submenu + actual content + let mut wrapper_column = + Column::with_children(vec![header_container.into()]).height(Length::Fill); + // Submenu Area + actual content + match state.mode { + Mode::Wallet => { + wrapper_column = + wrapper_column.push(wallet::data_container(wallet_settings_state, config)) + } + Mode::Node => { + wrapper_column = wrapper_column.push(node::data_container(node_settings_state)) + } + Mode::General => { + wrapper_column = + wrapper_column.push(general::data_container(general_settings_state, config)) + } + } + + Container::new(wrapper_column) + .style(grin_gui_core::theme::ContainerStyle::NormalBackground) + .padding(iced::Padding::from([ + DEFAULT_PADDING, // top + DEFAULT_PADDING, // right + DEFAULT_PADDING, // bottom + DEFAULT_PADDING, // left + ])) } diff --git a/src/gui/element/settings/node.rs b/src/gui/element/settings/node.rs index f79edc1..2900264 100644 --- a/src/gui/element/settings/node.rs +++ b/src/gui/element/settings/node.rs @@ -1,79 +1,77 @@ use { - super::DEFAULT_FONT_SIZE, - crate::gui::{GrinGui, Message}, - crate::localization::localized_string, - grin_gui_core::theme::ColorPalette, - grin_gui_core::theme::{Button, Column, Container, PickList, Row, Scrollable, Text, TextInput}, - iced::widget::{button, pick_list, scrollable, text_input, Checkbox, Space}, - iced::Length, - serde::{Deserialize, Serialize}, + super::DEFAULT_FONT_SIZE, + crate::gui::{GrinGui, Message}, + crate::localization::localized_string, + grin_gui_core::theme::ColorPalette, + grin_gui_core::theme::{Button, Column, Container, PickList, Row, Scrollable, Text, TextInput}, + iced::widget::{button, pick_list, scrollable, text_input, Checkbox, Space}, + iced::Length, + serde::{Deserialize, Serialize}, }; #[derive(Debug, Clone)] pub struct StateContainer { - pub mode: Mode, - // scrollable_state: scrollable::State, + pub mode: Mode, + // scrollable_state: scrollable::State, } impl Default for StateContainer { - fn default() -> Self { - Self { - mode: Mode::Wallet, - // scrollable_state: Default::default(), - } - } + fn default() -> Self { + Self { + mode: Mode::Wallet, + // scrollable_state: Default::default(), + } + } } #[derive(Serialize, Deserialize, Debug, Clone)] pub enum LocalViewInteraction { - SelectMode(Mode), + SelectMode(Mode), } #[derive(Serialize, Deserialize, Debug, Clone)] pub enum Mode { - Wallet, - Node, - General, + Wallet, + Node, + General, } pub fn handle_message(grin_gui: &mut GrinGui, message: LocalViewInteraction) { - match message { - LocalViewInteraction::SelectMode(mode) => { - log::debug!("Interaction::ModeSelectedSettings({:?})", mode); - // Set Mode - grin_gui.node_settings_state.mode = mode - } - } + match message { + LocalViewInteraction::SelectMode(mode) => { + log::debug!("Interaction::ModeSelectedSettings({:?})", mode); + // Set Mode + grin_gui.node_settings_state.mode = mode + } + } } -pub fn data_container<'a>( - state: &'a StateContainer, -) -> Container<'a, Message> { - let language_container = { - let title = Container::new(Text::new(localized_string("todo")).size(DEFAULT_FONT_SIZE)) - .style(grin_gui_core::theme::ContainerStyle::NormalBackground); +pub fn data_container<'a>(state: &'a StateContainer) -> Container<'a, Message> { + let language_container = { + let title = Container::new(Text::new(localized_string("todo")).size(DEFAULT_FONT_SIZE)) + .style(grin_gui_core::theme::ContainerStyle::NormalBackground); - Column::new() - .push(title) - .push(Space::new(Length::Fixed(0.0), Length::Fixed(5.0))) - }; + Column::new() + .push(title) + .push(Space::new(Length::Fixed(0.0), Length::Fixed(5.0))) + }; - // Colum wrapping all the settings content. - let scrollable = Scrollable::new(language_container) - .height(Length::Fill) - .style(grin_gui_core::theme::ScrollableStyle::Primary); + // Colum wrapping all the settings content. + let scrollable = Scrollable::new(language_container) + .height(Length::Fill) + .style(grin_gui_core::theme::ScrollableStyle::Primary); - let col = Column::new() - .push(Space::new(Length::Fixed(0.0), Length::Fixed(10.0))) - .push(scrollable) - .push(Space::new(Length::Fixed(0.0), Length::Fixed(20.0))); - let row = Row::new() - .push(Space::new(Length::Fixed(5.0), Length::Fixed(0.0))) - .push(col); + let col = Column::new() + .push(Space::new(Length::Fixed(0.0), Length::Fixed(10.0))) + .push(scrollable) + .push(Space::new(Length::Fixed(0.0), Length::Fixed(20.0))); + let row = Row::new() + .push(Space::new(Length::Fixed(5.0), Length::Fixed(0.0))) + .push(col); - // Returns the final container. - Container::new(row) - .width(Length::Fill) - .height(Length::Shrink) - .style(grin_gui_core::theme::ContainerStyle::NormalBackground) + // Returns the final container. + Container::new(row) + .width(Length::Fill) + .height(Length::Shrink) + .style(grin_gui_core::theme::ContainerStyle::NormalBackground) } diff --git a/src/gui/element/settings/wallet.rs b/src/gui/element/settings/wallet.rs index 4da08b2..59281d5 100644 --- a/src/gui/element/settings/wallet.rs +++ b/src/gui/element/settings/wallet.rs @@ -1,243 +1,248 @@ use { - super::{DEFAULT_FONT_SIZE}, - crate::gui::{GrinGui, Interaction, Message}, - crate::localization::localized_string, - grin_gui_core::config::{Config, TxMethod}, - grin_gui_core::theme::{Button, Column, Container, Element, PickList, Row, Scrollable, Text, TextInput}, - grin_gui_core::fs::PersistentData, - iced::Length, - iced::widget::{ - button, pick_list, scrollable, text_input, Checkbox, Space, - }, - iced::{alignment, Alignment}, - serde::{Deserialize, Serialize}, + super::DEFAULT_FONT_SIZE, + crate::gui::{GrinGui, Interaction, Message}, + crate::localization::localized_string, + grin_gui_core::config::{Config, TxMethod}, + grin_gui_core::fs::PersistentData, + grin_gui_core::theme::{ + Button, Column, Container, Element, PickList, Row, Scrollable, Text, TextInput, + }, + iced::widget::{button, pick_list, scrollable, text_input, Checkbox, Space}, + iced::Length, + iced::{alignment, Alignment}, + serde::{Deserialize, Serialize}, }; #[derive(Debug, Clone)] pub struct StateContainer { - // scrollable_state: scrollable::State, - mw_mixnet_address_1: String, - mw_mixnet_address_2: String, - mw_mixnet_address_3: String, + // scrollable_state: scrollable::State, + mw_mixnet_address_1: String, + mw_mixnet_address_2: String, + mw_mixnet_address_3: String, } impl Default for StateContainer { - fn default() -> Self { - Self { - mw_mixnet_address_1: "".to_string(), - mw_mixnet_address_2: "".to_string(), - mw_mixnet_address_3: "".to_string(), - } - } + fn default() -> Self { + Self { + mw_mixnet_address_1: "".to_string(), + mw_mixnet_address_2: "".to_string(), + mw_mixnet_address_3: "".to_string(), + } + } } #[derive(Serialize, Deserialize, Debug, Clone)] pub enum LocalViewInteraction { - TxMethodSelected(TxMethod), - MwMixnetAddress1Changed(String), - MwMixnetAddress2Changed(String), - MwMixnetAddress3Changed(String), + TxMethodSelected(TxMethod), + MwMixnetAddress1Changed(String), + MwMixnetAddress2Changed(String), + MwMixnetAddress3Changed(String), } #[derive(Serialize, Deserialize, Debug, Clone)] pub enum Mode { - Wallet, - Node, - General, + Wallet, + Node, + General, } -pub fn handle_message( - grin_gui: &mut GrinGui, - message: LocalViewInteraction, -) { - let state = &mut grin_gui.wallet_settings_state; - let mut check_mixnet_config = || { - if grin_gui.config.mixnet_keys.is_none() { - grin_gui.config.mixnet_keys = Some(vec![]); - grin_gui.config.mixnet_keys.as_mut().unwrap().push(String::new()); - grin_gui.config.mixnet_keys.as_mut().unwrap().push(String::new()); - grin_gui.config.mixnet_keys.as_mut().unwrap().push(String::new()); - } - }; - match message { - LocalViewInteraction::TxMethodSelected(method) => { - log::debug!("Interaction::TxMethodSelectedSettings({:?})", method); - // Set Mode - grin_gui.config.tx_method = method; - let _ = grin_gui.config.save(); - } - LocalViewInteraction::MwMixnetAddress1Changed(value) => { - check_mixnet_config(); - grin_gui.config.mixnet_keys.as_mut().unwrap()[0] = value.clone(); - state.mw_mixnet_address_1 = value; - let _ = grin_gui.config.save(); - } - LocalViewInteraction::MwMixnetAddress2Changed(value) => { - check_mixnet_config(); - grin_gui.config.mixnet_keys.as_mut().unwrap()[1] = value.clone(); - state.mw_mixnet_address_2 = value; - let _ = grin_gui.config.save(); - } - LocalViewInteraction::MwMixnetAddress3Changed(value) => { - check_mixnet_config(); - grin_gui.config.mixnet_keys.as_mut().unwrap()[2] = value.clone(); - state.mw_mixnet_address_3 = value; - let _ = grin_gui.config.save(); - } - } +pub fn handle_message(grin_gui: &mut GrinGui, message: LocalViewInteraction) { + let state = &mut grin_gui.wallet_settings_state; + let mut check_mixnet_config = || { + if grin_gui.config.mixnet_keys.is_none() { + grin_gui.config.mixnet_keys = Some(vec![]); + grin_gui + .config + .mixnet_keys + .as_mut() + .unwrap() + .push(String::new()); + grin_gui + .config + .mixnet_keys + .as_mut() + .unwrap() + .push(String::new()); + grin_gui + .config + .mixnet_keys + .as_mut() + .unwrap() + .push(String::new()); + } + }; + match message { + LocalViewInteraction::TxMethodSelected(method) => { + log::debug!("Interaction::TxMethodSelectedSettings({:?})", method); + // Set Mode + grin_gui.config.tx_method = method; + let _ = grin_gui.config.save(); + } + LocalViewInteraction::MwMixnetAddress1Changed(value) => { + check_mixnet_config(); + grin_gui.config.mixnet_keys.as_mut().unwrap()[0] = value.clone(); + state.mw_mixnet_address_1 = value; + let _ = grin_gui.config.save(); + } + LocalViewInteraction::MwMixnetAddress2Changed(value) => { + check_mixnet_config(); + grin_gui.config.mixnet_keys.as_mut().unwrap()[1] = value.clone(); + state.mw_mixnet_address_2 = value; + let _ = grin_gui.config.save(); + } + LocalViewInteraction::MwMixnetAddress3Changed(value) => { + check_mixnet_config(); + grin_gui.config.mixnet_keys.as_mut().unwrap()[2] = value.clone(); + state.mw_mixnet_address_3 = value; + let _ = grin_gui.config.save(); + } + } } -pub fn data_container<'a>( - state: &'a StateContainer, - config: &Config, -) -> Container<'a, Message> { - - let (config_addr_1, config_addr_2, config_addr_3) = if let Some(a) = config.mixnet_keys.as_ref() { - (a[0].clone(), a[1].clone(), a[2].clone()) - } else { - (String::new(), String::new(), String::new()) - }; - - let tx_method_column = { - let tx_method_container = - Container::new(Text::new(localized_string("tx-method")).size(DEFAULT_FONT_SIZE)) - .style(grin_gui_core::theme::ContainerStyle::NormalBackground); - - let tx_method_pick_list = PickList::new( - &TxMethod::ALL[..], - Some(config.tx_method), - |t| { - Message::Interaction(Interaction::WalletSettingsViewInteraction( - LocalViewInteraction::TxMethodSelected(t), - )) - }, - ) - .text_size(DEFAULT_FONT_SIZE) - .width(Length::Fixed(120.0)) - .style(grin_gui_core::theme::PickListStyle::Primary); - - // Data row for theme picker list. - let tx_method_data_row = Row::new() - .push(tx_method_pick_list) - .align_items(Alignment::Center) - .height(Length::Fixed(26.0)); - - Column::new() - .push(tx_method_container) - .push(Space::new(Length::Fixed(0.0), Length::Fixed(5.0))) - .push(tx_method_data_row) - }; - - let mw_mixnet_address_column = { - let mw_mixnet_address_container = - Container::new(Text::new(localized_string("mw-mixnet-addresses")).size(DEFAULT_FONT_SIZE)) - .style(grin_gui_core::theme::ContainerStyle::NormalBackground); - - let mw_mixnet_address_1 = Text::new(localized_string("mw-mixnet-address-1")) - .size(DEFAULT_FONT_SIZE) - .horizontal_alignment(alignment::Horizontal::Left); - - let mw_mixnet_address_1_container = Container::new(mw_mixnet_address_1) - .style(grin_gui_core::theme::ContainerStyle::NormalBackground); - - let mw_mixnet_address_1_input = TextInput::new("", &config_addr_1) - .on_input(|s| { - Interaction::WalletSettingsViewInteraction( - LocalViewInteraction::MwMixnetAddress1Changed(s), - ) - }) - .size(DEFAULT_FONT_SIZE) - .padding(6) - .width(Length::Fixed(400.0)) - .style(grin_gui_core::theme::TextInputStyle::AddonsQuery); - - let mw_mixnet_address_1_input: Element = mw_mixnet_address_1_input.into(); - - let mw_mixnet_address_2 = Text::new(localized_string("mw-mixnet-address-2")) - .size(DEFAULT_FONT_SIZE) - .horizontal_alignment(alignment::Horizontal::Left); - - let mw_mixnet_address_2_container = Container::new(mw_mixnet_address_2) - .style(grin_gui_core::theme::ContainerStyle::NormalBackground); - - let mw_mixnet_address_2_input = TextInput::new("", &config_addr_2) - .on_input(|s| { - Interaction::WalletSettingsViewInteraction( - LocalViewInteraction::MwMixnetAddress2Changed(s), - ) - }) - .size(DEFAULT_FONT_SIZE) - .padding(6) - .width(Length::Fixed(400.0)) - .style(grin_gui_core::theme::TextInputStyle::AddonsQuery); - - let mw_mixnet_address_2_input: Element = mw_mixnet_address_2_input.into(); - - let mw_mixnet_address_3 = Text::new(localized_string("mw-mixnet-address-3")) - .size(DEFAULT_FONT_SIZE) - .horizontal_alignment(alignment::Horizontal::Left); - - let mw_mixnet_address_3_container = Container::new(mw_mixnet_address_3) - .style(grin_gui_core::theme::ContainerStyle::NormalBackground); - - let mw_mixnet_address_3_input = TextInput::new("", &config_addr_3) - .on_input(|s| { - Interaction::WalletSettingsViewInteraction( - LocalViewInteraction::MwMixnetAddress3Changed(s), - ) - }) - .size(DEFAULT_FONT_SIZE) - .padding(6) - .width(Length::Fixed(400.0)) - .style(grin_gui_core::theme::TextInputStyle::AddonsQuery); - - let mw_mixnet_address_3_input: Element = mw_mixnet_address_3_input.into(); - - // Data row for theme picker list. - /*let tx_method_data_row = Row::new() - .push(tx_method_pick_list) - .align_items(Alignment::Center) - .height(Length::Fixed(26.0));*/ - - Column::new() - .push(mw_mixnet_address_container) - .push(Space::new(Length::Fixed(0.0), Length::Fixed(5.0))) - .push(mw_mixnet_address_1_container) - .push(Space::new(Length::Fixed(0.0), Length::Fixed(5.0))) - .push(mw_mixnet_address_1_input.map(Message::Interaction)) - .push(Space::new(Length::Fixed(0.0), Length::Fixed(5.0))) - .push(mw_mixnet_address_2_container) - .push(Space::new(Length::Fixed(0.0), Length::Fixed(5.0))) - .push(mw_mixnet_address_2_input.map(Message::Interaction)) - .push(Space::new(Length::Fixed(0.0), Length::Fixed(5.0))) - .push(mw_mixnet_address_3_container) - .push(Space::new(Length::Fixed(0.0), Length::Fixed(5.0))) - .push(mw_mixnet_address_3_input.map(Message::Interaction)) - }; - - - let wrap = { - Column::new() - .push(tx_method_column) - .push(Space::new(Length::Fixed(0.0), Length::Fixed(10.0))) - .push(mw_mixnet_address_column) - }; - - let scrollable = Scrollable::new(wrap) - .height(Length::Fill) - .style(grin_gui_core::theme::ScrollableStyle::Primary); - - let col = Column::new() - .push(Space::new(Length::Fixed(0.0), Length::Fixed(10.0))) - .push(scrollable) - .push(Space::new(Length::Fixed(0.0), Length::Fixed(20.0))); - let row = Row::new() - .push(Space::new(Length::Fixed(5.0), Length::Fixed(0.0))) - .push(col); - - // Returns the final container. - Container::new(row) - .width(Length::Fill) - .height(Length::Shrink) - .style(grin_gui_core::theme::ContainerStyle::NormalBackground) +pub fn data_container<'a>(state: &'a StateContainer, config: &Config) -> Container<'a, Message> { + let (config_addr_1, config_addr_2, config_addr_3) = if let Some(a) = config.mixnet_keys.as_ref() + { + (a[0].clone(), a[1].clone(), a[2].clone()) + } else { + (String::new(), String::new(), String::new()) + }; + + let tx_method_column = { + let tx_method_container = + Container::new(Text::new(localized_string("tx-method")).size(DEFAULT_FONT_SIZE)) + .style(grin_gui_core::theme::ContainerStyle::NormalBackground); + + let tx_method_pick_list = PickList::new(&TxMethod::ALL[..], Some(config.tx_method), |t| { + Message::Interaction(Interaction::WalletSettingsViewInteraction( + LocalViewInteraction::TxMethodSelected(t), + )) + }) + .text_size(DEFAULT_FONT_SIZE) + .width(Length::Fixed(120.0)) + .style(grin_gui_core::theme::PickListStyle::Primary); + + // Data row for theme picker list. + let tx_method_data_row = Row::new() + .push(tx_method_pick_list) + .align_items(Alignment::Center) + .height(Length::Fixed(26.0)); + + Column::new() + .push(tx_method_container) + .push(Space::new(Length::Fixed(0.0), Length::Fixed(5.0))) + .push(tx_method_data_row) + }; + + let mw_mixnet_address_column = { + let mw_mixnet_address_container = Container::new( + Text::new(localized_string("mw-mixnet-addresses")).size(DEFAULT_FONT_SIZE), + ) + .style(grin_gui_core::theme::ContainerStyle::NormalBackground); + + let mw_mixnet_address_1 = Text::new(localized_string("mw-mixnet-address-1")) + .size(DEFAULT_FONT_SIZE) + .horizontal_alignment(alignment::Horizontal::Left); + + let mw_mixnet_address_1_container = Container::new(mw_mixnet_address_1) + .style(grin_gui_core::theme::ContainerStyle::NormalBackground); + + let mw_mixnet_address_1_input = TextInput::new("", &config_addr_1) + .on_input(|s| { + Interaction::WalletSettingsViewInteraction( + LocalViewInteraction::MwMixnetAddress1Changed(s), + ) + }) + .size(DEFAULT_FONT_SIZE) + .padding(6) + .width(Length::Fixed(400.0)) + .style(grin_gui_core::theme::TextInputStyle::AddonsQuery); + + let mw_mixnet_address_1_input: Element = mw_mixnet_address_1_input.into(); + + let mw_mixnet_address_2 = Text::new(localized_string("mw-mixnet-address-2")) + .size(DEFAULT_FONT_SIZE) + .horizontal_alignment(alignment::Horizontal::Left); + + let mw_mixnet_address_2_container = Container::new(mw_mixnet_address_2) + .style(grin_gui_core::theme::ContainerStyle::NormalBackground); + + let mw_mixnet_address_2_input = TextInput::new("", &config_addr_2) + .on_input(|s| { + Interaction::WalletSettingsViewInteraction( + LocalViewInteraction::MwMixnetAddress2Changed(s), + ) + }) + .size(DEFAULT_FONT_SIZE) + .padding(6) + .width(Length::Fixed(400.0)) + .style(grin_gui_core::theme::TextInputStyle::AddonsQuery); + + let mw_mixnet_address_2_input: Element = mw_mixnet_address_2_input.into(); + + let mw_mixnet_address_3 = Text::new(localized_string("mw-mixnet-address-3")) + .size(DEFAULT_FONT_SIZE) + .horizontal_alignment(alignment::Horizontal::Left); + + let mw_mixnet_address_3_container = Container::new(mw_mixnet_address_3) + .style(grin_gui_core::theme::ContainerStyle::NormalBackground); + + let mw_mixnet_address_3_input = TextInput::new("", &config_addr_3) + .on_input(|s| { + Interaction::WalletSettingsViewInteraction( + LocalViewInteraction::MwMixnetAddress3Changed(s), + ) + }) + .size(DEFAULT_FONT_SIZE) + .padding(6) + .width(Length::Fixed(400.0)) + .style(grin_gui_core::theme::TextInputStyle::AddonsQuery); + + let mw_mixnet_address_3_input: Element = mw_mixnet_address_3_input.into(); + + // Data row for theme picker list. + /*let tx_method_data_row = Row::new() + .push(tx_method_pick_list) + .align_items(Alignment::Center) + .height(Length::Fixed(26.0));*/ + + Column::new() + .push(mw_mixnet_address_container) + .push(Space::new(Length::Fixed(0.0), Length::Fixed(5.0))) + .push(mw_mixnet_address_1_container) + .push(Space::new(Length::Fixed(0.0), Length::Fixed(5.0))) + .push(mw_mixnet_address_1_input.map(Message::Interaction)) + .push(Space::new(Length::Fixed(0.0), Length::Fixed(5.0))) + .push(mw_mixnet_address_2_container) + .push(Space::new(Length::Fixed(0.0), Length::Fixed(5.0))) + .push(mw_mixnet_address_2_input.map(Message::Interaction)) + .push(Space::new(Length::Fixed(0.0), Length::Fixed(5.0))) + .push(mw_mixnet_address_3_container) + .push(Space::new(Length::Fixed(0.0), Length::Fixed(5.0))) + .push(mw_mixnet_address_3_input.map(Message::Interaction)) + }; + + let wrap = { + Column::new() + .push(tx_method_column) + .push(Space::new(Length::Fixed(0.0), Length::Fixed(10.0))) + .push(mw_mixnet_address_column) + }; + + let scrollable = Scrollable::new(wrap) + .height(Length::Fill) + .style(grin_gui_core::theme::ScrollableStyle::Primary); + + let col = Column::new() + .push(Space::new(Length::Fixed(0.0), Length::Fixed(10.0))) + .push(scrollable) + .push(Space::new(Length::Fixed(0.0), Length::Fixed(20.0))); + let row = Row::new() + .push(Space::new(Length::Fixed(5.0), Length::Fixed(0.0))) + .push(col); + + // Returns the final container. + Container::new(row) + .width(Length::Fill) + .height(Length::Shrink) + .style(grin_gui_core::theme::ContainerStyle::NormalBackground) } diff --git a/src/gui/element/wallet/mod.rs b/src/gui/element/wallet/mod.rs index 7f910c5..f61420a 100644 --- a/src/gui/element/wallet/mod.rs +++ b/src/gui/element/wallet/mod.rs @@ -2,76 +2,72 @@ pub mod operation; pub mod setup; use { - crate::gui::{Message}, - grin_gui_core::config::Config, - grin_gui_core::theme::ColorPalette, - grin_gui_core::theme::{Container, Column}, - iced::Length, + crate::gui::Message, + grin_gui_core::config::Config, + grin_gui_core::theme::ColorPalette, + grin_gui_core::theme::{Column, Container}, + iced::Length, }; #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub enum Mode { - Init, - CreateWallet(String), - Operation, + Init, + CreateWallet(String), + Operation, } pub struct StateContainer { - pub mode: Mode, - pub setup_state: setup::StateContainer, - pub operation_state: operation::StateContainer, - // When changed to true, this should stay false until a config exists - has_config_check_failed_one_time: bool, + pub mode: Mode, + pub setup_state: setup::StateContainer, + pub operation_state: operation::StateContainer, + // When changed to true, this should stay false until a config exists + has_config_check_failed_one_time: bool, } impl Default for StateContainer { - fn default() -> Self { - Self { - mode: Mode::Operation, - setup_state: Default::default(), - operation_state: Default::default(), - has_config_check_failed_one_time: false, - } - } + fn default() -> Self { + Self { + mode: Mode::Operation, + setup_state: Default::default(), + operation_state: Default::default(), + has_config_check_failed_one_time: false, + } + } } impl StateContainer { - pub fn config_missing(&self) -> bool { - self.has_config_check_failed_one_time - } + pub fn config_missing(&self) -> bool { + self.has_config_check_failed_one_time + } - pub fn set_config_missing(&mut self) { - self.has_config_check_failed_one_time = true; - self.mode = Mode::Init; - self.setup_state.mode = crate::gui::element::wallet::setup::Mode::Init; - } + pub fn set_config_missing(&mut self) { + self.has_config_check_failed_one_time = true; + self.mode = Mode::Init; + self.setup_state.mode = crate::gui::element::wallet::setup::Mode::Init; + } - pub fn clear_config_missing(&mut self) { - self.has_config_check_failed_one_time = false; - } + pub fn clear_config_missing(&mut self) { + self.has_config_check_failed_one_time = false; + } } -pub fn data_container<'a>( - state: &'a StateContainer, - config: &'a Config, -) -> Container<'a, Message> { - let content = match &state.mode { - Mode::Init => setup::data_container(&state.setup_state, config), - Mode::Operation => { - operation::data_container(&state.operation_state, config) - } - Mode::CreateWallet(default_display_name) => { - setup::wallet_setup::data_container(&state.setup_state.setup_wallet_state, default_display_name) - } - }; +pub fn data_container<'a>(state: &'a StateContainer, config: &'a Config) -> Container<'a, Message> { + let content = match &state.mode { + Mode::Init => setup::data_container(&state.setup_state, config), + Mode::Operation => operation::data_container(&state.operation_state, config), + Mode::CreateWallet(default_display_name) => setup::wallet_setup::data_container( + &state.setup_state.setup_wallet_state, + default_display_name, + ), + }; - let column = Column::new() - //.push(Space::new(Length::Fixed(0.0), Length::Fixed(20))) - .push(content); + let column = Column::new() + //.push(Space::new(Length::Fixed(0.0), Length::Fixed(20))) + .push(content); - Container::new(column) - .center_y() - .center_x() - .width(Length::Fill) - .style(grin_gui_core::theme::ContainerStyle::NormalBackground) + Container::new(column) + .center_y() + .center_x() + .width(Length::Fill) + .style(grin_gui_core::theme::ContainerStyle::NormalBackground) } diff --git a/src/gui/element/wallet/operation/action_menu.rs b/src/gui/element/wallet/operation/action_menu.rs index 9f0eea9..29132ae 100644 --- a/src/gui/element/wallet/operation/action_menu.rs +++ b/src/gui/element/wallet/operation/action_menu.rs @@ -2,8 +2,8 @@ use super::tx_list::{self, ExpandType}; use crate::log_error; use async_std::prelude::FutureExt; use grin_gui_core::{ - config::Config, - wallet::{TxLogEntry, TxLogEntryType}, + config::Config, + wallet::{TxLogEntry, TxLogEntryType}, }; //use grin_gui_widgets::{header}; //use grin_gui_core::widgets::widget::header; @@ -15,157 +15,157 @@ use std::path::PathBuf; use super::tx_list::{HeaderState, TxList}; use { - super::super::super::{DEFAULT_FONT_SIZE, DEFAULT_HEADER_FONT_SIZE, DEFAULT_PADDING}, - crate::gui::{GrinGui, Interaction, Message}, - crate::localization::localized_string, - crate::Result, - anyhow::Context, - grin_gui_core::theme::{ - Button, Column, Container, Element, Header, PickList, Row, Scrollable, TableRow, Text, - TextInput, - }, - grin_gui_core::wallet::{StatusMessage, WalletInfo, WalletInterface}, - grin_gui_core::{node::amount_to_hr_string, theme::ColorPalette}, - iced::widget::{button, pick_list, scrollable, text_input, Checkbox, Space}, - iced::{Alignment, Command, Length}, - serde::{Deserialize, Serialize}, - std::sync::{Arc, RwLock}, + super::super::super::{DEFAULT_FONT_SIZE, DEFAULT_HEADER_FONT_SIZE, DEFAULT_PADDING}, + crate::gui::{GrinGui, Interaction, Message}, + crate::localization::localized_string, + crate::Result, + anyhow::Context, + grin_gui_core::theme::{ + Button, Column, Container, Element, Header, PickList, Row, Scrollable, TableRow, Text, + TextInput, + }, + grin_gui_core::wallet::{StatusMessage, WalletInfo, WalletInterface}, + grin_gui_core::{node::amount_to_hr_string, theme::ColorPalette}, + iced::widget::{button, pick_list, scrollable, text_input, Checkbox, Space}, + iced::{Alignment, Command, Length}, + serde::{Deserialize, Serialize}, + std::sync::{Arc, RwLock}, }; pub struct StateContainer { - // pub create_tx_button_state: button::State, - // pub apply_tx_button_state: button::State, + // pub create_tx_button_state: button::State, + // pub apply_tx_button_state: button::State, } impl Default for StateContainer { - fn default() -> Self { - Self { + fn default() -> Self { + Self { // create_tx_button_state: Default::default(), // apply_tx_button_state: Default::default(), } - } + } } #[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)] pub enum Action { - CreateTx, - ApplyTx, + CreateTx, + ApplyTx, } #[derive(Debug, Clone)] pub enum LocalViewInteraction { - SelectAction(Action), + SelectAction(Action), } pub fn handle_message<'a>( - grin_gui: &mut GrinGui, - message: LocalViewInteraction, + grin_gui: &mut GrinGui, + message: LocalViewInteraction, ) -> Result> { - let state = &mut grin_gui - .wallet_state - .operation_state - .home_state - .action_menu_state; - match message { - LocalViewInteraction::SelectAction(action) => { - log::debug!( - "Interaction::WalletOperationHomeActionMenuViewInteraction({:?})", - action - ); - match action { - Action::CreateTx => { - grin_gui.wallet_state.operation_state.mode = - crate::gui::element::wallet::operation::Mode::CreateTx - } - Action::ApplyTx => { - grin_gui.wallet_state.operation_state.mode = - crate::gui::element::wallet::operation::Mode::ApplyTx - } - } - } - } - Ok(Command::none()) + let state = &mut grin_gui + .wallet_state + .operation_state + .home_state + .action_menu_state; + match message { + LocalViewInteraction::SelectAction(action) => { + log::debug!( + "Interaction::WalletOperationHomeActionMenuViewInteraction({:?})", + action + ); + match action { + Action::CreateTx => { + grin_gui.wallet_state.operation_state.mode = + crate::gui::element::wallet::operation::Mode::CreateTx + } + Action::ApplyTx => { + grin_gui.wallet_state.operation_state.mode = + crate::gui::element::wallet::operation::Mode::ApplyTx + } + } + } + } + Ok(Command::none()) } pub fn data_container<'a>( - config: &'a Config, - state: &'a StateContainer, - home_state: &'a super::home::StateContainer, + config: &'a Config, + state: &'a StateContainer, + home_state: &'a super::home::StateContainer, ) -> Container<'a, Message> { - let button_width = Length::Fixed(70.0); - - let description = Text::new(localized_string("tx-transact")) - .size(DEFAULT_FONT_SIZE) - .horizontal_alignment(alignment::Horizontal::Center) - .vertical_alignment(alignment::Vertical::Center); - let description_container = Container::new(description).padding(iced::Padding::from([ - 7, // top - 5, // right - 5, // bottom - 5, // left - ])); - - // Buttons to perform wallet operations - let create_tx_container = - Container::new(Text::new(localized_string("wallet-create-tx")).size(DEFAULT_FONT_SIZE)) - .width(button_width) - .align_y(alignment::Vertical::Center) - .align_x(alignment::Horizontal::Center); - - let mut create_tx_button = Button::new(create_tx_container) - .width(button_width) - .style(grin_gui_core::theme::ButtonStyle::Primary); - - if home_state.node_synched { - create_tx_button = create_tx_button - .on_press(Interaction::WalletOperationHomeActionMenuViewInteraction( - LocalViewInteraction::SelectAction(Action::CreateTx), - )) - } - - let create_tx_button: Element = create_tx_button.into(); - - let apply_tx_container = - Container::new(Text::new(localized_string("wallet-apply-tx")).size(DEFAULT_FONT_SIZE)) - .width(button_width) - .align_y(alignment::Vertical::Center) - .align_x(alignment::Horizontal::Center); - - let mut apply_tx_button = Button::new(apply_tx_container) - .width(button_width) - .style(grin_gui_core::theme::ButtonStyle::Primary); - - if home_state.node_synched { - apply_tx_button = apply_tx_button - .on_press(Interaction::WalletOperationHomeActionMenuViewInteraction( - LocalViewInteraction::SelectAction(Action::ApplyTx), - )) - } - - let apply_tx_button: Element = apply_tx_button.into(); - - // TODO refactor since many of the buttons around the UI repeat this theme - let create_container = Container::new(create_tx_button.map(Message::Interaction)).padding(1); - let create_container = Container::new(create_container) - .style(grin_gui_core::theme::ContainerStyle::Segmented) - .padding(1); - - let apply_container = Container::new(apply_tx_button.map(Message::Interaction)).padding(1); - let apply_container = Container::new(apply_container) - .style(grin_gui_core::theme::ContainerStyle::Segmented) - .padding(1); - - let menu_column = Row::new() - .push(description_container) - .push(Space::with_width(Length::Fixed(DEFAULT_PADDING))) - .push(create_container) - .push(Space::with_width(Length::Fixed(DEFAULT_PADDING))) - .push(apply_container); - - Container::new(menu_column).padding(iced::Padding::from([ - 5, // top - 5, // right - 5, // bottom - 5, // left - ])) + let button_width = Length::Fixed(70.0); + + let description = Text::new(localized_string("tx-transact")) + .size(DEFAULT_FONT_SIZE) + .horizontal_alignment(alignment::Horizontal::Center) + .vertical_alignment(alignment::Vertical::Center); + let description_container = Container::new(description).padding(iced::Padding::from([ + 7, // top + 5, // right + 5, // bottom + 5, // left + ])); + + // Buttons to perform wallet operations + let create_tx_container = + Container::new(Text::new(localized_string("wallet-create-tx")).size(DEFAULT_FONT_SIZE)) + .width(button_width) + .align_y(alignment::Vertical::Center) + .align_x(alignment::Horizontal::Center); + + let mut create_tx_button = Button::new(create_tx_container) + .width(button_width) + .style(grin_gui_core::theme::ButtonStyle::Primary); + + if home_state.node_synched { + create_tx_button = + create_tx_button.on_press(Interaction::WalletOperationHomeActionMenuViewInteraction( + LocalViewInteraction::SelectAction(Action::CreateTx), + )) + } + + let create_tx_button: Element = create_tx_button.into(); + + let apply_tx_container = + Container::new(Text::new(localized_string("wallet-apply-tx")).size(DEFAULT_FONT_SIZE)) + .width(button_width) + .align_y(alignment::Vertical::Center) + .align_x(alignment::Horizontal::Center); + + let mut apply_tx_button = Button::new(apply_tx_container) + .width(button_width) + .style(grin_gui_core::theme::ButtonStyle::Primary); + + if home_state.node_synched { + apply_tx_button = + apply_tx_button.on_press(Interaction::WalletOperationHomeActionMenuViewInteraction( + LocalViewInteraction::SelectAction(Action::ApplyTx), + )) + } + + let apply_tx_button: Element = apply_tx_button.into(); + + // TODO refactor since many of the buttons around the UI repeat this theme + let create_container = Container::new(create_tx_button.map(Message::Interaction)).padding(1); + let create_container = Container::new(create_container) + .style(grin_gui_core::theme::ContainerStyle::Segmented) + .padding(1); + + let apply_container = Container::new(apply_tx_button.map(Message::Interaction)).padding(1); + let apply_container = Container::new(apply_container) + .style(grin_gui_core::theme::ContainerStyle::Segmented) + .padding(1); + + let menu_column = Row::new() + .push(description_container) + .push(Space::with_width(Length::Fixed(DEFAULT_PADDING))) + .push(create_container) + .push(Space::with_width(Length::Fixed(DEFAULT_PADDING))) + .push(apply_container); + + Container::new(menu_column).padding(iced::Padding::from([ + 5, // top + 5, // right + 5, // bottom + 5, // left + ])) } diff --git a/src/gui/element/wallet/operation/apply_tx.rs b/src/gui/element/wallet/operation/apply_tx.rs index af31d34..74c3fa0 100644 --- a/src/gui/element/wallet/operation/apply_tx.rs +++ b/src/gui/element/wallet/operation/apply_tx.rs @@ -2,8 +2,8 @@ use super::tx_list::{self, ExpandType}; use crate::log_error; use async_std::prelude::FutureExt; use grin_gui_core::{ - config::Config, - wallet::{Slate, Slatepack, TxLogEntry, TxLogEntryType}, + config::Config, + wallet::{Slate, Slatepack, TxLogEntry, TxLogEntryType}, }; use grin_gui_widgets::widget::header; use iced_aw::Card; @@ -13,54 +13,55 @@ use std::path::PathBuf; use super::tx_list::{HeaderState, TxList}; use { - super::super::super::{ - BUTTON_HEIGHT, BUTTON_WIDTH, DEFAULT_FONT_SIZE, DEFAULT_HEADER_FONT_SIZE, DEFAULT_PADDING, - DEFAULT_SUB_HEADER_FONT_SIZE, SMALLER_FONT_SIZE, - }, - crate::gui::{GrinGui, Interaction, Message}, - crate::localization::localized_string, - crate::Result, - anyhow::Context, - grin_gui_core::theme::{ - Button, Column, Container, Element, Header, PickList, Row, Scrollable, TableRow, Text, - TextInput, - }, - grin_gui_core::wallet::{StatusMessage, WalletInfo, WalletInterface}, - grin_gui_core::{node::amount_to_hr_string, theme::ColorPalette}, - iced::widget::{button, pick_list, scrollable, text_input, Checkbox, Space}, - iced::{alignment, Alignment, Command, Length}, - serde::{Deserialize, Serialize}, - std::sync::{Arc, RwLock}, + super::super::super::{ + BUTTON_HEIGHT, BUTTON_WIDTH, DEFAULT_FONT_SIZE, DEFAULT_HEADER_FONT_SIZE, DEFAULT_PADDING, + DEFAULT_SUB_HEADER_FONT_SIZE, SMALLER_FONT_SIZE, + }, + crate::gui::{GrinGui, Interaction, Message}, + crate::localization::localized_string, + crate::Result, + anyhow::Context, + grin_gui_core::theme::{ + Button, Column, Container, Element, Header, PickList, Row, Scrollable, TableRow, Text, + TextInput, + }, + grin_gui_core::wallet::{StatusMessage, WalletInfo, WalletInterface}, + grin_gui_core::{node::amount_to_hr_string, theme::ColorPalette}, + iced::widget::{button, pick_list, scrollable, text_input, Checkbox, Space}, + iced::{alignment, Alignment, Command, Length}, + serde::{Deserialize, Serialize}, + std::sync::{Arc, RwLock}, }; pub struct StateContainer { - // Slatepack data itself as read, or instructions - pub slatepack_read_data: String, - // Entire slatepack data - pub slatepack_read_data_full: String, - // whether we can continue - pub can_continue: bool, - // confirmation state, in separate panel - pub confirm_state: super::apply_tx_confirm::StateContainer, + // Slatepack data itself as read, or instructions + pub slatepack_read_data: String, + // Entire slatepack data + pub slatepack_read_data_full: String, + // whether we can continue + pub can_continue: bool, + // confirmation state, in separate panel + pub confirm_state: super::apply_tx_confirm::StateContainer, } impl Default for StateContainer { - fn default() -> Self { - Self { - slatepack_read_data: localized_string("tx-slatepack-read-result-default"), - slatepack_read_data_full: Default::default(), - can_continue: false, - confirm_state: Default::default(), - } - } + fn default() -> Self { + Self { + slatepack_read_data: localized_string("tx-slatepack-read-result-default"), + slatepack_read_data_full: Default::default(), + can_continue: false, + confirm_state: Default::default(), + } + } } impl StateContainer { - pub fn set_slate_direct(&mut self, slate: Slate, tx_log_entry: TxLogEntry) { - self.confirm_state.slatepack_parsed = Some((Slatepack::default(), slate, Some(tx_log_entry))); - self.confirm_state.is_self_send = true; - self.can_continue = true; - } + pub fn set_slate_direct(&mut self, slate: Slate, tx_log_entry: TxLogEntry) { + self.confirm_state.slatepack_parsed = + Some((Slatepack::default(), slate, Some(tx_log_entry))); + self.confirm_state.is_self_send = true; + self.can_continue = true; + } } #[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)] @@ -68,407 +69,404 @@ pub enum Action {} #[derive(Debug, Clone)] pub enum LocalViewInteraction { - Back, - BackCleanup, - Continue, - Address(String), - ApplyTransaction(String), - ReadFromClipboardSuccess(String), - ReadFromClipboardFailure, - ShowSlate, + Back, + BackCleanup, + Continue, + Address(String), + ApplyTransaction(String), + ReadFromClipboardSuccess(String), + ReadFromClipboardFailure, + ShowSlate, } pub fn handle_message<'a>( - grin_gui: &mut GrinGui, - message: LocalViewInteraction, + grin_gui: &mut GrinGui, + message: LocalViewInteraction, ) -> Result> { - let state = &mut grin_gui.wallet_state.operation_state.apply_tx_state; - match message { - LocalViewInteraction::Back => { - log::debug!("Interaction::WalletOperationApplyTxViewInteraction(Back)"); - // If this was a self-send, cancel the transaction and remove from log - if state.confirm_state.is_self_send { - // Unwrap tx id - let tx_id = match state.confirm_state.slatepack_parsed.as_ref() { - Some(p) => { - if let Some (t) = p.2.as_ref() { - Some(t.id) - } else { - None - } - }, - None => None, - }; - let w = grin_gui.wallet_interface.clone(); - let fut = move || { - WalletInterface::cancel_tx(w, tx_id.unwrap()) - }; - - return Ok(Command::perform(fut(), |_| { - return Message::Interaction( + let state = &mut grin_gui.wallet_state.operation_state.apply_tx_state; + match message { + LocalViewInteraction::Back => { + log::debug!("Interaction::WalletOperationApplyTxViewInteraction(Back)"); + // If this was a self-send, cancel the transaction and remove from log + if state.confirm_state.is_self_send { + // Unwrap tx id + let tx_id = match state.confirm_state.slatepack_parsed.as_ref() { + Some(p) => { + if let Some(t) = p.2.as_ref() { + Some(t.id) + } else { + None + } + } + None => None, + }; + let w = grin_gui.wallet_interface.clone(); + let fut = move || WalletInterface::cancel_tx(w, tx_id.unwrap()); + + return Ok(Command::perform(fut(), |_| { + return Message::Interaction( Interaction::WalletOperationApplyTxViewInteraction( crate::gui::element::wallet::operation::apply_tx::LocalViewInteraction::BackCleanup, ), ); - })); - } else { - let fut = move || async {}; - return Ok(Command::perform(fut(), |_| { - return Message::Interaction( + })); + } else { + let fut = move || async {}; + return Ok(Command::perform(fut(), |_| { + return Message::Interaction( Interaction::WalletOperationApplyTxViewInteraction( crate::gui::element::wallet::operation::apply_tx::LocalViewInteraction::BackCleanup, ), ); - })); - } - }, - LocalViewInteraction::BackCleanup => { - state.slatepack_read_data = localized_string("tx-slatepack-read-result-default"); - grin_gui.wallet_state.operation_state.mode = - crate::gui::element::wallet::operation::Mode::Home; - state.confirm_state.slatepack_parsed = None; - state.slatepack_read_data_full = Default::default(); - state.confirm_state.is_self_send = false; - state.can_continue = false; - - }, - LocalViewInteraction::ReadFromClipboardSuccess(value) => { - debug!("Read from clipboard: {}", value); - let w = grin_gui.wallet_interface.clone(); - let decode_res = WalletInterface::decrypt_slatepack(w, value.clone()); - match decode_res { - Err(e) => { - state.slatepack_read_data = localized_string("tx-slatepack-read-failure"); - state.confirm_state.slatepack_parsed = None; - state.slatepack_read_data_full = Default::default(); - state.can_continue = false; - } - Ok(s) => { - debug!("{}", s.1); - // Truncate a bit for compact display purposes - let mut s1 = value.clone(); - s1.truncate(27); - let s2 = value - .clone() - .split_off(usize::saturating_sub(value.len(), 23)); - let short_display = format!("{}...{}", s1, s2); - - state.slatepack_read_data_full = value.clone(); - state.slatepack_read_data = short_display; - state.confirm_state.slatepack_parsed = Some(s); - state.can_continue = true; - } - } - } - LocalViewInteraction::Continue => { - state.slatepack_read_data = localized_string("tx-slatepack-read-result-default"); - state.can_continue = false; - let fut = move || async {}; - return Ok(Command::perform(fut(), |_| { - return Message::Interaction( + })); + } + } + LocalViewInteraction::BackCleanup => { + state.slatepack_read_data = localized_string("tx-slatepack-read-result-default"); + grin_gui.wallet_state.operation_state.mode = + crate::gui::element::wallet::operation::Mode::Home; + state.confirm_state.slatepack_parsed = None; + state.slatepack_read_data_full = Default::default(); + state.confirm_state.is_self_send = false; + state.can_continue = false; + } + LocalViewInteraction::ReadFromClipboardSuccess(value) => { + debug!("Read from clipboard: {}", value); + let w = grin_gui.wallet_interface.clone(); + let decode_res = WalletInterface::decrypt_slatepack(w, value.clone()); + match decode_res { + Err(e) => { + state.slatepack_read_data = localized_string("tx-slatepack-read-failure"); + state.confirm_state.slatepack_parsed = None; + state.slatepack_read_data_full = Default::default(); + state.can_continue = false; + } + Ok(s) => { + debug!("{}", s.1); + // Truncate a bit for compact display purposes + let mut s1 = value.clone(); + s1.truncate(27); + let s2 = value + .clone() + .split_off(usize::saturating_sub(value.len(), 23)); + let short_display = format!("{}...{}", s1, s2); + + state.slatepack_read_data_full = value.clone(); + state.slatepack_read_data = short_display; + state.confirm_state.slatepack_parsed = Some(s); + state.can_continue = true; + } + } + } + LocalViewInteraction::Continue => { + state.slatepack_read_data = localized_string("tx-slatepack-read-result-default"); + state.can_continue = false; + let fut = move || async {}; + return Ok(Command::perform(fut(), |_| { + return Message::Interaction( Interaction::WalletOperationApplyTxConfirmViewInteraction( crate::gui::element::wallet::operation::apply_tx_confirm::LocalViewInteraction::Accept ), ); - })); - } - LocalViewInteraction::ReadFromClipboardFailure => { - error!("Failed to read from clipboard"); - } - LocalViewInteraction::ShowSlate => { - // ensure back button on showing slate screen comes back here - grin_gui - .wallet_state - .operation_state - .show_slatepack_state - .submit_mode = Some(crate::gui::element::wallet::operation::Mode::ApplyTx); - grin_gui - .wallet_state - .operation_state - .show_slatepack_state - .encrypted_slate = Some(state.slatepack_read_data_full.clone()); - - grin_gui.wallet_state.operation_state.mode = - crate::gui::element::wallet::operation::Mode::ShowSlatepack; - } - LocalViewInteraction::Address(_) => {} - LocalViewInteraction::ApplyTransaction(_) => {} - } - Ok(Command::none()) + })); + } + LocalViewInteraction::ReadFromClipboardFailure => { + error!("Failed to read from clipboard"); + } + LocalViewInteraction::ShowSlate => { + // ensure back button on showing slate screen comes back here + grin_gui + .wallet_state + .operation_state + .show_slatepack_state + .submit_mode = Some(crate::gui::element::wallet::operation::Mode::ApplyTx); + grin_gui + .wallet_state + .operation_state + .show_slatepack_state + .encrypted_slate = Some(state.slatepack_read_data_full.clone()); + + grin_gui.wallet_state.operation_state.mode = + crate::gui::element::wallet::operation::Mode::ShowSlatepack; + } + LocalViewInteraction::Address(_) => {} + LocalViewInteraction::ApplyTransaction(_) => {} + } + Ok(Command::none()) } pub fn data_container<'a>(config: &'a Config, state: &'a StateContainer) -> Container<'a, Message> { - let unit_spacing = 15.0; - let mut title_key = localized_string("apply-tx"); - - // Just display Signing... and return while signing futures are being called - if state.confirm_state.is_signing { - title_key = localized_string("signing-tx"); - } - - // Title row - let title = Text::new(title_key) - .size(DEFAULT_HEADER_FONT_SIZE) - .horizontal_alignment(alignment::Horizontal::Center); - - let title_container = Container::new(title) - .style(grin_gui_core::theme::ContainerStyle::BrightBackground) - .padding(iced::Padding::from([ - 2, // top - 0, // right - 2, // bottom - 0, // left - ])); - - // push more items on to header here: e.g. other buttons, things that belong on the header - let header_row = Row::new().push(title_container); - - let header_container = Container::new(header_row).padding(iced::Padding::from([ - 0, // top - 0, // right - DEFAULT_PADDING as u16, // bottom - 0, // left - ])); - - if state.confirm_state.is_signing { - let column = Column::new().push(header_container); - - let form_container = - Container::new(column) - .width(Length::Fill) - .padding(iced::Padding::from([ - 0, // top - 0, // right - 0, // bottom - 5, // left - ])); - - // form container should be scrollable in tiny windows - let scrollable = Scrollable::new(form_container) - .height(Length::Fill) - .style(grin_gui_core::theme::ScrollableStyle::Primary); - - let content = Container::new(scrollable) - .width(Length::Fill) - .height(Length::Shrink) - .style(grin_gui_core::theme::ContainerStyle::NormalBackground); - - let wrapper_column = Column::new().height(Length::Fill).push(content); - - // Returns the final container. - return Container::new(wrapper_column).padding(iced::Padding::from([ - DEFAULT_PADDING, // top - DEFAULT_PADDING, // right - DEFAULT_PADDING, // bottom - DEFAULT_PADDING, // left - ])); - } - - let paste_instruction = Text::new(state.slatepack_read_data.clone()) - .size(DEFAULT_FONT_SIZE) - .horizontal_alignment(alignment::Horizontal::Left); - - let paste_instruction_container = Container::new(paste_instruction) - .style(grin_gui_core::theme::ContainerStyle::NormalBackground); - - let mut instruction_row = Row::new().push(paste_instruction_container); - - if state.can_continue { - let show_slate_label_container = Container::new( - Text::new(localized_string("tx-show-full-slatepack")).size(SMALLER_FONT_SIZE), - ) - .height(Length::Fixed(14.0)) - .width(Length::Fixed(60.0)) - .center_y() - .center_x(); - - let show_slate_button: Element = Button::new(show_slate_label_container) - .style(grin_gui_core::theme::ButtonStyle::Bordered) - .on_press(Interaction::WalletOperationApplyTxViewInteraction( - LocalViewInteraction::ShowSlate, - )) - .padding(2) - .into(); - - let paste_again_label_container = - Container::new(Text::new(localized_string("tx-paste-again")).size(SMALLER_FONT_SIZE)) - .height(Length::Fixed(14.0)) - .width(Length::Fixed(60.0)) - .center_y() - .center_x(); - - let paste_again_button: Element = Button::new(paste_again_label_container) - .style(grin_gui_core::theme::ButtonStyle::Bordered) - .on_press(Interaction::ReadSlatepackFromClipboard) - .padding(2) - .into(); - - instruction_row = instruction_row - .push(Space::with_width(Length::Fixed(2.0))) - .push(show_slate_button.map(Message::Interaction)) - .push(Space::with_width(Length::Fixed(2.0))) - .push(paste_again_button.map(Message::Interaction)); - } - - let mut instruction_col = Column::new(); - - if state.can_continue { - let pasted_tx_label = Text::new(localized_string("pasted-slatepack")) - .size(DEFAULT_SUB_HEADER_FONT_SIZE) - .horizontal_alignment(alignment::Horizontal::Left); - let pasted_tx_label_container = Container::new(pasted_tx_label) - .style(grin_gui_core::theme::ContainerStyle::BrightBackground); - instruction_col = instruction_col - .push(pasted_tx_label_container) - .push(Space::new(Length::Fixed(0.0), Length::Fixed(unit_spacing))) - } - - instruction_col = instruction_col.push(instruction_row); - - /*if state.can_continue { - let decrypted_tx_label = Text::new(localized_string("pasted-slatepack-details")) - .size(DEFAULT_SUB_HEADER_FONT_SIZE) - .horizontal_alignment(alignment::Horizontal::Left); - - let decrypted_tx_label_container = Container::new(decrypted_tx_label) - .style(grin_gui_core::theme::ContainerStyle::BrightBackground); - instruction_col = instruction_col - .push(Space::new(Length::Fixed(0.0), Length::Fixed(unit_spacing))) - .push(decrypted_tx_label_container) - }*/ - - let mut slatepack_area = Column::new(); - if state.can_continue { - // Add parsed slatepack contents area here - let parsed_slate_content = - super::apply_tx_confirm::data_container(config, &state.confirm_state); - - slatepack_area = slatepack_area.push(parsed_slate_content); - } - - let slatepack_area_container = Container::new(slatepack_area); - - let button_height = Length::Fixed(BUTTON_HEIGHT); - let button_width = Length::Fixed(BUTTON_WIDTH); - - let submit_button_label_container = - Container::new(Text::new(localized_string("tx-paste")).size(DEFAULT_FONT_SIZE)) - .width(button_width) - .height(button_height) - .center_x() - .center_y() - .align_x(alignment::Horizontal::Center); - - let mut submit_button = Button::new(submit_button_label_container) - .style(grin_gui_core::theme::ButtonStyle::Primary) - .on_press(Interaction::ReadSlatepackFromClipboard); - - let submit_button: Element = submit_button.into(); - - let continue_button_label_container = - Container::new(Text::new(localized_string("tx-continue")).size(DEFAULT_FONT_SIZE)) - .width(button_width) - .height(button_height) - .center_x() - .center_y() - .align_x(alignment::Horizontal::Center); - - let continue_button: Element = Button::new(continue_button_label_container) - .style(grin_gui_core::theme::ButtonStyle::Primary) - .on_press(Interaction::WalletOperationApplyTxViewInteraction( - LocalViewInteraction::Continue, - )) - .into(); - - let cancel_button_label_container = - Container::new(Text::new(localized_string("cancel")).size(DEFAULT_FONT_SIZE)) - .width(button_width) - .height(button_height) - .center_x() - .center_y() - .align_x(alignment::Horizontal::Center); - - let cancel_button: Element = Button::new(cancel_button_label_container) - .style(grin_gui_core::theme::ButtonStyle::Primary) - .on_press(Interaction::WalletOperationApplyTxViewInteraction( - LocalViewInteraction::Back, - )) - .into(); - - let submit_container = Container::new(submit_button.map(Message::Interaction)).padding(1); - let submit_container = Container::new(submit_container) - .style(grin_gui_core::theme::ContainerStyle::Segmented) - .padding(1); - - let continue_container = Container::new(continue_button.map(Message::Interaction)).padding(1); - let continue_container = Container::new(continue_container) - .style(grin_gui_core::theme::ContainerStyle::Segmented) - .padding(1); - - let cancel_container = Container::new(cancel_button.map(Message::Interaction)).padding(1); - let cancel_container = Container::new(cancel_container) - .style(grin_gui_core::theme::ContainerStyle::Segmented) - .padding(1); - - let mut button_row = Row::new(); - if !state.can_continue { - button_row = button_row - .push(submit_container) - .push(Space::new(Length::Fixed(unit_spacing), Length::Fixed(0.0))); - } else { - button_row = button_row - .push(continue_container) - .push(Space::new(Length::Fixed(unit_spacing), Length::Fixed(0.0))) - } - - button_row = button_row.push(cancel_container); - - let mut column = Column::new() - .push(header_container) - .push(Space::new(Length::Fixed(0.0), Length::Fixed(unit_spacing))) - .push(slatepack_area_container) - .push(Space::new(Length::Fixed(0.0), Length::Fixed(unit_spacing))); - - if !state.confirm_state.is_self_send { - column = column - .push(instruction_col) - .push(Space::new(Length::Fixed(0.0), Length::Fixed(unit_spacing))); - } - - column = column - .push(button_row) - .push(Space::new(Length::Fixed(0.0), Length::Fixed(unit_spacing))) - .push(Space::new( - Length::Fixed(0.0), - Length::Fixed(unit_spacing + 10.0), - )); - - let form_container = Container::new(column) - .width(Length::Fill) - .padding(iced::Padding::from([ - 0, // top - 0, // right - 0, // bottom - 5, // left - ])); - - // form container should be scrollable in tiny windows - let scrollable = Scrollable::new(form_container) - .height(Length::Fill) - .style(grin_gui_core::theme::ScrollableStyle::Primary); - - let content = Container::new(scrollable) - .width(Length::Fill) - .height(Length::Shrink) - .style(grin_gui_core::theme::ContainerStyle::NormalBackground); - - let wrapper_column = Column::new().height(Length::Fill).push(content); - - // Returns the final container. - Container::new(wrapper_column).padding(iced::Padding::from([ - DEFAULT_PADDING, // top - DEFAULT_PADDING, // right - DEFAULT_PADDING, // bottom - DEFAULT_PADDING, // left - ])) + let unit_spacing = 15.0; + let mut title_key = localized_string("apply-tx"); + + // Just display Signing... and return while signing futures are being called + if state.confirm_state.is_signing { + title_key = localized_string("signing-tx"); + } + + // Title row + let title = Text::new(title_key) + .size(DEFAULT_HEADER_FONT_SIZE) + .horizontal_alignment(alignment::Horizontal::Center); + + let title_container = Container::new(title) + .style(grin_gui_core::theme::ContainerStyle::BrightBackground) + .padding(iced::Padding::from([ + 2, // top + 0, // right + 2, // bottom + 0, // left + ])); + + // push more items on to header here: e.g. other buttons, things that belong on the header + let header_row = Row::new().push(title_container); + + let header_container = Container::new(header_row).padding(iced::Padding::from([ + 0, // top + 0, // right + DEFAULT_PADDING as u16, // bottom + 0, // left + ])); + + if state.confirm_state.is_signing { + let column = Column::new().push(header_container); + + let form_container = + Container::new(column) + .width(Length::Fill) + .padding(iced::Padding::from([ + 0, // top + 0, // right + 0, // bottom + 5, // left + ])); + + // form container should be scrollable in tiny windows + let scrollable = Scrollable::new(form_container) + .height(Length::Fill) + .style(grin_gui_core::theme::ScrollableStyle::Primary); + + let content = Container::new(scrollable) + .width(Length::Fill) + .height(Length::Shrink) + .style(grin_gui_core::theme::ContainerStyle::NormalBackground); + + let wrapper_column = Column::new().height(Length::Fill).push(content); + + // Returns the final container. + return Container::new(wrapper_column).padding(iced::Padding::from([ + DEFAULT_PADDING, // top + DEFAULT_PADDING, // right + DEFAULT_PADDING, // bottom + DEFAULT_PADDING, // left + ])); + } + + let paste_instruction = Text::new(state.slatepack_read_data.clone()) + .size(DEFAULT_FONT_SIZE) + .horizontal_alignment(alignment::Horizontal::Left); + + let paste_instruction_container = Container::new(paste_instruction) + .style(grin_gui_core::theme::ContainerStyle::NormalBackground); + + let mut instruction_row = Row::new().push(paste_instruction_container); + + if state.can_continue { + let show_slate_label_container = Container::new( + Text::new(localized_string("tx-show-full-slatepack")).size(SMALLER_FONT_SIZE), + ) + .height(Length::Fixed(14.0)) + .width(Length::Fixed(60.0)) + .center_y() + .center_x(); + + let show_slate_button: Element = Button::new(show_slate_label_container) + .style(grin_gui_core::theme::ButtonStyle::Bordered) + .on_press(Interaction::WalletOperationApplyTxViewInteraction( + LocalViewInteraction::ShowSlate, + )) + .padding(2) + .into(); + + let paste_again_label_container = + Container::new(Text::new(localized_string("tx-paste-again")).size(SMALLER_FONT_SIZE)) + .height(Length::Fixed(14.0)) + .width(Length::Fixed(60.0)) + .center_y() + .center_x(); + + let paste_again_button: Element = Button::new(paste_again_label_container) + .style(grin_gui_core::theme::ButtonStyle::Bordered) + .on_press(Interaction::ReadSlatepackFromClipboard) + .padding(2) + .into(); + + instruction_row = instruction_row + .push(Space::with_width(Length::Fixed(2.0))) + .push(show_slate_button.map(Message::Interaction)) + .push(Space::with_width(Length::Fixed(2.0))) + .push(paste_again_button.map(Message::Interaction)); + } + + let mut instruction_col = Column::new(); + + if state.can_continue { + let pasted_tx_label = Text::new(localized_string("pasted-slatepack")) + .size(DEFAULT_SUB_HEADER_FONT_SIZE) + .horizontal_alignment(alignment::Horizontal::Left); + let pasted_tx_label_container = Container::new(pasted_tx_label) + .style(grin_gui_core::theme::ContainerStyle::BrightBackground); + instruction_col = instruction_col + .push(pasted_tx_label_container) + .push(Space::new(Length::Fixed(0.0), Length::Fixed(unit_spacing))) + } + + instruction_col = instruction_col.push(instruction_row); + + /*if state.can_continue { + let decrypted_tx_label = Text::new(localized_string("pasted-slatepack-details")) + .size(DEFAULT_SUB_HEADER_FONT_SIZE) + .horizontal_alignment(alignment::Horizontal::Left); + + let decrypted_tx_label_container = Container::new(decrypted_tx_label) + .style(grin_gui_core::theme::ContainerStyle::BrightBackground); + instruction_col = instruction_col + .push(Space::new(Length::Fixed(0.0), Length::Fixed(unit_spacing))) + .push(decrypted_tx_label_container) + }*/ + + let mut slatepack_area = Column::new(); + if state.can_continue { + // Add parsed slatepack contents area here + let parsed_slate_content = + super::apply_tx_confirm::data_container(config, &state.confirm_state); + + slatepack_area = slatepack_area.push(parsed_slate_content); + } + + let slatepack_area_container = Container::new(slatepack_area); + + let button_height = Length::Fixed(BUTTON_HEIGHT); + let button_width = Length::Fixed(BUTTON_WIDTH); + + let submit_button_label_container = + Container::new(Text::new(localized_string("tx-paste")).size(DEFAULT_FONT_SIZE)) + .width(button_width) + .height(button_height) + .center_x() + .center_y() + .align_x(alignment::Horizontal::Center); + + let mut submit_button = Button::new(submit_button_label_container) + .style(grin_gui_core::theme::ButtonStyle::Primary) + .on_press(Interaction::ReadSlatepackFromClipboard); + + let submit_button: Element = submit_button.into(); + + let continue_button_label_container = + Container::new(Text::new(localized_string("tx-continue")).size(DEFAULT_FONT_SIZE)) + .width(button_width) + .height(button_height) + .center_x() + .center_y() + .align_x(alignment::Horizontal::Center); + + let continue_button: Element = Button::new(continue_button_label_container) + .style(grin_gui_core::theme::ButtonStyle::Primary) + .on_press(Interaction::WalletOperationApplyTxViewInteraction( + LocalViewInteraction::Continue, + )) + .into(); + + let cancel_button_label_container = + Container::new(Text::new(localized_string("cancel")).size(DEFAULT_FONT_SIZE)) + .width(button_width) + .height(button_height) + .center_x() + .center_y() + .align_x(alignment::Horizontal::Center); + + let cancel_button: Element = Button::new(cancel_button_label_container) + .style(grin_gui_core::theme::ButtonStyle::Primary) + .on_press(Interaction::WalletOperationApplyTxViewInteraction( + LocalViewInteraction::Back, + )) + .into(); + + let submit_container = Container::new(submit_button.map(Message::Interaction)).padding(1); + let submit_container = Container::new(submit_container) + .style(grin_gui_core::theme::ContainerStyle::Segmented) + .padding(1); + + let continue_container = Container::new(continue_button.map(Message::Interaction)).padding(1); + let continue_container = Container::new(continue_container) + .style(grin_gui_core::theme::ContainerStyle::Segmented) + .padding(1); + + let cancel_container = Container::new(cancel_button.map(Message::Interaction)).padding(1); + let cancel_container = Container::new(cancel_container) + .style(grin_gui_core::theme::ContainerStyle::Segmented) + .padding(1); + + let mut button_row = Row::new(); + if !state.can_continue { + button_row = button_row + .push(submit_container) + .push(Space::new(Length::Fixed(unit_spacing), Length::Fixed(0.0))); + } else { + button_row = button_row + .push(continue_container) + .push(Space::new(Length::Fixed(unit_spacing), Length::Fixed(0.0))) + } + + button_row = button_row.push(cancel_container); + + let mut column = Column::new() + .push(header_container) + .push(Space::new(Length::Fixed(0.0), Length::Fixed(unit_spacing))) + .push(slatepack_area_container) + .push(Space::new(Length::Fixed(0.0), Length::Fixed(unit_spacing))); + + if !state.confirm_state.is_self_send { + column = column + .push(instruction_col) + .push(Space::new(Length::Fixed(0.0), Length::Fixed(unit_spacing))); + } + + column = column + .push(button_row) + .push(Space::new(Length::Fixed(0.0), Length::Fixed(unit_spacing))) + .push(Space::new( + Length::Fixed(0.0), + Length::Fixed(unit_spacing + 10.0), + )); + + let form_container = Container::new(column) + .width(Length::Fill) + .padding(iced::Padding::from([ + 0, // top + 0, // right + 0, // bottom + 5, // left + ])); + + // form container should be scrollable in tiny windows + let scrollable = Scrollable::new(form_container) + .height(Length::Fill) + .style(grin_gui_core::theme::ScrollableStyle::Primary); + + let content = Container::new(scrollable) + .width(Length::Fill) + .height(Length::Shrink) + .style(grin_gui_core::theme::ContainerStyle::NormalBackground); + + let wrapper_column = Column::new().height(Length::Fill).push(content); + + // Returns the final container. + Container::new(wrapper_column).padding(iced::Padding::from([ + DEFAULT_PADDING, // top + DEFAULT_PADDING, // right + DEFAULT_PADDING, // bottom + DEFAULT_PADDING, // left + ])) } diff --git a/src/gui/element/wallet/operation/apply_tx_confirm.rs b/src/gui/element/wallet/operation/apply_tx_confirm.rs index 3c91509..bc0fad3 100644 --- a/src/gui/element/wallet/operation/apply_tx_confirm.rs +++ b/src/gui/element/wallet/operation/apply_tx_confirm.rs @@ -2,11 +2,11 @@ use super::tx_list::{self, ExpandType}; use crate::log_error; use async_std::prelude::FutureExt; use grin_gui_core::{ - config::{Config, TxMethod}, - wallet::{ - ContractNewArgsAPI, ContractSetupArgsAPI, ProofArgs, Slate, SlateState, Slatepack, - TxLogEntry, TxLogEntryType, - }, + config::{Config, TxMethod}, + wallet::{ + ContractNewArgsAPI, ContractSetupArgsAPI, ProofArgs, Slate, SlateState, Slatepack, + TxLogEntry, TxLogEntryType, + }, }; use grin_gui_widgets::widget::header; use iced_aw::Card; @@ -18,54 +18,54 @@ use std::path::PathBuf; use super::tx_list::{HeaderState, TxList}; use { - super::super::super::{ - BUTTON_HEIGHT, BUTTON_WIDTH, DEFAULT_FONT_SIZE, DEFAULT_HEADER_FONT_SIZE, DEFAULT_PADDING, - SMALLER_FONT_SIZE, - }, - crate::gui::{GrinGui, Interaction, Message}, - crate::localization::localized_string, - crate::Result, - anyhow::Context, - grin_gui_core::theme::{ - Button, Column, Container, Element, Header, PickList, Row, Scrollable, TableRow, Text, - TextInput, - }, - grin_gui_core::wallet::{parse_abs_tx_amount_fee, StatusMessage, WalletInfo, WalletInterface}, - grin_gui_core::{node::amount_to_hr_string, theme::ColorPalette}, - iced::widget::{button, pick_list, scrollable, text_input, Checkbox, Space}, - iced::{alignment, Alignment, Command, Length}, - serde::{Deserialize, Serialize}, - std::sync::{Arc, RwLock}, + super::super::super::{ + BUTTON_HEIGHT, BUTTON_WIDTH, DEFAULT_FONT_SIZE, DEFAULT_HEADER_FONT_SIZE, DEFAULT_PADDING, + SMALLER_FONT_SIZE, + }, + crate::gui::{GrinGui, Interaction, Message}, + crate::localization::localized_string, + crate::Result, + anyhow::Context, + grin_gui_core::theme::{ + Button, Column, Container, Element, Header, PickList, Row, Scrollable, TableRow, Text, + TextInput, + }, + grin_gui_core::wallet::{parse_abs_tx_amount_fee, StatusMessage, WalletInfo, WalletInterface}, + grin_gui_core::{node::amount_to_hr_string, theme::ColorPalette}, + iced::widget::{button, pick_list, scrollable, text_input, Checkbox, Space}, + iced::{alignment, Alignment, Command, Length}, + serde::{Deserialize, Serialize}, + std::sync::{Arc, RwLock}, }; pub struct StateContainer { - // pub back_button_state: button::State, - // pub copy_address_button_state: button::State, - // pub address_state: text_input::State, - pub address_value: String, - // Slatepack read result - pub slatepack_read_result: String, - // Actual read slatepack - pub slatepack_parsed: Option<(Slatepack, Slate, Option)>, - // In the state of applying slatepack - pub is_signing: bool, - // Is a self send - pub is_self_send: bool, + // pub back_button_state: button::State, + // pub copy_address_button_state: button::State, + // pub address_state: text_input::State, + pub address_value: String, + // Slatepack read result + pub slatepack_read_result: String, + // Actual read slatepack + pub slatepack_parsed: Option<(Slatepack, Slate, Option)>, + // In the state of applying slatepack + pub is_signing: bool, + // Is a self send + pub is_self_send: bool, } impl Default for StateContainer { - fn default() -> Self { - Self { - // back_button_state: Default::default(), - // copy_address_button_state: Default::default(), - // address_state: Default::default(), - address_value: Default::default(), - slatepack_read_result: localized_string("tx-slatepack-read-result-default"), - slatepack_parsed: None, - is_signing: false, - is_self_send: false, - } - } + fn default() -> Self { + Self { + // back_button_state: Default::default(), + // copy_address_button_state: Default::default(), + // address_state: Default::default(), + address_value: Default::default(), + slatepack_read_result: localized_string("tx-slatepack-read-result-default"), + slatepack_parsed: None, + is_signing: false, + is_self_send: false, + } + } } #[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)] @@ -73,411 +73,411 @@ pub enum Action {} #[derive(Debug, Clone)] pub enum LocalViewInteraction { - Back, - Accept, - TxAcceptSuccess(Slate, Option, bool), - TxAcceptFailure(Arc>>), + Back, + Accept, + TxAcceptSuccess(Slate, Option, bool), + TxAcceptFailure(Arc>>), } pub fn handle_message<'a>( - grin_gui: &mut GrinGui, - message: LocalViewInteraction, + grin_gui: &mut GrinGui, + message: LocalViewInteraction, ) -> Result> { - let state = &mut grin_gui - .wallet_state - .operation_state - .apply_tx_state - .confirm_state; - match message { - LocalViewInteraction::Back => { - log::debug!("Interaction::Back"); - state.is_signing = false; - grin_gui.wallet_state.operation_state.mode = - crate::gui::element::wallet::operation::Mode::Home; - } - LocalViewInteraction::Accept => { - grin_gui.error.take(); - - log::debug!("Interaction::WalletOperationApplyTxConfirmViewInteraction(Accept)"); - if state.slatepack_parsed.is_none() { - log::debug!("you should never see this - dev make sure slatepack is not None"); - return Ok(Command::none()); - } - - let (slatepack, slate, tx_log_entry) = state.slatepack_parsed.as_ref().unwrap(); - - let sp_sending_address = match &slatepack.sender { - None => "None".to_string(), - Some(s) => s.to_string(), - }; - - let w = grin_gui.wallet_interface.clone(); - let out_slate = slate.clone(); - if grin_gui.config.tx_method == TxMethod::Legacy { - match slate.state { - SlateState::Standard1 => { - state.is_signing = true; - let fut = move || { - WalletInterface::receive_tx_from_s1(w, out_slate, sp_sending_address) - }; - - return Ok(Command::perform(fut(), |r| { - match r.context("Failed to Progress Transaction") { - Ok((slate, enc_slate)) => Message::Interaction( - Interaction::WalletOperationApplyTxConfirmViewInteraction( - LocalViewInteraction::TxAcceptSuccess( - slate, enc_slate, false, - ), - ), - ), - Err(e) => Message::Interaction( - Interaction::WalletOperationApplyTxConfirmViewInteraction( - LocalViewInteraction::TxAcceptFailure(Arc::new( - RwLock::new(Some(e)), - )), - ), - ), - } - })); - } - SlateState::Standard2 => { - state.is_signing = true; - let fut = move || WalletInterface::finalize_from_s2(w, out_slate, true); - - return Ok(Command::perform(fut(), |r| { - match r.context("Failed to Progress Transaction") { - Ok((slate, enc_slate)) => Message::Interaction( - Interaction::WalletOperationApplyTxConfirmViewInteraction( - LocalViewInteraction::TxAcceptSuccess( - slate, enc_slate, true, - ), - ), - ), - Err(e) => Message::Interaction( - Interaction::WalletOperationApplyTxConfirmViewInteraction( - LocalViewInteraction::TxAcceptFailure(Arc::new( - RwLock::new(Some(e)), - )), - ), - ), - } - })); - } - _ => { - log::error!("Slate state not yet supported"); - return Ok(Command::none()); - } - } - } else { - let (sp_sending_address, sender_pub_key) = match &slatepack.sender { - None => ("None".to_string(), None), - Some(s) => (s.to_string(), Some(s.pub_key)), - }; - - let net_change = match slate.state { - SlateState::Standard1 => Some(slate.amount as i64), - SlateState::Standard2 => None, - SlateState::Invoice1 => Some(-(slate.amount as i64)), - SlateState::Invoice2 => None, - _ => { - log::error!("Slate state not yet supported"); - return Ok(Command::none()); - } - }; - - // Should be a simplified context flow here, where we can be recipient or sender! - let mut args = ContractSetupArgsAPI { - net_change, - proof_args: ProofArgs { - sender_address: sender_pub_key, - ..Default::default() - }, - ..Default::default() - }; - state.is_signing = true; - - if slate.state == SlateState::Invoice1 { - args = ContractSetupArgsAPI { - net_change, - ..Default::default() - }; - } - - if slate.state == SlateState::Invoice2 { - args = ContractSetupArgsAPI { - ..Default::default() - }; - }; - - if state.is_self_send { - debug!("SLATE STATE SELF_SEND: {}", slate.state); - let fut = move || WalletInterface::post_tx(w, out_slate); - return Ok(Command::perform(fut(), |r| { - match r.context("Failed to Progress Transaction") { - Ok((slate, enc_slate)) => { - let finished = slate.state == SlateState::Standard3 - || slate.state == SlateState::Invoice3; - Message::Interaction( - Interaction::WalletOperationApplyTxConfirmViewInteraction( - LocalViewInteraction::TxAcceptSuccess( - slate, enc_slate, true, - ), - ), - ) - } - Err(e) => Message::Interaction( - Interaction::WalletOperationApplyTxConfirmViewInteraction( - LocalViewInteraction::TxAcceptFailure(Arc::new(RwLock::new( - Some(e), - ))), - ), - ), - } - })); - } else { - let fut = move || { - debug!("SIGN ARGS: {:?}", args); - WalletInterface::contract_sign(w, out_slate, args, sp_sending_address, true) - }; - - return Ok(Command::perform(fut(), |r| { - match r.context("Failed to Progress Transaction") { - Ok((slate, enc_slate)) => { - debug!("SLATE STATE: {}", slate.state); - let finished = slate.state == SlateState::Standard3 - || slate.state == SlateState::Invoice3; - Message::Interaction( - Interaction::WalletOperationApplyTxConfirmViewInteraction( - LocalViewInteraction::TxAcceptSuccess( - slate, enc_slate, finished, - ), - ), - ) - } - Err(e) => Message::Interaction( - Interaction::WalletOperationApplyTxConfirmViewInteraction( - LocalViewInteraction::TxAcceptFailure(Arc::new(RwLock::new( - Some(e), - ))), - ), - ), - } - })); - } - } - } - LocalViewInteraction::TxAcceptSuccess(slate, encrypted_slate, finished) => { - // Output the latest slatepack, overriding any previous - if let Some(ref s) = encrypted_slate { - if let Some(dir) = grin_gui.config.get_wallet_slatepack_dir() { - let out_file_name = format!("{}/{}.slatepack", dir, slate.id); - let mut output = File::create(out_file_name.clone())?; - output.write_all(&s.as_bytes())?; - output.sync_all()?; - } - } else { - // If no encrypted slate, tx was posted so remove file - if let Some(dir) = grin_gui.config.get_wallet_slatepack_dir() { - let out_file_name = format!("{}/{}.slatepack", dir, slate.id); - let _ = fs::remove_file(out_file_name); - } - } - - state.is_signing = false; - - if finished { - grin_gui.wallet_state.operation_state.mode = - crate::gui::element::wallet::operation::Mode::TxDone; - } else { - grin_gui - .wallet_state - .operation_state - .show_slatepack_state - .encrypted_slate = encrypted_slate; - - grin_gui - .wallet_state - .operation_state - .show_slatepack_state - .title_label = localized_string("tx-continue-success-title"); - - grin_gui - .wallet_state - .operation_state - .show_slatepack_state - .desc = localized_string("tx-continue-success-desc"); - - grin_gui.wallet_state.operation_state.mode = - crate::gui::element::wallet::operation::Mode::ShowSlatepack; - } - } - LocalViewInteraction::TxAcceptFailure(err) => { - state.is_signing = false; - grin_gui.error = err.write().unwrap().take(); - if let Some(e) = grin_gui.error.as_ref() { - log_error(e); - } - } - } - Ok(Command::none()) + let state = &mut grin_gui + .wallet_state + .operation_state + .apply_tx_state + .confirm_state; + match message { + LocalViewInteraction::Back => { + log::debug!("Interaction::Back"); + state.is_signing = false; + grin_gui.wallet_state.operation_state.mode = + crate::gui::element::wallet::operation::Mode::Home; + } + LocalViewInteraction::Accept => { + grin_gui.error.take(); + + log::debug!("Interaction::WalletOperationApplyTxConfirmViewInteraction(Accept)"); + if state.slatepack_parsed.is_none() { + log::debug!("you should never see this - dev make sure slatepack is not None"); + return Ok(Command::none()); + } + + let (slatepack, slate, tx_log_entry) = state.slatepack_parsed.as_ref().unwrap(); + + let sp_sending_address = match &slatepack.sender { + None => "None".to_string(), + Some(s) => s.to_string(), + }; + + let w = grin_gui.wallet_interface.clone(); + let out_slate = slate.clone(); + if grin_gui.config.tx_method == TxMethod::Legacy { + match slate.state { + SlateState::Standard1 => { + state.is_signing = true; + let fut = move || { + WalletInterface::receive_tx_from_s1(w, out_slate, sp_sending_address) + }; + + return Ok(Command::perform(fut(), |r| { + match r.context("Failed to Progress Transaction") { + Ok((slate, enc_slate)) => Message::Interaction( + Interaction::WalletOperationApplyTxConfirmViewInteraction( + LocalViewInteraction::TxAcceptSuccess( + slate, enc_slate, false, + ), + ), + ), + Err(e) => Message::Interaction( + Interaction::WalletOperationApplyTxConfirmViewInteraction( + LocalViewInteraction::TxAcceptFailure(Arc::new( + RwLock::new(Some(e)), + )), + ), + ), + } + })); + } + SlateState::Standard2 => { + state.is_signing = true; + let fut = move || WalletInterface::finalize_from_s2(w, out_slate, true); + + return Ok(Command::perform(fut(), |r| { + match r.context("Failed to Progress Transaction") { + Ok((slate, enc_slate)) => Message::Interaction( + Interaction::WalletOperationApplyTxConfirmViewInteraction( + LocalViewInteraction::TxAcceptSuccess( + slate, enc_slate, true, + ), + ), + ), + Err(e) => Message::Interaction( + Interaction::WalletOperationApplyTxConfirmViewInteraction( + LocalViewInteraction::TxAcceptFailure(Arc::new( + RwLock::new(Some(e)), + )), + ), + ), + } + })); + } + _ => { + log::error!("Slate state not yet supported"); + return Ok(Command::none()); + } + } + } else { + let (sp_sending_address, sender_pub_key) = match &slatepack.sender { + None => ("None".to_string(), None), + Some(s) => (s.to_string(), Some(s.pub_key)), + }; + + let net_change = match slate.state { + SlateState::Standard1 => Some(slate.amount as i64), + SlateState::Standard2 => None, + SlateState::Invoice1 => Some(-(slate.amount as i64)), + SlateState::Invoice2 => None, + _ => { + log::error!("Slate state not yet supported"); + return Ok(Command::none()); + } + }; + + // Should be a simplified context flow here, where we can be recipient or sender! + let mut args = ContractSetupArgsAPI { + net_change, + proof_args: ProofArgs { + sender_address: sender_pub_key, + ..Default::default() + }, + ..Default::default() + }; + state.is_signing = true; + + if slate.state == SlateState::Invoice1 { + args = ContractSetupArgsAPI { + net_change, + ..Default::default() + }; + } + + if slate.state == SlateState::Invoice2 { + args = ContractSetupArgsAPI { + ..Default::default() + }; + }; + + if state.is_self_send { + debug!("SLATE STATE SELF_SEND: {}", slate.state); + let fut = move || WalletInterface::post_tx(w, out_slate); + return Ok(Command::perform(fut(), |r| { + match r.context("Failed to Progress Transaction") { + Ok((slate, enc_slate)) => { + let finished = slate.state == SlateState::Standard3 + || slate.state == SlateState::Invoice3; + Message::Interaction( + Interaction::WalletOperationApplyTxConfirmViewInteraction( + LocalViewInteraction::TxAcceptSuccess( + slate, enc_slate, true, + ), + ), + ) + } + Err(e) => Message::Interaction( + Interaction::WalletOperationApplyTxConfirmViewInteraction( + LocalViewInteraction::TxAcceptFailure(Arc::new(RwLock::new( + Some(e), + ))), + ), + ), + } + })); + } else { + let fut = move || { + debug!("SIGN ARGS: {:?}", args); + WalletInterface::contract_sign(w, out_slate, args, sp_sending_address, true) + }; + + return Ok(Command::perform(fut(), |r| { + match r.context("Failed to Progress Transaction") { + Ok((slate, enc_slate)) => { + debug!("SLATE STATE: {}", slate.state); + let finished = slate.state == SlateState::Standard3 + || slate.state == SlateState::Invoice3; + Message::Interaction( + Interaction::WalletOperationApplyTxConfirmViewInteraction( + LocalViewInteraction::TxAcceptSuccess( + slate, enc_slate, finished, + ), + ), + ) + } + Err(e) => Message::Interaction( + Interaction::WalletOperationApplyTxConfirmViewInteraction( + LocalViewInteraction::TxAcceptFailure(Arc::new(RwLock::new( + Some(e), + ))), + ), + ), + } + })); + } + } + } + LocalViewInteraction::TxAcceptSuccess(slate, encrypted_slate, finished) => { + // Output the latest slatepack, overriding any previous + if let Some(ref s) = encrypted_slate { + if let Some(dir) = grin_gui.config.get_wallet_slatepack_dir() { + let out_file_name = format!("{}/{}.slatepack", dir, slate.id); + let mut output = File::create(out_file_name.clone())?; + output.write_all(&s.as_bytes())?; + output.sync_all()?; + } + } else { + // If no encrypted slate, tx was posted so remove file + if let Some(dir) = grin_gui.config.get_wallet_slatepack_dir() { + let out_file_name = format!("{}/{}.slatepack", dir, slate.id); + let _ = fs::remove_file(out_file_name); + } + } + + state.is_signing = false; + + if finished { + grin_gui.wallet_state.operation_state.mode = + crate::gui::element::wallet::operation::Mode::TxDone; + } else { + grin_gui + .wallet_state + .operation_state + .show_slatepack_state + .encrypted_slate = encrypted_slate; + + grin_gui + .wallet_state + .operation_state + .show_slatepack_state + .title_label = localized_string("tx-continue-success-title"); + + grin_gui + .wallet_state + .operation_state + .show_slatepack_state + .desc = localized_string("tx-continue-success-desc"); + + grin_gui.wallet_state.operation_state.mode = + crate::gui::element::wallet::operation::Mode::ShowSlatepack; + } + } + LocalViewInteraction::TxAcceptFailure(err) => { + state.is_signing = false; + grin_gui.error = err.write().unwrap().take(); + if let Some(e) = grin_gui.error.as_ref() { + log_error(e); + } + } + } + Ok(Command::none()) } // Very hacky, but these amount string will require different placements of // words + amount in different languages fn parse_info_strings(in_str: &str, amount: &str) -> String { - let amount_split: Vec<&str> = in_str.split("[AMOUNT]").collect(); - let mut amount_included = format!("{}{}", amount_split[0], amount); - if amount_split.len() > 1 { - amount_included = format!("{}{}", amount_included, amount_split[1]); - } - amount_included + let amount_split: Vec<&str> = in_str.split("[AMOUNT]").collect(); + let mut amount_included = format!("{}{}", amount_split[0], amount); + if amount_split.len() > 1 { + amount_included = format!("{}{}", amount_included, amount_split[1]); + } + amount_included } pub fn data_container<'a>(config: &'a Config, state: &'a StateContainer) -> Container<'a, Message> { - let unit_spacing = 15.0; - - if state.slatepack_parsed.is_none() { - return Container::new(Text::new( - "you should never see this - dev make sure slatepack is not None", - )); - } - - // Decode/parse/etc fields for display here - let (slatepack, slate, tx_log_entry) = state.slatepack_parsed.as_ref().unwrap(); - - let sp_sending_address = match &slatepack.sender { - None => "None".to_string(), - Some(s) => s.to_string(), - }; - - let mut amount = amount_to_hr_string(slate.amount, true); - let mut other_wallet_label = localized_string("tx-sender-name"); - let mut reception_instruction_1 = localized_string("tx-reception-instruction"); - let mut reception_instruction_2 = localized_string("tx-reception-instruction-2"); - - // TODO: What's displayed here should change based on the slate state - let mut state_text = match slate.state { - SlateState::Standard1 => parse_info_strings(&localized_string("tx-reception"), &amount), - SlateState::Standard2 => { - let mut fee = String::default(); - other_wallet_label = localized_string("tx-recipient-name"); - if let Some(tx) = tx_log_entry { - (amount, fee) = parse_abs_tx_amount_fee(tx, !state.is_self_send); - } - reception_instruction_2 = - parse_info_strings(&localized_string("tx-s1-finalization-3"), &fee); - reception_instruction_1 = - parse_info_strings(&localized_string("tx-s1-finalization-2"), &fee); - let amt_stmt = parse_info_strings(&localized_string("tx-s1-finalization-1"), &amount); - amt_stmt - } - SlateState::Standard3 => "This transaction is finalised - Standard workflow".to_owned(), - _ => "Support still in development".to_owned(), - }; - - if config.tx_method == TxMethod::Contracts { - state_text = match slate.state { - SlateState::Standard1 => { - other_wallet_label = localized_string("tx-sender-name"); - parse_info_strings(&localized_string("tx-reception"), &amount) - } - SlateState::Standard2 => { - let mut fee = String::default(); - other_wallet_label = localized_string("tx-sender-name"); - if let Some(tx) = tx_log_entry { - (amount, fee) = parse_abs_tx_amount_fee(tx, !state.is_self_send); - } - reception_instruction_2 = - parse_info_strings(&localized_string("tx-s1-finalization-3"), &fee); - reception_instruction_1 = - parse_info_strings(&localized_string("tx-s1-finalization-2"), &fee); - let amt_stmt = match state.is_self_send { - true => parse_info_strings( - &localized_string("tx-s1-finalization-self-send"), - &amount, - ), - false => parse_info_strings(&localized_string("tx-s1-finalization-1"), &amount), - }; - - amt_stmt - } - SlateState::Standard3 => "This transaction is finalised - Standard Workflow".to_owned(), - SlateState::Invoice1 => { - other_wallet_label = localized_string("tx-recipient-name"); - parse_info_strings(&localized_string("tx-sending"), &amount) - } - SlateState::Invoice2 => { - let mut fee = String::default(); - other_wallet_label = localized_string("tx-sender-name"); - if let Some(tx) = tx_log_entry { - (amount, fee) = parse_abs_tx_amount_fee(tx, false); - } - reception_instruction_2 = localized_string("tx-s1-finalization-3"); - reception_instruction_1 = "".to_owned(); - //parse_info_strings(&localized_string("tx-s1-finalization-2"), &fee); - - parse_info_strings(&localized_string("tx-i1-finalization-1"), &amount) - } - _ => state_text, - }; - - if state.is_self_send { - other_wallet_label = localized_string("wallet-self-send-instruction"); - } - } - - // TX State (i.e. Stage) - let state = Text::new(state_text).size(DEFAULT_FONT_SIZE); - - let state_container = - Container::new(state).style(grin_gui_core::theme::ContainerStyle::BrightBackground); - - let state_row = Row::new().push(state_container); - - // Sender address - let sender_address_label = Text::new(format!("{} ", other_wallet_label)) - .size(DEFAULT_FONT_SIZE) - .horizontal_alignment(alignment::Horizontal::Left); - - let sender_address_label_container = Container::new(sender_address_label) - .style(grin_gui_core::theme::ContainerStyle::NormalBackground); - - let sender_address = Text::new(sp_sending_address).size(DEFAULT_FONT_SIZE); - //.width(Length::Fixed(400)) - //.style(grin_gui_core::theme::TextInputStyle::AddonsQuery); - - let sender_address_container = Container::new(sender_address) - .style(grin_gui_core::theme::ContainerStyle::BrightBackground); - - let sender_address_row = Row::new() - .push(sender_address_label_container) - .push(sender_address_container); - - let instruction_label = Text::new(format!("{} ", reception_instruction_1)) - .size(DEFAULT_FONT_SIZE) - .horizontal_alignment(alignment::Horizontal::Left); - - let instruction_label_container = Container::new(instruction_label) - .style(grin_gui_core::theme::ContainerStyle::NormalBackground); - - let instruction_label_2 = Text::new(format!("{} ", localized_string(&reception_instruction_2))) - .size(DEFAULT_FONT_SIZE) - .horizontal_alignment(alignment::Horizontal::Left); - - let instruction_label_container_2 = Container::new(instruction_label_2) - .style(grin_gui_core::theme::ContainerStyle::NormalBackground); - - let column = Column::new() - .push(state_row) - .push(Space::new(Length::Fixed(0.0), Length::Fixed(unit_spacing))) - .push(sender_address_row) - .push(Space::new(Length::Fixed(0.0), Length::Fixed(unit_spacing))) - .push(instruction_label_container) - .push(Space::new(Length::Fixed(0.0), Length::Fixed(unit_spacing))) - .push(instruction_label_container_2); - - let wrapper_column = Column::new().height(Length::Fill).push(column); - - // Returns the final container. - Container::new(wrapper_column) + let unit_spacing = 15.0; + + if state.slatepack_parsed.is_none() { + return Container::new(Text::new( + "you should never see this - dev make sure slatepack is not None", + )); + } + + // Decode/parse/etc fields for display here + let (slatepack, slate, tx_log_entry) = state.slatepack_parsed.as_ref().unwrap(); + + let sp_sending_address = match &slatepack.sender { + None => "None".to_string(), + Some(s) => s.to_string(), + }; + + let mut amount = amount_to_hr_string(slate.amount, true); + let mut other_wallet_label = localized_string("tx-sender-name"); + let mut reception_instruction_1 = localized_string("tx-reception-instruction"); + let mut reception_instruction_2 = localized_string("tx-reception-instruction-2"); + + // TODO: What's displayed here should change based on the slate state + let mut state_text = match slate.state { + SlateState::Standard1 => parse_info_strings(&localized_string("tx-reception"), &amount), + SlateState::Standard2 => { + let mut fee = String::default(); + other_wallet_label = localized_string("tx-recipient-name"); + if let Some(tx) = tx_log_entry { + (amount, fee) = parse_abs_tx_amount_fee(tx, !state.is_self_send); + } + reception_instruction_2 = + parse_info_strings(&localized_string("tx-s1-finalization-3"), &fee); + reception_instruction_1 = + parse_info_strings(&localized_string("tx-s1-finalization-2"), &fee); + let amt_stmt = parse_info_strings(&localized_string("tx-s1-finalization-1"), &amount); + amt_stmt + } + SlateState::Standard3 => "This transaction is finalised - Standard workflow".to_owned(), + _ => "Support still in development".to_owned(), + }; + + if config.tx_method == TxMethod::Contracts { + state_text = match slate.state { + SlateState::Standard1 => { + other_wallet_label = localized_string("tx-sender-name"); + parse_info_strings(&localized_string("tx-reception"), &amount) + } + SlateState::Standard2 => { + let mut fee = String::default(); + other_wallet_label = localized_string("tx-sender-name"); + if let Some(tx) = tx_log_entry { + (amount, fee) = parse_abs_tx_amount_fee(tx, !state.is_self_send); + } + reception_instruction_2 = + parse_info_strings(&localized_string("tx-s1-finalization-3"), &fee); + reception_instruction_1 = + parse_info_strings(&localized_string("tx-s1-finalization-2"), &fee); + let amt_stmt = match state.is_self_send { + true => parse_info_strings( + &localized_string("tx-s1-finalization-self-send"), + &amount, + ), + false => parse_info_strings(&localized_string("tx-s1-finalization-1"), &amount), + }; + + amt_stmt + } + SlateState::Standard3 => "This transaction is finalised - Standard Workflow".to_owned(), + SlateState::Invoice1 => { + other_wallet_label = localized_string("tx-recipient-name"); + parse_info_strings(&localized_string("tx-sending"), &amount) + } + SlateState::Invoice2 => { + let mut fee = String::default(); + other_wallet_label = localized_string("tx-sender-name"); + if let Some(tx) = tx_log_entry { + (amount, fee) = parse_abs_tx_amount_fee(tx, false); + } + reception_instruction_2 = localized_string("tx-s1-finalization-3"); + reception_instruction_1 = "".to_owned(); + //parse_info_strings(&localized_string("tx-s1-finalization-2"), &fee); + + parse_info_strings(&localized_string("tx-i1-finalization-1"), &amount) + } + _ => state_text, + }; + + if state.is_self_send { + other_wallet_label = localized_string("wallet-self-send-instruction"); + } + } + + // TX State (i.e. Stage) + let state = Text::new(state_text).size(DEFAULT_FONT_SIZE); + + let state_container = + Container::new(state).style(grin_gui_core::theme::ContainerStyle::BrightBackground); + + let state_row = Row::new().push(state_container); + + // Sender address + let sender_address_label = Text::new(format!("{} ", other_wallet_label)) + .size(DEFAULT_FONT_SIZE) + .horizontal_alignment(alignment::Horizontal::Left); + + let sender_address_label_container = Container::new(sender_address_label) + .style(grin_gui_core::theme::ContainerStyle::NormalBackground); + + let sender_address = Text::new(sp_sending_address).size(DEFAULT_FONT_SIZE); + //.width(Length::Fixed(400)) + //.style(grin_gui_core::theme::TextInputStyle::AddonsQuery); + + let sender_address_container = Container::new(sender_address) + .style(grin_gui_core::theme::ContainerStyle::BrightBackground); + + let sender_address_row = Row::new() + .push(sender_address_label_container) + .push(sender_address_container); + + let instruction_label = Text::new(format!("{} ", reception_instruction_1)) + .size(DEFAULT_FONT_SIZE) + .horizontal_alignment(alignment::Horizontal::Left); + + let instruction_label_container = Container::new(instruction_label) + .style(grin_gui_core::theme::ContainerStyle::NormalBackground); + + let instruction_label_2 = Text::new(format!("{} ", localized_string(&reception_instruction_2))) + .size(DEFAULT_FONT_SIZE) + .horizontal_alignment(alignment::Horizontal::Left); + + let instruction_label_container_2 = Container::new(instruction_label_2) + .style(grin_gui_core::theme::ContainerStyle::NormalBackground); + + let column = Column::new() + .push(state_row) + .push(Space::new(Length::Fixed(0.0), Length::Fixed(unit_spacing))) + .push(sender_address_row) + .push(Space::new(Length::Fixed(0.0), Length::Fixed(unit_spacing))) + .push(instruction_label_container) + .push(Space::new(Length::Fixed(0.0), Length::Fixed(unit_spacing))) + .push(instruction_label_container_2); + + let wrapper_column = Column::new().height(Length::Fill).push(column); + + // Returns the final container. + Container::new(wrapper_column) } diff --git a/src/gui/element/wallet/operation/chart.rs b/src/gui/element/wallet/operation/chart.rs index 84ff9fa..70451e8 100644 --- a/src/gui/element/wallet/operation/chart.rs +++ b/src/gui/element/wallet/operation/chart.rs @@ -4,23 +4,23 @@ extern crate plotters; use crate::gui::{element::DEFAULT_PADDING, Message}; use chrono::{DateTime, Utc}; use grin_gui_core::theme::{ - Button, Column, Container, Element, Header, PickList, Row, Scrollable, TableRow, Text, - TextInput, Theme, + Button, Column, Container, Element, Header, PickList, Row, Scrollable, TableRow, Text, + TextInput, Theme, }; use iced::{ - alignment::{Horizontal, Vertical}, - executor, - widget::{ - canvas::{self, event, Cache, Frame, Geometry}, - Space, - }, - mouse::Cursor, - Alignment, Command, Font, Length, Point, Settings, Size, Subscription, + alignment::{Horizontal, Vertical}, + executor, + mouse::Cursor, + widget::{ + canvas::{self, event, Cache, Frame, Geometry}, + Space, + }, + Alignment, Command, Font, Length, Point, Settings, Size, Subscription, }; use plotters::{ - coord::{types::RangedCoordf32, ReverseCoordTranslate}, - prelude::*, + coord::{types::RangedCoordf32, ReverseCoordTranslate}, + prelude::*, }; use plotters_backend::DrawingBackend; use plotters_iced::{Chart, ChartWidget}; @@ -35,244 +35,246 @@ const FONT_BOLD: Font = Font::with_name("notosans-bold.ttf"); #[derive(Default)] pub struct BalanceChart { - data_points: VecDeque<(DateTime, f64)>, - cursor_index: Option, - caption_index: Option, - theme: Theme, + data_points: VecDeque<(DateTime, f64)>, + cursor_index: Option, + caption_index: Option, + theme: Theme, } impl BalanceChart { - /// Create a new chart widget - /// `data` is an iterator of `(DateTime, f64)` tuples in descending order - newest datetime first - pub fn new( - theme: Theme, - data: impl Iterator, f64)>, - cursor_index: Option, - caption_index: Option, - ) -> Element<'static, Message> { - let data_points: VecDeque<_> = data.collect(); - let chart = BalanceChart { - data_points, - theme, - cursor_index, - caption_index, - }; - - - Container::new( - Column::new() - .width(Length::Fill) - .height(Length::Fill) - .spacing(5) - .push( - ChartWidget::new(chart).height(Length::Fill)/* .resolve_font( - |_, style| match style { - plotters_backend::FontStyle::Bold => FONT_BOLD, - _ => FONT_REGULAR, - },*/ - ), - ) - .width(Length::Fill) - .height(Length::Fill) - .align_x(Horizontal::Center) - .align_y(Vertical::Center) - .into() - } - - pub fn push_data(&mut self, time: DateTime, value: f64) { - self.data_points.push_front((time, value)); - } + /// Create a new chart widget + /// `data` is an iterator of `(DateTime, f64)` tuples in descending order - newest datetime first + pub fn new( + theme: Theme, + data: impl Iterator, f64)>, + cursor_index: Option, + caption_index: Option, + ) -> Element<'static, Message> { + let data_points: VecDeque<_> = data.collect(); + let chart = BalanceChart { + data_points, + theme, + cursor_index, + caption_index, + }; + + Container::new( + Column::new() + .width(Length::Fill) + .height(Length::Fill) + .spacing(5) + .push( + ChartWidget::new(chart).height(Length::Fill), /* .resolve_font( + |_, style| match style { + plotters_backend::FontStyle::Bold => FONT_BOLD, + _ => FONT_REGULAR, + },*/ + ), + ) + .width(Length::Fill) + .height(Length::Fill) + .align_x(Horizontal::Center) + .align_y(Vertical::Center) + .into() + } + + pub fn push_data(&mut self, time: DateTime, value: f64) { + self.data_points.push_front((time, value)); + } } impl Chart for BalanceChart { - type State = (); - - fn update( - &self, - _state: &mut Self::State, - event: canvas::Event, - bounds: iced::Rectangle, - cursor: Cursor, - ) -> (iced_core::event::Status, Option) { - if let Cursor::Available(point) = cursor { - match event { - canvas::Event::Mouse(_evt) if bounds.contains(point) => { - let p_origin = bounds.position(); - let p = point - p_origin; - let percent = p.x / bounds.width; - - let len = self.data_points.len() - 1; - - let approx_index = len as f32 * percent; - let cursor_index = len.saturating_sub(approx_index.floor() as usize); - let mut caption_index = cursor_index; - - // TODO the caption width 55 here should be dynamic based on the width of the caption text - // USD value is 55px wide - // BTC value is ??px wide - // Grin value is ??px wide - let caption_width = 55.0; - - // caption index is cursor index until the caption reaches the edge of the chart - if p.x / (bounds.width - caption_width) >= 1.0 { - let tail = caption_width / bounds.width; - let approx_tail = len as f32 * tail; - caption_index = approx_tail.floor() as usize; - } - - return ( - iced_core::event::Status::Captured, - Some(Message::Interaction( - crate::gui::Interaction::WalletOperationHomeViewInteraction( - super::home::LocalViewInteraction::MouseIndex(cursor_index, caption_index), - ), - )), - ); - } - _ => { - return ( - iced_core::event::Status::Captured, - Some(Message::Interaction( - crate::gui::Interaction::WalletOperationHomeViewInteraction( - super::home::LocalViewInteraction::MouseExit, - ), - )), - ); - } - } - } - (event::Status::Ignored, None) - } - - fn build_chart(&self, _state: &Self::State, mut chart: ChartBuilder) { - use plotters::{prelude::*, style::Color}; - - const PLOT_LINE_COLOR: RGBColor = RGBColor(0, 175, 255); - - // Acquire time range - let newest_time = self - .data_points - .front() - .unwrap_or(&(chrono::Utc::now(), 0.0)) - .0; - - let mut oldest_time = self - .data_points - .back() - .unwrap_or(&(chrono::Utc::now() - chrono::Duration::days(7), 0.0)) - .0; - - if newest_time == oldest_time { - oldest_time = chrono::Utc::now() - chrono::Duration::days(7); - } - - // get largest amount from data points - let mut max_value = 0.0; - for (_, amount) in self.data_points.iter() { - if *amount > max_value { - max_value = *amount; - } - } - // we add 10% to the max value to make sure the chart is not cut off - max_value = max_value * 1.1; - - let mut chart = chart - .x_label_area_size(6) - .y_label_area_size(0) - .build_cartesian_2d(oldest_time..newest_time, 0.0_f64..max_value) - .expect("failed to build chart"); - - let chart_color = self.theme.palette.bright.primary; - let chart_color = RGBColor( - (chart_color.r * 255.0) as u8, - (chart_color.g * 255.0) as u8, - (chart_color.b * 255.0) as u8, - ); - - let date_color = self.theme.palette.normal.surface; - let date_color = RGBColor( - (date_color.r * 255.0) as u8, - (date_color.g * 255.0) as u8, - (date_color.b * 255.0) as u8, - ); - - let background_color = self.theme.palette.base.background; - let background_color = RGBColor( - (background_color.r * 255.0) as u8, - (background_color.g * 255.0) as u8, - (background_color.b * 255.0) as u8, - ); - - let text_color = self.theme.palette.bright.surface; - let text_color = RGBColor( - (text_color.r * 255.0) as u8, - (text_color.g * 255.0) as u8, - (text_color.b * 255.0) as u8, - ); - - chart - .configure_mesh() - .bold_line_style(background_color) - .light_line_style(background_color) - .axis_style(background_color) - .x_labels(4) - .x_label_style( - ("sans-serif", 15) - .into_font() - .color(&date_color) - .transform(FontTransform::Rotate90), - ) - .x_label_formatter(&|x| format!("{}", x.format("%b %d, %Y"))) - .draw() - .expect("failed to draw chart mesh"); - - chart - .draw_series( - AreaSeries::new( - self.data_points.iter().map(|x| (x.0, x.1 as f64)), - 0.0, - chart_color.mix(0.075), - ) - .border_style(ShapeStyle::from(chart_color).stroke_width(2)), - ) - .expect("failed to draw chart data"); - - if let Some(cursor) = self.cursor_index { - let caption_index = self.caption_index.unwrap(); - let (time1, amount) = self.data_points[cursor]; - let (time2, _) = self.data_points[caption_index]; - //debug!("index: {}, time: {}, amount: {}", index, time, amount); - - // draws a circle at (date, balance) point of the chart - chart - .draw_series(std::iter::once(Circle::new( - (time1, amount), - 5_i32, - chart_color.filled(), - ))) - .expect("Failed to draw hover point"); - - // draw balance above the point - chart - .draw_series(std::iter::once(Text::new( - format!("{}", amount), - (time2, max_value), - ("sans-serif", CHART_CAPTION_HEAD) - .into_font() - .color(&text_color.mix(1.0)), - ))) - .expect("Failed to draw text"); - - // date below balance with a slight faded color - chart - .draw_series(std::iter::once(Text::new( - format!("{}", time1.format("%b %d, %Y")), - (time2, max_value * 0.84), - ("sans-serif", CHART_CAPTION_SUB) - .into_font() - .color(&text_color.mix(0.7)), - ))) - .expect("Failed to draw text"); - } - } + type State = (); + + fn update( + &self, + _state: &mut Self::State, + event: canvas::Event, + bounds: iced::Rectangle, + cursor: Cursor, + ) -> (iced_core::event::Status, Option) { + if let Cursor::Available(point) = cursor { + match event { + canvas::Event::Mouse(_evt) if bounds.contains(point) => { + let p_origin = bounds.position(); + let p = point - p_origin; + let percent = p.x / bounds.width; + + let len = self.data_points.len() - 1; + + let approx_index = len as f32 * percent; + let cursor_index = len.saturating_sub(approx_index.floor() as usize); + let mut caption_index = cursor_index; + + // TODO the caption width 55 here should be dynamic based on the width of the caption text + // USD value is 55px wide + // BTC value is ??px wide + // Grin value is ??px wide + let caption_width = 55.0; + + // caption index is cursor index until the caption reaches the edge of the chart + if p.x / (bounds.width - caption_width) >= 1.0 { + let tail = caption_width / bounds.width; + let approx_tail = len as f32 * tail; + caption_index = approx_tail.floor() as usize; + } + + return ( + iced_core::event::Status::Captured, + Some(Message::Interaction( + crate::gui::Interaction::WalletOperationHomeViewInteraction( + super::home::LocalViewInteraction::MouseIndex( + cursor_index, + caption_index, + ), + ), + )), + ); + } + _ => { + return ( + iced_core::event::Status::Captured, + Some(Message::Interaction( + crate::gui::Interaction::WalletOperationHomeViewInteraction( + super::home::LocalViewInteraction::MouseExit, + ), + )), + ); + } + } + } + (event::Status::Ignored, None) + } + + fn build_chart(&self, _state: &Self::State, mut chart: ChartBuilder) { + use plotters::{prelude::*, style::Color}; + + const PLOT_LINE_COLOR: RGBColor = RGBColor(0, 175, 255); + + // Acquire time range + let newest_time = self + .data_points + .front() + .unwrap_or(&(chrono::Utc::now(), 0.0)) + .0; + + let mut oldest_time = self + .data_points + .back() + .unwrap_or(&(chrono::Utc::now() - chrono::Duration::days(7), 0.0)) + .0; + + if newest_time == oldest_time { + oldest_time = chrono::Utc::now() - chrono::Duration::days(7); + } + + // get largest amount from data points + let mut max_value = 0.0; + for (_, amount) in self.data_points.iter() { + if *amount > max_value { + max_value = *amount; + } + } + // we add 10% to the max value to make sure the chart is not cut off + max_value = max_value * 1.1; + + let mut chart = chart + .x_label_area_size(6) + .y_label_area_size(0) + .build_cartesian_2d(oldest_time..newest_time, 0.0_f64..max_value) + .expect("failed to build chart"); + + let chart_color = self.theme.palette.bright.primary; + let chart_color = RGBColor( + (chart_color.r * 255.0) as u8, + (chart_color.g * 255.0) as u8, + (chart_color.b * 255.0) as u8, + ); + + let date_color = self.theme.palette.normal.surface; + let date_color = RGBColor( + (date_color.r * 255.0) as u8, + (date_color.g * 255.0) as u8, + (date_color.b * 255.0) as u8, + ); + + let background_color = self.theme.palette.base.background; + let background_color = RGBColor( + (background_color.r * 255.0) as u8, + (background_color.g * 255.0) as u8, + (background_color.b * 255.0) as u8, + ); + + let text_color = self.theme.palette.bright.surface; + let text_color = RGBColor( + (text_color.r * 255.0) as u8, + (text_color.g * 255.0) as u8, + (text_color.b * 255.0) as u8, + ); + + chart + .configure_mesh() + .bold_line_style(background_color) + .light_line_style(background_color) + .axis_style(background_color) + .x_labels(4) + .x_label_style( + ("sans-serif", 15) + .into_font() + .color(&date_color) + .transform(FontTransform::Rotate90), + ) + .x_label_formatter(&|x| format!("{}", x.format("%b %d, %Y"))) + .draw() + .expect("failed to draw chart mesh"); + + chart + .draw_series( + AreaSeries::new( + self.data_points.iter().map(|x| (x.0, x.1 as f64)), + 0.0, + chart_color.mix(0.075), + ) + .border_style(ShapeStyle::from(chart_color).stroke_width(2)), + ) + .expect("failed to draw chart data"); + + if let Some(cursor) = self.cursor_index { + let caption_index = self.caption_index.unwrap(); + let (time1, amount) = self.data_points[cursor]; + let (time2, _) = self.data_points[caption_index]; + //debug!("index: {}, time: {}, amount: {}", index, time, amount); + + // draws a circle at (date, balance) point of the chart + chart + .draw_series(std::iter::once(Circle::new( + (time1, amount), + 5_i32, + chart_color.filled(), + ))) + .expect("Failed to draw hover point"); + + // draw balance above the point + chart + .draw_series(std::iter::once(Text::new( + format!("{}", amount), + (time2, max_value), + ("sans-serif", CHART_CAPTION_HEAD) + .into_font() + .color(&text_color.mix(1.0)), + ))) + .expect("Failed to draw text"); + + // date below balance with a slight faded color + chart + .draw_series(std::iter::once(Text::new( + format!("{}", time1.format("%b %d, %Y")), + (time2, max_value * 0.84), + ("sans-serif", CHART_CAPTION_SUB) + .into_font() + .color(&text_color.mix(0.7)), + ))) + .expect("Failed to draw text"); + } + } } diff --git a/src/gui/element/wallet/operation/create_tx.rs b/src/gui/element/wallet/operation/create_tx.rs index d7b3ee0..12d9a13 100644 --- a/src/gui/element/wallet/operation/create_tx.rs +++ b/src/gui/element/wallet/operation/create_tx.rs @@ -2,9 +2,9 @@ use super::tx_list::{self, ExpandType}; use crate::log_error; use async_std::prelude::FutureExt; use grin_gui_core::{ - config::Config, - error::GrinWalletInterfaceError, - wallet::{TxLogEntry, TxLogEntryType}, + config::Config, + error::GrinWalletInterfaceError, + wallet::{TxLogEntry, TxLogEntryType}, }; use grin_gui_widgets::widget::header; use iced_aw::Card; @@ -16,48 +16,48 @@ use std::path::PathBuf; use super::tx_list::{HeaderState, TxList}; use { - super::super::super::{ - BUTTON_HEIGHT, BUTTON_WIDTH, DEFAULT_FONT_SIZE, DEFAULT_HEADER_FONT_SIZE, DEFAULT_PADDING, - SMALLER_FONT_SIZE, - }, - crate::gui::{GrinGui, Interaction, Message}, - crate::localization::localized_string, - crate::Result, - anyhow::Context, - grin_gui_core::theme::{ - Button, Column, Container, Element, Header, PickList, Row, Scrollable, TableRow, Text, - TextInput, - }, - grin_gui_core::wallet::{InitTxArgs, Slate, StatusMessage, WalletInfo, WalletInterface}, - grin_gui_core::{ - node::{amount_from_hr_string, amount_to_hr_string}, - theme::{ButtonStyle, ColorPalette, ContainerStyle}, - }, - iced::widget::{button, pick_list, scrollable, text_input, Checkbox, Space}, - iced::{alignment, Alignment, Command, Length}, - serde::{Deserialize, Serialize}, - std::sync::{Arc, RwLock}, + super::super::super::{ + BUTTON_HEIGHT, BUTTON_WIDTH, DEFAULT_FONT_SIZE, DEFAULT_HEADER_FONT_SIZE, DEFAULT_PADDING, + SMALLER_FONT_SIZE, + }, + crate::gui::{GrinGui, Interaction, Message}, + crate::localization::localized_string, + crate::Result, + anyhow::Context, + grin_gui_core::theme::{ + Button, Column, Container, Element, Header, PickList, Row, Scrollable, TableRow, Text, + TextInput, + }, + grin_gui_core::wallet::{InitTxArgs, Slate, StatusMessage, WalletInfo, WalletInterface}, + grin_gui_core::{ + node::{amount_from_hr_string, amount_to_hr_string}, + theme::{ButtonStyle, ColorPalette, ContainerStyle}, + }, + iced::widget::{button, pick_list, scrollable, text_input, Checkbox, Space}, + iced::{alignment, Alignment, Command, Length}, + serde::{Deserialize, Serialize}, + std::sync::{Arc, RwLock}, }; pub struct StateContainer { - pub recipient_address_value: String, - // pub amount_input_state: text_input::State, - pub amount_value: String, - // whether amount has errored - amount_error: bool, - // slatepack address error - slatepack_address_error: bool, + pub recipient_address_value: String, + // pub amount_input_state: text_input::State, + pub amount_value: String, + // whether amount has errored + amount_error: bool, + // slatepack address error + slatepack_address_error: bool, } impl Default for StateContainer { - fn default() -> Self { - Self { - recipient_address_value: Default::default(), - amount_value: Default::default(), - amount_error: false, - slatepack_address_error: false, - } - } + fn default() -> Self { + Self { + recipient_address_value: Default::default(), + amount_value: Default::default(), + amount_error: false, + slatepack_address_error: false, + } + } } #[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)] @@ -65,332 +65,332 @@ pub enum Action {} #[derive(Debug, Clone)] pub enum LocalViewInteraction { - Back, - RecipientAddress(String), - Amount(String), - CreateTransaction(), - - TxCreatedOk(Slate, String), - TxCreateError(Arc>>), - SlatepackAddressError, + Back, + RecipientAddress(String), + Amount(String), + CreateTransaction(), + + TxCreatedOk(Slate, String), + TxCreateError(Arc>>), + SlatepackAddressError, } pub fn handle_message<'a>( - grin_gui: &mut GrinGui, - message: LocalViewInteraction, + grin_gui: &mut GrinGui, + message: LocalViewInteraction, ) -> Result> { - let state = &mut grin_gui.wallet_state.operation_state.create_tx_state; - - match message { - LocalViewInteraction::Back => { - log::debug!("Interaction::WalletOperationCreateTxViewInteraction(Back)"); - grin_gui.wallet_state.operation_state.mode = - crate::gui::element::wallet::operation::Mode::Home; - } - LocalViewInteraction::RecipientAddress(s) => { - state.recipient_address_value = s; - } - LocalViewInteraction::Amount(s) => { - state.amount_value = s; - } - LocalViewInteraction::CreateTransaction() => { - grin_gui.error.take(); - state.amount_error = false; - state.slatepack_address_error = false; - - log::debug!("Interaction::WalletOperationCreateTxViewInteraction"); - - let w = grin_gui.wallet_interface.clone(); - - let amount = match amount_from_hr_string(&state.amount_value) { - Ok(0) | Err(_) => { - state.amount_error = true; - return Ok(Command::none()); - } - Ok(a) => a, - }; - - // Todo: Amount parsing + validation, just testing the flow for now - let args = InitTxArgs { - src_acct_name: None, - amount, - minimum_confirmations: 2, - max_outputs: 500, - num_change_outputs: 1, - selection_strategy_is_use_all: false, - late_lock: Some(false), - ..Default::default() - }; - let fut = - move || WalletInterface::create_tx(w, args, state.recipient_address_value.clone()); - - return Ok(Command::perform(fut(), |r| match r { - Ok((enc_slate, unenc_slate)) => { - Message::Interaction(Interaction::WalletOperationCreateTxViewInteraction( - LocalViewInteraction::TxCreatedOk(enc_slate, unenc_slate), - )) - } - Err(e) => match e { - GrinWalletInterfaceError::InvalidSlatepackAddress => { - Message::Interaction(Interaction::WalletOperationCreateTxViewInteraction( - LocalViewInteraction::SlatepackAddressError, - )) - } - _ => Message::Interaction(Interaction::WalletOperationCreateTxViewInteraction( - LocalViewInteraction::TxCreateError(Arc::new(RwLock::new(Some( - anyhow::Error::from(e), - )))), - )), - }, - })); - } - LocalViewInteraction::TxCreatedOk(unencrypted_slate, encrypted_slate) => { - log::debug!("{:?}", encrypted_slate); - grin_gui - .wallet_state - .operation_state - .show_slatepack_state - .encrypted_slate = Some(encrypted_slate.to_string()); - - grin_gui - .wallet_state - .operation_state - .show_slatepack_state - .title_label = localized_string("tx-create-success-title"); - - grin_gui - .wallet_state - .operation_state - .show_slatepack_state - .desc = localized_string("tx-create-success-desc"); - - // create a directory to which files will be output, if it doesn't exist - if let Some(dir) = grin_gui.config.get_wallet_slatepack_dir() { - let out_file_name = format!("{}/{}.slatepack", dir, unencrypted_slate.id); - let mut output = File::create(out_file_name.clone())?; - output.write_all(&encrypted_slate.as_bytes())?; - output.sync_all()?; - } - - grin_gui.wallet_state.operation_state.mode = - crate::gui::element::wallet::operation::Mode::ShowSlatepack; - } - LocalViewInteraction::TxCreateError(err) => { - grin_gui.error = err.write().unwrap().take(); - if let Some(e) = grin_gui.error.as_ref() { - log_error(e); - } - } - LocalViewInteraction::SlatepackAddressError => state.slatepack_address_error = true, - } - - Ok(Command::none()) + let state = &mut grin_gui.wallet_state.operation_state.create_tx_state; + + match message { + LocalViewInteraction::Back => { + log::debug!("Interaction::WalletOperationCreateTxViewInteraction(Back)"); + grin_gui.wallet_state.operation_state.mode = + crate::gui::element::wallet::operation::Mode::Home; + } + LocalViewInteraction::RecipientAddress(s) => { + state.recipient_address_value = s; + } + LocalViewInteraction::Amount(s) => { + state.amount_value = s; + } + LocalViewInteraction::CreateTransaction() => { + grin_gui.error.take(); + state.amount_error = false; + state.slatepack_address_error = false; + + log::debug!("Interaction::WalletOperationCreateTxViewInteraction"); + + let w = grin_gui.wallet_interface.clone(); + + let amount = match amount_from_hr_string(&state.amount_value) { + Ok(0) | Err(_) => { + state.amount_error = true; + return Ok(Command::none()); + } + Ok(a) => a, + }; + + // Todo: Amount parsing + validation, just testing the flow for now + let args = InitTxArgs { + src_acct_name: None, + amount, + minimum_confirmations: 2, + max_outputs: 500, + num_change_outputs: 1, + selection_strategy_is_use_all: false, + late_lock: Some(false), + ..Default::default() + }; + let fut = + move || WalletInterface::create_tx(w, args, state.recipient_address_value.clone()); + + return Ok(Command::perform(fut(), |r| match r { + Ok((enc_slate, unenc_slate)) => { + Message::Interaction(Interaction::WalletOperationCreateTxViewInteraction( + LocalViewInteraction::TxCreatedOk(enc_slate, unenc_slate), + )) + } + Err(e) => match e { + GrinWalletInterfaceError::InvalidSlatepackAddress => { + Message::Interaction(Interaction::WalletOperationCreateTxViewInteraction( + LocalViewInteraction::SlatepackAddressError, + )) + } + _ => Message::Interaction(Interaction::WalletOperationCreateTxViewInteraction( + LocalViewInteraction::TxCreateError(Arc::new(RwLock::new(Some( + anyhow::Error::from(e), + )))), + )), + }, + })); + } + LocalViewInteraction::TxCreatedOk(unencrypted_slate, encrypted_slate) => { + log::debug!("{:?}", encrypted_slate); + grin_gui + .wallet_state + .operation_state + .show_slatepack_state + .encrypted_slate = Some(encrypted_slate.to_string()); + + grin_gui + .wallet_state + .operation_state + .show_slatepack_state + .title_label = localized_string("tx-create-success-title"); + + grin_gui + .wallet_state + .operation_state + .show_slatepack_state + .desc = localized_string("tx-create-success-desc"); + + // create a directory to which files will be output, if it doesn't exist + if let Some(dir) = grin_gui.config.get_wallet_slatepack_dir() { + let out_file_name = format!("{}/{}.slatepack", dir, unencrypted_slate.id); + let mut output = File::create(out_file_name.clone())?; + output.write_all(&encrypted_slate.as_bytes())?; + output.sync_all()?; + } + + grin_gui.wallet_state.operation_state.mode = + crate::gui::element::wallet::operation::Mode::ShowSlatepack; + } + LocalViewInteraction::TxCreateError(err) => { + grin_gui.error = err.write().unwrap().take(); + if let Some(e) = grin_gui.error.as_ref() { + log_error(e); + } + } + LocalViewInteraction::SlatepackAddressError => state.slatepack_address_error = true, + } + + Ok(Command::none()) } pub fn data_container<'a>(config: &'a Config, state: &'a StateContainer) -> Container<'a, Message> { - // Title row - let title = Text::new(localized_string("create-tx")) - .size(DEFAULT_HEADER_FONT_SIZE) - .horizontal_alignment(alignment::Horizontal::Center); - - let title_container = Container::new(title) - .style(grin_gui_core::theme::ContainerStyle::BrightBackground) - .padding(iced::Padding::from([ - 2, // top - 0, // right - 2, // bottom - 5, // left - ])); - - // push more items on to header here: e.g. other buttons, things that belong on the header - let header_row = Row::new().push(title_container); - - let header_container = Container::new(header_row).padding(iced::Padding::from([ - 0, // top - 0, // right - DEFAULT_PADDING as u16, // bottom - 0, // left - ])); - - let recipient_address = Text::new(localized_string("recipient-address")) - .size(DEFAULT_FONT_SIZE) - .horizontal_alignment(alignment::Horizontal::Left); - - let recipient_address_container = Container::new(recipient_address) - .style(grin_gui_core::theme::ContainerStyle::NormalBackground); - - let recipient_address_input = TextInput::new("", &state.recipient_address_value) - .on_input(|s| { - Interaction::WalletOperationCreateTxViewInteraction( - LocalViewInteraction::RecipientAddress(s), - ) - }) - .size(DEFAULT_FONT_SIZE) - .padding(6) - .width(Length::Fixed(400.0)) - .style(grin_gui_core::theme::TextInputStyle::AddonsQuery); - - let recipient_address_input: Element = recipient_address_input.into(); - - let address_error = Text::new(localized_string("create-tx-address-error")) - .size(DEFAULT_FONT_SIZE) - .horizontal_alignment(alignment::Horizontal::Left) - .style(grin_gui_core::theme::text::TextStyle::Warning); - - let address_error_container = - Container::new(address_error).style(grin_gui_core::theme::ContainerStyle::NormalBackground); - - let amount = Text::new(localized_string("create-tx-amount")) - .size(DEFAULT_FONT_SIZE) - .horizontal_alignment(alignment::Horizontal::Left); - - let amount_container = - Container::new(amount).style(grin_gui_core::theme::ContainerStyle::NormalBackground); - - let amount_input = TextInput::new( - // &mut state.amount_input_state, - "", - &state.amount_value, - ) - .on_input(|s| { - Interaction::WalletOperationCreateTxViewInteraction(LocalViewInteraction::Amount(s)) - }) - .size(DEFAULT_FONT_SIZE) - .padding(6) - .width(Length::Fixed(100.0)) - .style(grin_gui_core::theme::TextInputStyle::AddonsQuery); - - let amount_input: Element = amount_input.into(); - - let amount_error = Text::new(localized_string("create-tx-amount-error")) - .size(DEFAULT_FONT_SIZE) - .horizontal_alignment(alignment::Horizontal::Left) - .style(grin_gui_core::theme::text::TextStyle::Warning); - - let amount_error_container = - Container::new(amount_error).style(grin_gui_core::theme::ContainerStyle::NormalBackground); - - let address_instruction_container = - Text::new(localized_string("recipient-address-instruction")) - .size(SMALLER_FONT_SIZE) - .horizontal_alignment(alignment::Horizontal::Left); - - let address_instruction_container = - Container::new(address_instruction_container).style(ContainerStyle::NormalBackground); - - let button_height = Length::Fixed(BUTTON_HEIGHT); - let button_width = Length::Fixed(BUTTON_WIDTH); - - let submit_button_label_container = - Container::new(Text::new(localized_string("tx-create-submit")).size(DEFAULT_FONT_SIZE)) - .width(button_width) - .height(button_height) - .center_x() - .center_y() - .align_x(alignment::Horizontal::Center); - - let mut submit_button = Button::new(submit_button_label_container) - .style(grin_gui_core::theme::ButtonStyle::Primary); - let submit_button = - submit_button.on_press(Interaction::WalletOperationCreateTxViewInteraction( - LocalViewInteraction::CreateTransaction(), - )); - let submit_button: Element = submit_button.into(); - - let cancel_button_label_container = - Container::new(Text::new(localized_string("cancel")).size(DEFAULT_FONT_SIZE)) - .width(button_width) - .height(button_height) - .center_x() - .center_y() - .align_x(alignment::Horizontal::Center); - - let cancel_button: Element = Button::new(cancel_button_label_container) - .style(grin_gui_core::theme::ButtonStyle::Primary) - .on_press(Interaction::WalletOperationCreateTxViewInteraction( - LocalViewInteraction::Back, - )) - .into(); - - let submit_container = Container::new(submit_button.map(Message::Interaction)).padding(1); - let submit_container = Container::new(submit_container) - .style(grin_gui_core::theme::ContainerStyle::Segmented) - .padding(1); - - let cancel_container = Container::new(cancel_button.map(Message::Interaction)).padding(1); - let cancel_container = Container::new(cancel_container) - .style(grin_gui_core::theme::ContainerStyle::Segmented) - .padding(1); - - let unit_spacing = 15.0; - let button_row = Row::new() - .push(submit_container) - .push(Space::new(Length::Fixed(unit_spacing), Length::Fixed(0.0))) - .push(cancel_container); - - let mut column = Column::new() - .push(recipient_address_container) - .push(Space::new(Length::Fixed(0.0), Length::Fixed(unit_spacing))) - .push(address_instruction_container) - .push(Space::new(Length::Fixed(0.0), Length::Fixed(unit_spacing))) - .push(recipient_address_input.map(Message::Interaction)) - .push(Space::new(Length::Fixed(0.0), Length::Fixed(unit_spacing))); - - if state.slatepack_address_error { - column = column - .push(address_error_container) - .push(Space::new(Length::Fixed(0.0), Length::Fixed(unit_spacing))); - } - - column = column - .push(amount_container) - .push(Space::new(Length::Fixed(0.0), Length::Fixed(unit_spacing))) - .push(amount_input.map(Message::Interaction)) - .push(Space::new(Length::Fixed(0.0), Length::Fixed(unit_spacing))); - - if state.amount_error { - column = column - .push(amount_error_container) - .push(Space::new(Length::Fixed(0.0), Length::Fixed(unit_spacing))); - } - - column = column - .push(button_row) - .push(Space::new(Length::Fixed(0.0), Length::Fixed(unit_spacing))) - .push(Space::new( - Length::Fixed(0.0), - Length::Fixed(unit_spacing + 10.0), - )); - - let form_container = Container::new(column) - .width(Length::Fill) - .padding(iced::Padding::from([ - 0, // top - 0, // right - 0, // bottom - 5, // left - ])); - - // form container should be scrollable in tiny windows - let scrollable = Scrollable::new(form_container) - .height(Length::Fill) - .style(grin_gui_core::theme::ScrollableStyle::Primary); - - let content = Container::new(scrollable) - .width(Length::Fill) - .height(Length::Shrink) - .style(grin_gui_core::theme::ContainerStyle::NormalBackground); - - let wrapper_column = Column::new() - .height(Length::Fill) - .push(header_container) - .push(content); - - // Returns the final container. - Container::new(wrapper_column).padding(iced::Padding::from([ - DEFAULT_PADDING, // top - DEFAULT_PADDING, // right - DEFAULT_PADDING, // bottom - DEFAULT_PADDING, // left - ])) + // Title row + let title = Text::new(localized_string("create-tx")) + .size(DEFAULT_HEADER_FONT_SIZE) + .horizontal_alignment(alignment::Horizontal::Center); + + let title_container = Container::new(title) + .style(grin_gui_core::theme::ContainerStyle::BrightBackground) + .padding(iced::Padding::from([ + 2, // top + 0, // right + 2, // bottom + 5, // left + ])); + + // push more items on to header here: e.g. other buttons, things that belong on the header + let header_row = Row::new().push(title_container); + + let header_container = Container::new(header_row).padding(iced::Padding::from([ + 0, // top + 0, // right + DEFAULT_PADDING as u16, // bottom + 0, // left + ])); + + let recipient_address = Text::new(localized_string("recipient-address")) + .size(DEFAULT_FONT_SIZE) + .horizontal_alignment(alignment::Horizontal::Left); + + let recipient_address_container = Container::new(recipient_address) + .style(grin_gui_core::theme::ContainerStyle::NormalBackground); + + let recipient_address_input = TextInput::new("", &state.recipient_address_value) + .on_input(|s| { + Interaction::WalletOperationCreateTxViewInteraction( + LocalViewInteraction::RecipientAddress(s), + ) + }) + .size(DEFAULT_FONT_SIZE) + .padding(6) + .width(Length::Fixed(400.0)) + .style(grin_gui_core::theme::TextInputStyle::AddonsQuery); + + let recipient_address_input: Element = recipient_address_input.into(); + + let address_error = Text::new(localized_string("create-tx-address-error")) + .size(DEFAULT_FONT_SIZE) + .horizontal_alignment(alignment::Horizontal::Left) + .style(grin_gui_core::theme::text::TextStyle::Warning); + + let address_error_container = + Container::new(address_error).style(grin_gui_core::theme::ContainerStyle::NormalBackground); + + let amount = Text::new(localized_string("create-tx-amount")) + .size(DEFAULT_FONT_SIZE) + .horizontal_alignment(alignment::Horizontal::Left); + + let amount_container = + Container::new(amount).style(grin_gui_core::theme::ContainerStyle::NormalBackground); + + let amount_input = TextInput::new( + // &mut state.amount_input_state, + "", + &state.amount_value, + ) + .on_input(|s| { + Interaction::WalletOperationCreateTxViewInteraction(LocalViewInteraction::Amount(s)) + }) + .size(DEFAULT_FONT_SIZE) + .padding(6) + .width(Length::Fixed(100.0)) + .style(grin_gui_core::theme::TextInputStyle::AddonsQuery); + + let amount_input: Element = amount_input.into(); + + let amount_error = Text::new(localized_string("create-tx-amount-error")) + .size(DEFAULT_FONT_SIZE) + .horizontal_alignment(alignment::Horizontal::Left) + .style(grin_gui_core::theme::text::TextStyle::Warning); + + let amount_error_container = + Container::new(amount_error).style(grin_gui_core::theme::ContainerStyle::NormalBackground); + + let address_instruction_container = + Text::new(localized_string("recipient-address-instruction")) + .size(SMALLER_FONT_SIZE) + .horizontal_alignment(alignment::Horizontal::Left); + + let address_instruction_container = + Container::new(address_instruction_container).style(ContainerStyle::NormalBackground); + + let button_height = Length::Fixed(BUTTON_HEIGHT); + let button_width = Length::Fixed(BUTTON_WIDTH); + + let submit_button_label_container = + Container::new(Text::new(localized_string("tx-create-submit")).size(DEFAULT_FONT_SIZE)) + .width(button_width) + .height(button_height) + .center_x() + .center_y() + .align_x(alignment::Horizontal::Center); + + let mut submit_button = Button::new(submit_button_label_container) + .style(grin_gui_core::theme::ButtonStyle::Primary); + let submit_button = + submit_button.on_press(Interaction::WalletOperationCreateTxViewInteraction( + LocalViewInteraction::CreateTransaction(), + )); + let submit_button: Element = submit_button.into(); + + let cancel_button_label_container = + Container::new(Text::new(localized_string("cancel")).size(DEFAULT_FONT_SIZE)) + .width(button_width) + .height(button_height) + .center_x() + .center_y() + .align_x(alignment::Horizontal::Center); + + let cancel_button: Element = Button::new(cancel_button_label_container) + .style(grin_gui_core::theme::ButtonStyle::Primary) + .on_press(Interaction::WalletOperationCreateTxViewInteraction( + LocalViewInteraction::Back, + )) + .into(); + + let submit_container = Container::new(submit_button.map(Message::Interaction)).padding(1); + let submit_container = Container::new(submit_container) + .style(grin_gui_core::theme::ContainerStyle::Segmented) + .padding(1); + + let cancel_container = Container::new(cancel_button.map(Message::Interaction)).padding(1); + let cancel_container = Container::new(cancel_container) + .style(grin_gui_core::theme::ContainerStyle::Segmented) + .padding(1); + + let unit_spacing = 15.0; + let button_row = Row::new() + .push(submit_container) + .push(Space::new(Length::Fixed(unit_spacing), Length::Fixed(0.0))) + .push(cancel_container); + + let mut column = Column::new() + .push(recipient_address_container) + .push(Space::new(Length::Fixed(0.0), Length::Fixed(unit_spacing))) + .push(address_instruction_container) + .push(Space::new(Length::Fixed(0.0), Length::Fixed(unit_spacing))) + .push(recipient_address_input.map(Message::Interaction)) + .push(Space::new(Length::Fixed(0.0), Length::Fixed(unit_spacing))); + + if state.slatepack_address_error { + column = column + .push(address_error_container) + .push(Space::new(Length::Fixed(0.0), Length::Fixed(unit_spacing))); + } + + column = column + .push(amount_container) + .push(Space::new(Length::Fixed(0.0), Length::Fixed(unit_spacing))) + .push(amount_input.map(Message::Interaction)) + .push(Space::new(Length::Fixed(0.0), Length::Fixed(unit_spacing))); + + if state.amount_error { + column = column + .push(amount_error_container) + .push(Space::new(Length::Fixed(0.0), Length::Fixed(unit_spacing))); + } + + column = column + .push(button_row) + .push(Space::new(Length::Fixed(0.0), Length::Fixed(unit_spacing))) + .push(Space::new( + Length::Fixed(0.0), + Length::Fixed(unit_spacing + 10.0), + )); + + let form_container = Container::new(column) + .width(Length::Fill) + .padding(iced::Padding::from([ + 0, // top + 0, // right + 0, // bottom + 5, // left + ])); + + // form container should be scrollable in tiny windows + let scrollable = Scrollable::new(form_container) + .height(Length::Fill) + .style(grin_gui_core::theme::ScrollableStyle::Primary); + + let content = Container::new(scrollable) + .width(Length::Fill) + .height(Length::Shrink) + .style(grin_gui_core::theme::ContainerStyle::NormalBackground); + + let wrapper_column = Column::new() + .height(Length::Fill) + .push(header_container) + .push(content); + + // Returns the final container. + Container::new(wrapper_column).padding(iced::Padding::from([ + DEFAULT_PADDING, // top + DEFAULT_PADDING, // right + DEFAULT_PADDING, // bottom + DEFAULT_PADDING, // left + ])) } diff --git a/src/gui/element/wallet/operation/create_tx_contracts.rs b/src/gui/element/wallet/operation/create_tx_contracts.rs index 32660c8..6f33d4c 100644 --- a/src/gui/element/wallet/operation/create_tx_contracts.rs +++ b/src/gui/element/wallet/operation/create_tx_contracts.rs @@ -2,9 +2,12 @@ use super::tx_list::{self, ExpandType}; use crate::log_error; use async_std::prelude::FutureExt; use grin_gui_core::{ - config::Config, - error::GrinWalletInterfaceError, - wallet::{ContractNewArgsAPI, ContractSetupArgsAPI, Slatepack, TxLogEntry, TxLogEntryType, SlatepackAddress}, + config::Config, + error::GrinWalletInterfaceError, + wallet::{ + ContractNewArgsAPI, ContractSetupArgsAPI, Slatepack, SlatepackAddress, TxLogEntry, + TxLogEntryType, + }, }; use grin_gui_widgets::widget::header; use iced_aw::Card; @@ -16,60 +19,60 @@ use std::path::PathBuf; use super::tx_list::{HeaderState, TxList}; use { - super::super::super::{ - BUTTON_HEIGHT, BUTTON_WIDTH, DEFAULT_FONT_SIZE, DEFAULT_HEADER_FONT_SIZE, DEFAULT_PADDING, - SMALLER_FONT_SIZE, - }, - crate::gui::{GrinGui, Interaction, Message}, - crate::localization::localized_string, - crate::Result, - anyhow::Context, - grin_gui_core::theme::{ - Button, Column, Container, Element, Header, PickList, Radio, Row, Scrollable, TableRow, - Text, TextInput, - }, - grin_gui_core::wallet::{InitTxArgs, Slate, StatusMessage, WalletInfo, WalletInterface}, - grin_gui_core::{ - node::{amount_from_hr_string, amount_to_hr_string}, - theme::{ButtonStyle, ColorPalette, ContainerStyle}, - }, - iced::widget::{button, pick_list, radio, scrollable, text_input, Checkbox, Space}, - iced::{alignment, Alignment, Command, Length}, - serde::{Deserialize, Serialize}, - std::sync::{Arc, RwLock}, + super::super::super::{ + BUTTON_HEIGHT, BUTTON_WIDTH, DEFAULT_FONT_SIZE, DEFAULT_HEADER_FONT_SIZE, DEFAULT_PADDING, + SMALLER_FONT_SIZE, + }, + crate::gui::{GrinGui, Interaction, Message}, + crate::localization::localized_string, + crate::Result, + anyhow::Context, + grin_gui_core::theme::{ + Button, Column, Container, Element, Header, PickList, Radio, Row, Scrollable, TableRow, + Text, TextInput, + }, + grin_gui_core::wallet::{InitTxArgs, Slate, StatusMessage, WalletInfo, WalletInterface}, + grin_gui_core::{ + node::{amount_from_hr_string, amount_to_hr_string}, + theme::{ButtonStyle, ColorPalette, ContainerStyle}, + }, + iced::widget::{button, pick_list, radio, scrollable, text_input, Checkbox, Space}, + iced::{alignment, Alignment, Command, Length}, + serde::{Deserialize, Serialize}, + std::sync::{Arc, RwLock}, }; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum ContributionChoice { - Credit, - Debit, + Credit, + Debit, } pub struct StateContainer { - pub recipient_address_value: String, - // pub amount_input_state: text_input::State, - pub amount_value: String, - // Choice of contribution to transaction - pub contribution_choice: ContributionChoice, - // Self-send checkbox - pub is_self_send: bool, - // whether amount has errored - amount_error: bool, - // slatepack address error - slatepack_address_error: bool, + pub recipient_address_value: String, + // pub amount_input_state: text_input::State, + pub amount_value: String, + // Choice of contribution to transaction + pub contribution_choice: ContributionChoice, + // Self-send checkbox + pub is_self_send: bool, + // whether amount has errored + amount_error: bool, + // slatepack address error + slatepack_address_error: bool, } impl Default for StateContainer { - fn default() -> Self { - Self { - recipient_address_value: Default::default(), - contribution_choice: ContributionChoice::Debit, - amount_value: Default::default(), - is_self_send: false, - amount_error: false, - slatepack_address_error: false, - } - } + fn default() -> Self { + Self { + recipient_address_value: Default::default(), + contribution_choice: ContributionChoice::Debit, + amount_value: Default::default(), + is_self_send: false, + amount_error: false, + slatepack_address_error: false, + } + } } #[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)] @@ -77,526 +80,525 @@ pub enum Action {} #[derive(Debug, Clone)] pub enum LocalViewInteraction { - Back, - RecipientAddress(String), - ContributionChoice(ContributionChoice), - Amount(String), - CreateTransaction(), - SelfSendSelected(bool), - - TxCreatedOk(Slate, String), - SelfSendCreatedOk(Slate, TxLogEntry), - TxCreateError(Arc>>), - SlatepackAddressError, + Back, + RecipientAddress(String), + ContributionChoice(ContributionChoice), + Amount(String), + CreateTransaction(), + SelfSendSelected(bool), + + TxCreatedOk(Slate, String), + SelfSendCreatedOk(Slate, TxLogEntry), + TxCreateError(Arc>>), + SlatepackAddressError, } pub fn handle_message<'a>( - grin_gui: &mut GrinGui, - message: LocalViewInteraction, + grin_gui: &mut GrinGui, + message: LocalViewInteraction, ) -> Result> { - let state = &mut grin_gui - .wallet_state - .operation_state - .create_tx_contracts_state; - - match message { - LocalViewInteraction::Back => { - log::debug!("Interaction::WalletOperationCreateTxViewInteraction(Back)"); - grin_gui.wallet_state.operation_state.mode = - crate::gui::element::wallet::operation::Mode::Home; - } - LocalViewInteraction::RecipientAddress(s) => { - state.recipient_address_value = s; - if Some(state.recipient_address_value.clone()) - == grin_gui - .wallet_state - .operation_state - .home_state - .address_value - { - state.is_self_send = true; - } else { - state.is_self_send = false; - } - } - LocalViewInteraction::ContributionChoice(c) => { - log::debug!("Chosen: {:?}", c); - state.contribution_choice = c; - } - LocalViewInteraction::Amount(s) => { - state.amount_value = s; - } - LocalViewInteraction::SelfSendSelected(v) => { - state.is_self_send = v; - if let Some(ref a) = grin_gui - .wallet_state - .operation_state - .home_state - .address_value - { - state.recipient_address_value = a.clone(); - } - } - LocalViewInteraction::CreateTransaction() => { - grin_gui.error.take(); - state.amount_error = false; - state.slatepack_address_error = false; - - log::debug!("Interaction::WalletOperationCreateTxViewInteraction"); - - let w = grin_gui.wallet_interface.clone(); - - let amount = match amount_from_hr_string(&state.amount_value) { - Ok(0) | Err(_) => { - if !state.is_self_send { - state.amount_error = true; - return Ok(Command::none()); - } else { - 0i64 - } - } - Ok(a) => { - if a > std::i64::MAX as u64 { - state.amount_error = true; - return Ok(Command::none()); - } - if state.is_self_send { - 0i64 - } else { - a as i64 - } - } - }; - - let mut args = ContractNewArgsAPI { - setup_args: ContractSetupArgsAPI { - net_change: if state.is_self_send { - // None makes the contracts API cry for now - Some(0) - } else { - match state.contribution_choice { - ContributionChoice::Credit => Some(amount), - ContributionChoice::Debit => Some(-amount), - } - }, - num_participants: if state.is_self_send { - 1 - } else { - 2 - }, - ..Default::default() - }, - ..Default::default() - }; - - if state.contribution_choice == ContributionChoice::Credit { - debug!("CREDITOR ADDRESS: {}", state.recipient_address_value); - let res:Result = state.recipient_address_value.as_str().try_into(); - if let Ok(creditor_address) = res { - args.setup_args.proof_args.sender_address = Some(creditor_address.pub_key); - debug!("CREDITOR ADDRESS: {:?}", args.setup_args.proof_args.sender_address); - } - } - - if state.is_self_send || state.contribution_choice == ContributionChoice::Debit { - if let Some(a) = &grin_gui.wallet_state.operation_state.home_state.address { - args.setup_args.proof_args.sender_address = Some(a.pub_key); - } - }; - - if state.is_self_send { - let fut = move || WalletInterface::contract_self_send(w, args); - - return Ok(Command::perform(fut(), |r| match r { - Ok((unenc_slate, tx_log_entry)) => Message::Interaction( - Interaction::WalletOperationCreateTxContractsViewInteraction( - LocalViewInteraction::SelfSendCreatedOk(unenc_slate, tx_log_entry), - ), - ), - Err(e) => match e { - GrinWalletInterfaceError::InvalidSlatepackAddress => Message::Interaction( - Interaction::WalletOperationCreateTxContractsViewInteraction( - LocalViewInteraction::SlatepackAddressError, - ), - ), - _ => Message::Interaction( - Interaction::WalletOperationCreateTxContractsViewInteraction( - LocalViewInteraction::TxCreateError(Arc::new(RwLock::new(Some( - anyhow::Error::from(e), - )))), - ), - ), - }, - })); - } else { - let fut = move || { - WalletInterface::contract_new(w, args, state.recipient_address_value.clone()) - }; - - return Ok(Command::perform(fut(), |r| match r { - Ok((enc_slate, unenc_slate)) => Message::Interaction( - - Interaction::WalletOperationCreateTxContractsViewInteraction( - LocalViewInteraction::TxCreatedOk(enc_slate, unenc_slate), - ), - ), - Err(e) => match e { - GrinWalletInterfaceError::InvalidSlatepackAddress => Message::Interaction( - Interaction::WalletOperationCreateTxContractsViewInteraction( - LocalViewInteraction::SlatepackAddressError, - ), - ), - _ => Message::Interaction( - Interaction::WalletOperationCreateTxContractsViewInteraction( - LocalViewInteraction::TxCreateError(Arc::new(RwLock::new(Some( - anyhow::Error::from(e), - )))), - ), - ), - }, - })); - } - } - LocalViewInteraction::TxCreatedOk(unencrypted_slate, encrypted_slate) => { - log::debug!("{}", unencrypted_slate); - grin_gui - .wallet_state - .operation_state - .show_slatepack_state - .encrypted_slate = Some(encrypted_slate.to_string()); - - grin_gui - .wallet_state - .operation_state - .show_slatepack_state - .title_label = localized_string("tx-create-success-title"); - - grin_gui - .wallet_state - .operation_state - .show_slatepack_state - .desc = localized_string("tx-create-success-desc"); - - // create a directory to which files will be output, if it doesn't exist - if let Some(dir) = grin_gui.config.get_wallet_slatepack_dir() { - let out_file_name = format!("{}/{}.slatepack", dir, unencrypted_slate.id); - let mut output = File::create(out_file_name.clone())?; - output.write_all(&encrypted_slate.as_bytes())?; - output.sync_all()?; - } - - grin_gui - .wallet_state - .operation_state - .apply_tx_state - .confirm_state - .is_self_send = false; - - grin_gui.wallet_state.operation_state.mode = - crate::gui::element::wallet::operation::Mode::ShowSlatepack; - } - LocalViewInteraction::SelfSendCreatedOk(unencrypted_slate, tx_log_entry) => { - grin_gui - .wallet_state - .operation_state - .apply_tx_state - .set_slate_direct(unencrypted_slate, tx_log_entry); - - grin_gui.wallet_state.operation_state.mode = - crate::gui::element::wallet::operation::Mode::ApplyTx; - } - LocalViewInteraction::TxCreateError(err) => { - grin_gui.error = err.write().unwrap().take(); - if let Some(e) = grin_gui.error.as_ref() { - log_error(e); - } - } - LocalViewInteraction::SlatepackAddressError => state.slatepack_address_error = true, - } - - Ok(Command::none()) + let state = &mut grin_gui + .wallet_state + .operation_state + .create_tx_contracts_state; + + match message { + LocalViewInteraction::Back => { + log::debug!("Interaction::WalletOperationCreateTxViewInteraction(Back)"); + grin_gui.wallet_state.operation_state.mode = + crate::gui::element::wallet::operation::Mode::Home; + } + LocalViewInteraction::RecipientAddress(s) => { + state.recipient_address_value = s; + if Some(state.recipient_address_value.clone()) + == grin_gui + .wallet_state + .operation_state + .home_state + .address_value + { + state.is_self_send = true; + } else { + state.is_self_send = false; + } + } + LocalViewInteraction::ContributionChoice(c) => { + log::debug!("Chosen: {:?}", c); + state.contribution_choice = c; + } + LocalViewInteraction::Amount(s) => { + state.amount_value = s; + } + LocalViewInteraction::SelfSendSelected(v) => { + state.is_self_send = v; + if let Some(ref a) = grin_gui + .wallet_state + .operation_state + .home_state + .address_value + { + state.recipient_address_value = a.clone(); + } + } + LocalViewInteraction::CreateTransaction() => { + grin_gui.error.take(); + state.amount_error = false; + state.slatepack_address_error = false; + + log::debug!("Interaction::WalletOperationCreateTxViewInteraction"); + + let w = grin_gui.wallet_interface.clone(); + + let amount = match amount_from_hr_string(&state.amount_value) { + Ok(0) | Err(_) => { + if !state.is_self_send { + state.amount_error = true; + return Ok(Command::none()); + } else { + 0i64 + } + } + Ok(a) => { + if a > std::i64::MAX as u64 { + state.amount_error = true; + return Ok(Command::none()); + } + if state.is_self_send { + 0i64 + } else { + a as i64 + } + } + }; + + let mut args = ContractNewArgsAPI { + setup_args: ContractSetupArgsAPI { + net_change: if state.is_self_send { + // None makes the contracts API cry for now + Some(0) + } else { + match state.contribution_choice { + ContributionChoice::Credit => Some(amount), + ContributionChoice::Debit => Some(-amount), + } + }, + num_participants: if state.is_self_send { 1 } else { 2 }, + ..Default::default() + }, + ..Default::default() + }; + + if state.contribution_choice == ContributionChoice::Credit { + debug!("CREDITOR ADDRESS: {}", state.recipient_address_value); + let res: Result = + state.recipient_address_value.as_str().try_into(); + if let Ok(creditor_address) = res { + args.setup_args.proof_args.sender_address = Some(creditor_address.pub_key); + debug!( + "CREDITOR ADDRESS: {:?}", + args.setup_args.proof_args.sender_address + ); + } + } + + if state.is_self_send || state.contribution_choice == ContributionChoice::Debit { + if let Some(a) = &grin_gui.wallet_state.operation_state.home_state.address { + args.setup_args.proof_args.sender_address = Some(a.pub_key); + } + }; + + if state.is_self_send { + let fut = move || WalletInterface::contract_self_send(w, args); + + return Ok(Command::perform(fut(), |r| match r { + Ok((unenc_slate, tx_log_entry)) => Message::Interaction( + Interaction::WalletOperationCreateTxContractsViewInteraction( + LocalViewInteraction::SelfSendCreatedOk(unenc_slate, tx_log_entry), + ), + ), + Err(e) => match e { + GrinWalletInterfaceError::InvalidSlatepackAddress => Message::Interaction( + Interaction::WalletOperationCreateTxContractsViewInteraction( + LocalViewInteraction::SlatepackAddressError, + ), + ), + _ => Message::Interaction( + Interaction::WalletOperationCreateTxContractsViewInteraction( + LocalViewInteraction::TxCreateError(Arc::new(RwLock::new(Some( + anyhow::Error::from(e), + )))), + ), + ), + }, + })); + } else { + let fut = move || { + WalletInterface::contract_new(w, args, state.recipient_address_value.clone()) + }; + + return Ok(Command::perform(fut(), |r| match r { + Ok((enc_slate, unenc_slate)) => Message::Interaction( + Interaction::WalletOperationCreateTxContractsViewInteraction( + LocalViewInteraction::TxCreatedOk(enc_slate, unenc_slate), + ), + ), + Err(e) => match e { + GrinWalletInterfaceError::InvalidSlatepackAddress => Message::Interaction( + Interaction::WalletOperationCreateTxContractsViewInteraction( + LocalViewInteraction::SlatepackAddressError, + ), + ), + _ => Message::Interaction( + Interaction::WalletOperationCreateTxContractsViewInteraction( + LocalViewInteraction::TxCreateError(Arc::new(RwLock::new(Some( + anyhow::Error::from(e), + )))), + ), + ), + }, + })); + } + } + LocalViewInteraction::TxCreatedOk(unencrypted_slate, encrypted_slate) => { + log::debug!("{}", unencrypted_slate); + grin_gui + .wallet_state + .operation_state + .show_slatepack_state + .encrypted_slate = Some(encrypted_slate.to_string()); + + grin_gui + .wallet_state + .operation_state + .show_slatepack_state + .title_label = localized_string("tx-create-success-title"); + + grin_gui + .wallet_state + .operation_state + .show_slatepack_state + .desc = localized_string("tx-create-success-desc"); + + // create a directory to which files will be output, if it doesn't exist + if let Some(dir) = grin_gui.config.get_wallet_slatepack_dir() { + let out_file_name = format!("{}/{}.slatepack", dir, unencrypted_slate.id); + let mut output = File::create(out_file_name.clone())?; + output.write_all(&encrypted_slate.as_bytes())?; + output.sync_all()?; + } + + grin_gui + .wallet_state + .operation_state + .apply_tx_state + .confirm_state + .is_self_send = false; + + grin_gui.wallet_state.operation_state.mode = + crate::gui::element::wallet::operation::Mode::ShowSlatepack; + } + LocalViewInteraction::SelfSendCreatedOk(unencrypted_slate, tx_log_entry) => { + grin_gui + .wallet_state + .operation_state + .apply_tx_state + .set_slate_direct(unencrypted_slate, tx_log_entry); + + grin_gui.wallet_state.operation_state.mode = + crate::gui::element::wallet::operation::Mode::ApplyTx; + } + LocalViewInteraction::TxCreateError(err) => { + grin_gui.error = err.write().unwrap().take(); + if let Some(e) = grin_gui.error.as_ref() { + log_error(e); + } + } + LocalViewInteraction::SlatepackAddressError => state.slatepack_address_error = true, + } + + Ok(Command::none()) } pub fn data_container<'a>(config: &'a Config, state: &'a StateContainer) -> Container<'a, Message> { - let unit_spacing = 15.0; - - // Title row - let title = Text::new(localized_string("wallet-create-contract")) - .size(DEFAULT_HEADER_FONT_SIZE) - .horizontal_alignment(alignment::Horizontal::Center); - - let title_container = Container::new(title) - .style(grin_gui_core::theme::ContainerStyle::BrightBackground) - .padding(iced::Padding::from([ - 2, // top - 0, // right - 2, // bottom - 5, // left - ])); - - // push more items on to header here: e.g. other buttons, things that belong on the header - let header_row = Row::new().push(title_container); - - let header_container = Container::new(header_row).padding(iced::Padding::from([ - 0, // top - 0, // right - DEFAULT_PADDING as u16, // bottom - 0, // left - ])); - - let recipient_address = Text::new(localized_string("wallet-create-contract-other-address")) - .size(DEFAULT_FONT_SIZE) - .horizontal_alignment(alignment::Horizontal::Left); - - let recipient_address_container = Container::new(recipient_address) - .style(grin_gui_core::theme::ContainerStyle::NormalBackground); - - let recipient_address_input = TextInput::new("", &state.recipient_address_value) - .on_input(|s| { - Interaction::WalletOperationCreateTxContractsViewInteraction( - LocalViewInteraction::RecipientAddress(s), - ) - }) - .size(DEFAULT_FONT_SIZE) - .padding(6) - .width(Length::Fixed(400.0)) - .style(grin_gui_core::theme::TextInputStyle::AddonsQuery); - - let recipient_address_input: Element = recipient_address_input.into(); - - /*let self_send_check = Text::new(localized_string("wallet-self-send")) - .size(DEFAULT_FONT_SIZE) - .horizontal_alignment(alignment::Horizontal::Left); - - let self_send_container = Container::new(self_send_check) - .style(grin_gui_core::theme::ContainerStyle::NormalBackground);*/ - - let checkbox_column = { - let checkbox = Checkbox::new( - localized_string("wallet-self-send"), - state.is_self_send, - |v| { - Interaction::WalletOperationCreateTxContractsViewInteraction( - LocalViewInteraction::SelfSendSelected(v), - ) - }, - ) - .style(grin_gui_core::theme::CheckboxStyle::Normal) - .text_size(DEFAULT_FONT_SIZE) - .spacing(5); - - let checkbox: Element = checkbox.into(); - - let checkbox_container = Container::new(checkbox.map(Message::Interaction)) - .style(grin_gui_core::theme::ContainerStyle::NormalBackground) - .align_y(alignment::Vertical::Bottom); - Column::new().push(checkbox_container) - }; - - let address_row = Row::new() - //.push(recipient_address_container) - .push(recipient_address_input.map(Message::Interaction)) - .push(Space::new(Length::Fixed(unit_spacing), Length::Fixed(0.0))) - .push(checkbox_column) - .align_items(Alignment::End); - - let a: Element = Radio::new( - localized_string("tx-contract-debit"), - ContributionChoice::Debit, - Some(state.contribution_choice), - |c| { - Interaction::WalletOperationCreateTxContractsViewInteraction( - LocalViewInteraction::ContributionChoice(c), - ) - }, - ) - .style(grin_gui_core::theme::radio::RadioStyle::Primary) - .into(); - - let b: Element = Radio::new( - localized_string("tx-contract-credit"), - ContributionChoice::Credit, - Some(state.contribution_choice), - |c| { - Interaction::WalletOperationCreateTxContractsViewInteraction( - LocalViewInteraction::ContributionChoice(c), - ) - }, - ) - .style(grin_gui_core::theme::radio::RadioStyle::Primary) - .into(); - - let radio_column = Column::new() - .push(a.map(Message::Interaction)) - .push(b.map(Message::Interaction)); - - let address_error = Text::new(localized_string("create-tx-address-error")) - .size(DEFAULT_FONT_SIZE) - .horizontal_alignment(alignment::Horizontal::Left) - .style(grin_gui_core::theme::text::TextStyle::Warning); - - let address_error_container = - Container::new(address_error).style(grin_gui_core::theme::ContainerStyle::NormalBackground); - - let amount = Text::new(localized_string("create-tx-amount")) - .size(DEFAULT_FONT_SIZE) - .horizontal_alignment(alignment::Horizontal::Left); - - let amount_container = - Container::new(amount).style(grin_gui_core::theme::ContainerStyle::NormalBackground); - - let amount_input = TextInput::new( - // &mut state.amount_input_state, - "", - &state.amount_value, - ) - .on_input(|s| { - Interaction::WalletOperationCreateTxContractsViewInteraction(LocalViewInteraction::Amount( - s, - )) - }) - .size(DEFAULT_FONT_SIZE) - .padding(6) - .width(Length::Fixed(100.0)) - .style(grin_gui_core::theme::TextInputStyle::AddonsQuery); - - let amount_input: Element = amount_input.into(); - - let amount_error = Text::new(localized_string("create-tx-amount-error")) - .size(DEFAULT_FONT_SIZE) - .horizontal_alignment(alignment::Horizontal::Left) - .style(grin_gui_core::theme::text::TextStyle::Warning); - - let amount_error_container = - Container::new(amount_error).style(grin_gui_core::theme::ContainerStyle::NormalBackground); - - let address_instruction_container = - Text::new(localized_string("recipient-address-instruction-contract")) - .size(SMALLER_FONT_SIZE) - .horizontal_alignment(alignment::Horizontal::Left); - - let address_instruction_container = - Container::new(address_instruction_container).style(ContainerStyle::NormalBackground); - - let button_height = Length::Fixed(BUTTON_HEIGHT); - let button_width = Length::Fixed(BUTTON_WIDTH); - - let submit_button_label_container = - Container::new(Text::new(localized_string("tx-create-submit")).size(DEFAULT_FONT_SIZE)) - .width(button_width) - .height(button_height) - .center_x() - .center_y() - .align_x(alignment::Horizontal::Center); - - let mut submit_button = Button::new(submit_button_label_container) - .style(grin_gui_core::theme::ButtonStyle::Primary); - let submit_button = submit_button.on_press( - Interaction::WalletOperationCreateTxContractsViewInteraction( - LocalViewInteraction::CreateTransaction(), - ), - ); - let submit_button: Element = submit_button.into(); - - let cancel_button_label_container = - Container::new(Text::new(localized_string("cancel")).size(DEFAULT_FONT_SIZE)) - .width(button_width) - .height(button_height) - .center_x() - .center_y() - .align_x(alignment::Horizontal::Center); - - let cancel_button: Element = Button::new(cancel_button_label_container) - .style(grin_gui_core::theme::ButtonStyle::Primary) - .on_press( - Interaction::WalletOperationCreateTxContractsViewInteraction( - LocalViewInteraction::Back, - ), - ) - .into(); - - let submit_container = Container::new(submit_button.map(Message::Interaction)).padding(1); - let submit_container = Container::new(submit_container) - .style(grin_gui_core::theme::ContainerStyle::Segmented) - .padding(1); - - let cancel_container = Container::new(cancel_button.map(Message::Interaction)).padding(1); - let cancel_container = Container::new(cancel_container) - .style(grin_gui_core::theme::ContainerStyle::Segmented) - .padding(1); - - let button_row = Row::new() - .push(submit_container) - .push(Space::new(Length::Fixed(unit_spacing), Length::Fixed(0.0))) - .push(cancel_container); - - let mut column = Column::new() - .push(recipient_address_container) - .push(Space::new(Length::Fixed(0.0), Length::Fixed(unit_spacing))) - .push(address_instruction_container) - .push(Space::new(Length::Fixed(0.0), Length::Fixed(unit_spacing))) - .push(address_row) - .push(Space::new(Length::Fixed(0.0), Length::Fixed(unit_spacing))); - - if state.slatepack_address_error { - column = column - .push(address_error_container) - .push(Space::new(Length::Fixed(0.0), Length::Fixed(unit_spacing))); - } - - if !state.is_self_send { - column = column - .push(radio_column) - .push(Space::new(Length::Fixed(0.0), Length::Fixed(unit_spacing))) - .push(amount_container) - .push(Space::new(Length::Fixed(0.0), Length::Fixed(unit_spacing))) - .push(amount_input.map(Message::Interaction)) - .push(Space::new(Length::Fixed(0.0), Length::Fixed(unit_spacing))); - } - - if state.amount_error { - column = column - .push(amount_error_container) - .push(Space::new(Length::Fixed(0.0), Length::Fixed(unit_spacing))); - } - - column = column - .push(button_row) - .push(Space::new(Length::Fixed(0.0), Length::Fixed(unit_spacing))) - .push(Space::new( - Length::Fixed(0.0), - Length::Fixed(unit_spacing + 10.0), - )); - - let form_container = Container::new(column) - .width(Length::Fill) - .padding(iced::Padding::from([ - 0, // top - 0, // right - 0, // bottom - 5, // left - ])); - - // form container should be scrollable in tiny windows - let scrollable = Scrollable::new(form_container) - .height(Length::Fill) - .style(grin_gui_core::theme::ScrollableStyle::Primary); - - let content = Container::new(scrollable) - .width(Length::Fill) - .height(Length::Shrink) - .style(grin_gui_core::theme::ContainerStyle::NormalBackground); - - let wrapper_column = Column::new() - .height(Length::Fill) - .push(header_container) - .push(content); - - // Returns the final container. - Container::new(wrapper_column).padding(iced::Padding::from([ - DEFAULT_PADDING, // top - DEFAULT_PADDING, // right - DEFAULT_PADDING, // bottom - DEFAULT_PADDING, // left - ])) + let unit_spacing = 15.0; + + // Title row + let title = Text::new(localized_string("wallet-create-contract")) + .size(DEFAULT_HEADER_FONT_SIZE) + .horizontal_alignment(alignment::Horizontal::Center); + + let title_container = Container::new(title) + .style(grin_gui_core::theme::ContainerStyle::BrightBackground) + .padding(iced::Padding::from([ + 2, // top + 0, // right + 2, // bottom + 5, // left + ])); + + // push more items on to header here: e.g. other buttons, things that belong on the header + let header_row = Row::new().push(title_container); + + let header_container = Container::new(header_row).padding(iced::Padding::from([ + 0, // top + 0, // right + DEFAULT_PADDING as u16, // bottom + 0, // left + ])); + + let recipient_address = Text::new(localized_string("wallet-create-contract-other-address")) + .size(DEFAULT_FONT_SIZE) + .horizontal_alignment(alignment::Horizontal::Left); + + let recipient_address_container = Container::new(recipient_address) + .style(grin_gui_core::theme::ContainerStyle::NormalBackground); + + let recipient_address_input = TextInput::new("", &state.recipient_address_value) + .on_input(|s| { + Interaction::WalletOperationCreateTxContractsViewInteraction( + LocalViewInteraction::RecipientAddress(s), + ) + }) + .size(DEFAULT_FONT_SIZE) + .padding(6) + .width(Length::Fixed(400.0)) + .style(grin_gui_core::theme::TextInputStyle::AddonsQuery); + + let recipient_address_input: Element = recipient_address_input.into(); + + /*let self_send_check = Text::new(localized_string("wallet-self-send")) + .size(DEFAULT_FONT_SIZE) + .horizontal_alignment(alignment::Horizontal::Left); + + let self_send_container = Container::new(self_send_check) + .style(grin_gui_core::theme::ContainerStyle::NormalBackground);*/ + + let checkbox_column = { + let checkbox = Checkbox::new( + localized_string("wallet-self-send"), + state.is_self_send, + |v| { + Interaction::WalletOperationCreateTxContractsViewInteraction( + LocalViewInteraction::SelfSendSelected(v), + ) + }, + ) + .style(grin_gui_core::theme::CheckboxStyle::Normal) + .text_size(DEFAULT_FONT_SIZE) + .spacing(5); + + let checkbox: Element = checkbox.into(); + + let checkbox_container = Container::new(checkbox.map(Message::Interaction)) + .style(grin_gui_core::theme::ContainerStyle::NormalBackground) + .align_y(alignment::Vertical::Bottom); + Column::new().push(checkbox_container) + }; + + let address_row = Row::new() + //.push(recipient_address_container) + .push(recipient_address_input.map(Message::Interaction)) + .push(Space::new(Length::Fixed(unit_spacing), Length::Fixed(0.0))) + .push(checkbox_column) + .align_items(Alignment::End); + + let a: Element = Radio::new( + localized_string("tx-contract-debit"), + ContributionChoice::Debit, + Some(state.contribution_choice), + |c| { + Interaction::WalletOperationCreateTxContractsViewInteraction( + LocalViewInteraction::ContributionChoice(c), + ) + }, + ) + .style(grin_gui_core::theme::radio::RadioStyle::Primary) + .into(); + + let b: Element = Radio::new( + localized_string("tx-contract-credit"), + ContributionChoice::Credit, + Some(state.contribution_choice), + |c| { + Interaction::WalletOperationCreateTxContractsViewInteraction( + LocalViewInteraction::ContributionChoice(c), + ) + }, + ) + .style(grin_gui_core::theme::radio::RadioStyle::Primary) + .into(); + + let radio_column = Column::new() + .push(a.map(Message::Interaction)) + .push(b.map(Message::Interaction)); + + let address_error = Text::new(localized_string("create-tx-address-error")) + .size(DEFAULT_FONT_SIZE) + .horizontal_alignment(alignment::Horizontal::Left) + .style(grin_gui_core::theme::text::TextStyle::Warning); + + let address_error_container = + Container::new(address_error).style(grin_gui_core::theme::ContainerStyle::NormalBackground); + + let amount = Text::new(localized_string("create-tx-amount")) + .size(DEFAULT_FONT_SIZE) + .horizontal_alignment(alignment::Horizontal::Left); + + let amount_container = + Container::new(amount).style(grin_gui_core::theme::ContainerStyle::NormalBackground); + + let amount_input = TextInput::new( + // &mut state.amount_input_state, + "", + &state.amount_value, + ) + .on_input(|s| { + Interaction::WalletOperationCreateTxContractsViewInteraction(LocalViewInteraction::Amount( + s, + )) + }) + .size(DEFAULT_FONT_SIZE) + .padding(6) + .width(Length::Fixed(100.0)) + .style(grin_gui_core::theme::TextInputStyle::AddonsQuery); + + let amount_input: Element = amount_input.into(); + + let amount_error = Text::new(localized_string("create-tx-amount-error")) + .size(DEFAULT_FONT_SIZE) + .horizontal_alignment(alignment::Horizontal::Left) + .style(grin_gui_core::theme::text::TextStyle::Warning); + + let amount_error_container = + Container::new(amount_error).style(grin_gui_core::theme::ContainerStyle::NormalBackground); + + let address_instruction_container = + Text::new(localized_string("recipient-address-instruction-contract")) + .size(SMALLER_FONT_SIZE) + .horizontal_alignment(alignment::Horizontal::Left); + + let address_instruction_container = + Container::new(address_instruction_container).style(ContainerStyle::NormalBackground); + + let button_height = Length::Fixed(BUTTON_HEIGHT); + let button_width = Length::Fixed(BUTTON_WIDTH); + + let submit_button_label_container = + Container::new(Text::new(localized_string("tx-create-submit")).size(DEFAULT_FONT_SIZE)) + .width(button_width) + .height(button_height) + .center_x() + .center_y() + .align_x(alignment::Horizontal::Center); + + let mut submit_button = Button::new(submit_button_label_container) + .style(grin_gui_core::theme::ButtonStyle::Primary); + let submit_button = submit_button.on_press( + Interaction::WalletOperationCreateTxContractsViewInteraction( + LocalViewInteraction::CreateTransaction(), + ), + ); + let submit_button: Element = submit_button.into(); + + let cancel_button_label_container = + Container::new(Text::new(localized_string("cancel")).size(DEFAULT_FONT_SIZE)) + .width(button_width) + .height(button_height) + .center_x() + .center_y() + .align_x(alignment::Horizontal::Center); + + let cancel_button: Element = Button::new(cancel_button_label_container) + .style(grin_gui_core::theme::ButtonStyle::Primary) + .on_press( + Interaction::WalletOperationCreateTxContractsViewInteraction( + LocalViewInteraction::Back, + ), + ) + .into(); + + let submit_container = Container::new(submit_button.map(Message::Interaction)).padding(1); + let submit_container = Container::new(submit_container) + .style(grin_gui_core::theme::ContainerStyle::Segmented) + .padding(1); + + let cancel_container = Container::new(cancel_button.map(Message::Interaction)).padding(1); + let cancel_container = Container::new(cancel_container) + .style(grin_gui_core::theme::ContainerStyle::Segmented) + .padding(1); + + let button_row = Row::new() + .push(submit_container) + .push(Space::new(Length::Fixed(unit_spacing), Length::Fixed(0.0))) + .push(cancel_container); + + let mut column = Column::new() + .push(recipient_address_container) + .push(Space::new(Length::Fixed(0.0), Length::Fixed(unit_spacing))) + .push(address_instruction_container) + .push(Space::new(Length::Fixed(0.0), Length::Fixed(unit_spacing))) + .push(address_row) + .push(Space::new(Length::Fixed(0.0), Length::Fixed(unit_spacing))); + + if state.slatepack_address_error { + column = column + .push(address_error_container) + .push(Space::new(Length::Fixed(0.0), Length::Fixed(unit_spacing))); + } + + if !state.is_self_send { + column = column + .push(radio_column) + .push(Space::new(Length::Fixed(0.0), Length::Fixed(unit_spacing))) + .push(amount_container) + .push(Space::new(Length::Fixed(0.0), Length::Fixed(unit_spacing))) + .push(amount_input.map(Message::Interaction)) + .push(Space::new(Length::Fixed(0.0), Length::Fixed(unit_spacing))); + } + + if state.amount_error { + column = column + .push(amount_error_container) + .push(Space::new(Length::Fixed(0.0), Length::Fixed(unit_spacing))); + } + + column = column + .push(button_row) + .push(Space::new(Length::Fixed(0.0), Length::Fixed(unit_spacing))) + .push(Space::new( + Length::Fixed(0.0), + Length::Fixed(unit_spacing + 10.0), + )); + + let form_container = Container::new(column) + .width(Length::Fill) + .padding(iced::Padding::from([ + 0, // top + 0, // right + 0, // bottom + 5, // left + ])); + + // form container should be scrollable in tiny windows + let scrollable = Scrollable::new(form_container) + .height(Length::Fill) + .style(grin_gui_core::theme::ScrollableStyle::Primary); + + let content = Container::new(scrollable) + .width(Length::Fill) + .height(Length::Shrink) + .style(grin_gui_core::theme::ContainerStyle::NormalBackground); + + let wrapper_column = Column::new() + .height(Length::Fill) + .push(header_container) + .push(content); + + // Returns the final container. + Container::new(wrapper_column).padding(iced::Padding::from([ + DEFAULT_PADDING, // top + DEFAULT_PADDING, // right + DEFAULT_PADDING, // bottom + DEFAULT_PADDING, // left + ])) } diff --git a/src/gui/element/wallet/operation/home.rs b/src/gui/element/wallet/operation/home.rs index ddd18c6..2bbb959 100644 --- a/src/gui/element/wallet/operation/home.rs +++ b/src/gui/element/wallet/operation/home.rs @@ -1,8 +1,8 @@ use super::tx_list::{HeaderState, TxList, TxLogEntryWrap}; use super::{action_menu, tx_list_display}; use super::{ - chart::BalanceChart, - tx_list::{self, ExpandType}, + chart::BalanceChart, + tx_list::{self, ExpandType}, }; use async_std::{prelude::FutureExt, task::current}; use chrono::{DateTime, DurationRound, TimeZone, Utc}; @@ -10,16 +10,16 @@ use grin_gui_core::error::GrinWalletInterfaceError; use grin_gui_core::node::SyncStatus; use grin_gui_core::wallet::SlatepackAddress; use grin_gui_core::{ - config::{Config, Currency}, - wallet::{InvoiceProof, RetrieveTxQueryArgs, TxLogEntry, TxLogEntryType}, + config::{Config, Currency}, + wallet::{InvoiceProof, RetrieveTxQueryArgs, TxLogEntry, TxLogEntryType}, }; use grin_gui_widgets::widget::header; use iced::Point; use iced_aw::Card; use iced_core::Widget; use plotters::{ - coord::{types::RangedCoordf32, ReverseCoordTranslate}, - prelude::*, + coord::{types::RangedCoordf32, ReverseCoordTranslate}, + prelude::*, }; use serde::{Deserialize, Serialize}; use std::cell::RefCell; @@ -28,872 +28,871 @@ use std::io::Read; use std::{collections::HashMap, path::PathBuf}; use { - super::super::super::{ - DEFAULT_FONT_SIZE, DEFAULT_HEADER_FONT_SIZE, DEFAULT_PADDING, DEFAULT_SUB_HEADER_FONT_SIZE, - SMALLER_FONT_SIZE, - }, - crate::gui::{GrinGui, Interaction, Message}, - crate::localization::localized_string, - crate::log_error, - crate::Result, - anyhow::Context, - grin_gui_core::theme::{ - Button, Column, Container, Element, Header, PickList, Row, Scrollable, TableRow, Text, - TextInput, - }, - grin_gui_core::wallet::{StatusMessage, WalletInfo, WalletInterface}, - grin_gui_core::{ - node::{amount_to_hr_string, ServerStats}, - theme::ColorPalette, - }, - iced::widget::{button, pick_list, scrollable, text_input, Checkbox, Space}, - iced::{alignment, Alignment, Command, Length}, - std::sync::{Arc, RwLock}, + super::super::super::{ + DEFAULT_FONT_SIZE, DEFAULT_HEADER_FONT_SIZE, DEFAULT_PADDING, DEFAULT_SUB_HEADER_FONT_SIZE, + SMALLER_FONT_SIZE, + }, + crate::gui::{GrinGui, Interaction, Message}, + crate::localization::localized_string, + crate::log_error, + crate::Result, + anyhow::Context, + grin_gui_core::theme::{ + Button, Column, Container, Element, Header, PickList, Row, Scrollable, TableRow, Text, + TextInput, + }, + grin_gui_core::wallet::{StatusMessage, WalletInfo, WalletInterface}, + grin_gui_core::{ + node::{amount_to_hr_string, ServerStats}, + theme::ColorPalette, + }, + iced::widget::{button, pick_list, scrollable, text_input, Checkbox, Space}, + iced::{alignment, Alignment, Command, Length}, + std::sync::{Arc, RwLock}, }; #[derive(Default)] pub struct StateContainer { - pub action_menu_state: action_menu::StateContainer, - pub tx_list_display_state: tx_list_display::StateContainer, - pub address_value: Option, - pub address: Option, - - wallet_info: Option, - wallet_status: String, - last_summary_update: chrono::DateTime, - tx_header_state: HeaderState, - node_status: Option, - pub node_synched: bool, - - cursor_index: Option, - caption_index: Option, - price_history: HashMap, f64>, + pub action_menu_state: action_menu::StateContainer, + pub tx_list_display_state: tx_list_display::StateContainer, + pub address_value: Option, + pub address: Option, + + wallet_info: Option, + wallet_status: String, + last_summary_update: chrono::DateTime, + tx_header_state: HeaderState, + node_status: Option, + pub node_synched: bool, + + cursor_index: Option, + caption_index: Option, + price_history: HashMap, f64>, } impl StateContainer { - pub fn parse_node_status(&self) -> String { - // Node status string - // BodySync - match &self.node_status { - Some(s) => match s.sync_status { - SyncStatus::NoSync => localized_string("node-synched"), - _ => localized_string("node-unsynched"), - }, - None => localized_string("unknown"), - } - } - pub fn update_node_status(&mut self, stats: &ServerStats) { - self.node_status = Some(stats.clone()); - match stats.sync_status { - SyncStatus::NoSync => self.node_synched = true, - _ => self.node_synched = false, - } - } + pub fn parse_node_status(&self) -> String { + // Node status string + // BodySync + match &self.node_status { + Some(s) => match s.sync_status { + SyncStatus::NoSync => localized_string("node-synched"), + _ => localized_string("node-unsynched"), + }, + None => localized_string("unknown"), + } + } + pub fn update_node_status(&mut self, stats: &ServerStats) { + self.node_status = Some(stats.clone()); + match stats.sync_status { + SyncStatus::NoSync => self.node_synched = true, + _ => self.node_synched = false, + } + } } #[derive(Debug, Clone)] pub enum LocalViewInteraction { - Back, - Submit, - /// was updated from node, info - WalletInfoUpdateSuccess(bool, WalletInfo), - WalletInfoUpdateFailure(Arc>>), - WalletSlatepackAddressUpdateSuccess((String, SlatepackAddress)), - WalletCloseError(Arc>>), - WalletCloseSuccess, - CancelTx(u32, String), - TxDetails(TxLogEntryWrap), - TxProof(TxLogEntryWrap), - TxCancelledOk(u32, String), - TxCancelError(Arc>>), - ProofRetrievedOk(InvoiceProof, TxLogEntryWrap), - ProofRetrievedError(Arc>>), - ReloadTxSlate(String), - - // chart stuff - MouseIndex(usize, usize), - MouseExit, - UpdatePrices, + Back, + Submit, + /// was updated from node, info + WalletInfoUpdateSuccess(bool, WalletInfo), + WalletInfoUpdateFailure(Arc>>), + WalletSlatepackAddressUpdateSuccess((String, SlatepackAddress)), + WalletCloseError(Arc>>), + WalletCloseSuccess, + CancelTx(u32, String), + TxDetails(TxLogEntryWrap), + TxProof(TxLogEntryWrap), + TxCancelledOk(u32, String), + TxCancelError(Arc>>), + ProofRetrievedOk(InvoiceProof, TxLogEntryWrap), + ProofRetrievedError(Arc>>), + ReloadTxSlate(String), + + // chart stuff + MouseIndex(usize, usize), + MouseExit, + UpdatePrices, } /// update the historical price data fn update_prices(state: &mut StateContainer, currency: Currency) -> Result<()> { - // if we are using grin, we don't need to update the price history - if currency == Currency::GRIN { - return Ok(()); - } - - #[derive(Deserialize, Serialize, Debug)] - struct Price { - time: u64, - price: f64, - } - - #[derive(Deserialize, Serialize, Debug)] - struct PriceHistory { - prices: Vec, - } - - // pull price history from coingecko - // TODO this url should not be hardcoded - let price_history_url = format!("https://api.coingecko.com/api/v3/coins/grin/market_chart?vs_currency={}&days=11430&interval=daily", currency.shortname()); - let mut res = reqwest::blocking::get(price_history_url)?; - let mut body = String::new(); - res.read_to_string(&mut body)?; - - //debug!("price history data: {:#?}", body); - let history = serde_json::from_str::(&body).unwrap(); - - let mut prices = std::collections::HashMap::new(); - for price in history.prices { - let date_time = Utc.timestamp_millis_opt(price.time as i64).unwrap(); - prices.insert(date_time, price.price); - } - - // update the price hashmap in the state - state.price_history = prices; - Ok(()) + // if we are using grin, we don't need to update the price history + if currency == Currency::GRIN { + return Ok(()); + } + + #[derive(Deserialize, Serialize, Debug)] + struct Price { + time: u64, + price: f64, + } + + #[derive(Deserialize, Serialize, Debug)] + struct PriceHistory { + prices: Vec, + } + + // pull price history from coingecko + // TODO this url should not be hardcoded + let price_history_url = format!("https://api.coingecko.com/api/v3/coins/grin/market_chart?vs_currency={}&days=11430&interval=daily", currency.shortname()); + let mut res = reqwest::blocking::get(price_history_url)?; + let mut body = String::new(); + res.read_to_string(&mut body)?; + + //debug!("price history data: {:#?}", body); + let history = serde_json::from_str::(&body).unwrap(); + + let mut prices = std::collections::HashMap::new(); + for price in history.prices { + let date_time = Utc.timestamp_millis_opt(price.time as i64).unwrap(); + prices.insert(date_time, price.price); + } + + // update the price hashmap in the state + state.price_history = prices; + Ok(()) } // Okay to modify state and access wallet here pub fn handle_tick<'a>( - grin_gui: &mut GrinGui, - time: chrono::DateTime, + grin_gui: &mut GrinGui, + time: chrono::DateTime, ) -> Result> { - { - let w = grin_gui.wallet_interface.read().unwrap(); - if !w.wallet_is_open() { - return Ok(Command::none()); - } - } - let messages = WalletInterface::get_wallet_updater_status(grin_gui.wallet_interface.clone())?; - let state = &mut grin_gui.wallet_state.operation_state.home_state; - let last_message = messages.get(0); - if let Some(m) = last_message { - state.wallet_status = match m { - StatusMessage::UpdatingOutputs(s) => format!("{}", s), - StatusMessage::UpdatingTransactions(s) => format!("{}", s), - StatusMessage::FullScanWarn(s) => format!("{}", s), - StatusMessage::Scanning(s, m) => format!("Scanning - {}% complete", m), - StatusMessage::ScanningComplete(s) => format!("{}", s), - StatusMessage::UpdateWarning(s) => format!("{}", s), - } - } - - // don't display status if node is still synching - if !state.node_synched { - state.wallet_status = localized_string("awaiting-sync"); - } - - // calls to API should be limited to once per minute - if time - state.last_summary_update - > chrono::Duration::from_std(std::time::Duration::from_secs(60)).unwrap() - { - update_prices(state, grin_gui.config.currency)?; - } - - if time - state.last_summary_update - > chrono::Duration::from_std(std::time::Duration::from_secs(10)).unwrap() - { - state.last_summary_update = chrono::Local::now(); - - let mut query_args = RetrieveTxQueryArgs::default(); - - query_args.exclude_cancelled = Some(true); - query_args.include_outstanding_only = Some(true); - - let w = grin_gui.wallet_interface.clone(); - let node_synched = state.node_synched; - - let fut = move || WalletInterface::get_wallet_info(w.clone(), node_synched); //.join(WalletInterface::get_txs(w, Some(query_args))); - - return Ok(Command::perform(fut(), |wallet_info_res| { - if wallet_info_res.is_err() { - let e = wallet_info_res - .context("Failed to retrieve wallet info status") - .unwrap_err(); - return Message::Interaction(Interaction::WalletOperationHomeViewInteraction( - LocalViewInteraction::WalletInfoUpdateFailure(Arc::new(RwLock::new(Some(e)))), - )); - } - let (node_success, wallet_info) = wallet_info_res.unwrap(); - //let (_, txs) = txs_res.unwrap(); - Message::Interaction(Interaction::WalletOperationHomeViewInteraction( - //LocalViewInteraction::WalletInfoUpdateSuccess(node_success, wallet_info, txs), - LocalViewInteraction::WalletInfoUpdateSuccess(node_success, wallet_info), - )) - })); - } - // If slatepack address is not filled out, go get it - if state.address_value.is_none() { - let w = grin_gui.wallet_interface.clone(); - - let fut = move || WalletInterface::get_slatepack_address(w.clone()); - return Ok(Command::perform(fut(), |get_slatepack_address_res| { - if get_slatepack_address_res.is_err() { - let e = get_slatepack_address_res - .context("Failed to retrieve wallet slatepack address") - .unwrap_err(); - return Message::Interaction(Interaction::WalletOperationHomeViewInteraction( - LocalViewInteraction::WalletInfoUpdateFailure(Arc::new(RwLock::new(Some(e)))), - )); - } - Message::Interaction(Interaction::WalletOperationHomeViewInteraction( - LocalViewInteraction::WalletSlatepackAddressUpdateSuccess( - get_slatepack_address_res.unwrap(), - ), - )) - })); - } - - Ok(Command::none()) + { + let w = grin_gui.wallet_interface.read().unwrap(); + if !w.wallet_is_open() { + return Ok(Command::none()); + } + } + let messages = WalletInterface::get_wallet_updater_status(grin_gui.wallet_interface.clone())?; + let state = &mut grin_gui.wallet_state.operation_state.home_state; + let last_message = messages.get(0); + if let Some(m) = last_message { + state.wallet_status = match m { + StatusMessage::UpdatingOutputs(s) => format!("{}", s), + StatusMessage::UpdatingTransactions(s) => format!("{}", s), + StatusMessage::FullScanWarn(s) => format!("{}", s), + StatusMessage::Scanning(s, m) => format!("Scanning - {}% complete", m), + StatusMessage::ScanningComplete(s) => format!("{}", s), + StatusMessage::UpdateWarning(s) => format!("{}", s), + } + } + + // don't display status if node is still synching + if !state.node_synched { + state.wallet_status = localized_string("awaiting-sync"); + } + + // calls to API should be limited to once per minute + if time - state.last_summary_update + > chrono::Duration::from_std(std::time::Duration::from_secs(60)).unwrap() + { + update_prices(state, grin_gui.config.currency)?; + } + + if time - state.last_summary_update + > chrono::Duration::from_std(std::time::Duration::from_secs(10)).unwrap() + { + state.last_summary_update = chrono::Local::now(); + + let mut query_args = RetrieveTxQueryArgs::default(); + + query_args.exclude_cancelled = Some(true); + query_args.include_outstanding_only = Some(true); + + let w = grin_gui.wallet_interface.clone(); + let node_synched = state.node_synched; + + let fut = move || WalletInterface::get_wallet_info(w.clone(), node_synched); //.join(WalletInterface::get_txs(w, Some(query_args))); + + return Ok(Command::perform(fut(), |wallet_info_res| { + if wallet_info_res.is_err() { + let e = wallet_info_res + .context("Failed to retrieve wallet info status") + .unwrap_err(); + return Message::Interaction(Interaction::WalletOperationHomeViewInteraction( + LocalViewInteraction::WalletInfoUpdateFailure(Arc::new(RwLock::new(Some(e)))), + )); + } + let (node_success, wallet_info) = wallet_info_res.unwrap(); + //let (_, txs) = txs_res.unwrap(); + Message::Interaction(Interaction::WalletOperationHomeViewInteraction( + //LocalViewInteraction::WalletInfoUpdateSuccess(node_success, wallet_info, txs), + LocalViewInteraction::WalletInfoUpdateSuccess(node_success, wallet_info), + )) + })); + } + // If slatepack address is not filled out, go get it + if state.address_value.is_none() { + let w = grin_gui.wallet_interface.clone(); + + let fut = move || WalletInterface::get_slatepack_address(w.clone()); + return Ok(Command::perform(fut(), |get_slatepack_address_res| { + if get_slatepack_address_res.is_err() { + let e = get_slatepack_address_res + .context("Failed to retrieve wallet slatepack address") + .unwrap_err(); + return Message::Interaction(Interaction::WalletOperationHomeViewInteraction( + LocalViewInteraction::WalletInfoUpdateFailure(Arc::new(RwLock::new(Some(e)))), + )); + } + Message::Interaction(Interaction::WalletOperationHomeViewInteraction( + LocalViewInteraction::WalletSlatepackAddressUpdateSuccess( + get_slatepack_address_res.unwrap(), + ), + )) + })); + } + + Ok(Command::none()) } pub fn handle_message<'a>( - grin_gui: &mut GrinGui, - message: LocalViewInteraction, + grin_gui: &mut GrinGui, + message: LocalViewInteraction, ) -> Result> { - let state = &mut grin_gui.wallet_state.operation_state.home_state; - match message { - LocalViewInteraction::UpdatePrices => { - update_prices(state, grin_gui.config.currency)?; - } - LocalViewInteraction::MouseIndex(index1, index2) => { - state.cursor_index = Some(index1); - state.caption_index = Some(index2); - } - LocalViewInteraction::MouseExit => { - state.cursor_index = None; - state.caption_index = None; - } - LocalViewInteraction::Back => { - let wallet_interface = grin_gui.wallet_interface.clone(); - let fut = WalletInterface::close_wallet(wallet_interface); - - return Ok(Command::perform(fut, |r| { - match r.context("Failed to close wallet") { - Ok(()) => { - Message::Interaction(Interaction::WalletOperationHomeViewInteraction( - LocalViewInteraction::WalletCloseSuccess, - )) - } - Err(e) => { - Message::Interaction(Interaction::WalletOperationHomeViewInteraction( - LocalViewInteraction::WalletCloseError(Arc::new(RwLock::new(Some(e)))), - )) - } - } - })); - } - LocalViewInteraction::Submit => {} - LocalViewInteraction::WalletInfoUpdateSuccess(node_success, wallet_info) => { - debug!( - "Update Wallet Info Summary: {}, {:?}", - node_success, wallet_info - ); - // check if different from last update, if so refresh the current transaction listing - if state.wallet_info.as_ref() != Some(&wallet_info) { - // If transaction list hasn't been init yet, refresh the list with latest - debug!( - "Updating transactions based on new wallet info data: {:?} (old) vs {:?} (new)", - state.wallet_info.as_ref(), - wallet_info - ); - state.wallet_info = Some(wallet_info); - if grin_gui - .wallet_state - .operation_state - .home_state - .tx_list_display_state - .mode - == crate::gui::element::wallet::operation::tx_list_display::Mode::NotInit - { - let fut = move || async {}; - return Ok(Command::perform(fut(), |_| { - return Message::Interaction( + let state = &mut grin_gui.wallet_state.operation_state.home_state; + match message { + LocalViewInteraction::UpdatePrices => { + update_prices(state, grin_gui.config.currency)?; + } + LocalViewInteraction::MouseIndex(index1, index2) => { + state.cursor_index = Some(index1); + state.caption_index = Some(index2); + } + LocalViewInteraction::MouseExit => { + state.cursor_index = None; + state.caption_index = None; + } + LocalViewInteraction::Back => { + let wallet_interface = grin_gui.wallet_interface.clone(); + let fut = WalletInterface::close_wallet(wallet_interface); + + return Ok(Command::perform(fut, |r| { + match r.context("Failed to close wallet") { + Ok(()) => { + Message::Interaction(Interaction::WalletOperationHomeViewInteraction( + LocalViewInteraction::WalletCloseSuccess, + )) + } + Err(e) => { + Message::Interaction(Interaction::WalletOperationHomeViewInteraction( + LocalViewInteraction::WalletCloseError(Arc::new(RwLock::new(Some(e)))), + )) + } + } + })); + } + LocalViewInteraction::Submit => {} + LocalViewInteraction::WalletInfoUpdateSuccess(node_success, wallet_info) => { + debug!( + "Update Wallet Info Summary: {}, {:?}", + node_success, wallet_info + ); + // check if different from last update, if so refresh the current transaction listing + if state.wallet_info.as_ref() != Some(&wallet_info) { + // If transaction list hasn't been init yet, refresh the list with latest + debug!( + "Updating transactions based on new wallet info data: {:?} (old) vs {:?} (new)", + state.wallet_info.as_ref(), + wallet_info + ); + state.wallet_info = Some(wallet_info); + if grin_gui + .wallet_state + .operation_state + .home_state + .tx_list_display_state + .mode == crate::gui::element::wallet::operation::tx_list_display::Mode::NotInit + { + let fut = move || async {}; + return Ok(Command::perform(fut(), |_| { + return Message::Interaction( Interaction::WalletOperationHomeTxListDisplayInteraction( crate::gui::element::wallet::operation::tx_list_display::LocalViewInteraction::SelectMode( crate::gui::element::wallet::operation::tx_list_display::Mode::Recent ), ), ); - })); - } else { - let fut = move || async {}; - return Ok(Command::perform(fut(), |_| { - return Message::Interaction( + })); + } else { + let fut = move || async {}; + return Ok(Command::perform(fut(), |_| { + return Message::Interaction( Interaction::WalletOperationHomeTxListDisplayInteraction( crate::gui::element::wallet::operation::tx_list_display::LocalViewInteraction::RefreshList , ), ); - })); - } - } - } - LocalViewInteraction::WalletInfoUpdateFailure(err) => { - grin_gui.error = err.write().unwrap().take(); - if let Some(e) = grin_gui.error.as_ref() { - log_error(e); - } - } - LocalViewInteraction::WalletCloseSuccess => { - // Also blank out all relevant info first, and perform all shutdown - // so it doesn't appear when opening another wallet - state.wallet_info = None; - state.address_value = None; - state.address = None; - grin_gui - .wallet_state - .operation_state - .tx_detail_state - .current_tx = None; - - grin_gui.wallet_state.operation_state.mode = - crate::gui::element::wallet::operation::Mode::Open; - } - LocalViewInteraction::WalletCloseError(err) => { - grin_gui.error = err.write().unwrap().take(); - if let Some(e) = grin_gui.error.as_ref() { - log_error(e); - } - } - LocalViewInteraction::WalletSlatepackAddressUpdateSuccess((address_string, address)) => { - state.address_value = Some(address_string); - state.address = Some(address); - } - LocalViewInteraction::TxDetails(tx_log_entry_wrap) => { - log::debug!("Interaction::WalletOperationHomeViewInteraction::TxDetails"); - grin_gui - .wallet_state - .operation_state - .tx_detail_state - .current_tx = Some(tx_log_entry_wrap.tx); - grin_gui.wallet_state.operation_state.mode = - crate::gui::element::wallet::operation::Mode::TxDetail; - } - LocalViewInteraction::TxProof(tx_log_entry_wrap) => { - log::debug!("Interaction::WalletOperationHomeViewInteraction::TxProof"); - grin_gui.error.take(); - - let w = grin_gui.wallet_interface.clone(); - let fut = move || { - WalletInterface::retrieve_payment_proof_invoice(w, Some(tx_log_entry_wrap.tx.id)) - }; - - return Ok(Command::perform(fut(), |r| { - match r.context("Failed to Retrieve Invoice Proof") { - Ok(ret) => { - Message::Interaction(Interaction::WalletOperationHomeViewInteraction( - LocalViewInteraction::ProofRetrievedOk(ret, tx_log_entry_wrap), - )) - } - Err(e) => { - Message::Interaction(Interaction::WalletOperationHomeViewInteraction( - LocalViewInteraction::ProofRetrievedError(Arc::new(RwLock::new(Some( - e, - )))), - )) - } - } - })); - } - LocalViewInteraction::CancelTx(id, uuid) => { - debug!("Cancel Tx: {}", id); - grin_gui.error.take(); - - log::debug!("Interaction::WalletOperationHomeViewInteraction::CancelTx"); - - let w = grin_gui.wallet_interface.clone(); - - let fut = move || WalletInterface::cancel_tx(w, id); - - return Ok(Command::perform(fut(), |r| { - match r.context("Failed to Cancel Transaction") { - Ok(ret) => { - Message::Interaction(Interaction::WalletOperationHomeViewInteraction( - LocalViewInteraction::TxCancelledOk(ret, uuid), - )) - } - Err(e) => { - Message::Interaction(Interaction::WalletOperationHomeViewInteraction( - LocalViewInteraction::TxCancelError(Arc::new(RwLock::new(Some(e)))), - )) - } - } - })); - } - LocalViewInteraction::TxCancelledOk(id, uuid) => { - // Delete file - if let Some(dir) = grin_gui.config.get_wallet_slatepack_dir() { - let out_file_name = format!("{}/{}.slatepack", dir, uuid); - let _ = fs::remove_file(out_file_name); - } - - // Trigger event to reload transaction list - let mode = grin_gui - .wallet_state - .operation_state - .home_state - .tx_list_display_state - .mode - .clone(); - let fut = move || async {}; - return Ok(Command::perform(fut(), |r| { - Message::Interaction(Interaction::WalletOperationHomeTxListDisplayInteraction( - super::home::tx_list_display::LocalViewInteraction::SelectMode(mode), - )) - })); - } - LocalViewInteraction::TxCancelError(err) => { - grin_gui.error = err.write().unwrap().take(); - if let Some(e) = grin_gui.error.as_ref() { - log_error(e); - } - } - LocalViewInteraction::ProofRetrievedOk(proof, tx_log_entry_wrap)=> { - grin_gui - .wallet_state - .operation_state - .tx_proof_state - .current_tx = Some(tx_log_entry_wrap.tx); - grin_gui - .wallet_state - .operation_state - .tx_proof_state - .current_proof = Some(proof); - grin_gui.wallet_state.operation_state.mode = - crate::gui::element::wallet::operation::Mode::TxProof; - } - LocalViewInteraction::ProofRetrievedError(err) => { - grin_gui.error = err.write().unwrap().take(); - if let Some(e) = grin_gui.error.as_ref() { - log_error(e); - } - } - LocalViewInteraction::ReloadTxSlate(id) => { - debug!("Reload stored slatepack at: {}", id); - if let Some(dir) = grin_gui.config.get_wallet_slatepack_dir() { - let in_file_name = format!("{}/{}.slatepack", dir, id); - if let Ok(s) = fs::read_to_string(in_file_name.clone()) { - grin_gui - .wallet_state - .operation_state - .show_slatepack_state - .encrypted_slate = Some(s.to_string()); - // Just go to create tx success screen for now - grin_gui.wallet_state.operation_state.mode = - crate::gui::element::wallet::operation::Mode::ShowSlatepack; - } else { - // Error that we're unable to load the file - grin_gui.error = Some( - GrinWalletInterfaceError::InvalidSlatepackFile { file: in_file_name } - .into(), - ); - } - } - } - } - Ok(Command::none()) + })); + } + } + } + LocalViewInteraction::WalletInfoUpdateFailure(err) => { + grin_gui.error = err.write().unwrap().take(); + if let Some(e) = grin_gui.error.as_ref() { + log_error(e); + } + } + LocalViewInteraction::WalletCloseSuccess => { + // Also blank out all relevant info first, and perform all shutdown + // so it doesn't appear when opening another wallet + state.wallet_info = None; + state.address_value = None; + state.address = None; + grin_gui + .wallet_state + .operation_state + .tx_detail_state + .current_tx = None; + + grin_gui.wallet_state.operation_state.mode = + crate::gui::element::wallet::operation::Mode::Open; + } + LocalViewInteraction::WalletCloseError(err) => { + grin_gui.error = err.write().unwrap().take(); + if let Some(e) = grin_gui.error.as_ref() { + log_error(e); + } + } + LocalViewInteraction::WalletSlatepackAddressUpdateSuccess((address_string, address)) => { + state.address_value = Some(address_string); + state.address = Some(address); + } + LocalViewInteraction::TxDetails(tx_log_entry_wrap) => { + log::debug!("Interaction::WalletOperationHomeViewInteraction::TxDetails"); + grin_gui + .wallet_state + .operation_state + .tx_detail_state + .current_tx = Some(tx_log_entry_wrap.tx); + grin_gui.wallet_state.operation_state.mode = + crate::gui::element::wallet::operation::Mode::TxDetail; + } + LocalViewInteraction::TxProof(tx_log_entry_wrap) => { + log::debug!("Interaction::WalletOperationHomeViewInteraction::TxProof"); + grin_gui.error.take(); + + let w = grin_gui.wallet_interface.clone(); + let fut = move || { + WalletInterface::retrieve_payment_proof_invoice(w, Some(tx_log_entry_wrap.tx.id)) + }; + + return Ok(Command::perform(fut(), |r| { + match r.context("Failed to Retrieve Invoice Proof") { + Ok(ret) => { + Message::Interaction(Interaction::WalletOperationHomeViewInteraction( + LocalViewInteraction::ProofRetrievedOk(ret, tx_log_entry_wrap), + )) + } + Err(e) => { + Message::Interaction(Interaction::WalletOperationHomeViewInteraction( + LocalViewInteraction::ProofRetrievedError(Arc::new(RwLock::new(Some( + e, + )))), + )) + } + } + })); + } + LocalViewInteraction::CancelTx(id, uuid) => { + debug!("Cancel Tx: {}", id); + grin_gui.error.take(); + + log::debug!("Interaction::WalletOperationHomeViewInteraction::CancelTx"); + + let w = grin_gui.wallet_interface.clone(); + + let fut = move || WalletInterface::cancel_tx(w, id); + + return Ok(Command::perform(fut(), |r| { + match r.context("Failed to Cancel Transaction") { + Ok(ret) => { + Message::Interaction(Interaction::WalletOperationHomeViewInteraction( + LocalViewInteraction::TxCancelledOk(ret, uuid), + )) + } + Err(e) => { + Message::Interaction(Interaction::WalletOperationHomeViewInteraction( + LocalViewInteraction::TxCancelError(Arc::new(RwLock::new(Some(e)))), + )) + } + } + })); + } + LocalViewInteraction::TxCancelledOk(id, uuid) => { + // Delete file + if let Some(dir) = grin_gui.config.get_wallet_slatepack_dir() { + let out_file_name = format!("{}/{}.slatepack", dir, uuid); + let _ = fs::remove_file(out_file_name); + } + + // Trigger event to reload transaction list + let mode = grin_gui + .wallet_state + .operation_state + .home_state + .tx_list_display_state + .mode + .clone(); + let fut = move || async {}; + return Ok(Command::perform(fut(), |r| { + Message::Interaction(Interaction::WalletOperationHomeTxListDisplayInteraction( + super::home::tx_list_display::LocalViewInteraction::SelectMode(mode), + )) + })); + } + LocalViewInteraction::TxCancelError(err) => { + grin_gui.error = err.write().unwrap().take(); + if let Some(e) = grin_gui.error.as_ref() { + log_error(e); + } + } + LocalViewInteraction::ProofRetrievedOk(proof, tx_log_entry_wrap) => { + grin_gui + .wallet_state + .operation_state + .tx_proof_state + .current_tx = Some(tx_log_entry_wrap.tx); + grin_gui + .wallet_state + .operation_state + .tx_proof_state + .current_proof = Some(proof); + grin_gui.wallet_state.operation_state.mode = + crate::gui::element::wallet::operation::Mode::TxProof; + } + LocalViewInteraction::ProofRetrievedError(err) => { + grin_gui.error = err.write().unwrap().take(); + if let Some(e) = grin_gui.error.as_ref() { + log_error(e); + } + } + LocalViewInteraction::ReloadTxSlate(id) => { + debug!("Reload stored slatepack at: {}", id); + if let Some(dir) = grin_gui.config.get_wallet_slatepack_dir() { + let in_file_name = format!("{}/{}.slatepack", dir, id); + if let Ok(s) = fs::read_to_string(in_file_name.clone()) { + grin_gui + .wallet_state + .operation_state + .show_slatepack_state + .encrypted_slate = Some(s.to_string()); + // Just go to create tx success screen for now + grin_gui.wallet_state.operation_state.mode = + crate::gui::element::wallet::operation::Mode::ShowSlatepack; + } else { + // Error that we're unable to load the file + grin_gui.error = Some( + GrinWalletInterfaceError::InvalidSlatepackFile { file: in_file_name } + .into(), + ); + } + } + } + } + Ok(Command::none()) } pub fn data_container<'a>(config: &'a Config, state: &'a StateContainer) -> Container<'a, Message> { - // Buttons to perform operations go here, but empty container for now - let operations_menu = action_menu::data_container(config, &state.action_menu_state, &state); - - // Basic Info "Box" - let waiting_string = "---------"; - let ( - total_string, - amount_spendable_string, - awaiting_confirmation_string, - awaiting_finalization_string, - locked_string, - ) = match state.wallet_info.as_ref() { - Some(info) => ( - amount_to_hr_string(info.total, false), - amount_to_hr_string(info.amount_currently_spendable, false), - amount_to_hr_string(info.amount_awaiting_confirmation, false), - amount_to_hr_string(info.amount_awaiting_finalization, false), - amount_to_hr_string(info.amount_locked, false), - ), - None => ( - waiting_string.to_owned(), - waiting_string.to_owned(), - waiting_string.to_owned(), - waiting_string.to_owned(), - waiting_string.to_owned(), - ), - }; - - let wallet_name = if let Some(index) = config.current_wallet_index { - config.wallets[index].display_name.clone() - } else { - "wallet".to_owned() - }; - - let currency = config.currency; - let balance = if currency == Currency::GRIN { - amount_spendable_string.clone() - } else if let Some(info) = state.wallet_info.as_ref() { - let today = Utc::now() - .duration_trunc(chrono::Duration::days(1)) - .unwrap(); - - // grap latest price if we don't have one for today - let price = match state.price_history.get(&today) { - Some(price) => *price, - None => { - let prev = today - chrono::Duration::days(1); - *state.price_history.get(&prev).unwrap() - } - }; - - let amount_spendable = info.amount_currently_spendable / grin_gui_core::GRIN_BASE; - let price_adjusted = amount_spendable as f64 * price; - let trunc = format!("{:.1$}", price_adjusted, currency.precision()); - format!("{}{}", currency.symbol(), trunc) - } else { - waiting_string.to_owned() - }; - - // Title row - let title = Text::new(balance).size(DEFAULT_HEADER_FONT_SIZE); - let title_container = - Container::new(title).style(grin_gui_core::theme::ContainerStyle::BrightBackground); - - let subtitle = Text::new(wallet_name).size(SMALLER_FONT_SIZE); - let subtitle_container = Container::new(subtitle) - .style(grin_gui_core::theme::ContainerStyle::NormalBackground) - .padding(iced::Padding::from([ - 3, // top - 0, // right - 0, // bottom - 0, // left - ])); - - let close_wallet_label_container = - Container::new(Text::new(localized_string("close")).size(SMALLER_FONT_SIZE)) - .height(Length::Fixed(14.0)) - .width(Length::Fixed(30.0)) - .center_y() - .center_x(); - - let close_wallet_button: Element = Button::new(close_wallet_label_container) - .style(grin_gui_core::theme::ButtonStyle::Bordered) - .on_press(Interaction::WalletOperationHomeViewInteraction( - LocalViewInteraction::Back, - )) - .padding(2) - .into(); - - let subtitle_row = Row::new() - .push(subtitle_container) - .push(Space::with_width(Length::Fixed(2.0))) - .push(close_wallet_button.map(Message::Interaction)); - - let address_label = Text::new(format!( - "{}: ", - localized_string("this-wallet-receive-addr") - )) - .size(SMALLER_FONT_SIZE); - let address_label_container = Container::new(address_label) - .style(grin_gui_core::theme::ContainerStyle::NormalBackground) - .padding(iced::Padding::from([ - 3, // top - 0, // right - 0, // bottom - 0, // left - ])); - - // Truncate a bit for compact display purposes - let mut copied_address_value = "".into(); - let address = match &state.address_value { - Some(a) => { - let mut s = a.clone(); - copied_address_value = a.clone(); - s.truncate(10); - let s2 = a.clone().split_off(60); - format!("{}...{}", s, s2) - } - None => "".to_owned(), - }; - - let address = Text::new(address).size(SMALLER_FONT_SIZE); - let address_container = Container::new(address) - .style(grin_gui_core::theme::ContainerStyle::NormalBackground) - .padding(iced::Padding::from([ - 3, // top - 0, // right - 0, // bottom - 0, // left - ])); - - let copy_address_label_container = - Container::new(Text::new(localized_string("copy-to-clipboard")).size(SMALLER_FONT_SIZE)) - .height(Length::Fixed(14.0)) - .width(Length::Fixed(30.0)) - .center_y() - .center_x(); - - let copy_address_button: Element = Button::new(copy_address_label_container) - .style(grin_gui_core::theme::ButtonStyle::Bordered) - .on_press(Interaction::WriteToClipboard(copied_address_value)) - .padding(2) - .into(); - - let address_row = Row::new() - .push(address_label_container) - .push(Space::with_width(Length::Fixed(2.0))) - .push(address_container) - .push(Space::with_width(Length::Fixed(2.0))) - .push(copy_address_button.map(Message::Interaction)); - - let title_container = Container::new( - Column::new() - .push(title_container) - .push(subtitle_row) - .push(address_row), - ) - .padding(iced::Padding::from([ - 0, // top - 0, // right - 0, // bottom - 5, // left - ])); - - let header_row = Row::new() - .push(title_container) - .push(Space::with_width(Length::Fill)) - .push(operations_menu); - - let header_container = Container::new(header_row).padding(iced::Padding::from([ - 0, // top - 0, // right - DEFAULT_PADDING as u16, // bottom - 0, // left - ])); - - let total_value_label = - Text::new(format!("{}:", localized_string("info-confirmed-total"))).size(DEFAULT_FONT_SIZE); - let total_value_label_container = Container::new(total_value_label) - .style(grin_gui_core::theme::ContainerStyle::BrightBackground); - - let total_value = Text::new(total_string).size(DEFAULT_FONT_SIZE); - let total_value_container = Container::new(total_value) - .style(grin_gui_core::theme::ContainerStyle::BrightBackground) - .width(Length::Fill) - .align_x(alignment::Horizontal::Right); - - let total_row = Row::new() - .push(total_value_label_container) - .push(total_value_container) - .width(Length::Fill); - - let awaiting_confirmation_label = Text::new(format!( - "{}:", - localized_string("info-awaiting-confirmation") - )) - .size(DEFAULT_FONT_SIZE); - let awaiting_confirmation_label_container = Container::new(awaiting_confirmation_label) - .style(grin_gui_core::theme::ContainerStyle::BrightBackground); - - let awaiting_confirmation_value = - Text::new(awaiting_confirmation_string).size(DEFAULT_FONT_SIZE); - let awaiting_confirmation_value_container = Container::new(awaiting_confirmation_value) - .style(grin_gui_core::theme::ContainerStyle::BrightBackground) - .width(Length::Fill) - .align_x(alignment::Horizontal::Right); - - let awaiting_confirmation_row = Row::new() - .push(awaiting_confirmation_label_container) - .push(awaiting_confirmation_value_container) - .width(Length::Fill); - - let awaiting_finalization_label = Text::new(format!( - "{}:", - localized_string("info-awaiting-finalization") - )) - .size(DEFAULT_FONT_SIZE); - let awaiting_finalization_label_container = Container::new(awaiting_finalization_label) - .style(grin_gui_core::theme::ContainerStyle::BrightBackground); - - let awaiting_finalization_value = - Text::new(awaiting_finalization_string).size(DEFAULT_FONT_SIZE); - let awaiting_finalization_value_container = Container::new(awaiting_finalization_value) - .style(grin_gui_core::theme::ContainerStyle::BrightBackground) - .width(Length::Fill) - .align_x(alignment::Horizontal::Right); - - let awaiting_finalization_row = Row::new() - .push(awaiting_finalization_label_container) - .push(awaiting_finalization_value_container) - .width(Length::Fill); - - let locked_label = - Text::new(format!("{}:", localized_string("info-locked"))).size(DEFAULT_FONT_SIZE); - let locked_label_container = - Container::new(locked_label).style(grin_gui_core::theme::ContainerStyle::BrightBackground); - - let locked_value = Text::new(locked_string).size(DEFAULT_FONT_SIZE); - let locked_value_container = Container::new(locked_value) - .style(grin_gui_core::theme::ContainerStyle::BrightBackground) - .width(Length::Fill) - .align_x(alignment::Horizontal::Right); - - let locked_row = Row::new() - .push(locked_label_container) - .push(locked_value_container) - .width(Length::Fill); - - let amount_spendable_label = - Text::new(format!("{}:", localized_string("info-amount-spendable"))) - .size(DEFAULT_FONT_SIZE); - let amount_spendable_label_container = Container::new(amount_spendable_label) - .style(grin_gui_core::theme::ContainerStyle::BrightBackground); - - let amount_spendable_value = Text::new(amount_spendable_string).size(DEFAULT_FONT_SIZE); - let amount_spendable_value_container = Container::new(amount_spendable_value) - .style(grin_gui_core::theme::ContainerStyle::BrightBackground) - .width(Length::Fill) - .align_x(alignment::Horizontal::Right); - - let amount_spendable_row = Row::new() - .push(amount_spendable_label_container) - .push(amount_spendable_value_container) - .width(Length::Fill); - - let info_column = Column::new() - .push(total_row) - .push(awaiting_confirmation_row) - .push(awaiting_finalization_row) - .push(locked_row) - .push(amount_spendable_row) - .spacing(7); - - let wallet_info_card_container = Container::new(info_column) - .width(Length::Fixed(240.0)) - .padding(iced::Padding::from([ - DEFAULT_PADDING, // top - DEFAULT_PADDING, // right - DEFAULT_PADDING, // bottom - 5.0, // left - ])); - - let mut first_row_container = Row::new() - .push(wallet_info_card_container) - .height(Length::Fixed(120.0)); - - // if there is transaction data, display the balance chart - let mut balance_data = state.tx_list_display_state.balance_data.clone(); - if !balance_data.is_empty() { - // if there is price history data, convert the balance data to the currency - if !state.price_history.is_empty() && currency != Currency::GRIN { - balance_data = balance_data - .iter() - .map(|(date, balance)| { - let price = state.price_history.get(date).unwrap_or(&0.0); - let precision = i32::pow(10, currency.precision() as u32) as f64; - let adjusted_price = f64::trunc(balance * price * precision) / precision; - (date.clone(), adjusted_price) - }) - .collect::>(); - } - - let theme_name = config.theme.clone().unwrap_or("Alliance".to_string()); - let theme = grin_gui_core::theme::Theme::all() - .iter() - .find(|t| t.0 == theme_name) - .unwrap() - .1 - .clone(); - - first_row_container = first_row_container.push(BalanceChart::new( - theme, - balance_data.into_iter().rev(), - state.cursor_index, - state.caption_index, - )); - } - - // Status container element for Node state - let status_container_node_state_label_text = - Text::new(format!("{}: ", localized_string("node-status"))) - .size(DEFAULT_FONT_SIZE) - .height(Length::Fill) - .horizontal_alignment(alignment::Horizontal::Left) - .vertical_alignment(alignment::Vertical::Center); - - let status_container_node_state_text = Text::new(state.parse_node_status()) - .size(DEFAULT_FONT_SIZE) - .height(Length::Fill) - .horizontal_alignment(alignment::Horizontal::Left) - .vertical_alignment(alignment::Vertical::Center); - - // Status container bar at bottom of screen - let status_container_label_text = Text::new(localized_string("wallet-status")) - .size(DEFAULT_FONT_SIZE) - .height(Length::Fill) - .horizontal_alignment(alignment::Horizontal::Right) - .vertical_alignment(alignment::Vertical::Center); - - let status_container_separator_text = Text::new(": ") - .size(DEFAULT_FONT_SIZE) - .height(Length::Fill) - .horizontal_alignment(alignment::Horizontal::Right) - .vertical_alignment(alignment::Vertical::Center); - - let status_container_status_text = Text::new(&state.wallet_status) - .size(DEFAULT_FONT_SIZE) - .height(Length::Fill) - .horizontal_alignment(alignment::Horizontal::Right) - .vertical_alignment(alignment::Vertical::Center); - - let status_container_contents = Row::new() - .push(Space::new( - Length::Fixed(DEFAULT_PADDING), - Length::Fixed(0.0), - )) - .push(status_container_node_state_label_text) - .push(status_container_node_state_text) - .push(Space::new(Length::Fill, Length::Fill)) - .push(status_container_label_text) - .push(status_container_separator_text) - .push(status_container_status_text) - .push(Space::new( - Length::Fixed(DEFAULT_PADDING), - Length::Fixed(0.0), - )); - - let status_container = Container::new(status_container_contents) - .style(grin_gui_core::theme::ContainerStyle::BrightForeground) - .height(Length::Fixed(25.0)) - .width(Length::Fill); - - let status_row = Row::new() - .push(status_container) - .align_items(Alignment::Center) - .spacing(25); - - // Buttons to perform operations go here, but empty container for now - let tx_list_display = - tx_list_display::data_container(config, &state, &state.tx_list_display_state) - .height(Length::Fill); - - // Overall Home screen layout column - let column = Column::new() - .push(header_container) - .push(first_row_container) - .push(Space::with_height(Length::Fixed(DEFAULT_PADDING * 3.0))) - .push(tx_list_display) - .push(Space::with_height(Length::Fixed(DEFAULT_PADDING))) - .push(status_row) - .height(Length::Fill); - - Container::new(column).padding(iced::Padding::from([ - DEFAULT_PADDING, // top - DEFAULT_PADDING, // right - DEFAULT_PADDING, // bottom - DEFAULT_PADDING, // left - ])) + // Buttons to perform operations go here, but empty container for now + let operations_menu = action_menu::data_container(config, &state.action_menu_state, &state); + + // Basic Info "Box" + let waiting_string = "---------"; + let ( + total_string, + amount_spendable_string, + awaiting_confirmation_string, + awaiting_finalization_string, + locked_string, + ) = match state.wallet_info.as_ref() { + Some(info) => ( + amount_to_hr_string(info.total, false), + amount_to_hr_string(info.amount_currently_spendable, false), + amount_to_hr_string(info.amount_awaiting_confirmation, false), + amount_to_hr_string(info.amount_awaiting_finalization, false), + amount_to_hr_string(info.amount_locked, false), + ), + None => ( + waiting_string.to_owned(), + waiting_string.to_owned(), + waiting_string.to_owned(), + waiting_string.to_owned(), + waiting_string.to_owned(), + ), + }; + + let wallet_name = if let Some(index) = config.current_wallet_index { + config.wallets[index].display_name.clone() + } else { + "wallet".to_owned() + }; + + let currency = config.currency; + let balance = if currency == Currency::GRIN { + amount_spendable_string.clone() + } else if let Some(info) = state.wallet_info.as_ref() { + let today = Utc::now() + .duration_trunc(chrono::Duration::days(1)) + .unwrap(); + + // grap latest price if we don't have one for today + let price = match state.price_history.get(&today) { + Some(price) => *price, + None => { + let prev = today - chrono::Duration::days(1); + *state.price_history.get(&prev).unwrap() + } + }; + + let amount_spendable = info.amount_currently_spendable / grin_gui_core::GRIN_BASE; + let price_adjusted = amount_spendable as f64 * price; + let trunc = format!("{:.1$}", price_adjusted, currency.precision()); + format!("{}{}", currency.symbol(), trunc) + } else { + waiting_string.to_owned() + }; + + // Title row + let title = Text::new(balance).size(DEFAULT_HEADER_FONT_SIZE); + let title_container = + Container::new(title).style(grin_gui_core::theme::ContainerStyle::BrightBackground); + + let subtitle = Text::new(wallet_name).size(SMALLER_FONT_SIZE); + let subtitle_container = Container::new(subtitle) + .style(grin_gui_core::theme::ContainerStyle::NormalBackground) + .padding(iced::Padding::from([ + 3, // top + 0, // right + 0, // bottom + 0, // left + ])); + + let close_wallet_label_container = + Container::new(Text::new(localized_string("close")).size(SMALLER_FONT_SIZE)) + .height(Length::Fixed(14.0)) + .width(Length::Fixed(30.0)) + .center_y() + .center_x(); + + let close_wallet_button: Element = Button::new(close_wallet_label_container) + .style(grin_gui_core::theme::ButtonStyle::Bordered) + .on_press(Interaction::WalletOperationHomeViewInteraction( + LocalViewInteraction::Back, + )) + .padding(2) + .into(); + + let subtitle_row = Row::new() + .push(subtitle_container) + .push(Space::with_width(Length::Fixed(2.0))) + .push(close_wallet_button.map(Message::Interaction)); + + let address_label = Text::new(format!( + "{}: ", + localized_string("this-wallet-receive-addr") + )) + .size(SMALLER_FONT_SIZE); + let address_label_container = Container::new(address_label) + .style(grin_gui_core::theme::ContainerStyle::NormalBackground) + .padding(iced::Padding::from([ + 3, // top + 0, // right + 0, // bottom + 0, // left + ])); + + // Truncate a bit for compact display purposes + let mut copied_address_value = "".into(); + let address = match &state.address_value { + Some(a) => { + let mut s = a.clone(); + copied_address_value = a.clone(); + s.truncate(10); + let s2 = a.clone().split_off(60); + format!("{}...{}", s, s2) + } + None => "".to_owned(), + }; + + let address = Text::new(address).size(SMALLER_FONT_SIZE); + let address_container = Container::new(address) + .style(grin_gui_core::theme::ContainerStyle::NormalBackground) + .padding(iced::Padding::from([ + 3, // top + 0, // right + 0, // bottom + 0, // left + ])); + + let copy_address_label_container = + Container::new(Text::new(localized_string("copy-to-clipboard")).size(SMALLER_FONT_SIZE)) + .height(Length::Fixed(14.0)) + .width(Length::Fixed(30.0)) + .center_y() + .center_x(); + + let copy_address_button: Element = Button::new(copy_address_label_container) + .style(grin_gui_core::theme::ButtonStyle::Bordered) + .on_press(Interaction::WriteToClipboard(copied_address_value)) + .padding(2) + .into(); + + let address_row = Row::new() + .push(address_label_container) + .push(Space::with_width(Length::Fixed(2.0))) + .push(address_container) + .push(Space::with_width(Length::Fixed(2.0))) + .push(copy_address_button.map(Message::Interaction)); + + let title_container = Container::new( + Column::new() + .push(title_container) + .push(subtitle_row) + .push(address_row), + ) + .padding(iced::Padding::from([ + 0, // top + 0, // right + 0, // bottom + 5, // left + ])); + + let header_row = Row::new() + .push(title_container) + .push(Space::with_width(Length::Fill)) + .push(operations_menu); + + let header_container = Container::new(header_row).padding(iced::Padding::from([ + 0, // top + 0, // right + DEFAULT_PADDING as u16, // bottom + 0, // left + ])); + + let total_value_label = + Text::new(format!("{}:", localized_string("info-confirmed-total"))).size(DEFAULT_FONT_SIZE); + let total_value_label_container = Container::new(total_value_label) + .style(grin_gui_core::theme::ContainerStyle::BrightBackground); + + let total_value = Text::new(total_string).size(DEFAULT_FONT_SIZE); + let total_value_container = Container::new(total_value) + .style(grin_gui_core::theme::ContainerStyle::BrightBackground) + .width(Length::Fill) + .align_x(alignment::Horizontal::Right); + + let total_row = Row::new() + .push(total_value_label_container) + .push(total_value_container) + .width(Length::Fill); + + let awaiting_confirmation_label = Text::new(format!( + "{}:", + localized_string("info-awaiting-confirmation") + )) + .size(DEFAULT_FONT_SIZE); + let awaiting_confirmation_label_container = Container::new(awaiting_confirmation_label) + .style(grin_gui_core::theme::ContainerStyle::BrightBackground); + + let awaiting_confirmation_value = + Text::new(awaiting_confirmation_string).size(DEFAULT_FONT_SIZE); + let awaiting_confirmation_value_container = Container::new(awaiting_confirmation_value) + .style(grin_gui_core::theme::ContainerStyle::BrightBackground) + .width(Length::Fill) + .align_x(alignment::Horizontal::Right); + + let awaiting_confirmation_row = Row::new() + .push(awaiting_confirmation_label_container) + .push(awaiting_confirmation_value_container) + .width(Length::Fill); + + let awaiting_finalization_label = Text::new(format!( + "{}:", + localized_string("info-awaiting-finalization") + )) + .size(DEFAULT_FONT_SIZE); + let awaiting_finalization_label_container = Container::new(awaiting_finalization_label) + .style(grin_gui_core::theme::ContainerStyle::BrightBackground); + + let awaiting_finalization_value = + Text::new(awaiting_finalization_string).size(DEFAULT_FONT_SIZE); + let awaiting_finalization_value_container = Container::new(awaiting_finalization_value) + .style(grin_gui_core::theme::ContainerStyle::BrightBackground) + .width(Length::Fill) + .align_x(alignment::Horizontal::Right); + + let awaiting_finalization_row = Row::new() + .push(awaiting_finalization_label_container) + .push(awaiting_finalization_value_container) + .width(Length::Fill); + + let locked_label = + Text::new(format!("{}:", localized_string("info-locked"))).size(DEFAULT_FONT_SIZE); + let locked_label_container = + Container::new(locked_label).style(grin_gui_core::theme::ContainerStyle::BrightBackground); + + let locked_value = Text::new(locked_string).size(DEFAULT_FONT_SIZE); + let locked_value_container = Container::new(locked_value) + .style(grin_gui_core::theme::ContainerStyle::BrightBackground) + .width(Length::Fill) + .align_x(alignment::Horizontal::Right); + + let locked_row = Row::new() + .push(locked_label_container) + .push(locked_value_container) + .width(Length::Fill); + + let amount_spendable_label = + Text::new(format!("{}:", localized_string("info-amount-spendable"))) + .size(DEFAULT_FONT_SIZE); + let amount_spendable_label_container = Container::new(amount_spendable_label) + .style(grin_gui_core::theme::ContainerStyle::BrightBackground); + + let amount_spendable_value = Text::new(amount_spendable_string).size(DEFAULT_FONT_SIZE); + let amount_spendable_value_container = Container::new(amount_spendable_value) + .style(grin_gui_core::theme::ContainerStyle::BrightBackground) + .width(Length::Fill) + .align_x(alignment::Horizontal::Right); + + let amount_spendable_row = Row::new() + .push(amount_spendable_label_container) + .push(amount_spendable_value_container) + .width(Length::Fill); + + let info_column = Column::new() + .push(total_row) + .push(awaiting_confirmation_row) + .push(awaiting_finalization_row) + .push(locked_row) + .push(amount_spendable_row) + .spacing(7); + + let wallet_info_card_container = Container::new(info_column) + .width(Length::Fixed(240.0)) + .padding(iced::Padding::from([ + DEFAULT_PADDING, // top + DEFAULT_PADDING, // right + DEFAULT_PADDING, // bottom + 5.0, // left + ])); + + let mut first_row_container = Row::new() + .push(wallet_info_card_container) + .height(Length::Fixed(120.0)); + + // if there is transaction data, display the balance chart + let mut balance_data = state.tx_list_display_state.balance_data.clone(); + if !balance_data.is_empty() { + // if there is price history data, convert the balance data to the currency + if !state.price_history.is_empty() && currency != Currency::GRIN { + balance_data = balance_data + .iter() + .map(|(date, balance)| { + let price = state.price_history.get(date).unwrap_or(&0.0); + let precision = i32::pow(10, currency.precision() as u32) as f64; + let adjusted_price = f64::trunc(balance * price * precision) / precision; + (date.clone(), adjusted_price) + }) + .collect::>(); + } + + let theme_name = config.theme.clone().unwrap_or("Alliance".to_string()); + let theme = grin_gui_core::theme::Theme::all() + .iter() + .find(|t| t.0 == theme_name) + .unwrap() + .1 + .clone(); + + first_row_container = first_row_container.push(BalanceChart::new( + theme, + balance_data.into_iter().rev(), + state.cursor_index, + state.caption_index, + )); + } + + // Status container element for Node state + let status_container_node_state_label_text = + Text::new(format!("{}: ", localized_string("node-status"))) + .size(DEFAULT_FONT_SIZE) + .height(Length::Fill) + .horizontal_alignment(alignment::Horizontal::Left) + .vertical_alignment(alignment::Vertical::Center); + + let status_container_node_state_text = Text::new(state.parse_node_status()) + .size(DEFAULT_FONT_SIZE) + .height(Length::Fill) + .horizontal_alignment(alignment::Horizontal::Left) + .vertical_alignment(alignment::Vertical::Center); + + // Status container bar at bottom of screen + let status_container_label_text = Text::new(localized_string("wallet-status")) + .size(DEFAULT_FONT_SIZE) + .height(Length::Fill) + .horizontal_alignment(alignment::Horizontal::Right) + .vertical_alignment(alignment::Vertical::Center); + + let status_container_separator_text = Text::new(": ") + .size(DEFAULT_FONT_SIZE) + .height(Length::Fill) + .horizontal_alignment(alignment::Horizontal::Right) + .vertical_alignment(alignment::Vertical::Center); + + let status_container_status_text = Text::new(&state.wallet_status) + .size(DEFAULT_FONT_SIZE) + .height(Length::Fill) + .horizontal_alignment(alignment::Horizontal::Right) + .vertical_alignment(alignment::Vertical::Center); + + let status_container_contents = Row::new() + .push(Space::new( + Length::Fixed(DEFAULT_PADDING), + Length::Fixed(0.0), + )) + .push(status_container_node_state_label_text) + .push(status_container_node_state_text) + .push(Space::new(Length::Fill, Length::Fill)) + .push(status_container_label_text) + .push(status_container_separator_text) + .push(status_container_status_text) + .push(Space::new( + Length::Fixed(DEFAULT_PADDING), + Length::Fixed(0.0), + )); + + let status_container = Container::new(status_container_contents) + .style(grin_gui_core::theme::ContainerStyle::BrightForeground) + .height(Length::Fixed(25.0)) + .width(Length::Fill); + + let status_row = Row::new() + .push(status_container) + .align_items(Alignment::Center) + .spacing(25); + + // Buttons to perform operations go here, but empty container for now + let tx_list_display = + tx_list_display::data_container(config, &state, &state.tx_list_display_state) + .height(Length::Fill); + + // Overall Home screen layout column + let column = Column::new() + .push(header_container) + .push(first_row_container) + .push(Space::with_height(Length::Fixed(DEFAULT_PADDING * 3.0))) + .push(tx_list_display) + .push(Space::with_height(Length::Fixed(DEFAULT_PADDING))) + .push(status_row) + .height(Length::Fill); + + Container::new(column).padding(iced::Padding::from([ + DEFAULT_PADDING, // top + DEFAULT_PADDING, // right + DEFAULT_PADDING, // bottom + DEFAULT_PADDING, // left + ])) } diff --git a/src/gui/element/wallet/operation/mod.rs b/src/gui/element/wallet/operation/mod.rs index 097a35c..c269dc7 100644 --- a/src/gui/element/wallet/operation/mod.rs +++ b/src/gui/element/wallet/operation/mod.rs @@ -4,124 +4,118 @@ pub mod apply_tx_confirm; pub mod chart; pub mod create_tx; pub mod create_tx_contracts; -pub mod show_slatepack; pub mod home; pub mod open; +pub mod show_slatepack; +pub mod tx_detail; +pub mod tx_done; pub mod tx_list; pub mod tx_list_display; -pub mod tx_detail; pub mod tx_proof; -pub mod tx_done; use { - crate::gui::{GrinGui, Message}, - crate::Result, - grin_gui_core::config::{Config, TxMethod}, - grin_gui_core::theme::ColorPalette, - grin_gui_core::theme::{ - Button, Column, Container, Element, PickList, Row, Scrollable, Text, TextInput, - }, - iced::{Command, Length}, + crate::gui::{GrinGui, Message}, + crate::Result, + grin_gui_core::config::{Config, TxMethod}, + grin_gui_core::theme::ColorPalette, + grin_gui_core::theme::{ + Button, Column, Container, Element, PickList, Row, Scrollable, Text, TextInput, + }, + iced::{Command, Length}, }; pub struct StateContainer { - pub mode: Mode, - pub open_state: open::StateContainer, - pub home_state: home::StateContainer, - pub create_tx_state: create_tx::StateContainer, - pub create_tx_contracts_state: create_tx_contracts::StateContainer, - pub show_slatepack_state: show_slatepack::StateContainer, - pub apply_tx_state: apply_tx::StateContainer, - pub tx_detail_state: tx_detail::StateContainer, - pub tx_proof_state: tx_proof::StateContainer, - pub tx_done_state: tx_done::StateContainer, - // When changed to true, this should stay false until a wallet is opened with a password - has_wallet_open_check_failed_one_time: bool, + pub mode: Mode, + pub open_state: open::StateContainer, + pub home_state: home::StateContainer, + pub create_tx_state: create_tx::StateContainer, + pub create_tx_contracts_state: create_tx_contracts::StateContainer, + pub show_slatepack_state: show_slatepack::StateContainer, + pub apply_tx_state: apply_tx::StateContainer, + pub tx_detail_state: tx_detail::StateContainer, + pub tx_proof_state: tx_proof::StateContainer, + pub tx_done_state: tx_done::StateContainer, + // When changed to true, this should stay false until a wallet is opened with a password + has_wallet_open_check_failed_one_time: bool, } #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub enum Mode { - Open, - Home, - CreateTx, - ApplyTx, - ShowSlatepack, - TxDetail, - TxProof, - TxDone, + Open, + Home, + CreateTx, + ApplyTx, + ShowSlatepack, + TxDetail, + TxProof, + TxDone, } impl Default for StateContainer { - fn default() -> Self { - Self { - mode: Mode::Home, - open_state: Default::default(), - home_state: Default::default(), - create_tx_state: Default::default(), - create_tx_contracts_state: Default::default(), - show_slatepack_state: Default::default(), - apply_tx_state: Default::default(), - tx_detail_state: Default::default(), - tx_proof_state: Default::default(), - tx_done_state: Default::default(), - has_wallet_open_check_failed_one_time: false, - } - } + fn default() -> Self { + Self { + mode: Mode::Home, + open_state: Default::default(), + home_state: Default::default(), + create_tx_state: Default::default(), + create_tx_contracts_state: Default::default(), + show_slatepack_state: Default::default(), + apply_tx_state: Default::default(), + tx_detail_state: Default::default(), + tx_proof_state: Default::default(), + tx_done_state: Default::default(), + has_wallet_open_check_failed_one_time: false, + } + } } impl StateContainer { - pub fn wallet_not_open(&self) -> bool { - self.has_wallet_open_check_failed_one_time - } + pub fn wallet_not_open(&self) -> bool { + self.has_wallet_open_check_failed_one_time + } - pub fn set_wallet_not_open(&mut self) { - self.has_wallet_open_check_failed_one_time = true; - self.mode = Mode::Open; - } + pub fn set_wallet_not_open(&mut self) { + self.has_wallet_open_check_failed_one_time = true; + self.mode = Mode::Open; + } - pub fn clear_wallet_not_open(&mut self) { - self.has_wallet_open_check_failed_one_time = false; - } + pub fn clear_wallet_not_open(&mut self) { + self.has_wallet_open_check_failed_one_time = false; + } } #[derive(Debug, Clone)] pub enum LocalViewInteraction {} pub fn handle_message( - grin_gui: &mut GrinGui, - message: LocalViewInteraction, + grin_gui: &mut GrinGui, + message: LocalViewInteraction, ) -> Result> { - Ok(Command::none()) + Ok(Command::none()) } pub fn data_container<'a>(state: &'a StateContainer, config: &'a Config) -> Container<'a, Message> { - let content = match state.mode { - Mode::Open => open::data_container(&state.open_state, config), - Mode::Home => home::data_container(config, &state.home_state), - Mode::CreateTx => match config.tx_method { - TxMethod::Legacy => create_tx::data_container(config, &state.create_tx_state), - TxMethod::Contracts => create_tx_contracts::data_container(config, &state.create_tx_contracts_state), - } - Mode::ShowSlatepack => { - show_slatepack::data_container(config, &state.show_slatepack_state) - } - Mode::ApplyTx => apply_tx::data_container(config, &state.apply_tx_state), - Mode::TxDetail => { - tx_detail::data_container(config, &state.tx_detail_state) - } - Mode::TxProof => { - tx_proof::data_container(config, &state.tx_proof_state) - } - Mode::TxDone => { - tx_done::data_container(config, &state.tx_done_state) - } - }; + let content = match state.mode { + Mode::Open => open::data_container(&state.open_state, config), + Mode::Home => home::data_container(config, &state.home_state), + Mode::CreateTx => match config.tx_method { + TxMethod::Legacy => create_tx::data_container(config, &state.create_tx_state), + TxMethod::Contracts => { + create_tx_contracts::data_container(config, &state.create_tx_contracts_state) + } + }, + Mode::ShowSlatepack => show_slatepack::data_container(config, &state.show_slatepack_state), + Mode::ApplyTx => apply_tx::data_container(config, &state.apply_tx_state), + Mode::TxDetail => tx_detail::data_container(config, &state.tx_detail_state), + Mode::TxProof => tx_proof::data_container(config, &state.tx_proof_state), + Mode::TxDone => tx_done::data_container(config, &state.tx_done_state), + }; - let column = Column::new().push(content); + let column = Column::new().push(content); - Container::new(column) - .center_y() - .center_x() - .width(Length::Fill) - .style(grin_gui_core::theme::ContainerStyle::NormalBackground) + Container::new(column) + .center_y() + .center_x() + .width(Length::Fill) + .style(grin_gui_core::theme::ContainerStyle::NormalBackground) } diff --git a/src/gui/element/wallet/operation/open.rs b/src/gui/element/wallet/operation/open.rs index ae41a8f..2ddc073 100644 --- a/src/gui/element/wallet/operation/open.rs +++ b/src/gui/element/wallet/operation/open.rs @@ -4,296 +4,296 @@ use crate::log_error; //use std::path::PathBuf; use { - super::super::super::{DEFAULT_FONT_SIZE, DEFAULT_HEADER_FONT_SIZE, DEFAULT_PADDING}, - crate::gui::{GrinGui, Interaction, Message}, - crate::localization::localized_string, - crate::Result, - anyhow::Context, - grin_gui_core::config::Config, - grin_gui_core::theme::ColorPalette, - grin_gui_core::theme::{ - Button, Column, Container, Element, PickList, Row, Scrollable, Text, TextInput, - }, - grin_gui_core::{ - node::ChainTypes::Mainnet, node::ChainTypes::Testnet, wallet::WalletInterface, - }, - iced::widget::{button, pick_list, scrollable, text_input, Space}, - iced::{alignment, Alignment, Command, Length}, - std::sync::{Arc, RwLock}, + super::super::super::{DEFAULT_FONT_SIZE, DEFAULT_HEADER_FONT_SIZE, DEFAULT_PADDING}, + crate::gui::{GrinGui, Interaction, Message}, + crate::localization::localized_string, + crate::Result, + anyhow::Context, + grin_gui_core::config::Config, + grin_gui_core::theme::ColorPalette, + grin_gui_core::theme::{ + Button, Column, Container, Element, PickList, Row, Scrollable, Text, TextInput, + }, + grin_gui_core::{ + node::ChainTypes::Mainnet, node::ChainTypes::Testnet, wallet::WalletInterface, + }, + iced::widget::{button, pick_list, scrollable, text_input, Space}, + iced::{alignment, Alignment, Command, Length}, + std::sync::{Arc, RwLock}, }; static INPUT_WIDTH: f32 = 212.0; static UNIT_SPACE: f32 = 15.0; pub struct StateContainer { - pub password_state: PasswordState, - pub wallet_message: String, + pub password_state: PasswordState, + pub wallet_message: String, } impl Default for StateContainer { - fn default() -> Self { - Self { - password_state: Default::default(), - wallet_message: localized_string("open-wallet-password"), - } - } + fn default() -> Self { + Self { + password_state: Default::default(), + wallet_message: localized_string("open-wallet-password"), + } + } } #[derive(Debug, Clone)] pub struct PasswordState { - pub input_value: String, + pub input_value: String, } impl Default for PasswordState { - fn default() -> Self { - PasswordState { - input_value: Default::default(), - } - } + fn default() -> Self { + PasswordState { + input_value: Default::default(), + } + } } #[derive(Debug, Clone)] pub enum LocalViewInteraction { - //TODO: ZeroingString these - PasswordInput(String), - PasswordInputEnterPressed, - OpenWallet, - CancelOpenWallet, - WalletOpenedOkay, - WalletOpenError(Arc>>), + //TODO: ZeroingString these + PasswordInput(String), + PasswordInputEnterPressed, + OpenWallet, + CancelOpenWallet, + WalletOpenedOkay, + WalletOpenError(Arc>>), } pub fn handle_message<'a>( - grin_gui: &mut GrinGui, - message: LocalViewInteraction, + grin_gui: &mut GrinGui, + message: LocalViewInteraction, ) -> Result> { - let state = &mut grin_gui.wallet_state.operation_state.open_state; - match message { - LocalViewInteraction::CancelOpenWallet => { - // TODO @sheldonth do we need to "close" any wallet interface? - // @sheldonth if the wallet we're currently prompted for uses - // the node it needs to be shutdown. - - // return user to wallet list - grin_gui.wallet_state.mode = element::wallet::Mode::Init; - grin_gui.wallet_state.setup_state.mode = element::wallet::setup::Mode::ListWallets; - - // reset user input values - grin_gui.wallet_state.operation_state.open_state = Default::default(); - } - LocalViewInteraction::PasswordInput(password) => { - state.password_state.input_value = password; - state.wallet_message = localized_string("open-wallet-password"); - } - LocalViewInteraction::PasswordInputEnterPressed => { - //state.password_state.input_state.unfocus(); - } - LocalViewInteraction::OpenWallet => { - grin_gui.error.take(); - - log::debug!("setup::wallet::operation::open::OpenWallet"); - - let password = state.password_state.input_value.clone(); - let wallet_interface = grin_gui.wallet_interface.clone(); - let running_chain_type = grin_gui.node_interface.read().unwrap().chain_type.unwrap(); - let wallet_index = grin_gui.config.current_wallet_index.unwrap(); - let current_wallet = &grin_gui.config.wallets[wallet_index]; - let wallet_chain_type = current_wallet.chain_type; - - if current_wallet.use_embedded_node { - // restart embedded server is chain types differ - if running_chain_type != wallet_chain_type { - let mut node = grin_gui.node_interface.write().unwrap(); - node.restart_server(wallet_chain_type); - } - - let node_interface = grin_gui.node_interface.read().unwrap(); - if let Some(c) = &node_interface.config { - if let Some(m) = &c.members { - WalletInterface::set_use_embedded_node(wallet_interface.clone(), true); - let mut w = wallet_interface.write().unwrap(); - w.check_node_foreign_api_secret_path = - m.server.foreign_api_secret_path.clone(); - } - } - } - let tld = current_wallet.tld.clone().unwrap(); - let fut = move || { - WalletInterface::open_wallet( - wallet_interface, - password.clone(), - tld, - current_wallet.chain_type, - ) - }; - - return Ok(Command::perform(fut(), |r| { - match r.context("Failed to Open Wallet") { - Ok(()) => { - Message::Interaction(Interaction::WalletOperationOpenViewInteraction( - LocalViewInteraction::WalletOpenedOkay, - )) - } - Err(e) => { - Message::Interaction(Interaction::WalletOperationOpenViewInteraction( - LocalViewInteraction::WalletOpenError(Arc::new(RwLock::new(Some(e)))), - )) - } - } - })); - } - LocalViewInteraction::WalletOpenedOkay => { - grin_gui - .wallet_state - .operation_state - .clear_wallet_not_open(); - grin_gui.wallet_state.operation_state.mode = - crate::gui::element::wallet::operation::Mode::Home; - - // reset user input values - grin_gui.wallet_state.operation_state.open_state = Default::default(); - } - - LocalViewInteraction::WalletOpenError(err) => { - //grin_gui.error = err.write().unwrap().take(); - // display wallet message to user - state.wallet_message = localized_string("open-wallet-error"); - err.write() - .unwrap() - .take() - .and_then(|e| Some(log_error(&e))); - } - } - Ok(Command::none()) + let state = &mut grin_gui.wallet_state.operation_state.open_state; + match message { + LocalViewInteraction::CancelOpenWallet => { + // TODO @sheldonth do we need to "close" any wallet interface? + // @sheldonth if the wallet we're currently prompted for uses + // the node it needs to be shutdown. + + // return user to wallet list + grin_gui.wallet_state.mode = element::wallet::Mode::Init; + grin_gui.wallet_state.setup_state.mode = element::wallet::setup::Mode::ListWallets; + + // reset user input values + grin_gui.wallet_state.operation_state.open_state = Default::default(); + } + LocalViewInteraction::PasswordInput(password) => { + state.password_state.input_value = password; + state.wallet_message = localized_string("open-wallet-password"); + } + LocalViewInteraction::PasswordInputEnterPressed => { + //state.password_state.input_state.unfocus(); + } + LocalViewInteraction::OpenWallet => { + grin_gui.error.take(); + + log::debug!("setup::wallet::operation::open::OpenWallet"); + + let password = state.password_state.input_value.clone(); + let wallet_interface = grin_gui.wallet_interface.clone(); + let running_chain_type = grin_gui.node_interface.read().unwrap().chain_type.unwrap(); + let wallet_index = grin_gui.config.current_wallet_index.unwrap(); + let current_wallet = &grin_gui.config.wallets[wallet_index]; + let wallet_chain_type = current_wallet.chain_type; + + if current_wallet.use_embedded_node { + // restart embedded server is chain types differ + if running_chain_type != wallet_chain_type { + let mut node = grin_gui.node_interface.write().unwrap(); + node.restart_server(wallet_chain_type); + } + + let node_interface = grin_gui.node_interface.read().unwrap(); + if let Some(c) = &node_interface.config { + if let Some(m) = &c.members { + WalletInterface::set_use_embedded_node(wallet_interface.clone(), true); + let mut w = wallet_interface.write().unwrap(); + w.check_node_foreign_api_secret_path = + m.server.foreign_api_secret_path.clone(); + } + } + } + let tld = current_wallet.tld.clone().unwrap(); + let fut = move || { + WalletInterface::open_wallet( + wallet_interface, + password.clone(), + tld, + current_wallet.chain_type, + ) + }; + + return Ok(Command::perform(fut(), |r| { + match r.context("Failed to Open Wallet") { + Ok(()) => { + Message::Interaction(Interaction::WalletOperationOpenViewInteraction( + LocalViewInteraction::WalletOpenedOkay, + )) + } + Err(e) => { + Message::Interaction(Interaction::WalletOperationOpenViewInteraction( + LocalViewInteraction::WalletOpenError(Arc::new(RwLock::new(Some(e)))), + )) + } + } + })); + } + LocalViewInteraction::WalletOpenedOkay => { + grin_gui + .wallet_state + .operation_state + .clear_wallet_not_open(); + grin_gui.wallet_state.operation_state.mode = + crate::gui::element::wallet::operation::Mode::Home; + + // reset user input values + grin_gui.wallet_state.operation_state.open_state = Default::default(); + } + + LocalViewInteraction::WalletOpenError(err) => { + //grin_gui.error = err.write().unwrap().take(); + // display wallet message to user + state.wallet_message = localized_string("open-wallet-error"); + err.write() + .unwrap() + .take() + .and_then(|e| Some(log_error(&e))); + } + } + Ok(Command::none()) } pub fn data_container<'a>(state: &'a StateContainer, config: &Config) -> Container<'a, Message> { - let mut display_name_string = match config.current_wallet_index { - Some(index) => config.wallets[index].display_name.clone(), - None => "".to_owned(), - }; - - // if there is no wallet display name - if display_name_string.is_empty() { - display_name_string = localized_string("open-wallet"); - } - - let display_name = Text::new(display_name_string) - .size(DEFAULT_HEADER_FONT_SIZE) - .horizontal_alignment(alignment::Horizontal::Center); - let display_name_container = - Container::new(display_name).style(grin_gui_core::theme::ContainerStyle::BrightBackground); - - let password_column = { - let password_input = TextInput::new( - // &mut state.password_state.input_state, - &localized_string("password")[..], - &state.password_state.input_value, - ) - .on_submit(Interaction::WalletOperationOpenViewInteraction( - LocalViewInteraction::PasswordInputEnterPressed, - )) - .on_input(|s| { - Interaction::WalletOperationOpenViewInteraction(LocalViewInteraction::PasswordInput(s)) - }) - .size(DEFAULT_FONT_SIZE) - .padding(6) - .style(grin_gui_core::theme::TextInputStyle::AddonsQuery) - .password(); - - let password_input: Element = password_input.into(); - - let password_input_col = Column::new() - .push(password_input.map(Message::Interaction)) - .spacing(DEFAULT_PADDING) - .align_items(Alignment::Center); - - Column::new().push(password_input_col) - }; - - let description = Text::new(state.wallet_message.clone()) - .size(DEFAULT_FONT_SIZE) - .horizontal_alignment(alignment::Horizontal::Center); - - let description_container = Container::new(description) - .width(Length::Fixed(INPUT_WIDTH)) - .style(grin_gui_core::theme::ContainerStyle::NormalBackground) - .padding(6); - - let submit_button_label_container = - Container::new(Text::new(localized_string("open")).size(DEFAULT_FONT_SIZE)) - .center_x() - .center_y() - .width(Length::Fixed(BUTTON_WIDTH)) - .height(Length::Fixed(BUTTON_HEIGHT)) - .align_x(alignment::Horizontal::Center); - - let mut submit_button = Button::new(submit_button_label_container) - .style(grin_gui_core::theme::ButtonStyle::Primary); - - submit_button = submit_button.on_press(Interaction::WalletOperationOpenViewInteraction( - LocalViewInteraction::OpenWallet, - )); - - let submit_button: Element = submit_button.into(); - - let cancel_button_label_container = - Container::new(Text::new(localized_string("cancel")).size(DEFAULT_FONT_SIZE)) - .center_x() - .center_y() - .width(Length::Fixed(BUTTON_WIDTH)) - .height(Length::Fixed(BUTTON_HEIGHT)) - .align_x(alignment::Horizontal::Center); - - let mut cancel_button = Button::new( - // &mut state.cancel_button_state, - cancel_button_label_container, - ) - .style(grin_gui_core::theme::ButtonStyle::Primary); - - cancel_button = cancel_button.on_press(Interaction::WalletOperationOpenViewInteraction( - LocalViewInteraction::CancelOpenWallet, - )); - - // give our buttons a nice double bordered look to match toolbar buttons - let submit_button: Element = submit_button.into(); - let submit_container = Container::new(submit_button.map(Message::Interaction)).padding(1); - let submit_container = Container::new(submit_container) - .style(grin_gui_core::theme::ContainerStyle::Segmented) - .padding(1); - - let cancel_button: Element = cancel_button.into(); - let cancel_container = Container::new(cancel_button.map(Message::Interaction)).padding(1); - let cancel_container = Container::new(cancel_container) - .style(grin_gui_core::theme::ContainerStyle::Segmented) - .padding(1); - - let button_row = Row::new() - .push(submit_container) - .push(Space::with_width(Length::Fixed(UNIT_SPACE))) - .push(cancel_container); - - let input_container = Container::new( - Column::new() - .push(description_container) - .push(Space::with_height(Length::Fixed(UNIT_SPACE / 2.0))) - .push(password_column), - ) - .width(Length::Fixed(INPUT_WIDTH)); - - let column = Column::new() - .push(display_name_container) - .push(Space::with_height(Length::Fixed(UNIT_SPACE))) - .push(input_container) - .push(Space::with_height(Length::Fixed( - UNIT_SPACE + DEFAULT_PADDING, - ))) - .push(button_row) - .align_items(Alignment::Center); - - Container::new(column) - .center_y() - .center_x() - .width(Length::Fill) - .height(Length::Fill) + let mut display_name_string = match config.current_wallet_index { + Some(index) => config.wallets[index].display_name.clone(), + None => "".to_owned(), + }; + + // if there is no wallet display name + if display_name_string.is_empty() { + display_name_string = localized_string("open-wallet"); + } + + let display_name = Text::new(display_name_string) + .size(DEFAULT_HEADER_FONT_SIZE) + .horizontal_alignment(alignment::Horizontal::Center); + let display_name_container = + Container::new(display_name).style(grin_gui_core::theme::ContainerStyle::BrightBackground); + + let password_column = { + let password_input = TextInput::new( + // &mut state.password_state.input_state, + &localized_string("password")[..], + &state.password_state.input_value, + ) + .on_submit(Interaction::WalletOperationOpenViewInteraction( + LocalViewInteraction::PasswordInputEnterPressed, + )) + .on_input(|s| { + Interaction::WalletOperationOpenViewInteraction(LocalViewInteraction::PasswordInput(s)) + }) + .size(DEFAULT_FONT_SIZE) + .padding(6) + .style(grin_gui_core::theme::TextInputStyle::AddonsQuery) + .password(); + + let password_input: Element = password_input.into(); + + let password_input_col = Column::new() + .push(password_input.map(Message::Interaction)) + .spacing(DEFAULT_PADDING) + .align_items(Alignment::Center); + + Column::new().push(password_input_col) + }; + + let description = Text::new(state.wallet_message.clone()) + .size(DEFAULT_FONT_SIZE) + .horizontal_alignment(alignment::Horizontal::Center); + + let description_container = Container::new(description) + .width(Length::Fixed(INPUT_WIDTH)) + .style(grin_gui_core::theme::ContainerStyle::NormalBackground) + .padding(6); + + let submit_button_label_container = + Container::new(Text::new(localized_string("open")).size(DEFAULT_FONT_SIZE)) + .center_x() + .center_y() + .width(Length::Fixed(BUTTON_WIDTH)) + .height(Length::Fixed(BUTTON_HEIGHT)) + .align_x(alignment::Horizontal::Center); + + let mut submit_button = Button::new(submit_button_label_container) + .style(grin_gui_core::theme::ButtonStyle::Primary); + + submit_button = submit_button.on_press(Interaction::WalletOperationOpenViewInteraction( + LocalViewInteraction::OpenWallet, + )); + + let submit_button: Element = submit_button.into(); + + let cancel_button_label_container = + Container::new(Text::new(localized_string("cancel")).size(DEFAULT_FONT_SIZE)) + .center_x() + .center_y() + .width(Length::Fixed(BUTTON_WIDTH)) + .height(Length::Fixed(BUTTON_HEIGHT)) + .align_x(alignment::Horizontal::Center); + + let mut cancel_button = Button::new( + // &mut state.cancel_button_state, + cancel_button_label_container, + ) + .style(grin_gui_core::theme::ButtonStyle::Primary); + + cancel_button = cancel_button.on_press(Interaction::WalletOperationOpenViewInteraction( + LocalViewInteraction::CancelOpenWallet, + )); + + // give our buttons a nice double bordered look to match toolbar buttons + let submit_button: Element = submit_button.into(); + let submit_container = Container::new(submit_button.map(Message::Interaction)).padding(1); + let submit_container = Container::new(submit_container) + .style(grin_gui_core::theme::ContainerStyle::Segmented) + .padding(1); + + let cancel_button: Element = cancel_button.into(); + let cancel_container = Container::new(cancel_button.map(Message::Interaction)).padding(1); + let cancel_container = Container::new(cancel_container) + .style(grin_gui_core::theme::ContainerStyle::Segmented) + .padding(1); + + let button_row = Row::new() + .push(submit_container) + .push(Space::with_width(Length::Fixed(UNIT_SPACE))) + .push(cancel_container); + + let input_container = Container::new( + Column::new() + .push(description_container) + .push(Space::with_height(Length::Fixed(UNIT_SPACE / 2.0))) + .push(password_column), + ) + .width(Length::Fixed(INPUT_WIDTH)); + + let column = Column::new() + .push(display_name_container) + .push(Space::with_height(Length::Fixed(UNIT_SPACE))) + .push(input_container) + .push(Space::with_height(Length::Fixed( + UNIT_SPACE + DEFAULT_PADDING, + ))) + .push(button_row) + .align_items(Alignment::Center); + + Container::new(column) + .center_y() + .center_x() + .width(Length::Fill) + .height(Length::Fill) } diff --git a/src/gui/element/wallet/operation/show_slatepack.rs b/src/gui/element/wallet/operation/show_slatepack.rs index 45c78ed..f7b3dd6 100644 --- a/src/gui/element/wallet/operation/show_slatepack.rs +++ b/src/gui/element/wallet/operation/show_slatepack.rs @@ -1,215 +1,214 @@ use { - super::super::super::{ - BUTTON_HEIGHT, BUTTON_WIDTH, DEFAULT_FONT_SIZE, DEFAULT_HEADER_FONT_SIZE, DEFAULT_PADDING, - SMALLER_FONT_SIZE, - }, - crate::gui::{GrinGui, Interaction, Message}, - crate::localization::localized_string, - crate::Result, - grin_gui_core::config::Config, - grin_gui_core::theme::ColorPalette, - grin_gui_core::theme::{ - Column, Container, Element, PickList, Row, Scrollable, Text, TextInput, - }, - iced::widget::{button, pick_list, scrollable, text_input, Button, Checkbox, Space}, - iced::{alignment, Alignment, Command, Length}, - iced_aw::Card, + super::super::super::{ + BUTTON_HEIGHT, BUTTON_WIDTH, DEFAULT_FONT_SIZE, DEFAULT_HEADER_FONT_SIZE, DEFAULT_PADDING, + SMALLER_FONT_SIZE, + }, + crate::gui::{GrinGui, Interaction, Message}, + crate::localization::localized_string, + crate::Result, + grin_gui_core::config::Config, + grin_gui_core::theme::ColorPalette, + grin_gui_core::theme::{ + Column, Container, Element, PickList, Row, Scrollable, Text, TextInput, + }, + iced::widget::{button, pick_list, scrollable, text_input, Button, Checkbox, Space}, + iced::{alignment, Alignment, Command, Length}, + iced_aw::Card, }; pub struct StateContainer { - // Encrypted slate to send to recipient - pub encrypted_slate: Option, - // Where the 'submit' or back button leads to - pub submit_mode: Option, - // Label to display as title - pub title_label: String, - // description - pub desc: String, + // Encrypted slate to send to recipient + pub encrypted_slate: Option, + // Where the 'submit' or back button leads to + pub submit_mode: Option, + // Label to display as title + pub title_label: String, + // description + pub desc: String, } impl Default for StateContainer { - fn default() -> Self { - Self { - encrypted_slate: Default::default(), - submit_mode: None, - title_label: localized_string("tx-view"), - desc: localized_string("tx-view-desc") - } - } + fn default() -> Self { + Self { + encrypted_slate: Default::default(), + submit_mode: None, + title_label: localized_string("tx-view"), + desc: localized_string("tx-view-desc"), + } + } } impl StateContainer { - pub fn reset_defaults(&mut self) { - self.title_label = localized_string("tx-view"); - self.desc = localized_string("tx-view-desc"); - } + pub fn reset_defaults(&mut self) { + self.title_label = localized_string("tx-view"); + self.desc = localized_string("tx-view-desc"); + } } #[derive(Debug, Clone)] pub enum LocalViewInteraction { - Submit, + Submit, } pub fn handle_message( - grin_gui: &mut GrinGui, - message: LocalViewInteraction, + grin_gui: &mut GrinGui, + message: LocalViewInteraction, ) -> Result> { - let state = &mut grin_gui.wallet_state.operation_state.show_slatepack_state; - match message { - LocalViewInteraction::Submit => { - state.encrypted_slate = None; - state.reset_defaults(); - if let Some(ref m) = state.submit_mode { - grin_gui.wallet_state.operation_state.mode = m.clone(); - } else { - grin_gui.wallet_state.operation_state.mode = - crate::gui::element::wallet::operation::Mode::Home; - } - state.submit_mode = None; - } - } - Ok(Command::none()) + let state = &mut grin_gui.wallet_state.operation_state.show_slatepack_state; + match message { + LocalViewInteraction::Submit => { + state.encrypted_slate = None; + state.reset_defaults(); + if let Some(ref m) = state.submit_mode { + grin_gui.wallet_state.operation_state.mode = m.clone(); + } else { + grin_gui.wallet_state.operation_state.mode = + crate::gui::element::wallet::operation::Mode::Home; + } + state.submit_mode = None; + } + } + Ok(Command::none()) } pub fn data_container<'a>( - _config: &'a Config, - state: &'a StateContainer, + _config: &'a Config, + state: &'a StateContainer, ) -> Container<'a, Message> { - // Title row - let title = Text::new(state.title_label.clone()) - .size(DEFAULT_HEADER_FONT_SIZE) - .horizontal_alignment(alignment::Horizontal::Center); - - let title_container = Container::new(title) - .style(grin_gui_core::theme::ContainerStyle::BrightBackground) - .padding(iced::Padding::from([ - 2, // top - 0, // right - 2, // bottom - 5, // left - ])); - - // push more items on to header here: e.g. other buttons, things that belong on the header - let header_row = Row::new().push(title_container); - - let header_container = Container::new(header_row).padding(iced::Padding::from([ - 0, // top - 0, // right - DEFAULT_PADDING as u16, // bottom - 0, // left - ])); - - let description = Text::new(state.desc.clone()) - .size(DEFAULT_FONT_SIZE) - .horizontal_alignment(alignment::Horizontal::Center); - let description_container = - Container::new(description).style(grin_gui_core::theme::ContainerStyle::NormalBackground); - - let card_contents = match &state.encrypted_slate { - Some(s) => s.to_owned(), - None => "".to_owned() - }; - - let encrypted_slate_card = Card::new( - Text::new(localized_string("tx-paste-success-title")) - .size(DEFAULT_HEADER_FONT_SIZE), - Text::new(card_contents.clone()).size(DEFAULT_FONT_SIZE), - ) - .foot( - Column::new() - .spacing(10) - .padding(5) - .width(Length::Fill) - .align_items(Alignment::Center) - .push( - Button::new( - Text::new(localized_string("copy-to-clipboard")) - .size(SMALLER_FONT_SIZE) - .horizontal_alignment(alignment::Horizontal::Center), - ) - .style(grin_gui_core::theme::ButtonStyle::NormalText) - .on_press(Message::Interaction(Interaction::WriteToClipboard( - card_contents.clone(), - ))), - ), - ) - .max_width(400.0) - .style(grin_gui_core::theme::CardStyle::Normal); - - let unit_spacing = 15.0; - - let button_height = Length::Fixed(BUTTON_HEIGHT); - let button_width = Length::Fixed(BUTTON_WIDTH); - - let cancel_button_label_container = - Container::new(Text::new(localized_string("ok-caps")).size(DEFAULT_FONT_SIZE)) - .width(button_width) - .height(button_height) - .center_x() - .center_y() - .align_x(alignment::Horizontal::Center); - - let cancel_button: Element = Button::new(cancel_button_label_container) - .style(grin_gui_core::theme::ButtonStyle::Primary) - .on_press(Interaction::WalletOperationShowSlatepackViewInteraction( - LocalViewInteraction::Submit, - )) - .into(); - - let cancel_container = Container::new(cancel_button.map(Message::Interaction)).padding(1); - let cancel_container = Container::new(cancel_container) - .style(grin_gui_core::theme::ContainerStyle::Segmented) - .padding(1); - - let unit_spacing = 15.0; - let button_row = Row::new().push(cancel_container); - - let column = Column::new() - .push(description_container) - .push(Space::new( - Length::Fixed(0.0), - Length::Fixed(unit_spacing + 5.0), - )) - .push(encrypted_slate_card) - .push(Space::new( - Length::Fixed(0.0), - Length::Fixed(unit_spacing + 10.0), - )) - .push(button_row) - .push(Space::new( - Length::Fixed(0.0), - Length::Fixed(unit_spacing + 10.0), - )); - - let form_container = Container::new(column) - .width(Length::Fill) - .padding(iced::Padding::from([ - 0, // top - 0, // right - 0, // bottom - 5, // left - ])); - - // form container should be scrollable in tiny windows - let scrollable = Scrollable::new(form_container) - .height(Length::Fill) - .style(grin_gui_core::theme::ScrollableStyle::Primary); - - let content = Container::new(scrollable) - .width(Length::Fill) - .height(Length::Shrink) - .style(grin_gui_core::theme::ContainerStyle::NormalBackground); - - let wrapper_column = Column::new() - .height(Length::Fill) - .push(header_container) - .push(content); - - // Returns the final container. - Container::new(wrapper_column).padding(iced::Padding::from([ - DEFAULT_PADDING, // top - DEFAULT_PADDING, // right - DEFAULT_PADDING, // bottom - DEFAULT_PADDING, // left - ])) + // Title row + let title = Text::new(state.title_label.clone()) + .size(DEFAULT_HEADER_FONT_SIZE) + .horizontal_alignment(alignment::Horizontal::Center); + + let title_container = Container::new(title) + .style(grin_gui_core::theme::ContainerStyle::BrightBackground) + .padding(iced::Padding::from([ + 2, // top + 0, // right + 2, // bottom + 5, // left + ])); + + // push more items on to header here: e.g. other buttons, things that belong on the header + let header_row = Row::new().push(title_container); + + let header_container = Container::new(header_row).padding(iced::Padding::from([ + 0, // top + 0, // right + DEFAULT_PADDING as u16, // bottom + 0, // left + ])); + + let description = Text::new(state.desc.clone()) + .size(DEFAULT_FONT_SIZE) + .horizontal_alignment(alignment::Horizontal::Center); + let description_container = + Container::new(description).style(grin_gui_core::theme::ContainerStyle::NormalBackground); + + let card_contents = match &state.encrypted_slate { + Some(s) => s.to_owned(), + None => "".to_owned(), + }; + + let encrypted_slate_card = Card::new( + Text::new(localized_string("tx-paste-success-title")).size(DEFAULT_HEADER_FONT_SIZE), + Text::new(card_contents.clone()).size(DEFAULT_FONT_SIZE), + ) + .foot( + Column::new() + .spacing(10) + .padding(5) + .width(Length::Fill) + .align_items(Alignment::Center) + .push( + Button::new( + Text::new(localized_string("copy-to-clipboard")) + .size(SMALLER_FONT_SIZE) + .horizontal_alignment(alignment::Horizontal::Center), + ) + .style(grin_gui_core::theme::ButtonStyle::NormalText) + .on_press(Message::Interaction(Interaction::WriteToClipboard( + card_contents.clone(), + ))), + ), + ) + .max_width(400.0) + .style(grin_gui_core::theme::CardStyle::Normal); + + let unit_spacing = 15.0; + + let button_height = Length::Fixed(BUTTON_HEIGHT); + let button_width = Length::Fixed(BUTTON_WIDTH); + + let cancel_button_label_container = + Container::new(Text::new(localized_string("ok-caps")).size(DEFAULT_FONT_SIZE)) + .width(button_width) + .height(button_height) + .center_x() + .center_y() + .align_x(alignment::Horizontal::Center); + + let cancel_button: Element = Button::new(cancel_button_label_container) + .style(grin_gui_core::theme::ButtonStyle::Primary) + .on_press(Interaction::WalletOperationShowSlatepackViewInteraction( + LocalViewInteraction::Submit, + )) + .into(); + + let cancel_container = Container::new(cancel_button.map(Message::Interaction)).padding(1); + let cancel_container = Container::new(cancel_container) + .style(grin_gui_core::theme::ContainerStyle::Segmented) + .padding(1); + + let unit_spacing = 15.0; + let button_row = Row::new().push(cancel_container); + + let column = Column::new() + .push(description_container) + .push(Space::new( + Length::Fixed(0.0), + Length::Fixed(unit_spacing + 5.0), + )) + .push(encrypted_slate_card) + .push(Space::new( + Length::Fixed(0.0), + Length::Fixed(unit_spacing + 10.0), + )) + .push(button_row) + .push(Space::new( + Length::Fixed(0.0), + Length::Fixed(unit_spacing + 10.0), + )); + + let form_container = Container::new(column) + .width(Length::Fill) + .padding(iced::Padding::from([ + 0, // top + 0, // right + 0, // bottom + 5, // left + ])); + + // form container should be scrollable in tiny windows + let scrollable = Scrollable::new(form_container) + .height(Length::Fill) + .style(grin_gui_core::theme::ScrollableStyle::Primary); + + let content = Container::new(scrollable) + .width(Length::Fill) + .height(Length::Shrink) + .style(grin_gui_core::theme::ContainerStyle::NormalBackground); + + let wrapper_column = Column::new() + .height(Length::Fill) + .push(header_container) + .push(content); + + // Returns the final container. + Container::new(wrapper_column).padding(iced::Padding::from([ + DEFAULT_PADDING, // top + DEFAULT_PADDING, // right + DEFAULT_PADDING, // bottom + DEFAULT_PADDING, // left + ])) } diff --git a/src/gui/element/wallet/operation/tx_detail.rs b/src/gui/element/wallet/operation/tx_detail.rs index b99a5a4..6c01635 100644 --- a/src/gui/element/wallet/operation/tx_detail.rs +++ b/src/gui/element/wallet/operation/tx_detail.rs @@ -2,9 +2,9 @@ use super::tx_list::{self, ExpandType}; use crate::log_error; use async_std::prelude::FutureExt; use grin_gui_core::{ - config::Config, - error::GrinWalletInterfaceError, - wallet::{TxLogEntry, TxLogEntryType}, + config::Config, + error::GrinWalletInterfaceError, + wallet::{TxLogEntry, TxLogEntryType}, }; use grin_gui_widgets::widget::header; use iced_aw::Card; @@ -16,40 +16,40 @@ use std::path::PathBuf; use super::tx_list::{HeaderState, TxList}; use { - super::super::super::{ - BUTTON_HEIGHT, BUTTON_WIDTH, DEFAULT_FONT_SIZE, DEFAULT_HEADER_FONT_SIZE, DEFAULT_PADDING, - SMALLER_FONT_SIZE, - }, - crate::gui::{GrinGui, Interaction, Message}, - crate::localization::localized_string, - crate::Result, - anyhow::Context, - grin_gui_core::theme::{ - Button, Column, Container, Element, Header, PickList, Row, Scrollable, TableRow, Text, - TextInput, - }, - grin_gui_core::wallet::{InitTxArgs, Slate, StatusMessage, WalletInfo, WalletInterface}, - grin_gui_core::{ - node::{amount_from_hr_string, amount_to_hr_string}, - theme::{ButtonStyle, ColorPalette, ContainerStyle}, - }, - iced::widget::{button, pick_list, scrollable, text_input, Checkbox, Space}, - iced::{alignment, Alignment, Command, Length}, - serde::{Deserialize, Serialize}, - std::sync::{Arc, RwLock}, + super::super::super::{ + BUTTON_HEIGHT, BUTTON_WIDTH, DEFAULT_FONT_SIZE, DEFAULT_HEADER_FONT_SIZE, DEFAULT_PADDING, + SMALLER_FONT_SIZE, + }, + crate::gui::{GrinGui, Interaction, Message}, + crate::localization::localized_string, + crate::Result, + anyhow::Context, + grin_gui_core::theme::{ + Button, Column, Container, Element, Header, PickList, Row, Scrollable, TableRow, Text, + TextInput, + }, + grin_gui_core::wallet::{InitTxArgs, Slate, StatusMessage, WalletInfo, WalletInterface}, + grin_gui_core::{ + node::{amount_from_hr_string, amount_to_hr_string}, + theme::{ButtonStyle, ColorPalette, ContainerStyle}, + }, + iced::widget::{button, pick_list, scrollable, text_input, Checkbox, Space}, + iced::{alignment, Alignment, Command, Length}, + serde::{Deserialize, Serialize}, + std::sync::{Arc, RwLock}, }; pub struct StateContainer { - // Transaction that we're viewing - pub current_tx: Option, + // Transaction that we're viewing + pub current_tx: Option, } impl Default for StateContainer { - fn default() -> Self { - Self { - current_tx: Default::default(), - } - } + fn default() -> Self { + Self { + current_tx: Default::default(), + } + } } #[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)] @@ -57,333 +57,361 @@ pub enum Action {} #[derive(Debug, Clone)] pub enum LocalViewInteraction { - Back, + Back, } pub fn handle_message<'a>( - grin_gui: &mut GrinGui, - message: LocalViewInteraction, + grin_gui: &mut GrinGui, + message: LocalViewInteraction, ) -> Result> { - let state = &mut grin_gui.wallet_state.operation_state.create_tx_state; + let state = &mut grin_gui.wallet_state.operation_state.create_tx_state; - match message { - LocalViewInteraction::Back => { - log::debug!("Interaction::WalletOperationTxDetailViewInteraction(Back)"); - grin_gui.wallet_state.operation_state.mode = - crate::gui::element::wallet::operation::Mode::Home; - } - } + match message { + LocalViewInteraction::Back => { + log::debug!("Interaction::WalletOperationTxDetailViewInteraction(Back)"); + grin_gui.wallet_state.operation_state.mode = + crate::gui::element::wallet::operation::Mode::Home; + } + } - Ok(Command::none()) + Ok(Command::none()) } pub fn data_container<'a>(config: &'a Config, state: &'a StateContainer) -> Container<'a, Message> { - // Title row - let title = Text::new(localized_string("tx-details-title")) - .size(DEFAULT_HEADER_FONT_SIZE) - .horizontal_alignment(alignment::Horizontal::Center); + // Title row + let title = Text::new(localized_string("tx-details-title")) + .size(DEFAULT_HEADER_FONT_SIZE) + .horizontal_alignment(alignment::Horizontal::Center); - let title_container = Container::new(title) - .style(grin_gui_core::theme::ContainerStyle::BrightBackground) - .padding(iced::Padding::from([ - 2, // top - 0, // right - 2, // bottom - 5, // left - ])); + let title_container = Container::new(title) + .style(grin_gui_core::theme::ContainerStyle::BrightBackground) + .padding(iced::Padding::from([ + 2, // top + 0, // right + 2, // bottom + 5, // left + ])); - let header_row = Row::new().push(title_container); + let header_row = Row::new().push(title_container); - let header_container = Container::new(header_row).padding(iced::Padding::from([ - 0, // top - 0, // right - DEFAULT_PADDING as u16, // bottom - 0, // left - ])); + let header_container = Container::new(header_row).padding(iced::Padding::from([ + 0, // top + 0, // right + DEFAULT_PADDING as u16, // bottom + 0, // left + ])); - let unit_spacing = 15.0; - let row_spacing = 5.0; + let unit_spacing = 15.0; + let row_spacing = 5.0; - let button_height = Length::Fixed(BUTTON_HEIGHT); - let button_width = Length::Fixed(BUTTON_WIDTH); + let button_height = Length::Fixed(BUTTON_HEIGHT); + let button_width = Length::Fixed(BUTTON_WIDTH); - let mut column = Column::new(); + let mut column = Column::new(); - if let Some(ref tx) = state.current_tx { - // ID - let id_label = Text::new(format!("{}: ", localized_string("tx-id"))) - .size(DEFAULT_FONT_SIZE) - .horizontal_alignment(alignment::Horizontal::Left); + if let Some(ref tx) = state.current_tx { + // ID + let id_label = Text::new(format!("{}: ", localized_string("tx-id"))) + .size(DEFAULT_FONT_SIZE) + .horizontal_alignment(alignment::Horizontal::Left); - let id_label_container = - Container::new(id_label).style(grin_gui_core::theme::ContainerStyle::NormalBackground); + let id_label_container = + Container::new(id_label).style(grin_gui_core::theme::ContainerStyle::NormalBackground); - let id_value = Text::new(format!("{}", tx.id)) - .size(DEFAULT_FONT_SIZE) - .horizontal_alignment(alignment::Horizontal::Left); + let id_value = Text::new(format!("{}", tx.id)) + .size(DEFAULT_FONT_SIZE) + .horizontal_alignment(alignment::Horizontal::Left); - let id_value_container = - Container::new(id_value).style(grin_gui_core::theme::ContainerStyle::NormalBackground); + let id_value_container = + Container::new(id_value).style(grin_gui_core::theme::ContainerStyle::NormalBackground); - let id_row = Row::new().push(id_label_container).push(id_value_container); + let id_row = Row::new().push(id_label_container).push(id_value_container); - column = column - .push(id_row) - .push(Space::new(Length::Fixed(0.0), Length::Fixed(row_spacing))); + column = column + .push(id_row) + .push(Space::new(Length::Fixed(0.0), Length::Fixed(row_spacing))); - // Tx Type - let tx_type_label = Text::new(format!("{}: ", localized_string("tx-type"))) - .size(DEFAULT_FONT_SIZE) - .horizontal_alignment(alignment::Horizontal::Left); + // Tx Type + let tx_type_label = Text::new(format!("{}: ", localized_string("tx-type"))) + .size(DEFAULT_FONT_SIZE) + .horizontal_alignment(alignment::Horizontal::Left); - let tx_type_label_container = - Container::new(tx_type_label).style(grin_gui_core::theme::ContainerStyle::NormalBackground); + let tx_type_label_container = Container::new(tx_type_label) + .style(grin_gui_core::theme::ContainerStyle::NormalBackground); - let tx_type_value = Text::new(format!("{}", tx.tx_type)) - .size(DEFAULT_FONT_SIZE) - .horizontal_alignment(alignment::Horizontal::Left); + let tx_type_value = Text::new(format!("{}", tx.tx_type)) + .size(DEFAULT_FONT_SIZE) + .horizontal_alignment(alignment::Horizontal::Left); - let tx_type_value_container = - Container::new(tx_type_value).style(grin_gui_core::theme::ContainerStyle::NormalBackground); + let tx_type_value_container = Container::new(tx_type_value) + .style(grin_gui_core::theme::ContainerStyle::NormalBackground); - let tx_type_row = Row::new().push(tx_type_label_container).push(tx_type_value_container); + let tx_type_row = Row::new() + .push(tx_type_label_container) + .push(tx_type_value_container); - column = column - .push(tx_type_row) - .push(Space::new(Length::Fixed(0.0), Length::Fixed(row_spacing))); + column = column + .push(tx_type_row) + .push(Space::new(Length::Fixed(0.0), Length::Fixed(row_spacing))); + // UUID + let shared_tx_id_label = Text::new(format!("{}: ", localized_string("tx-shared-id"))) + .size(DEFAULT_FONT_SIZE) + .horizontal_alignment(alignment::Horizontal::Left); - // UUID - let shared_tx_id_label = Text::new(format!("{}: ", localized_string("tx-shared-id"))) - .size(DEFAULT_FONT_SIZE) - .horizontal_alignment(alignment::Horizontal::Left); + let shared_tx_id_label_container = Container::new(shared_tx_id_label) + .style(grin_gui_core::theme::ContainerStyle::NormalBackground); - let shared_tx_id_label_container = - Container::new(shared_tx_id_label).style(grin_gui_core::theme::ContainerStyle::NormalBackground); - - let uuid = match tx.tx_slate_id { - Some(u) => u.to_string(), - None => "None".to_owned(), - }; - - let shared_tx_id_value = Text::new(format!("{}", uuid)) - .size(DEFAULT_FONT_SIZE) - .horizontal_alignment(alignment::Horizontal::Left); - - let shared_tx_id_value_container = - Container::new(shared_tx_id_value).style(grin_gui_core::theme::ContainerStyle::NormalBackground); - - let shared_tx_id_row = Row::new().push(shared_tx_id_label_container).push(shared_tx_id_value_container); - - column = column - .push(shared_tx_id_row) - .push(Space::new(Length::Fixed(0.0), Length::Fixed(row_spacing))); - - // Creation Time - let tx_creation_time_label = Text::new(format!("{}: ", localized_string("tx-creation-time"))) - .size(DEFAULT_FONT_SIZE) - .horizontal_alignment(alignment::Horizontal::Left); - - let tx_creation_time_label_container = - Container::new(tx_creation_time_label).style(grin_gui_core::theme::ContainerStyle::NormalBackground); - - let tx_creation_time_value = Text::new(format!("{}", tx.creation_ts)) - .size(DEFAULT_FONT_SIZE) - .horizontal_alignment(alignment::Horizontal::Left); - - let tx_creation_time_value_container = - Container::new(tx_creation_time_value).style(grin_gui_core::theme::ContainerStyle::NormalBackground); - - let tx_creation_time_row = Row::new().push(tx_creation_time_label_container).push(tx_creation_time_value_container); - - column = column - .push(tx_creation_time_row) - .push(Space::new(Length::Fixed(0.0), Length::Fixed(row_spacing))); - - // TTL Cutoff Height - let ttl_cutoff_label = Text::new(format!("{}: ", localized_string("tx-ttl-cutoff"))) - .size(DEFAULT_FONT_SIZE) - .horizontal_alignment(alignment::Horizontal::Left); - - let ttl_cutoff_label_container = - Container::new(ttl_cutoff_label).style(grin_gui_core::theme::ContainerStyle::NormalBackground); - - let ttl = match tx.ttl_cutoff_height { - Some(u) => u.to_string(), - None => "None".to_owned(), - }; - - let ttl_cutoff_value = Text::new(format!("{}", ttl)) - .size(DEFAULT_FONT_SIZE) - .horizontal_alignment(alignment::Horizontal::Left); - - let ttl_cutoff_value_container = - Container::new(ttl_cutoff_value).style(grin_gui_core::theme::ContainerStyle::NormalBackground); - - let ttl_cutoff_row = Row::new().push(ttl_cutoff_label_container).push(ttl_cutoff_value_container); - - column = column - .push(ttl_cutoff_row) - .push(Space::new(Length::Fixed(0.0), Length::Fixed(row_spacing))); - - // Confirmed - let confirmed_label = Text::new(format!("{}: ", localized_string("tx-is-confirmed"))) - .size(DEFAULT_FONT_SIZE) - .horizontal_alignment(alignment::Horizontal::Left); - - let confirmed_label_container = - Container::new(confirmed_label).style(grin_gui_core::theme::ContainerStyle::NormalBackground); - - let confirmed_value = Text::new(format!("{}", tx.confirmed)) - .size(DEFAULT_FONT_SIZE) - .horizontal_alignment(alignment::Horizontal::Left); - - let confirmed_value_container = - Container::new(confirmed_value).style(grin_gui_core::theme::ContainerStyle::NormalBackground); - - let confirmed_row = Row::new().push(confirmed_label_container).push(confirmed_value_container); - - column = column - .push(confirmed_row) - .push(Space::new(Length::Fixed(0.0), Length::Fixed(row_spacing))); - - // Confirmation Time - let tx_confirmation_time_label = Text::new(format!("{}: ", localized_string("tx-confirmation-time"))) - .size(DEFAULT_FONT_SIZE) - .horizontal_alignment(alignment::Horizontal::Left); - - let tx_confirmation_time_label_container = - Container::new(tx_confirmation_time_label).style(grin_gui_core::theme::ContainerStyle::NormalBackground); + let uuid = match tx.tx_slate_id { + Some(u) => u.to_string(), + None => "None".to_owned(), + }; - let time = match tx.confirmation_ts { - Some(u) => u.to_string(), - None => "None".to_owned(), - }; + let shared_tx_id_value = Text::new(format!("{}", uuid)) + .size(DEFAULT_FONT_SIZE) + .horizontal_alignment(alignment::Horizontal::Left); - let tx_confirmation_time_value = Text::new(format!("{}", time)) - .size(DEFAULT_FONT_SIZE) - .horizontal_alignment(alignment::Horizontal::Left); + let shared_tx_id_value_container = Container::new(shared_tx_id_value) + .style(grin_gui_core::theme::ContainerStyle::NormalBackground); - let tx_confirmation_time_value_container = - Container::new(tx_confirmation_time_value).style(grin_gui_core::theme::ContainerStyle::NormalBackground); + let shared_tx_id_row = Row::new() + .push(shared_tx_id_label_container) + .push(shared_tx_id_value_container); - let tx_confirmation_time_row = Row::new().push(tx_confirmation_time_label_container).push(tx_confirmation_time_value_container); - column = column - .push(tx_confirmation_time_row) - .push(Space::new(Length::Fixed(0.0), Length::Fixed(row_spacing))); + column = column + .push(shared_tx_id_row) + .push(Space::new(Length::Fixed(0.0), Length::Fixed(row_spacing))); - // Number of Inputs - let tx_num_inputs_label = Text::new(format!("{}: ", localized_string("tx-num-inputs"))) - .size(DEFAULT_FONT_SIZE) - .horizontal_alignment(alignment::Horizontal::Left); + // Creation Time + let tx_creation_time_label = + Text::new(format!("{}: ", localized_string("tx-creation-time"))) + .size(DEFAULT_FONT_SIZE) + .horizontal_alignment(alignment::Horizontal::Left); - let tx_num_inputs_label_container = - Container::new(tx_num_inputs_label).style(grin_gui_core::theme::ContainerStyle::NormalBackground); + let tx_creation_time_label_container = Container::new(tx_creation_time_label) + .style(grin_gui_core::theme::ContainerStyle::NormalBackground); - let tx_num_inputs_value = Text::new(format!("{}", tx.num_inputs)) - .size(DEFAULT_FONT_SIZE) - .horizontal_alignment(alignment::Horizontal::Left); + let tx_creation_time_value = Text::new(format!("{}", tx.creation_ts)) + .size(DEFAULT_FONT_SIZE) + .horizontal_alignment(alignment::Horizontal::Left); - let tx_num_inputs_value_container = - Container::new(tx_num_inputs_value).style(grin_gui_core::theme::ContainerStyle::NormalBackground); + let tx_creation_time_value_container = Container::new(tx_creation_time_value) + .style(grin_gui_core::theme::ContainerStyle::NormalBackground); - let tx_num_inputs_row = Row::new().push(tx_num_inputs_label_container).push(tx_num_inputs_value_container); - column = column - .push(tx_num_inputs_row) - .push(Space::new(Length::Fixed(0.0), Length::Fixed(row_spacing))); + let tx_creation_time_row = Row::new() + .push(tx_creation_time_label_container) + .push(tx_creation_time_value_container); - // Number of Outputs - let tx_num_outputs_label = Text::new(format!("{}: ", localized_string("tx-num-outputs"))) - .size(DEFAULT_FONT_SIZE) - .horizontal_alignment(alignment::Horizontal::Left); + column = column + .push(tx_creation_time_row) + .push(Space::new(Length::Fixed(0.0), Length::Fixed(row_spacing))); - let tx_num_outputs_label_container = - Container::new(tx_num_outputs_label).style(grin_gui_core::theme::ContainerStyle::NormalBackground); + // TTL Cutoff Height + let ttl_cutoff_label = Text::new(format!("{}: ", localized_string("tx-ttl-cutoff"))) + .size(DEFAULT_FONT_SIZE) + .horizontal_alignment(alignment::Horizontal::Left); - let tx_num_outputs_value = Text::new(format!("{}", tx.num_outputs)) - .size(DEFAULT_FONT_SIZE) - .horizontal_alignment(alignment::Horizontal::Left); + let ttl_cutoff_label_container = Container::new(ttl_cutoff_label) + .style(grin_gui_core::theme::ContainerStyle::NormalBackground); - let tx_num_outputs_value_container = - Container::new(tx_num_outputs_value).style(grin_gui_core::theme::ContainerStyle::NormalBackground); + let ttl = match tx.ttl_cutoff_height { + Some(u) => u.to_string(), + None => "None".to_owned(), + }; - let tx_num_outputs_row = Row::new().push(tx_num_outputs_label_container).push(tx_num_outputs_value_container); - column = column - .push(tx_num_outputs_row) - .push(Space::new(Length::Fixed(0.0), Length::Fixed(row_spacing))); + let ttl_cutoff_value = Text::new(format!("{}", ttl)) + .size(DEFAULT_FONT_SIZE) + .horizontal_alignment(alignment::Horizontal::Left); - // Amount Credited - let tx_amount_credited_label = Text::new(format!("{}: ", localized_string("tx-amount-credited"))) - .size(DEFAULT_FONT_SIZE) - .horizontal_alignment(alignment::Horizontal::Left); + let ttl_cutoff_value_container = Container::new(ttl_cutoff_value) + .style(grin_gui_core::theme::ContainerStyle::NormalBackground); - let tx_amount_credited_label_container = - Container::new(tx_amount_credited_label).style(grin_gui_core::theme::ContainerStyle::NormalBackground); + let ttl_cutoff_row = Row::new() + .push(ttl_cutoff_label_container) + .push(ttl_cutoff_value_container); - let tx_amount_credited_value = Text::new(format!("{}", amount_to_hr_string(tx.amount_credited, true))) - .size(DEFAULT_FONT_SIZE) - .horizontal_alignment(alignment::Horizontal::Left); + column = column + .push(ttl_cutoff_row) + .push(Space::new(Length::Fixed(0.0), Length::Fixed(row_spacing))); - let tx_amount_credited_value_container = - Container::new(tx_amount_credited_value).style(grin_gui_core::theme::ContainerStyle::NormalBackground); + // Confirmed + let confirmed_label = Text::new(format!("{}: ", localized_string("tx-is-confirmed"))) + .size(DEFAULT_FONT_SIZE) + .horizontal_alignment(alignment::Horizontal::Left); - let tx_amount_credited_row = Row::new().push(tx_amount_credited_label_container).push(tx_amount_credited_value_container); - column = column - .push(tx_amount_credited_row) - .push(Space::new(Length::Fixed(0.0), Length::Fixed(row_spacing))); + let confirmed_label_container = Container::new(confirmed_label) + .style(grin_gui_core::theme::ContainerStyle::NormalBackground); - // Amount Debited - let tx_amount_debited_label = Text::new(format!("{}: ", localized_string("tx-amount-debited"))) - .size(DEFAULT_FONT_SIZE) - .horizontal_alignment(alignment::Horizontal::Left); + let confirmed_value = Text::new(format!("{}", tx.confirmed)) + .size(DEFAULT_FONT_SIZE) + .horizontal_alignment(alignment::Horizontal::Left); - let tx_amount_debited_label_container = - Container::new(tx_amount_debited_label).style(grin_gui_core::theme::ContainerStyle::NormalBackground); + let confirmed_value_container = Container::new(confirmed_value) + .style(grin_gui_core::theme::ContainerStyle::NormalBackground); - let tx_amount_debited_value = Text::new(format!("{}", amount_to_hr_string(tx.amount_debited, true))) - .size(DEFAULT_FONT_SIZE) - .horizontal_alignment(alignment::Horizontal::Left); + let confirmed_row = Row::new() + .push(confirmed_label_container) + .push(confirmed_value_container); - let tx_amount_debited_value_container = - Container::new(tx_amount_debited_value).style(grin_gui_core::theme::ContainerStyle::NormalBackground); + column = column + .push(confirmed_row) + .push(Space::new(Length::Fixed(0.0), Length::Fixed(row_spacing))); - let tx_amount_debited_row = Row::new().push(tx_amount_debited_label_container).push(tx_amount_debited_value_container); - column = column - .push(tx_amount_debited_row) - .push(Space::new(Length::Fixed(0.0), Length::Fixed(row_spacing))); + // Confirmation Time + let tx_confirmation_time_label = + Text::new(format!("{}: ", localized_string("tx-confirmation-time"))) + .size(DEFAULT_FONT_SIZE) + .horizontal_alignment(alignment::Horizontal::Left); - // Fee - let tx_fee_label = Text::new(format!("{}: ", localized_string("tx-fee"))) - .size(DEFAULT_FONT_SIZE) - .horizontal_alignment(alignment::Horizontal::Left); + let tx_confirmation_time_label_container = Container::new(tx_confirmation_time_label) + .style(grin_gui_core::theme::ContainerStyle::NormalBackground); - let tx_fee_label_container = - Container::new(tx_fee_label).style(grin_gui_core::theme::ContainerStyle::NormalBackground); + let time = match tx.confirmation_ts { + Some(u) => u.to_string(), + None => "None".to_owned(), + }; - let fee = match tx.fee { - Some(u) => format!("{}", amount_to_hr_string(u.fee(), true)), - None => "None".to_owned(), - }; + let tx_confirmation_time_value = Text::new(format!("{}", time)) + .size(DEFAULT_FONT_SIZE) + .horizontal_alignment(alignment::Horizontal::Left); + + let tx_confirmation_time_value_container = Container::new(tx_confirmation_time_value) + .style(grin_gui_core::theme::ContainerStyle::NormalBackground); + + let tx_confirmation_time_row = Row::new() + .push(tx_confirmation_time_label_container) + .push(tx_confirmation_time_value_container); + column = column + .push(tx_confirmation_time_row) + .push(Space::new(Length::Fixed(0.0), Length::Fixed(row_spacing))); + + // Number of Inputs + let tx_num_inputs_label = Text::new(format!("{}: ", localized_string("tx-num-inputs"))) + .size(DEFAULT_FONT_SIZE) + .horizontal_alignment(alignment::Horizontal::Left); + + let tx_num_inputs_label_container = Container::new(tx_num_inputs_label) + .style(grin_gui_core::theme::ContainerStyle::NormalBackground); + + let tx_num_inputs_value = Text::new(format!("{}", tx.num_inputs)) + .size(DEFAULT_FONT_SIZE) + .horizontal_alignment(alignment::Horizontal::Left); + + let tx_num_inputs_value_container = Container::new(tx_num_inputs_value) + .style(grin_gui_core::theme::ContainerStyle::NormalBackground); + + let tx_num_inputs_row = Row::new() + .push(tx_num_inputs_label_container) + .push(tx_num_inputs_value_container); + column = column + .push(tx_num_inputs_row) + .push(Space::new(Length::Fixed(0.0), Length::Fixed(row_spacing))); + + // Number of Outputs + let tx_num_outputs_label = Text::new(format!("{}: ", localized_string("tx-num-outputs"))) + .size(DEFAULT_FONT_SIZE) + .horizontal_alignment(alignment::Horizontal::Left); + + let tx_num_outputs_label_container = Container::new(tx_num_outputs_label) + .style(grin_gui_core::theme::ContainerStyle::NormalBackground); + + let tx_num_outputs_value = Text::new(format!("{}", tx.num_outputs)) + .size(DEFAULT_FONT_SIZE) + .horizontal_alignment(alignment::Horizontal::Left); + + let tx_num_outputs_value_container = Container::new(tx_num_outputs_value) + .style(grin_gui_core::theme::ContainerStyle::NormalBackground); + + let tx_num_outputs_row = Row::new() + .push(tx_num_outputs_label_container) + .push(tx_num_outputs_value_container); + column = column + .push(tx_num_outputs_row) + .push(Space::new(Length::Fixed(0.0), Length::Fixed(row_spacing))); + + // Amount Credited + let tx_amount_credited_label = + Text::new(format!("{}: ", localized_string("tx-amount-credited"))) + .size(DEFAULT_FONT_SIZE) + .horizontal_alignment(alignment::Horizontal::Left); + + let tx_amount_credited_label_container = Container::new(tx_amount_credited_label) + .style(grin_gui_core::theme::ContainerStyle::NormalBackground); + + let tx_amount_credited_value = + Text::new(format!("{}", amount_to_hr_string(tx.amount_credited, true))) + .size(DEFAULT_FONT_SIZE) + .horizontal_alignment(alignment::Horizontal::Left); + + let tx_amount_credited_value_container = Container::new(tx_amount_credited_value) + .style(grin_gui_core::theme::ContainerStyle::NormalBackground); + + let tx_amount_credited_row = Row::new() + .push(tx_amount_credited_label_container) + .push(tx_amount_credited_value_container); + column = column + .push(tx_amount_credited_row) + .push(Space::new(Length::Fixed(0.0), Length::Fixed(row_spacing))); + + // Amount Debited + let tx_amount_debited_label = + Text::new(format!("{}: ", localized_string("tx-amount-debited"))) + .size(DEFAULT_FONT_SIZE) + .horizontal_alignment(alignment::Horizontal::Left); + + let tx_amount_debited_label_container = Container::new(tx_amount_debited_label) + .style(grin_gui_core::theme::ContainerStyle::NormalBackground); + + let tx_amount_debited_value = + Text::new(format!("{}", amount_to_hr_string(tx.amount_debited, true))) + .size(DEFAULT_FONT_SIZE) + .horizontal_alignment(alignment::Horizontal::Left); + + let tx_amount_debited_value_container = Container::new(tx_amount_debited_value) + .style(grin_gui_core::theme::ContainerStyle::NormalBackground); + + let tx_amount_debited_row = Row::new() + .push(tx_amount_debited_label_container) + .push(tx_amount_debited_value_container); + column = column + .push(tx_amount_debited_row) + .push(Space::new(Length::Fixed(0.0), Length::Fixed(row_spacing))); + + // Fee + let tx_fee_label = Text::new(format!("{}: ", localized_string("tx-fee"))) + .size(DEFAULT_FONT_SIZE) + .horizontal_alignment(alignment::Horizontal::Left); + + let tx_fee_label_container = Container::new(tx_fee_label) + .style(grin_gui_core::theme::ContainerStyle::NormalBackground); + + let fee = match tx.fee { + Some(u) => format!("{}", amount_to_hr_string(u.fee(), true)), + None => "None".to_owned(), + }; - let tx_fee_value = Text::new(format!("{}", fee)) - .size(DEFAULT_FONT_SIZE) - .horizontal_alignment(alignment::Horizontal::Left); + let tx_fee_value = Text::new(format!("{}", fee)) + .size(DEFAULT_FONT_SIZE) + .horizontal_alignment(alignment::Horizontal::Left); - let tx_fee_value_container = - Container::new(tx_fee_value).style(grin_gui_core::theme::ContainerStyle::NormalBackground); + let tx_fee_value_container = Container::new(tx_fee_value) + .style(grin_gui_core::theme::ContainerStyle::NormalBackground); - let tx_fee_row = Row::new().push(tx_fee_label_container).push(tx_fee_value_container); - column = column - .push(tx_fee_row) - .push(Space::new(Length::Fixed(0.0), Length::Fixed(row_spacing))); + let tx_fee_row = Row::new() + .push(tx_fee_label_container) + .push(tx_fee_value_container); + column = column + .push(tx_fee_row) + .push(Space::new(Length::Fixed(0.0), Length::Fixed(row_spacing))); - // Net Difference - let tx_net_difference_label = Text::new(format!("{}: ", localized_string("tx-net-difference"))) - .size(DEFAULT_FONT_SIZE) - .horizontal_alignment(alignment::Horizontal::Left); + // Net Difference + let tx_net_difference_label = + Text::new(format!("{}: ", localized_string("tx-net-difference"))) + .size(DEFAULT_FONT_SIZE) + .horizontal_alignment(alignment::Horizontal::Left); - let tx_net_difference_label_container = - Container::new(tx_net_difference_label).style(grin_gui_core::theme::ContainerStyle::NormalBackground); + let tx_net_difference_label_container = Container::new(tx_net_difference_label) + .style(grin_gui_core::theme::ContainerStyle::NormalBackground); let net_diff = if tx.amount_credited >= tx.amount_debited { amount_to_hr_string(tx.amount_credited - tx.amount_debited, true) @@ -393,76 +421,77 @@ pub fn data_container<'a>(config: &'a Config, state: &'a StateContainer) -> Cont amount_to_hr_string(tx.amount_debited - tx.amount_credited, true) ) }; - - let tx_net_difference_value = Text::new(format!("{}", net_diff)) - .size(DEFAULT_FONT_SIZE) - .horizontal_alignment(alignment::Horizontal::Left); - - let tx_net_difference_value_container = - Container::new(tx_net_difference_value).style(grin_gui_core::theme::ContainerStyle::NormalBackground); - - let tx_net_difference_row = Row::new().push(tx_net_difference_label_container).push(tx_net_difference_value_container); - column = column - .push(tx_net_difference_row) - .push(Space::new(Length::Fixed(0.0), Length::Fixed(unit_spacing))); - - } - - let cancel_button_label_container = - Container::new(Text::new(localized_string("back")).size(DEFAULT_FONT_SIZE)) - .width(button_width) - .height(button_height) - .center_x() - .center_y() - .align_x(alignment::Horizontal::Center); - - let cancel_button: Element = Button::new(cancel_button_label_container) - .style(grin_gui_core::theme::ButtonStyle::Primary) - .on_press(Interaction::WalletOperationTxDetailViewInteraction( - LocalViewInteraction::Back, - )) - .into(); - - let cancel_container = Container::new(cancel_button.map(Message::Interaction)).padding(1); - let cancel_container = Container::new(cancel_container) - .style(grin_gui_core::theme::ContainerStyle::Segmented) - .padding(1); - - let button_row = Row::new() - .push(cancel_container) - .push(Space::new(Length::Fixed(unit_spacing), Length::Fixed(0.0))); - - column = column.push(button_row); - - let form_container = Container::new(column) - .width(Length::Fill) - .padding(iced::Padding::from([ - 0, // top - 0, // right - 0, // bottom - 5, // left - ])); - - // form container should be scrollable in tiny windows - let scrollable = Scrollable::new(form_container) - .height(Length::Fill) - .style(grin_gui_core::theme::ScrollableStyle::Primary); - - let content = Container::new(scrollable) - .width(Length::Fill) - .height(Length::Shrink) - .style(grin_gui_core::theme::ContainerStyle::NormalBackground); - - let wrapper_column = Column::new() - .height(Length::Fill) - .push(header_container) - .push(content); - - // Returns the final container. - Container::new(wrapper_column).padding(iced::Padding::from([ - DEFAULT_PADDING, // top - DEFAULT_PADDING, // right - DEFAULT_PADDING, // bottom - DEFAULT_PADDING, // left - ])) + + let tx_net_difference_value = Text::new(format!("{}", net_diff)) + .size(DEFAULT_FONT_SIZE) + .horizontal_alignment(alignment::Horizontal::Left); + + let tx_net_difference_value_container = Container::new(tx_net_difference_value) + .style(grin_gui_core::theme::ContainerStyle::NormalBackground); + + let tx_net_difference_row = Row::new() + .push(tx_net_difference_label_container) + .push(tx_net_difference_value_container); + column = column + .push(tx_net_difference_row) + .push(Space::new(Length::Fixed(0.0), Length::Fixed(unit_spacing))); + } + + let cancel_button_label_container = + Container::new(Text::new(localized_string("back")).size(DEFAULT_FONT_SIZE)) + .width(button_width) + .height(button_height) + .center_x() + .center_y() + .align_x(alignment::Horizontal::Center); + + let cancel_button: Element = Button::new(cancel_button_label_container) + .style(grin_gui_core::theme::ButtonStyle::Primary) + .on_press(Interaction::WalletOperationTxDetailViewInteraction( + LocalViewInteraction::Back, + )) + .into(); + + let cancel_container = Container::new(cancel_button.map(Message::Interaction)).padding(1); + let cancel_container = Container::new(cancel_container) + .style(grin_gui_core::theme::ContainerStyle::Segmented) + .padding(1); + + let button_row = Row::new() + .push(cancel_container) + .push(Space::new(Length::Fixed(unit_spacing), Length::Fixed(0.0))); + + column = column.push(button_row); + + let form_container = Container::new(column) + .width(Length::Fill) + .padding(iced::Padding::from([ + 0, // top + 0, // right + 0, // bottom + 5, // left + ])); + + // form container should be scrollable in tiny windows + let scrollable = Scrollable::new(form_container) + .height(Length::Fill) + .style(grin_gui_core::theme::ScrollableStyle::Primary); + + let content = Container::new(scrollable) + .width(Length::Fill) + .height(Length::Shrink) + .style(grin_gui_core::theme::ContainerStyle::NormalBackground); + + let wrapper_column = Column::new() + .height(Length::Fill) + .push(header_container) + .push(content); + + // Returns the final container. + Container::new(wrapper_column).padding(iced::Padding::from([ + DEFAULT_PADDING, // top + DEFAULT_PADDING, // right + DEFAULT_PADDING, // bottom + DEFAULT_PADDING, // left + ])) } diff --git a/src/gui/element/wallet/operation/tx_done.rs b/src/gui/element/wallet/operation/tx_done.rs index cc77af6..5ce20fc 100644 --- a/src/gui/element/wallet/operation/tx_done.rs +++ b/src/gui/element/wallet/operation/tx_done.rs @@ -1,153 +1,153 @@ use { - super::super::super::{ - BUTTON_HEIGHT, BUTTON_WIDTH, DEFAULT_FONT_SIZE, DEFAULT_HEADER_FONT_SIZE, DEFAULT_PADDING, - SMALLER_FONT_SIZE, - }, - crate::gui::{GrinGui, Interaction, Message}, - crate::localization::localized_string, - crate::Result, - grin_gui_core::config::Config, - grin_gui_core::theme::ColorPalette, - grin_gui_core::theme::{ - Column, Container, Element, PickList, Row, Scrollable, Text, TextInput, - }, - iced::widget::{button, pick_list, scrollable, text_input, Button, Checkbox, Space}, - iced::{alignment, Alignment, Command, Length}, - iced_aw::Card, + super::super::super::{ + BUTTON_HEIGHT, BUTTON_WIDTH, DEFAULT_FONT_SIZE, DEFAULT_HEADER_FONT_SIZE, DEFAULT_PADDING, + SMALLER_FONT_SIZE, + }, + crate::gui::{GrinGui, Interaction, Message}, + crate::localization::localized_string, + crate::Result, + grin_gui_core::config::Config, + grin_gui_core::theme::ColorPalette, + grin_gui_core::theme::{ + Column, Container, Element, PickList, Row, Scrollable, Text, TextInput, + }, + iced::widget::{button, pick_list, scrollable, text_input, Button, Checkbox, Space}, + iced::{alignment, Alignment, Command, Length}, + iced_aw::Card, }; pub struct StateContainer {} impl Default for StateContainer { - fn default() -> Self { - Self {} - } + fn default() -> Self { + Self {} + } } impl StateContainer {} #[derive(Debug, Clone)] pub enum LocalViewInteraction { - Submit, + Submit, } pub fn handle_message( - grin_gui: &mut GrinGui, - message: LocalViewInteraction, + grin_gui: &mut GrinGui, + message: LocalViewInteraction, ) -> Result> { - let state = &mut grin_gui.wallet_state.operation_state.tx_done_state; - match message { - LocalViewInteraction::Submit => { - grin_gui.wallet_state.operation_state.mode = - crate::gui::element::wallet::operation::Mode::Home; - } - } - Ok(Command::none()) + let state = &mut grin_gui.wallet_state.operation_state.tx_done_state; + match message { + LocalViewInteraction::Submit => { + grin_gui.wallet_state.operation_state.mode = + crate::gui::element::wallet::operation::Mode::Home; + } + } + Ok(Command::none()) } pub fn data_container<'a>( - _config: &'a Config, - state: &'a StateContainer, + _config: &'a Config, + state: &'a StateContainer, ) -> Container<'a, Message> { - // Title row - let title = Text::new(localized_string("tx-done")) - .size(DEFAULT_HEADER_FONT_SIZE) - .horizontal_alignment(alignment::Horizontal::Center); - - let title_container = Container::new(title) - .style(grin_gui_core::theme::ContainerStyle::BrightBackground) - .padding(iced::Padding::from([ - 2, // top - 0, // right - 2, // bottom - 5, // left - ])); - - // push more items on to header here: e.g. other buttons, things that belong on the header - let header_row = Row::new().push(title_container); - - let header_container = Container::new(header_row).padding(iced::Padding::from([ - 0, // top - 0, // right - DEFAULT_PADDING as u16, // bottom - 0, // left - ])); - - let description = Text::new(localized_string("tx-done-instruction")) - .size(DEFAULT_FONT_SIZE) - .horizontal_alignment(alignment::Horizontal::Center); - let description_container = - Container::new(description).style(grin_gui_core::theme::ContainerStyle::NormalBackground); - - let unit_spacing = 15.0; - - let button_height = Length::Fixed(BUTTON_HEIGHT); - let button_width = Length::Fixed(BUTTON_WIDTH); - - let cancel_button_label_container = - Container::new(Text::new(localized_string("ok-caps")).size(DEFAULT_FONT_SIZE)) - .width(button_width) - .height(button_height) - .center_x() - .center_y() - .align_x(alignment::Horizontal::Center); - - let cancel_button: Element = Button::new(cancel_button_label_container) - .style(grin_gui_core::theme::ButtonStyle::Primary) - .on_press(Interaction::WalletOperationTxDoneViewInteraction( - LocalViewInteraction::Submit, - )) - .into(); - - let cancel_container = Container::new(cancel_button.map(Message::Interaction)).padding(1); - let cancel_container = Container::new(cancel_container) - .style(grin_gui_core::theme::ContainerStyle::Segmented) - .padding(1); - - let unit_spacing = 15.0; - let button_row = Row::new().push(cancel_container); - - let column = Column::new() - .push(description_container) - .push(Space::new( - Length::Fixed(0.0), - Length::Fixed(unit_spacing + 5.0), - )) - .push(button_row) - .push(Space::new( - Length::Fixed(0.0), - Length::Fixed(unit_spacing + 10.0), - )); - - let form_container = Container::new(column) - .width(Length::Fill) - .padding(iced::Padding::from([ - 0, // top - 0, // right - 0, // bottom - 5, // left - ])); - - // form container should be scrollable in tiny windows - let scrollable = Scrollable::new(form_container) - .height(Length::Fill) - .style(grin_gui_core::theme::ScrollableStyle::Primary); - - let content = Container::new(scrollable) - .width(Length::Fill) - .height(Length::Shrink) - .style(grin_gui_core::theme::ContainerStyle::NormalBackground); - - let wrapper_column = Column::new() - .height(Length::Fill) - .push(header_container) - .push(content); - - // Returns the final container. - Container::new(wrapper_column).padding(iced::Padding::from([ - DEFAULT_PADDING, // top - DEFAULT_PADDING, // right - DEFAULT_PADDING, // bottom - DEFAULT_PADDING, // left - ])) + // Title row + let title = Text::new(localized_string("tx-done")) + .size(DEFAULT_HEADER_FONT_SIZE) + .horizontal_alignment(alignment::Horizontal::Center); + + let title_container = Container::new(title) + .style(grin_gui_core::theme::ContainerStyle::BrightBackground) + .padding(iced::Padding::from([ + 2, // top + 0, // right + 2, // bottom + 5, // left + ])); + + // push more items on to header here: e.g. other buttons, things that belong on the header + let header_row = Row::new().push(title_container); + + let header_container = Container::new(header_row).padding(iced::Padding::from([ + 0, // top + 0, // right + DEFAULT_PADDING as u16, // bottom + 0, // left + ])); + + let description = Text::new(localized_string("tx-done-instruction")) + .size(DEFAULT_FONT_SIZE) + .horizontal_alignment(alignment::Horizontal::Center); + let description_container = + Container::new(description).style(grin_gui_core::theme::ContainerStyle::NormalBackground); + + let unit_spacing = 15.0; + + let button_height = Length::Fixed(BUTTON_HEIGHT); + let button_width = Length::Fixed(BUTTON_WIDTH); + + let cancel_button_label_container = + Container::new(Text::new(localized_string("ok-caps")).size(DEFAULT_FONT_SIZE)) + .width(button_width) + .height(button_height) + .center_x() + .center_y() + .align_x(alignment::Horizontal::Center); + + let cancel_button: Element = Button::new(cancel_button_label_container) + .style(grin_gui_core::theme::ButtonStyle::Primary) + .on_press(Interaction::WalletOperationTxDoneViewInteraction( + LocalViewInteraction::Submit, + )) + .into(); + + let cancel_container = Container::new(cancel_button.map(Message::Interaction)).padding(1); + let cancel_container = Container::new(cancel_container) + .style(grin_gui_core::theme::ContainerStyle::Segmented) + .padding(1); + + let unit_spacing = 15.0; + let button_row = Row::new().push(cancel_container); + + let column = Column::new() + .push(description_container) + .push(Space::new( + Length::Fixed(0.0), + Length::Fixed(unit_spacing + 5.0), + )) + .push(button_row) + .push(Space::new( + Length::Fixed(0.0), + Length::Fixed(unit_spacing + 10.0), + )); + + let form_container = Container::new(column) + .width(Length::Fill) + .padding(iced::Padding::from([ + 0, // top + 0, // right + 0, // bottom + 5, // left + ])); + + // form container should be scrollable in tiny windows + let scrollable = Scrollable::new(form_container) + .height(Length::Fill) + .style(grin_gui_core::theme::ScrollableStyle::Primary); + + let content = Container::new(scrollable) + .width(Length::Fill) + .height(Length::Shrink) + .style(grin_gui_core::theme::ContainerStyle::NormalBackground); + + let wrapper_column = Column::new() + .height(Length::Fill) + .push(header_container) + .push(content); + + // Returns the final container. + Container::new(wrapper_column).padding(iced::Padding::from([ + DEFAULT_PADDING, // top + DEFAULT_PADDING, // right + DEFAULT_PADDING, // bottom + DEFAULT_PADDING, // left + ])) } diff --git a/src/gui/element/wallet/operation/tx_list.rs b/src/gui/element/wallet/operation/tx_list.rs index e363415..6a64718 100644 --- a/src/gui/element/wallet/operation/tx_list.rs +++ b/src/gui/element/wallet/operation/tx_list.rs @@ -4,38 +4,38 @@ use grin_gui_core::config::TxMethod; use iced_core::Widget; use { - super::super::super::{BUTTON_WIDTH, DEFAULT_FONT_SIZE, DEFAULT_PADDING, SMALLER_FONT_SIZE}, - crate::gui::{GrinGui, Interaction, Message}, - crate::localization::localized_string, - crate::Result, - grin_gui_core::theme::{ - Button, Column, Container, Element, Header, PickList, Row, Scrollable, TableRow, Text, - TextInput, - }, - grin_gui_core::{ - config::Config, - node::amount_to_hr_string, - theme::{ButtonStyle, ColorPalette, ContainerStyle}, - wallet::TxLogEntry, - }, - grin_gui_widgets::widget::header, - iced::widget::{button, pick_list, scrollable, text_input, Space}, - iced::{alignment, Alignment, Command, Length}, - serde::{Deserialize, Serialize}, - std::collections::HashMap, - strfmt::strfmt, + super::super::super::{BUTTON_WIDTH, DEFAULT_FONT_SIZE, DEFAULT_PADDING, SMALLER_FONT_SIZE}, + crate::gui::{GrinGui, Interaction, Message}, + crate::localization::localized_string, + crate::Result, + grin_gui_core::theme::{ + Button, Column, Container, Element, Header, PickList, Row, Scrollable, TableRow, Text, + TextInput, + }, + grin_gui_core::{ + config::Config, + node::amount_to_hr_string, + theme::{ButtonStyle, ColorPalette, ContainerStyle}, + wallet::TxLogEntry, + }, + grin_gui_widgets::widget::header, + iced::widget::{button, pick_list, scrollable, text_input, Space}, + iced::{alignment, Alignment, Command, Length}, + serde::{Deserialize, Serialize}, + std::collections::HashMap, + strfmt::strfmt, }; #[derive(Debug, Clone)] pub enum ExpandType { - Details(TxLogEntryWrap), - None, + Details(TxLogEntryWrap), + None, } #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub enum Confirm { - DeleteAddon, - DeleteSavedVariables, + DeleteAddon, + DeleteSavedVariables, } /* @@ -44,7 +44,7 @@ For reference: Transaction Log - Account 'default' - Block Height: 1926614 --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Id Type Shared Transaction Id Creation Time TTL Cutoff Height Confirmed? Confirmation Time Num. Num. Amount Amount Fee Net Payment Kernel Tx - Inputs Outputs Credited Debited Difference Proof Data + Inputs Outputs Credited Debited Difference Proof Data ========================================================================================================================================================================================================= 0 Received Tx None 2021-03-31 08:41:34 None true 2021-03-31 08:41:34 0 1 x.x 0.0 None x.x None None None --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- @@ -57,1894 +57,1894 @@ Transaction Log - Account 'default' - Block Height: 1926614 #[derive(Debug, Clone, Copy, PartialEq, Hash, Eq)] pub enum ColumnKey { - Id, - Type, - SharedTransactionId, - CreationTime, - Status, - TTLCutoff, - Height, - IsConfirmed, - ConfirmationTime, - NumInputs, - NumOutputs, - AmountCredited, - AmountDebited, - Fee, - NetDifference, - PaymentProof, - Kernel, - TxData, - // Only used for sorting, not an actual visible column that can be shown - FuzzyScore, + Id, + Type, + SharedTransactionId, + CreationTime, + Status, + TTLCutoff, + Height, + IsConfirmed, + ConfirmationTime, + NumInputs, + NumOutputs, + AmountCredited, + AmountDebited, + Fee, + NetDifference, + PaymentProof, + Kernel, + TxData, + // Only used for sorting, not an actual visible column that can be shown + FuzzyScore, } impl ColumnKey { - fn title(self) -> String { - use ColumnKey::*; - - match self { - Id => localized_string("tx_id"), - Type => localized_string("tx_type"), - SharedTransactionId => localized_string("tx_shared_id"), - CreationTime => localized_string("tx-creation-time"), - Status => localized_string("tx-status"), - TTLCutoff => localized_string("tx_ttl_cutoff"), - Height => localized_string("tx_height"), - IsConfirmed => localized_string("tx_is_confirmed"), - ConfirmationTime => localized_string("tx-confirmation-time"), - NumInputs => localized_string("tx_num_inputs"), - NumOutputs => localized_string("tx_num_outputs"), - AmountCredited => localized_string("tx_amount_credited"), - AmountDebited => localized_string("tx_amount_debited"), - Fee => localized_string("tx_fee"), - NetDifference => localized_string("tx-net-difference"), - PaymentProof => localized_string("tx_payment_proof"), - Kernel => localized_string("tx_kernel"), - TxData => localized_string("tx_data"), - FuzzyScore => unreachable!("fuzzy score not used as an actual column"), - } - } - - fn as_string(self) -> String { - use ColumnKey::*; - - let s = match self { - Id => "tx_id", - Type => "tx_type", - SharedTransactionId => "tx_shared_id", - CreationTime => "tx-creation-time", - Status => "tx-status", - TTLCutoff => "tx_ttl_cutoff", - Height => "tx_height", - IsConfirmed => "tx_is_confirmed", - ConfirmationTime => "tx-confirmation-time", - NumInputs => "tx_num_inputs", - NumOutputs => "tx_num_outputs", - AmountCredited => "tx_amount_credited", - AmountDebited => "tx_amount_debited", - Fee => "tx_fee", - NetDifference => "tx-net-difference", - PaymentProof => "tx_payment_proof", - Kernel => "tx_kernel", - TxData => "tx_data", - FuzzyScore => unreachable!("fuzzy score not used as an actual column"), - }; - - s.to_string() - } + fn title(self) -> String { + use ColumnKey::*; + + match self { + Id => localized_string("tx_id"), + Type => localized_string("tx_type"), + SharedTransactionId => localized_string("tx_shared_id"), + CreationTime => localized_string("tx-creation-time"), + Status => localized_string("tx-status"), + TTLCutoff => localized_string("tx_ttl_cutoff"), + Height => localized_string("tx_height"), + IsConfirmed => localized_string("tx_is_confirmed"), + ConfirmationTime => localized_string("tx-confirmation-time"), + NumInputs => localized_string("tx_num_inputs"), + NumOutputs => localized_string("tx_num_outputs"), + AmountCredited => localized_string("tx_amount_credited"), + AmountDebited => localized_string("tx_amount_debited"), + Fee => localized_string("tx_fee"), + NetDifference => localized_string("tx-net-difference"), + PaymentProof => localized_string("tx_payment_proof"), + Kernel => localized_string("tx_kernel"), + TxData => localized_string("tx_data"), + FuzzyScore => unreachable!("fuzzy score not used as an actual column"), + } + } + + fn as_string(self) -> String { + use ColumnKey::*; + + let s = match self { + Id => "tx_id", + Type => "tx_type", + SharedTransactionId => "tx_shared_id", + CreationTime => "tx-creation-time", + Status => "tx-status", + TTLCutoff => "tx_ttl_cutoff", + Height => "tx_height", + IsConfirmed => "tx_is_confirmed", + ConfirmationTime => "tx-confirmation-time", + NumInputs => "tx_num_inputs", + NumOutputs => "tx_num_outputs", + AmountCredited => "tx_amount_credited", + AmountDebited => "tx_amount_debited", + Fee => "tx_fee", + NetDifference => "tx-net-difference", + PaymentProof => "tx_payment_proof", + Kernel => "tx_kernel", + TxData => "tx_data", + FuzzyScore => unreachable!("fuzzy score not used as an actual column"), + }; + + s.to_string() + } } impl From<&str> for ColumnKey { - fn from(s: &str) -> Self { - match s { - "tx_id" => ColumnKey::Id, - "tx_type" => ColumnKey::Type, - "tx_shared_id" => ColumnKey::SharedTransactionId, - "tx_creation_time" => ColumnKey::CreationTime, - "tx-status" => ColumnKey::Status, - "tx_ttl_cutoff" => ColumnKey::TTLCutoff, - "tx_height" => ColumnKey::Height, - "tx_is_confirmed" => ColumnKey::IsConfirmed, - "tx-confirmation-time" => ColumnKey::ConfirmationTime, - "tx_num_inputs" => ColumnKey::NumInputs, - "tx_num_outputs" => ColumnKey::NumOutputs, - "tx_amount_credited" => ColumnKey::AmountCredited, - "tx_amount_debited" => ColumnKey::AmountDebited, - "tx_fee" => ColumnKey::Fee, - "tx-net-difference" => ColumnKey::NetDifference, - "tx_payment_proof" => ColumnKey::PaymentProof, - "tx_kernel" => ColumnKey::Kernel, - "tx_data" => ColumnKey::TxData, - _ => panic!("Unknown ColumnKey for {}", s), - } - } + fn from(s: &str) -> Self { + match s { + "tx_id" => ColumnKey::Id, + "tx_type" => ColumnKey::Type, + "tx_shared_id" => ColumnKey::SharedTransactionId, + "tx_creation_time" => ColumnKey::CreationTime, + "tx-status" => ColumnKey::Status, + "tx_ttl_cutoff" => ColumnKey::TTLCutoff, + "tx_height" => ColumnKey::Height, + "tx_is_confirmed" => ColumnKey::IsConfirmed, + "tx-confirmation-time" => ColumnKey::ConfirmationTime, + "tx_num_inputs" => ColumnKey::NumInputs, + "tx_num_outputs" => ColumnKey::NumOutputs, + "tx_amount_credited" => ColumnKey::AmountCredited, + "tx_amount_debited" => ColumnKey::AmountDebited, + "tx_fee" => ColumnKey::Fee, + "tx-net-difference" => ColumnKey::NetDifference, + "tx_payment_proof" => ColumnKey::PaymentProof, + "tx_kernel" => ColumnKey::Kernel, + "tx_data" => ColumnKey::TxData, + _ => panic!("Unknown ColumnKey for {}", s), + } + } } #[derive(Debug, Clone, Copy, PartialEq)] pub enum SortDirection { - Asc, - Desc, + Asc, + Desc, } impl SortDirection { - fn toggle(self) -> SortDirection { - match self { - SortDirection::Asc => SortDirection::Desc, - SortDirection::Desc => SortDirection::Asc, - } - } + fn toggle(self) -> SortDirection { + match self { + SortDirection::Asc => SortDirection::Desc, + SortDirection::Desc => SortDirection::Asc, + } + } } #[derive(Debug, Clone)] pub struct TxLogEntryWrap { - pub tx: TxLogEntry, + pub tx: TxLogEntry, } impl TxLogEntryWrap { - pub fn new(tx: TxLogEntry) -> Self { - Self { tx } - } + pub fn new(tx: TxLogEntry) -> Self { + Self { tx } + } } #[derive(Debug, Clone)] pub struct TxList { - pub txs: Vec, + pub txs: Vec, } impl Default for TxList { - fn default() -> Self { - Self { txs: vec![] } - } + fn default() -> Self { + Self { txs: vec![] } + } } #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)] pub enum TxListResultSize { - _25, - _50, - _100, - _500, + _25, + _50, + _100, + _500, } impl Default for TxListResultSize { - fn default() -> Self { - TxListResultSize::_25 - } + fn default() -> Self { + TxListResultSize::_25 + } } impl TxListResultSize { - pub fn all() -> Vec { - vec![ - TxListResultSize::_25, - TxListResultSize::_50, - TxListResultSize::_100, - TxListResultSize::_500, - ] - } - - pub fn as_usize(self) -> usize { - match self { - TxListResultSize::_25 => 25, - TxListResultSize::_50 => 50, - TxListResultSize::_100 => 100, - TxListResultSize::_500 => 500, - } - } + pub fn all() -> Vec { + vec![ + TxListResultSize::_25, + TxListResultSize::_50, + TxListResultSize::_100, + TxListResultSize::_500, + ] + } + + pub fn as_usize(self) -> usize { + match self { + TxListResultSize::_25 => 25, + TxListResultSize::_50 => 50, + TxListResultSize::_100 => 100, + TxListResultSize::_500 => 500, + } + } } impl std::fmt::Display for TxListResultSize { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - let mut vars = HashMap::new(); - vars.insert("number".to_string(), self.as_usize()); - let fmt = localized_string("tx-list-results"); + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + let mut vars = HashMap::new(); + vars.insert("number".to_string(), self.as_usize()); + let fmt = localized_string("tx-list-results"); - write!(f, "{}", strfmt(&fmt, &vars).unwrap()) - } + write!(f, "{}", strfmt(&fmt, &vars).unwrap()) + } } pub struct HeaderState { - pub state: header::State, - pub previous_column_key: Option, - pub previous_sort_direction: Option, - pub columns: Vec, + pub state: header::State, + pub previous_column_key: Option, + pub previous_sort_direction: Option, + pub columns: Vec, } impl HeaderState { - pub fn column_config(&self) -> Vec<(ColumnKey, Length, bool)> { - self.columns - .iter() - .map(|c| (c.key, c.width, c.hidden)) - .collect() - } + pub fn column_config(&self) -> Vec<(ColumnKey, Length, bool)> { + self.columns + .iter() + .map(|c| (c.key, c.width, c.hidden)) + .collect() + } } impl Default for HeaderState { - fn default() -> Self { - Self { - state: Default::default(), - previous_column_key: None, - previous_sort_direction: None, - columns: vec![ - ColumnState { - key: ColumnKey::Id, - // btn_state: Default::default(), - width: Length::Fixed(20.0), - hidden: true, - order: 0, - }, - ColumnState { - key: ColumnKey::NetDifference, - // btn_state: Default::default(), - width: Length::Fixed(110.0), - hidden: false, - order: 1, - }, - ColumnState { - key: ColumnKey::CreationTime, - // btn_state: Default::default(), - width: Length::Fixed(110.0), - hidden: false, - order: 2, - }, - ColumnState { - key: ColumnKey::Status, - // btn_state: Default::default(), - width: Length::Fixed(300.0), - hidden: false, - order: 3, - }, - ColumnState { - key: ColumnKey::ConfirmationTime, - // btn_state: Default::default(), - width: Length::Fixed(110.0), - hidden: true, - order: 4, - }, - ColumnState { - key: ColumnKey::Type, - // btn_state: Default::default(), - width: Length::Fixed(150.0), - hidden: true, - order: 5, - }, - ColumnState { - key: ColumnKey::SharedTransactionId, - // btn_state: Default::default(), - width: Length::Fixed(150.0), - hidden: true, - order: 6, - }, - ColumnState { - key: ColumnKey::TTLCutoff, - // btn_state: Default::default(), - width: Length::Fixed(85.0), - hidden: true, - order: 7, - }, - ColumnState { - key: ColumnKey::Height, - // btn_state: Default::default(), - width: Length::Fixed(85.0), - hidden: true, - order: 8, - }, - ColumnState { - key: ColumnKey::IsConfirmed, - // btn_state: Default::default(), - width: Length::Fixed(110.0), - hidden: true, - order: 9, - }, - ColumnState { - key: ColumnKey::NumInputs, - // btn_state: Default::default(), - width: Length::Fixed(110.0), - hidden: true, - order: 10, - }, - ColumnState { - key: ColumnKey::NumOutputs, - // btn_state: Default::default(), - width: Length::Fixed(110.0), - hidden: true, - order: 11, - }, - ColumnState { - key: ColumnKey::AmountCredited, - // btn_state: Default::default(), - width: Length::Fixed(110.0), - hidden: true, - order: 12, - }, - ColumnState { - key: ColumnKey::AmountDebited, - // btn_state: Default::default(), - width: Length::Fixed(110.0), - hidden: true, - order: 13, - }, - ColumnState { - key: ColumnKey::Fee, - // btn_state: Default::default(), - width: Length::Fixed(110.0), - hidden: true, - order: 14, - }, - ColumnState { - key: ColumnKey::PaymentProof, - // btn_state: Default::default(), - width: Length::Fixed(110.0), - hidden: true, - order: 15, - }, - ColumnState { - key: ColumnKey::Kernel, - // btn_state: Default::default(), - width: Length::Fixed(110.0), - hidden: true, - order: 16, - }, - ColumnState { - key: ColumnKey::TxData, - // btn_state: Default::default(), - width: Length::Fixed(110.0), - hidden: true, - order: 17, - }, - ], - } - } + fn default() -> Self { + Self { + state: Default::default(), + previous_column_key: None, + previous_sort_direction: None, + columns: vec![ + ColumnState { + key: ColumnKey::Id, + // btn_state: Default::default(), + width: Length::Fixed(20.0), + hidden: true, + order: 0, + }, + ColumnState { + key: ColumnKey::NetDifference, + // btn_state: Default::default(), + width: Length::Fixed(110.0), + hidden: false, + order: 1, + }, + ColumnState { + key: ColumnKey::CreationTime, + // btn_state: Default::default(), + width: Length::Fixed(110.0), + hidden: false, + order: 2, + }, + ColumnState { + key: ColumnKey::Status, + // btn_state: Default::default(), + width: Length::Fixed(300.0), + hidden: false, + order: 3, + }, + ColumnState { + key: ColumnKey::ConfirmationTime, + // btn_state: Default::default(), + width: Length::Fixed(110.0), + hidden: true, + order: 4, + }, + ColumnState { + key: ColumnKey::Type, + // btn_state: Default::default(), + width: Length::Fixed(150.0), + hidden: true, + order: 5, + }, + ColumnState { + key: ColumnKey::SharedTransactionId, + // btn_state: Default::default(), + width: Length::Fixed(150.0), + hidden: true, + order: 6, + }, + ColumnState { + key: ColumnKey::TTLCutoff, + // btn_state: Default::default(), + width: Length::Fixed(85.0), + hidden: true, + order: 7, + }, + ColumnState { + key: ColumnKey::Height, + // btn_state: Default::default(), + width: Length::Fixed(85.0), + hidden: true, + order: 8, + }, + ColumnState { + key: ColumnKey::IsConfirmed, + // btn_state: Default::default(), + width: Length::Fixed(110.0), + hidden: true, + order: 9, + }, + ColumnState { + key: ColumnKey::NumInputs, + // btn_state: Default::default(), + width: Length::Fixed(110.0), + hidden: true, + order: 10, + }, + ColumnState { + key: ColumnKey::NumOutputs, + // btn_state: Default::default(), + width: Length::Fixed(110.0), + hidden: true, + order: 11, + }, + ColumnState { + key: ColumnKey::AmountCredited, + // btn_state: Default::default(), + width: Length::Fixed(110.0), + hidden: true, + order: 12, + }, + ColumnState { + key: ColumnKey::AmountDebited, + // btn_state: Default::default(), + width: Length::Fixed(110.0), + hidden: true, + order: 13, + }, + ColumnState { + key: ColumnKey::Fee, + // btn_state: Default::default(), + width: Length::Fixed(110.0), + hidden: true, + order: 14, + }, + ColumnState { + key: ColumnKey::PaymentProof, + // btn_state: Default::default(), + width: Length::Fixed(110.0), + hidden: true, + order: 15, + }, + ColumnState { + key: ColumnKey::Kernel, + // btn_state: Default::default(), + width: Length::Fixed(110.0), + hidden: true, + order: 16, + }, + ColumnState { + key: ColumnKey::TxData, + // btn_state: Default::default(), + width: Length::Fixed(110.0), + hidden: true, + order: 17, + }, + ], + } + } } pub struct ColumnState { - key: ColumnKey, - // btn_state: button::State, - width: Length, - hidden: bool, - order: usize, + key: ColumnKey, + // btn_state: button::State, + width: Length, + hidden: bool, + order: usize, } pub struct ColumnSettings { - // pub scrollable_state: scrollable::State, - pub columns: Vec, + // pub scrollable_state: scrollable::State, + pub columns: Vec, } impl Default for ColumnSettings { - fn default() -> Self { - ColumnSettings { - // scrollable_state: Default::default(), - columns: vec![ - ColumnSettingState { - key: ColumnKey::Id, - order: 0, - }, - ColumnSettingState { - key: ColumnKey::NetDifference, - order: 1, - }, - ColumnSettingState { - key: ColumnKey::CreationTime, - order: 2, - }, - ColumnSettingState { - key: ColumnKey::Status, - order: 3, - }, - ColumnSettingState { - key: ColumnKey::ConfirmationTime, - order: 4, - }, - ColumnSettingState { - key: ColumnKey::Type, - order: 5, - }, - ColumnSettingState { - key: ColumnKey::SharedTransactionId, - order: 6, - }, - ColumnSettingState { - key: ColumnKey::TTLCutoff, - order: 7, - }, - ColumnSettingState { - key: ColumnKey::Height, - order: 8, - }, - ColumnSettingState { - key: ColumnKey::IsConfirmed, - order: 9, - }, - ColumnSettingState { - key: ColumnKey::NumInputs, - order: 10, - }, - ColumnSettingState { - key: ColumnKey::NumOutputs, - order: 11, - }, - ColumnSettingState { - key: ColumnKey::AmountCredited, - order: 12, - }, - ColumnSettingState { - key: ColumnKey::AmountDebited, - order: 13, - }, - ColumnSettingState { - key: ColumnKey::Fee, - order: 14, - }, - ColumnSettingState { - key: ColumnKey::PaymentProof, - order: 15, - }, - ColumnSettingState { - key: ColumnKey::Kernel, - order: 16, - }, - ColumnSettingState { - key: ColumnKey::TxData, - order: 17, - }, - ], - } - } + fn default() -> Self { + ColumnSettings { + // scrollable_state: Default::default(), + columns: vec![ + ColumnSettingState { + key: ColumnKey::Id, + order: 0, + }, + ColumnSettingState { + key: ColumnKey::NetDifference, + order: 1, + }, + ColumnSettingState { + key: ColumnKey::CreationTime, + order: 2, + }, + ColumnSettingState { + key: ColumnKey::Status, + order: 3, + }, + ColumnSettingState { + key: ColumnKey::ConfirmationTime, + order: 4, + }, + ColumnSettingState { + key: ColumnKey::Type, + order: 5, + }, + ColumnSettingState { + key: ColumnKey::SharedTransactionId, + order: 6, + }, + ColumnSettingState { + key: ColumnKey::TTLCutoff, + order: 7, + }, + ColumnSettingState { + key: ColumnKey::Height, + order: 8, + }, + ColumnSettingState { + key: ColumnKey::IsConfirmed, + order: 9, + }, + ColumnSettingState { + key: ColumnKey::NumInputs, + order: 10, + }, + ColumnSettingState { + key: ColumnKey::NumOutputs, + order: 11, + }, + ColumnSettingState { + key: ColumnKey::AmountCredited, + order: 12, + }, + ColumnSettingState { + key: ColumnKey::AmountDebited, + order: 13, + }, + ColumnSettingState { + key: ColumnKey::Fee, + order: 14, + }, + ColumnSettingState { + key: ColumnKey::PaymentProof, + order: 15, + }, + ColumnSettingState { + key: ColumnKey::Kernel, + order: 16, + }, + ColumnSettingState { + key: ColumnKey::TxData, + order: 17, + }, + ], + } + } } pub struct ColumnSettingState { - pub key: ColumnKey, - pub order: usize, - // pub up_btn_state: button::State, - // pub down_btn_state: button::State, + pub key: ColumnKey, + pub order: usize, + // pub up_btn_state: button::State, + // pub down_btn_state: button::State, } #[derive(Debug, Clone, Copy, PartialEq, Hash, Eq)] pub enum TxListColumnKey { - Id, - Type, - SharedTransactionId, - CreationTime, - TTLCutoff, - Height, - IsConfirmed, - ConfirmationTime, - NumInputs, - NumOutputs, - AmountCredited, - AmountDebited, - Fee, - NetDifference, - PaymentProof, - Kernel, - TxData, + Id, + Type, + SharedTransactionId, + CreationTime, + TTLCutoff, + Height, + IsConfirmed, + ConfirmationTime, + NumInputs, + NumOutputs, + AmountCredited, + AmountDebited, + Fee, + NetDifference, + PaymentProof, + Kernel, + TxData, } impl TxListColumnKey { - fn title(self) -> String { - use TxListColumnKey::*; - - match self { - Id => localized_string("tx_id"), - Type => localized_string("tx_type"), - SharedTransactionId => localized_string("tx_shared_id"), - CreationTime => localized_string("tx_creation_time"), - TTLCutoff => localized_string("tx_ttl_cutoff"), - Height => localized_string("tx_height"), - IsConfirmed => localized_string("tx_is_confirmed"), - ConfirmationTime => localized_string("tx-confirmation-time"), - NumInputs => localized_string("tx_num_inputs"), - NumOutputs => localized_string("tx_num_outputs"), - AmountCredited => localized_string("tx_amount_credited"), - AmountDebited => localized_string("tx_amount_debited"), - Fee => localized_string("tx_fee"), - NetDifference => localized_string("tx-net-difference"), - PaymentProof => localized_string("tx_payment_proof"), - Kernel => localized_string("tx_kernel"), - TxData => localized_string("tx_data"), - } - } - - fn as_string(self) -> String { - use TxListColumnKey::*; - - let s = match self { - Id => "tx_id", - Type => "tx_type", - SharedTransactionId => "tx_shared_id", - CreationTime => "tx_creation_time", - TTLCutoff => "tx_ttl_cutoff", - Height => "tx_height", - IsConfirmed => "tx_is_confirmed", - ConfirmationTime => "tx-confirmation-time", - NumInputs => "tx_num_inputs", - NumOutputs => "tx_num_outputs", - AmountCredited => "tx_amount_credited", - AmountDebited => "tx_amount_debited", - Fee => "tx_fee", - NetDifference => "tx-net-difference", - PaymentProof => "tx_payment_proof", - Kernel => "tx_kernel", - TxData => "tx_data", - }; - - s.to_string() - } + fn title(self) -> String { + use TxListColumnKey::*; + + match self { + Id => localized_string("tx_id"), + Type => localized_string("tx_type"), + SharedTransactionId => localized_string("tx_shared_id"), + CreationTime => localized_string("tx_creation_time"), + TTLCutoff => localized_string("tx_ttl_cutoff"), + Height => localized_string("tx_height"), + IsConfirmed => localized_string("tx_is_confirmed"), + ConfirmationTime => localized_string("tx-confirmation-time"), + NumInputs => localized_string("tx_num_inputs"), + NumOutputs => localized_string("tx_num_outputs"), + AmountCredited => localized_string("tx_amount_credited"), + AmountDebited => localized_string("tx_amount_debited"), + Fee => localized_string("tx_fee"), + NetDifference => localized_string("tx-net-difference"), + PaymentProof => localized_string("tx_payment_proof"), + Kernel => localized_string("tx_kernel"), + TxData => localized_string("tx_data"), + } + } + + fn as_string(self) -> String { + use TxListColumnKey::*; + + let s = match self { + Id => "tx_id", + Type => "tx_type", + SharedTransactionId => "tx_shared_id", + CreationTime => "tx_creation_time", + TTLCutoff => "tx_ttl_cutoff", + Height => "tx_height", + IsConfirmed => "tx_is_confirmed", + ConfirmationTime => "tx-confirmation-time", + NumInputs => "tx_num_inputs", + NumOutputs => "tx_num_outputs", + AmountCredited => "tx_amount_credited", + AmountDebited => "tx_amount_debited", + Fee => "tx_fee", + NetDifference => "tx-net-difference", + PaymentProof => "tx_payment_proof", + Kernel => "tx_kernel", + TxData => "tx_data", + }; + + s.to_string() + } } impl From<&str> for TxListColumnKey { - fn from(s: &str) -> Self { - match s { - "tx_id" => TxListColumnKey::Id, - "tx_type" => TxListColumnKey::Type, - "tx_shared_id" => TxListColumnKey::SharedTransactionId, - "tx_creation_time" => TxListColumnKey::CreationTime, - "tx_ttl_cutoff" => TxListColumnKey::TTLCutoff, - "tx_height" => TxListColumnKey::Height, - "tx_is_confirmed" => TxListColumnKey::IsConfirmed, - "tx-confirmation-time" => TxListColumnKey::ConfirmationTime, - "tx_num_inputs" => TxListColumnKey::NumInputs, - "tx_num_outputs" => TxListColumnKey::NumOutputs, - "tx_amount_credited" => TxListColumnKey::AmountCredited, - "tx_amount_debited" => TxListColumnKey::AmountDebited, - "tx_fee" => TxListColumnKey::Fee, - "tx-net-difference" => TxListColumnKey::NetDifference, - "tx_payment_proof" => TxListColumnKey::PaymentProof, - "tx_kernel" => TxListColumnKey::Kernel, - "tx_data" => TxListColumnKey::TxData, - _ => panic!("Unknown CatalogTxListColumnKey for {}", s), - } - } + fn from(s: &str) -> Self { + match s { + "tx_id" => TxListColumnKey::Id, + "tx_type" => TxListColumnKey::Type, + "tx_shared_id" => TxListColumnKey::SharedTransactionId, + "tx_creation_time" => TxListColumnKey::CreationTime, + "tx_ttl_cutoff" => TxListColumnKey::TTLCutoff, + "tx_height" => TxListColumnKey::Height, + "tx_is_confirmed" => TxListColumnKey::IsConfirmed, + "tx-confirmation-time" => TxListColumnKey::ConfirmationTime, + "tx_num_inputs" => TxListColumnKey::NumInputs, + "tx_num_outputs" => TxListColumnKey::NumOutputs, + "tx_amount_credited" => TxListColumnKey::AmountCredited, + "tx_amount_debited" => TxListColumnKey::AmountDebited, + "tx_fee" => TxListColumnKey::Fee, + "tx-net-difference" => TxListColumnKey::NetDifference, + "tx_payment_proof" => TxListColumnKey::PaymentProof, + "tx_kernel" => TxListColumnKey::Kernel, + "tx_data" => TxListColumnKey::TxData, + _ => panic!("Unknown CatalogTxListColumnKey for {}", s), + } + } } pub struct TxListColumnState { - key: ColumnKey, - width: Length, - hidden: bool, - order: usize, + key: ColumnKey, + width: Length, + hidden: bool, + order: usize, } pub struct TxListHeaderState { - state: header::State, - previous_column_key: Option, - previous_sort_direction: Option, - columns: Vec, + state: header::State, + previous_column_key: Option, + previous_sort_direction: Option, + columns: Vec, } impl TxListHeaderState { - fn column_config(&self) -> Vec<(ColumnKey, Length, bool)> { - self.columns - .iter() - .map(|c| (c.key, c.width, c.hidden)) - .collect() - } + fn column_config(&self) -> Vec<(ColumnKey, Length, bool)> { + self.columns + .iter() + .map(|c| (c.key, c.width, c.hidden)) + .collect() + } } impl Default for TxListHeaderState { - fn default() -> Self { - Self { - state: Default::default(), - previous_column_key: None, - previous_sort_direction: None, - columns: vec![ - TxListColumnState { - key: ColumnKey::Id, - // btn_state: Default::default(), - width: Length::Fixed(20.0), - hidden: false, - order: 0, - }, - TxListColumnState { - key: ColumnKey::NetDifference, - // btn_state: Default::default(), - width: Length::Fixed(85.0), - hidden: true, - order: 1, - }, - TxListColumnState { - key: ColumnKey::CreationTime, - // btn_state: Default::default(), - width: Length::Fixed(105.0), - hidden: true, - order: 2, - }, - TxListColumnState { - key: ColumnKey::Status, - // btn_state: Default::default(), - width: Length::Fixed(105.0), - hidden: false, - order: 3, - }, - TxListColumnState { - key: ColumnKey::ConfirmationTime, - // btn_state: Default::default(), - width: Length::Fixed(105.0), - hidden: false, - order: 4, - }, - TxListColumnState { - key: ColumnKey::Type, - // btn_state: Default::default(), - width: Length::Fixed(150.0), - hidden: true, - order: 5, - }, - TxListColumnState { - key: ColumnKey::SharedTransactionId, - // btn_state: Default::default(), - width: Length::Fixed(110.0), - hidden: false, - order: 6, - }, - TxListColumnState { - key: ColumnKey::TTLCutoff, - // btn_state: Default::default(), - width: Length::Fixed(105.0), - hidden: true, - order: 7, - }, - TxListColumnState { - key: ColumnKey::Height, - // btn_state: Default::default(), - width: Length::Fixed(105.0), - hidden: false, - order: 8, - }, - TxListColumnState { - key: ColumnKey::IsConfirmed, - // btn_state: Default::default(), - width: Length::Fixed(85.0), - hidden: false, - order: 9, - }, - TxListColumnState { - key: ColumnKey::NumInputs, - // btn_state: Default::default(), - width: Length::Fixed(85.0), - hidden: true, - order: 10, - }, - TxListColumnState { - key: ColumnKey::NumOutputs, - // btn_state: Default::default(), - width: Length::Fixed(85.0), - hidden: true, - order: 11, - }, - TxListColumnState { - key: ColumnKey::AmountCredited, - // btn_state: Default::default(), - width: Length::Fixed(85.0), - hidden: true, - order: 12, - }, - TxListColumnState { - key: ColumnKey::AmountDebited, - // btn_state: Default::default(), - width: Length::Fixed(85.0), - hidden: true, - order: 13, - }, - TxListColumnState { - key: ColumnKey::Fee, - // btn_state: Default::default(), - width: Length::Fixed(85.0), - hidden: true, - order: 14, - }, - TxListColumnState { - key: ColumnKey::PaymentProof, - // btn_state: Default::default(), - width: Length::Fixed(85.0), - hidden: true, - order: 15, - }, - TxListColumnState { - key: ColumnKey::Kernel, - // btn_state: Default::default(), - width: Length::Fixed(85.0), - hidden: true, - order: 16, - }, - TxListColumnState { - key: ColumnKey::TxData, - // btn_state: Default::default(), - width: Length::Fixed(85.0), - hidden: true, - order: 17, - }, - ], - } - } + fn default() -> Self { + Self { + state: Default::default(), + previous_column_key: None, + previous_sort_direction: None, + columns: vec![ + TxListColumnState { + key: ColumnKey::Id, + // btn_state: Default::default(), + width: Length::Fixed(20.0), + hidden: false, + order: 0, + }, + TxListColumnState { + key: ColumnKey::NetDifference, + // btn_state: Default::default(), + width: Length::Fixed(85.0), + hidden: true, + order: 1, + }, + TxListColumnState { + key: ColumnKey::CreationTime, + // btn_state: Default::default(), + width: Length::Fixed(105.0), + hidden: true, + order: 2, + }, + TxListColumnState { + key: ColumnKey::Status, + // btn_state: Default::default(), + width: Length::Fixed(105.0), + hidden: false, + order: 3, + }, + TxListColumnState { + key: ColumnKey::ConfirmationTime, + // btn_state: Default::default(), + width: Length::Fixed(105.0), + hidden: false, + order: 4, + }, + TxListColumnState { + key: ColumnKey::Type, + // btn_state: Default::default(), + width: Length::Fixed(150.0), + hidden: true, + order: 5, + }, + TxListColumnState { + key: ColumnKey::SharedTransactionId, + // btn_state: Default::default(), + width: Length::Fixed(110.0), + hidden: false, + order: 6, + }, + TxListColumnState { + key: ColumnKey::TTLCutoff, + // btn_state: Default::default(), + width: Length::Fixed(105.0), + hidden: true, + order: 7, + }, + TxListColumnState { + key: ColumnKey::Height, + // btn_state: Default::default(), + width: Length::Fixed(105.0), + hidden: false, + order: 8, + }, + TxListColumnState { + key: ColumnKey::IsConfirmed, + // btn_state: Default::default(), + width: Length::Fixed(85.0), + hidden: false, + order: 9, + }, + TxListColumnState { + key: ColumnKey::NumInputs, + // btn_state: Default::default(), + width: Length::Fixed(85.0), + hidden: true, + order: 10, + }, + TxListColumnState { + key: ColumnKey::NumOutputs, + // btn_state: Default::default(), + width: Length::Fixed(85.0), + hidden: true, + order: 11, + }, + TxListColumnState { + key: ColumnKey::AmountCredited, + // btn_state: Default::default(), + width: Length::Fixed(85.0), + hidden: true, + order: 12, + }, + TxListColumnState { + key: ColumnKey::AmountDebited, + // btn_state: Default::default(), + width: Length::Fixed(85.0), + hidden: true, + order: 13, + }, + TxListColumnState { + key: ColumnKey::Fee, + // btn_state: Default::default(), + width: Length::Fixed(85.0), + hidden: true, + order: 14, + }, + TxListColumnState { + key: ColumnKey::PaymentProof, + // btn_state: Default::default(), + width: Length::Fixed(85.0), + hidden: true, + order: 15, + }, + TxListColumnState { + key: ColumnKey::Kernel, + // btn_state: Default::default(), + width: Length::Fixed(85.0), + hidden: true, + order: 16, + }, + TxListColumnState { + key: ColumnKey::TxData, + // btn_state: Default::default(), + width: Length::Fixed(85.0), + hidden: true, + order: 17, + }, + ], + } + } } pub struct TxListColumnSettings { - pub columns: Vec, + pub columns: Vec, } impl Default for TxListColumnSettings { - fn default() -> Self { - TxListColumnSettings { - columns: vec![ - TxListColumnSettingState { - key: ColumnKey::Id, - order: 0, - }, - TxListColumnSettingState { - key: ColumnKey::NetDifference, - order: 1, - }, - TxListColumnSettingState { - key: ColumnKey::CreationTime, - order: 2, - }, - TxListColumnSettingState { - key: ColumnKey::Status, - order: 3, - }, - TxListColumnSettingState { - key: ColumnKey::ConfirmationTime, - order: 4, - }, - TxListColumnSettingState { - key: ColumnKey::Type, - order: 5, - }, - TxListColumnSettingState { - key: ColumnKey::SharedTransactionId, - order: 6, - }, - TxListColumnSettingState { - key: ColumnKey::TTLCutoff, - order: 7, - }, - TxListColumnSettingState { - key: ColumnKey::Height, - order: 8, - }, - TxListColumnSettingState { - key: ColumnKey::IsConfirmed, - order: 9, - }, - TxListColumnSettingState { - key: ColumnKey::NumInputs, - order: 10, - }, - TxListColumnSettingState { - key: ColumnKey::NumOutputs, - order: 11, - }, - TxListColumnSettingState { - key: ColumnKey::AmountCredited, - order: 12, - }, - TxListColumnSettingState { - key: ColumnKey::AmountDebited, - order: 13, - }, - TxListColumnSettingState { - key: ColumnKey::Fee, - order: 14, - }, - TxListColumnSettingState { - key: ColumnKey::PaymentProof, - order: 15, - }, - TxListColumnSettingState { - key: ColumnKey::Kernel, - order: 16, - }, - TxListColumnSettingState { - key: ColumnKey::TxData, - order: 17, - }, - ], - } - } + fn default() -> Self { + TxListColumnSettings { + columns: vec![ + TxListColumnSettingState { + key: ColumnKey::Id, + order: 0, + }, + TxListColumnSettingState { + key: ColumnKey::NetDifference, + order: 1, + }, + TxListColumnSettingState { + key: ColumnKey::CreationTime, + order: 2, + }, + TxListColumnSettingState { + key: ColumnKey::Status, + order: 3, + }, + TxListColumnSettingState { + key: ColumnKey::ConfirmationTime, + order: 4, + }, + TxListColumnSettingState { + key: ColumnKey::Type, + order: 5, + }, + TxListColumnSettingState { + key: ColumnKey::SharedTransactionId, + order: 6, + }, + TxListColumnSettingState { + key: ColumnKey::TTLCutoff, + order: 7, + }, + TxListColumnSettingState { + key: ColumnKey::Height, + order: 8, + }, + TxListColumnSettingState { + key: ColumnKey::IsConfirmed, + order: 9, + }, + TxListColumnSettingState { + key: ColumnKey::NumInputs, + order: 10, + }, + TxListColumnSettingState { + key: ColumnKey::NumOutputs, + order: 11, + }, + TxListColumnSettingState { + key: ColumnKey::AmountCredited, + order: 12, + }, + TxListColumnSettingState { + key: ColumnKey::AmountDebited, + order: 13, + }, + TxListColumnSettingState { + key: ColumnKey::Fee, + order: 14, + }, + TxListColumnSettingState { + key: ColumnKey::PaymentProof, + order: 15, + }, + TxListColumnSettingState { + key: ColumnKey::Kernel, + order: 16, + }, + TxListColumnSettingState { + key: ColumnKey::TxData, + order: 17, + }, + ], + } + } } pub struct TxListColumnSettingState { - pub key: ColumnKey, - pub order: usize, + pub key: ColumnKey, + pub order: usize, } pub struct CatalogSearchState { - pub catalog_rows: Vec, - pub query: Option, - // pub query_state: text_input::State, - pub result_size: TxListResultSize, - pub result_sizes: Vec, - // pub result_sizes_state: pick_list::State, + pub catalog_rows: Vec, + pub query: Option, + // pub query_state: text_input::State, + pub result_size: TxListResultSize, + pub result_sizes: Vec, + // pub result_sizes_state: pick_list::State, } impl Default for CatalogSearchState { - fn default() -> Self { - CatalogSearchState { - catalog_rows: Default::default(), - query: None, - // query_state: Default::default(), - result_size: Default::default(), - result_sizes: TxListResultSize::all(), - // result_sizes_state: Default::default(), - } - } + fn default() -> Self { + CatalogSearchState { + catalog_rows: Default::default(), + query: None, + // query_state: Default::default(), + result_size: Default::default(), + result_sizes: TxListResultSize::all(), + // result_sizes_state: Default::default(), + } + } } pub struct CatalogRow { - // install_button_state: button::State, + // install_button_state: button::State, } fn row_title( - column_key: T, - previous_column_key: Option, - previous_sort_direction: Option, - title: &str, + column_key: T, + previous_column_key: Option, + previous_sort_direction: Option, + title: &str, ) -> String { - if Some(column_key) == previous_column_key { - match previous_sort_direction { - Some(SortDirection::Asc) => format!("{} ▲", title), - Some(SortDirection::Desc) => format!("{} ▼", title), - _ => title.to_string(), - } - } else { - title.to_string() - } + if Some(column_key) == previous_column_key { + match previous_sort_direction { + Some(SortDirection::Asc) => format!("{} ▲", title), + Some(SortDirection::Desc) => format!("{} ▼", title), + _ => title.to_string(), + } + } else { + title.to_string() + } } pub fn titles_row_header<'a>( - tx_list: &TxList, - header_state: &'a header::State, - column_state: &'a [ColumnState], - previous_column_key: Option, - previous_sort_direction: Option, + tx_list: &TxList, + header_state: &'a header::State, + column_state: &'a [ColumnState], + previous_column_key: Option, + previous_sort_direction: Option, ) -> Header<'a, Message> { - // A row containing titles above the addon rows. - let mut row_titles = vec![]; - - for column in column_state.iter().filter(|c| !c.hidden) { - let column_key = column.key; - - let row_title = row_title( - column_key, - previous_column_key, - previous_sort_direction, - &column.key.title(), - ); - - let mut row_header = Button::new( - // &mut column.btn_state, - Text::new(row_title) - .size(DEFAULT_FONT_SIZE) - .width(Length::Fill), - ) - .width(Length::Fill); - - //if column_key != ColumnKey::Install { - //TODO - row_header = row_header.on_press(Interaction::SortCatalogColumn(column_key)); - //} - - if previous_column_key == Some(column_key) { - row_header = row_header.style(grin_gui_core::theme::ButtonStyle::SelectedColumn); - } - /*else if column_key == ColumnKey::Install { - row_header = row_header.style(style::UnclickableColumnHeaderButton); - } */ - else { - row_header = row_header.style(grin_gui_core::theme::ButtonStyle::ColumnHeader); - } - - let row_header: Element = row_header.into(); - - let row_container = Container::new(row_header.map(Message::Interaction)) - .width(column.width) - .style(grin_gui_core::theme::ContainerStyle::NormalBackground); - - // Only shows row titles if we have any catalog results. - if !tx_list.txs.is_empty() { - row_titles.push((column.key.as_string(), row_container)); - } - } - - Header::new( - header_state.clone(), - row_titles, - // Some(Length::Fixed(DEFAULT_PADDING)), - // Some(Length::Fixed(DEFAULT_PADDING + 5)), - None, - None, - ) - .spacing(1) - .height(Length::Fixed(25.0)) - /* .on_resize(3, |event| { - //TODO - //Message::Interaction(Interaction::ResizeColumn(Mode::Catalog, event)) - })*/ + // A row containing titles above the addon rows. + let mut row_titles = vec![]; + + for column in column_state.iter().filter(|c| !c.hidden) { + let column_key = column.key; + + let row_title = row_title( + column_key, + previous_column_key, + previous_sort_direction, + &column.key.title(), + ); + + let mut row_header = Button::new( + // &mut column.btn_state, + Text::new(row_title) + .size(DEFAULT_FONT_SIZE) + .width(Length::Fill), + ) + .width(Length::Fill); + + //if column_key != ColumnKey::Install { + //TODO + row_header = row_header.on_press(Interaction::SortCatalogColumn(column_key)); + //} + + if previous_column_key == Some(column_key) { + row_header = row_header.style(grin_gui_core::theme::ButtonStyle::SelectedColumn); + } + /*else if column_key == ColumnKey::Install { + row_header = row_header.style(style::UnclickableColumnHeaderButton); + } */ + else { + row_header = row_header.style(grin_gui_core::theme::ButtonStyle::ColumnHeader); + } + + let row_header: Element = row_header.into(); + + let row_container = Container::new(row_header.map(Message::Interaction)) + .width(column.width) + .style(grin_gui_core::theme::ContainerStyle::NormalBackground); + + // Only shows row titles if we have any catalog results. + if !tx_list.txs.is_empty() { + row_titles.push((column.key.as_string(), row_container)); + } + } + + Header::new( + header_state.clone(), + row_titles, + // Some(Length::Fixed(DEFAULT_PADDING)), + // Some(Length::Fixed(DEFAULT_PADDING + 5)), + None, + None, + ) + .spacing(1) + .height(Length::Fixed(25.0)) + /* .on_resize(3, |event| { + //TODO + //Message::Interaction(Interaction::ResizeColumn(Mode::Catalog, event)) + })*/ } //TODO: Move somewhere else pub fn create_tx_display_status(log_entry: &TxLogEntry) -> String { - if log_entry.confirmed { - localized_string("tx-confirmed") - } else { - localized_string("tx-unconfirmed") - } + if log_entry.confirmed { + localized_string("tx-confirmed") + } else { + localized_string("tx-unconfirmed") + } } #[allow(clippy::too_many_arguments)] pub fn data_row_container<'a, 'b>( - tx_log_entry_wrap: &'a TxLogEntryWrap, - is_tx_expanded: bool, - expand_type: &'a ExpandType, - config: &Config, - column_config: &'b [(ColumnKey, Length, bool)], - is_odd: Option, - pending_confirmation: &Option, - node_synched: bool, + tx_log_entry_wrap: &'a TxLogEntryWrap, + is_tx_expanded: bool, + expand_type: &'a ExpandType, + config: &Config, + column_config: &'b [(ColumnKey, Length, bool)], + is_odd: Option, + pending_confirmation: &Option, + node_synched: bool, ) -> Container<'a, Message> { - let default_height = Length::Fixed(26.0); - let mut default_row_height = 26; - - let mut row_containers = vec![]; - - let id = tx_log_entry_wrap.tx.id.to_string(); - let mut tx_type = format!( - "{}", - tx_log_entry_wrap.tx.tx_type.to_string().replace("\n", "") - ); - let shared_tx_id = match tx_log_entry_wrap.tx.tx_slate_id { - Some(t) => t.to_string(), - None => "None".to_string(), - }; - let creation_time = tx_log_entry_wrap.tx.creation_ts.to_string(); - let ttl_cutoff = tx_log_entry_wrap.tx.ttl_cutoff_height; - let height = tx_log_entry_wrap.tx.kernel_lookup_min_height; - - let tx_cloned = tx_log_entry_wrap.clone(); - let tx_cloned_for_row = tx_log_entry_wrap.clone(); - - let creation_time = tx_log_entry_wrap.tx.creation_ts.to_string(); - let confirmation_time = tx_log_entry_wrap.tx.creation_ts.to_string(); - let net_diff = if tx_log_entry_wrap.tx.amount_credited >= tx_log_entry_wrap.tx.amount_debited { - amount_to_hr_string( - tx_log_entry_wrap.tx.amount_credited - tx_log_entry_wrap.tx.amount_debited, - true, - ) - } else { - format!( - "-{}", - amount_to_hr_string( - tx_log_entry_wrap.tx.amount_debited - tx_log_entry_wrap.tx.amount_credited, - true - ) - ) - }; - //TODO this will show the latest status - // Unconfirmed - Created time - // Confirmed - let status = create_tx_display_status(&tx_log_entry_wrap.tx); - - /*let version = tx - .version() - .map(str::to_string) - .unwrap_or_else(|| "-".to_string()); - let release_package = addon_cloned.relevant_release_package(global_release_channel);*/ - - /*if let Some((idx, width)) = column_config - .iter() - .enumerate() - .filter_map(|(idx, (key, width, hidden))| { - if *key == ColumnKey::Title && !hidden { - Some((idx, width)) - } else { - None - } - }) - .next() - { - let title = Text::new(addon.title()).size(DEFAULT_FONT_SIZE); - - let mut title_row = Row::new().push(title).spacing(5).align_items(Align::Center); - - if addon.release_channel != ReleaseChannel::Default { - let release_channel = - Container::new(Text::new(addon.release_channel.to_string()).size(10)) - .style(style::ChannelBadge) - .padding(3); - - title_row = title_row.push(release_channel); - } - - let mut title_container = Container::new(title_row) - .padding(5) - .height(default_height) - .width(*width) - .center_y(); - if is_addon_expanded && matches!(expand_type, ExpandType::Details(_)) { - title_container = - title_container.style(style::SelectedBrightForegroundContainer); - } else { - title_container = - title_container.style(grin_gui_core::theme::container::Container::HoverableBrightForeground); - } - - row_containers.push((idx, title_container)); - }*/ - - if let Some((idx, width)) = column_config - .iter() - .enumerate() - .filter_map(|(idx, (key, width, hidden))| { - if *key == ColumnKey::Id && !hidden { - Some((idx, width)) - } else { - None - } - }) - .next() - { - let display_id = Text::new(id.clone()).size(DEFAULT_FONT_SIZE); - - let id_container = Container::new(display_id) - .padding(5) - .height(default_height) - .width(*width) - .center_y() - .style(grin_gui_core::theme::ContainerStyle::HoverableForeground); - - row_containers.push((idx, id_container)); - } - - if let Some((idx, width)) = column_config - .iter() - .enumerate() - .filter_map(|(idx, (key, width, hidden))| { - if *key == ColumnKey::CreationTime && !hidden { - Some((idx, width)) - } else { - None - } - }) - .next() - { - let display_creation_time = Text::new(creation_time).size(DEFAULT_FONT_SIZE); - - let display_creation_time_container = Container::new(display_creation_time) - .padding(5) - .height(default_height) - .width(*width) - .center_y() - .style(grin_gui_core::theme::ContainerStyle::HoverableForeground); - - row_containers.push((idx, display_creation_time_container)); - } - - if let Some((idx, width)) = column_config - .iter() - .enumerate() - .filter_map(|(idx, (key, width, hidden))| { - if *key == ColumnKey::ConfirmationTime && !hidden { - Some((idx, width)) - } else { - None - } - }) - .next() - { - let display_confirmation_time = Text::new(confirmation_time).size(DEFAULT_FONT_SIZE); - - let display_confirmation_time_container = Container::new(display_confirmation_time) - .padding(5) - .height(default_height) - .width(*width) - .center_y() - .style(grin_gui_core::theme::ContainerStyle::HoverableForeground); - - row_containers.push((idx, display_confirmation_time_container)); - } - - if let Some((idx, width)) = column_config - .iter() - .enumerate() - .filter_map(|(idx, (key, width, hidden))| { - if *key == ColumnKey::NetDifference && !hidden { - Some((idx, width)) - } else { - None - } - }) - .next() - { - let display_net_difference = Text::new(net_diff).size(DEFAULT_FONT_SIZE); - - let display_net_difference_container = Container::new(display_net_difference) - .padding(5) - .height(default_height) - .width(*width) - .center_y() - .style(grin_gui_core::theme::ContainerStyle::HoverableForeground); - - row_containers.push((idx, display_net_difference_container)); - } - - if let Some((idx, width)) = column_config - .iter() - .enumerate() - .filter_map(|(idx, (key, width, hidden))| { - if *key == ColumnKey::Status && !hidden { - Some((idx, width)) - } else { - None - } - }) - .next() - { - let display_status = Text::new(status).size(DEFAULT_FONT_SIZE); - - let display_status_container = Container::new(display_status) - .padding(5) - .height(default_height) - .width(*width) - .center_y() - .style(grin_gui_core::theme::ContainerStyle::HoverableForeground); - - row_containers.push((idx, display_status_container)); - } - - /*if let Some((idx, width)) = column_config - .iter() - .enumerate() - .filter_map(|(idx, (key, width, hidden))| { - if *key == ColumnKey::Type && !hidden { - Some((idx, width)) - } else { - None - } - }) - .next() - { - let display_type = if let Some(package) = &release_package { - package.version.clone() - } else { - String::from("-") - }; - let remote_version = Text::new(remote_version).size(DEFAULT_FONT_SIZE); - - let mut remote_version_button = - Button::new(&mut addon.remote_version_btn_state, remote_version) - .style(grin_gui_core::theme::button::Button::NormalText); - - if changelog_url.is_some() { - remote_version_button = - remote_version_button.on_press(Interaction::Expand(ExpandType::Changelog { - addon: addon_cloned.clone(), - changelog: None, - })); - } - - let remote_version_button: Element = remote_version_button.into(); - - let remote_version_container = - Container::new(remote_version_button.map(Message::Interaction)) - .height(default_height) - .width(*width) - .center_y() - .style(grin_gui_core::theme::container::Container::HoverableForeground); - - row_containers.push((idx, remote_version_container)); - }*/ - - if let Some((idx, width)) = column_config - .iter() - .enumerate() - .filter_map(|(idx, (key, width, hidden))| { - if *key == ColumnKey::Type && !hidden { - Some((idx, width)) - } else { - None - } - }) - .next() - { - let display_tx_type = Text::new(tx_type.clone()).size(SMALLER_FONT_SIZE); - let display_tx_type_container = Container::new(display_tx_type) - .height(default_height) - .width(*width) - .center_y() - .padding(5) - .style(grin_gui_core::theme::ContainerStyle::HoverableForeground); - - row_containers.push((idx, display_tx_type_container)); - } - - /*if let Some((idx, width)) = column_config - .iter() - .enumerate() - .filter_map(|(idx, (key, width, hidden))| { - if *key == ColumnKey::Author && !hidden { - Some((idx, width)) - } else { - None - } - }) - .next() - { - let author = Text::new(author.as_deref().unwrap_or("-")).size(DEFAULT_FONT_SIZE); - let author_container = Container::new(author) - .height(default_height) - .width(*width) - .center_y() - .padding(5) - .style(grin_gui_core::theme::container::Container::HoverableForeground); - - row_containers.push((idx, author_container)); - }*/ - - /*if let Some((idx, width)) = column_config - .iter() - .enumerate() - .filter_map(|(idx, (key, width, hidden))| { - if *key == ColumnKey::GameVersion && !hidden { - Some((idx, width)) - } else { - None - } - }) - .next() - { - let game_version = - Text::new(game_version.as_deref().unwrap_or("-")).size(DEFAULT_FONT_SIZE); - let game_version_container = Container::new(game_version) - .height(default_height) - .width(*width) - .center_y() - .padding(5) - .style(grin_gui_core::theme::container::Container::HoverableForeground); - - row_containers.push((idx, game_version_container)); - }*/ - - /*if let Some((idx, width)) = column_config - .iter() - .enumerate() - .filter_map(|(idx, (key, width, hidden))| { - if *key == ColumnKey::DateReleased && !hidden { - Some((idx, width)) - } else { - None - } - }) - .next() - { - let release_date_text: String = if let Some(package) = &release_package { - let f = localized_timeago_formatter(); - let now = Local::now(); - - if let Some(time) = package.date_time.as_ref() { - f.convert_chrono(*time, now) - } else { - "".to_string() - } - } else { - "-".to_string() - }; - let release_date_text = Text::new(release_date_text).size(DEFAULT_FONT_SIZE); - let game_version_container = Container::new(release_date_text) - .height(default_height) - .width(*width) - .center_y() - .padding(5) - .style(grin_gui_core::theme::container::Container::HoverableForeground); - - row_containers.push((idx, game_version_container)); - }*/ - - /*if let Some((idx, width)) = column_config - .iter() - .enumerate() - .filter_map(|(idx, (key, width, hidden))| { - if *key == ColumnKey::Source && !hidden { - Some((idx, width)) - } else { - None - } - }) - .next() - { - let source_text = - repository_kind.map_or_else(|| localized_string("unknown"), |a| a.to_string()); - let source = Text::new(source_text).size(DEFAULT_FONT_SIZE); - let source_container = Container::new(source) - .height(default_height) - .width(*width) - .center_y() - .padding(5) - .style(grin_gui_core::theme::container::Container::HoverableForeground); - - row_containers.push((idx, source_container)); - }*/ - - /*if let Some((idx, width)) = column_config - .iter() - .enumerate() - .filter_map(|(idx, (key, width, hidden))| { - if *key == ColumnKey::Summary && !hidden { - Some((idx, width)) - } else { - None - } - }) - .next() - { - let text = addon_cloned.notes().unwrap_or("-"); - let summary = Text::new(text).size(DEFAULT_FONT_SIZE); - let container = Container::new(summary) - .height(default_height) - .width(*width) - .center_y() - .padding(5) - .style(grin_gui_core::theme::container::Container::HoverableForeground); - - row_containers.push((idx, container)); - }*/ - - /*if let Some((idx, width)) = column_config - .iter() - .enumerate() - .filter_map(|(idx, (key, width, hidden))| { - if *key == ColumnKey::Status && !hidden { - Some((idx, width)) - } else { - None - } - }) - .next() - { - let update_button_container = match &addon.state { - AddonState::Idle => Container::new(Text::new("".to_string()).size(DEFAULT_FONT_SIZE)) - .height(default_height) - .width(*width) - .center_y() - .center_x() - .style(grin_gui_core::theme::container::Container::HoverableForeground), - AddonState::Completed => { - Container::new(Text::new(localized_string("completed")).size(DEFAULT_FONT_SIZE)) - .height(default_height) - .width(*width) - .center_y() - .center_x() - .style(grin_gui_core::theme::container::Container::HoverableForeground) - } - AddonState::Error(message) => { - Container::new(Text::new(message).size(DEFAULT_FONT_SIZE)) - .height(default_height) - .width(*width) - .center_y() - .center_x() - .style(grin_gui_core::theme::container::Container::HoverableForeground) - } - AddonState::Updatable | AddonState::Retry => { - let id = addon.primary_folder_id.clone(); - - let text = match addon.state { - AddonState::Updatable => localized_string("update"), - AddonState::Retry => localized_string("retry"), - _ => "".to_owned(), - }; - - let update_wrapper = Container::new(Text::new(text).size(DEFAULT_FONT_SIZE)) - .width(*width) - .center_x() - .align_x(Align::Center); - let update_button: Element = - Button::new(&mut addon.update_btn_state, update_wrapper) - .width(Length::FillPortion(1)) - .style(style::SecondaryButton) - .on_press(Interaction::Update(id)) - .into(); - - Container::new(update_button.map(Message::Interaction)) - .height(default_height) - .width(*width) - .center_y() - .center_x() - .style(grin_gui_core::theme::container::Container::HoverableBrightForeground) - } - AddonState::Downloading => { - Container::new(Text::new(localized_string("downloading")).size(DEFAULT_FONT_SIZE)) - .height(default_height) - .width(*width) - .center_y() - .center_x() - .padding(5) - .style(grin_gui_core::theme::container::Container::HoverableForeground) - } - AddonState::Unpacking => { - Container::new(Text::new(localized_string("unpacking")).size(DEFAULT_FONT_SIZE)) - .height(default_height) - .width(*width) - .center_y() - .center_x() - .padding(5) - .style(grin_gui_core::theme::container::Container::HoverableForeground) - } - AddonState::Fingerprint => { - Container::new(Text::new(localized_string("hashing")).size(DEFAULT_FONT_SIZE)) - .height(default_height) - .width(*width) - .center_y() - .center_x() - .padding(5) - .style(grin_gui_core::theme::container::Container::HoverableForeground) - } - AddonState::Ignored => { - Container::new(Text::new(localized_string("ignored")).size(DEFAULT_FONT_SIZE)) - .height(default_height) - .width(*width) - .center_y() - .center_x() - .padding(5) - .style(grin_gui_core::theme::container::Container::HoverableForeground) - } - AddonState::Unknown => Container::new(Text::new("").size(DEFAULT_FONT_SIZE)) - .height(default_height) - .width(*width) - .center_y() - .center_x() - .padding(5) - .style(grin_gui_core::theme::container::Container::HoverableForeground), - }; - - row_containers.push((idx, update_button_container)); - }*/ - - let left_spacer = Space::new(Length::Fixed(DEFAULT_PADDING), Length::Fixed(0.0)); - let right_spacer = Space::new(Length::Fixed(DEFAULT_PADDING + 5.0), Length::Fixed(0.0)); - - //let mut row = Row::new().push(left_spacer).spacing(1); - let mut row = Row::new().spacing(1); - - // Sort columns and push them into row - row_containers.sort_by(|a, b| a.0.cmp(&b.0)); - for (_, elem) in row_containers.into_iter() { - row = row.push(elem); - } - - row = row.push(right_spacer); - - let mut tx_column = Column::new().push(row); - let mut action_button_row = Row::new(); - - if is_tx_expanded { - match expand_type { - ExpandType::Details(_) => { - let button_width = Length::Fixed(BUTTON_WIDTH); - - // ID - let id_title_text = - Text::new(format!("{}: ", localized_string("tx-id"))).size(DEFAULT_FONT_SIZE); - let id_title_container = Container::new(id_title_text) - .style(grin_gui_core::theme::ContainerStyle::HoverableBrightForeground); - - let id_text = Text::new(id).size(DEFAULT_FONT_SIZE); - let id_text_container = Container::new(id_text) - .style(grin_gui_core::theme::ContainerStyle::HoverableBrightForeground); - - let id_row = Row::new() - .push(id_title_container) - .push(Space::new(Length::Fixed(5.0), Length::Fixed(0.0))) - .push(id_text_container); - - // UUID - let uuid_title_text = Text::new(format!("{}: ", localized_string("tx-shared-id"))) - .size(DEFAULT_FONT_SIZE); - let uuid_title_container = Container::new(uuid_title_text) - .style(grin_gui_core::theme::ContainerStyle::HoverableBrightForeground); - - let uuid_text = Text::new(shared_tx_id).size(DEFAULT_FONT_SIZE); - let uuid_text_container = Container::new(uuid_text) - .style(grin_gui_core::theme::ContainerStyle::HoverableBrightForeground); - - let uuid_row = Row::new() - .push(uuid_title_container) - .push(Space::new(Length::Fixed(5.0), Length::Fixed(0.0))) - .push(uuid_text_container); - - // Transaction type - let type_title_text = - Text::new(format!("{}: ", localized_string("tx-type"))).size(DEFAULT_FONT_SIZE); - let type_title_container = Container::new(type_title_text) - .style(grin_gui_core::theme::ContainerStyle::HoverableBrightForeground); - - let type_text = Text::new(tx_type).size(DEFAULT_FONT_SIZE); - let type_text_container = Container::new(type_text) - .style(grin_gui_core::theme::ContainerStyle::HoverableBrightForeground); - - let type_row = Row::new() - .push(type_title_container) - .push(Space::new(Length::Fixed(5.0), Length::Fixed(0.0))) - .push(type_text_container); - - /*let notes = notes.unwrap_or_else(|| localized_string("no-addon-description")); - let author = author.unwrap_or_else(|| "-".to_string());*/ - let left_spacer = Space::new(Length::Fixed(DEFAULT_PADDING), Length::Fixed(0.0)); - let space = Space::new(Length::Fixed(0.0), Length::Fixed(DEFAULT_PADDING * 2.0)); - let bottom_space = Space::new(Length::Fixed(0.0), Length::Fixed(4.0)); - - let confirmed = tx_cloned.tx.confirmed; - - let tx_details_container = Container::new( - Text::new(localized_string("tx-details")).size(DEFAULT_FONT_SIZE), - ) - .width(button_width) - .align_y(alignment::Vertical::Center) - .align_x(alignment::Horizontal::Center); - - let tx_details_button: Element = Button::new(tx_details_container) - .width(Length::Fixed(BUTTON_WIDTH)) - .style(grin_gui_core::theme::ButtonStyle::Primary) - .on_press(Interaction::WalletOperationHomeViewInteraction( - super::home::LocalViewInteraction::TxDetails(tx_cloned.clone()), - )) - .into(); - - let tx_details_wrap = - Container::new(tx_details_button.map(Message::Interaction)).padding(1.0); - let tx_details_wrap = Container::new(tx_details_wrap) - .style(grin_gui_core::theme::ContainerStyle::Segmented) - .padding(1); - - action_button_row = Row::new() - .push(Space::new( - Length::Fixed(DEFAULT_PADDING * 3.0), - Length::Fixed(0.0), - )) - .push(tx_details_wrap) - .push(Space::with_width(Length::Fixed(DEFAULT_PADDING))); - - // Invoice proof view/copy paste - if config.tx_method == TxMethod::Contracts { - let tx_proof_container = Container::new( - Text::new(localized_string("tx-proof")).size(DEFAULT_FONT_SIZE), - ) - .width(button_width) - .align_y(alignment::Vertical::Center) - .align_x(alignment::Horizontal::Center); - - let tx_proof_button: Element = Button::new(tx_proof_container) - .width(Length::Fixed(BUTTON_WIDTH)) - .style(grin_gui_core::theme::ButtonStyle::Primary) - .on_press(Interaction::WalletOperationHomeViewInteraction( - super::home::LocalViewInteraction::TxProof(tx_cloned), - )) - .into(); - - let tx_proof_wrap = - Container::new(tx_proof_button.map(Message::Interaction)).padding(1.0); - let tx_proof_wrap = Container::new(tx_proof_wrap) - .style(grin_gui_core::theme::ContainerStyle::Segmented) - .padding(1); - - action_button_row = action_button_row - .push(tx_proof_wrap) - .push(Space::with_width(Length::Fixed(DEFAULT_PADDING))); - } - - if !confirmed { - // Re-fetch the slate representing the last saved state - let tx_reload_slate_container = Container::new( - Text::new(localized_string("tx-reload-slate")).size(DEFAULT_FONT_SIZE), - ) - .width(Length::Fixed(BUTTON_WIDTH * 2.0)) - .align_y(alignment::Vertical::Center) - .align_x(alignment::Horizontal::Center); - - let tx_reload_slate_button: Element = - Button::new(tx_reload_slate_container) - .width(Length::Fixed(BUTTON_WIDTH * 2.0)) - .style(grin_gui_core::theme::ButtonStyle::Primary) - .on_press(Interaction::WalletOperationHomeViewInteraction( - super::home::LocalViewInteraction::ReloadTxSlate( - tx_cloned_for_row.tx.tx_slate_id.unwrap().to_string(), - ), - )) - .into(); - - let tx_reload_slate_wrap = - Container::new(tx_reload_slate_button.map(Message::Interaction)).padding(1); - let tx_reload_slate_wrap = Container::new(tx_reload_slate_wrap) - .style(grin_gui_core::theme::ContainerStyle::Segmented) - .padding(1); - - // Present cancel button - let tx_button_cancel_container = Container::new( - Text::new(localized_string("cancel-tx")).size(DEFAULT_FONT_SIZE), - ) - .width(button_width) - .align_y(alignment::Vertical::Center) - .align_x(alignment::Horizontal::Center); - - let mut tx_cancel_button = Button::new(tx_button_cancel_container) - .width(Length::Fixed(BUTTON_WIDTH)) - .style(grin_gui_core::theme::ButtonStyle::Primary); - - if node_synched { - tx_cancel_button = tx_cancel_button.on_press( - Interaction::WalletOperationHomeViewInteraction( - super::home::LocalViewInteraction::CancelTx( - tx_log_entry_wrap.tx.id, - tx_log_entry_wrap.tx.tx_slate_id.unwrap().to_string(), - ), - ), - ); - } - let tx_cancel_button: Element = tx_cancel_button.into(); - - let tx_cancel_wrap = - Container::new(tx_cancel_button.map(Message::Interaction)).padding(1); - let tx_cancel_wrap = Container::new(tx_cancel_wrap) - .style(grin_gui_core::theme::ContainerStyle::Segmented) - .padding(1); - - action_button_row = action_button_row - .push(tx_reload_slate_wrap) - .push(Space::with_width(Length::Fixed(DEFAULT_PADDING))) - .push(tx_cancel_wrap) - } - - /* - let notes_title_text = - Text::new(localized_string("summary")).size(DEFAULT_FONT_SIZE); - let notes_text = Text::new(notes).size(DEFAULT_FONT_SIZE); - let author_text = Text::new(author).size(DEFAULT_FONT_SIZE); - let author_title_text = - Text::new(localized_string("authors")).size(DEFAULT_FONT_SIZE); - let author_title_container = Container::new(author_title_text) - .style(grin_gui_core::theme::container::Container::HoverableBrightForeground); - let notes_title_container = Container::new(notes_title_text) - .style(grin_gui_core::theme::container::Container::HoverableBrightForeground); - - let release_date_text: String = if let Some(package) = &release_package { - let f = localized_timeago_formatter(); - let now = Local::now(); - - if let Some(time) = package.date_time.as_ref() { - f.convert_chrono(*time, now) - } else { - "".to_string() - } - } else { - localized_string("release-channel-no-release") - }; - let release_date_text = Text::new(release_date_text).size(DEFAULT_FONT_SIZE); - let release_date_text_container = Container::new(release_date_text) - .center_y() - .padding(5) - .style(grin_gui_core::theme::container::Container::NormalBackground); - - let release_channel_title = - Text::new(localized_string("remote-release-channel")).size(DEFAULT_FONT_SIZE); - let release_channel_title_container = Container::new(release_channel_title) - .style(grin_gui_core::theme::container::Container::NormalBackground); - let release_channel_list = PickList::new( - &mut addon.pick_release_channel_state, - &ReleaseChannel::ALL[..], - Some(addon.release_channel), - Message::ReleaseChannelSelected, - ) - .text_size(14) - .width(Length::Fixed(100)) - .style(style::PickList); - - let mut website_button = Button::new( - &mut addon.website_btn_state, - Text::new(localized_string("website")).size(DEFAULT_FONT_SIZE), - ) - .style(grin_gui_core::theme::button::Button::Primary); - - if let Some(link) = website_url { - website_button = website_button.on_press(Interaction::OpenLink(link)); - } - - let website_button: Element = website_button.into(); - - let is_ignored = addon.state == AddonState::Ignored; - let ignore_button_text = if is_ignored { - Text::new(localized_string("unignore")).size(DEFAULT_FONT_SIZE) - } else { - Text::new(localized_string("ignore")).size(DEFAULT_FONT_SIZE) - }; - - let mut ignore_button = - Button::new(&mut addon.ignore_btn_state, ignore_button_text) - .on_press(Interaction::Ignore(addon.primary_folder_id.clone())) - .style(grin_gui_core::theme::button::Button::Primary); - - if is_ignored { - ignore_button = ignore_button - .on_press(Interaction::Unignore(addon.primary_folder_id.clone())); - } else { - ignore_button = ignore_button - .on_press(Interaction::Ignore(addon.primary_folder_id.clone())); - } - - let ignore_button: Element = ignore_button.into(); - - let (title, interaction) = if Some(Confirm::DeleteAddon) == *pending_confirmation { - ( - localized_string("confirm-deletion"), - Interaction::ConfirmDeleteAddon(addon.primary_folder_id.clone()), - ) - } else { - let mut vars = HashMap::new(); - vars.insert("addon".to_string(), addon_cloned.title()); - let fmt = localized_string("delete-addon"); - - (strfmt(&fmt, &vars).unwrap(), Interaction::DeleteAddon()) - }; - - let delete_button: Element = Button::new( - &mut addon.delete_btn_state, - Text::new(title).size(DEFAULT_FONT_SIZE), - ) - .on_press(interaction) - .style(style::DefaultDeleteButton) - .into(); - - let (title, interaction) = if Some(Confirm::DeleteSavedVariables) - == *pending_confirmation - { - ( - localized_string("confirm-deletion"), - Interaction::ConfirmDeleteSavedVariables(addon.primary_folder_id.clone()), - ) - } else { - ( - localized_string("delete-addon-saved-variables"), - Interaction::DeleteSavedVariables(), - ) - }; - let delete_savedvariables_button: Element = Button::new( - &mut addon.delete_saved_variables_btn_state, - Text::new(title).size(DEFAULT_FONT_SIZE), - ) - .on_press(interaction) - .style(style::DefaultDeleteButton) - .into(); - - let mut changelog_button = Button::new( - &mut addon.changelog_btn_state, - Text::new(localized_string("changelog")).size(DEFAULT_FONT_SIZE), - ) - .style(grin_gui_core::theme::button::Button::Primary); - - if changelog_url.is_some() { - changelog_button = - changelog_button.on_press(Interaction::Expand(ExpandType::Changelog { - addon: addon_cloned, - changelog: None, - })); - } - - let changelog_button: Element = changelog_button.into();*/ - - /*let test_row = Row::new() - .push(release_channel_list) - .push(release_date_text_container);*/ - - /*let button_row = Row::new() - .push(Space::new(Length::Fill, Length::Fixed(0.0))) - .push(website_button.map(Message::Interaction)) - .push(Space::new(Length::Fixed(5.0), Length::Fixed(0.0))) - .push(changelog_button.map(Message::Interaction)) - .push(Space::new(Length::Fixed(5.0), Length::Fixed(0.0))) - .push(ignore_button.map(Message::Interaction)) - .push(Space::new(Length::Fixed(5.0), Length::Fixed(0.0))) - .push(delete_savedvariables_button.map(Message::Interaction)) - .push(Space::new(Length::Fixed(5.0), Length::Fixed(0.0))) - .push(delete_button.map(Message::Interaction)) - .width(Length::Fill);*/ - let column = Column::new() - .push(id_row) - .push(Space::new(Length::Fixed(0.0), Length::Fixed(3.0))) - .push(uuid_row) - .push(Space::new(Length::Fixed(0.0), Length::Fixed(3.0))) - .push(type_row); - //.push(Space::new(Length::Fixed(0.0), Length::Fixed(3))) - /* .push(notes_title_container) - .push(Space::new(Length::Fixed(0.0), Length::Fixed(3))) - .push(notes_text) - .push(Space::new(Length::Fixed(0.0), Length::Fixed(15))) - .push(release_channel_title_container) - .push(Space::new(Length::Fixed(0.0), Length::Fixed(3))) - .push(test_row) - .push(space) - .push(button_row)*/ - //.push(bottom_space); - let details_container = Container::new(column) - .width(Length::Fill) - .padding(20) - .style(grin_gui_core::theme::ContainerStyle::NormalBackground); - - let row = Row::new() - .push(left_spacer) - .push(details_container) - .push(Space::new( - Length::Fixed(DEFAULT_PADDING + 5.0), - Length::Fixed(0.0), - )) - .spacing(1); - tx_column = tx_column - .push(Space::new(Length::FillPortion(1), Length::Fixed(1.0))) - .push(row); - } - ExpandType::None => {} - } - } - - let mut table_row = TableRow::new(tx_column) - .width(Length::Fill) - .inner_row_height(default_row_height) - .on_press(move |_| { - Message::Interaction(Interaction::WalletOperationTxListInteraction( - LocalViewInteraction::Expand(ExpandType::Details(tx_cloned_for_row.clone())), - )) - }); - - if is_odd == Some(true) { - table_row = table_row.style(grin_gui_core::theme::TableRowStyle::TableRowAlternate) - } else { - table_row = table_row.style(grin_gui_core::theme::TableRowStyle::Default) - } - - // Due to what feels like an iced-rs bug, don't put buttons within the actual row as they appear - // to clear their state between the press down and up event if included within the row itself - // Some kind of fix to the table row widget might rectify this - let mut return_column = Column::new().push(table_row).push(action_button_row); - - if is_tx_expanded { - return_column = return_column.push(Space::new( - Length::Fixed(0.0), - Length::Fixed(DEFAULT_PADDING * 2.0), - )); - } - - let return_container = Container::new(return_column); - - return_container + let default_height = Length::Fixed(26.0); + let mut default_row_height = 26; + + let mut row_containers = vec![]; + + let id = tx_log_entry_wrap.tx.id.to_string(); + let mut tx_type = format!( + "{}", + tx_log_entry_wrap.tx.tx_type.to_string().replace("\n", "") + ); + let shared_tx_id = match tx_log_entry_wrap.tx.tx_slate_id { + Some(t) => t.to_string(), + None => "None".to_string(), + }; + let creation_time = tx_log_entry_wrap.tx.creation_ts.to_string(); + let ttl_cutoff = tx_log_entry_wrap.tx.ttl_cutoff_height; + let height = tx_log_entry_wrap.tx.kernel_lookup_min_height; + + let tx_cloned = tx_log_entry_wrap.clone(); + let tx_cloned_for_row = tx_log_entry_wrap.clone(); + + let creation_time = tx_log_entry_wrap.tx.creation_ts.to_string(); + let confirmation_time = tx_log_entry_wrap.tx.creation_ts.to_string(); + let net_diff = if tx_log_entry_wrap.tx.amount_credited >= tx_log_entry_wrap.tx.amount_debited { + amount_to_hr_string( + tx_log_entry_wrap.tx.amount_credited - tx_log_entry_wrap.tx.amount_debited, + true, + ) + } else { + format!( + "-{}", + amount_to_hr_string( + tx_log_entry_wrap.tx.amount_debited - tx_log_entry_wrap.tx.amount_credited, + true + ) + ) + }; + //TODO this will show the latest status + // Unconfirmed - Created time + // Confirmed + let status = create_tx_display_status(&tx_log_entry_wrap.tx); + + /*let version = tx + .version() + .map(str::to_string) + .unwrap_or_else(|| "-".to_string()); + let release_package = addon_cloned.relevant_release_package(global_release_channel);*/ + + /*if let Some((idx, width)) = column_config + .iter() + .enumerate() + .filter_map(|(idx, (key, width, hidden))| { + if *key == ColumnKey::Title && !hidden { + Some((idx, width)) + } else { + None + } + }) + .next() + { + let title = Text::new(addon.title()).size(DEFAULT_FONT_SIZE); + + let mut title_row = Row::new().push(title).spacing(5).align_items(Align::Center); + + if addon.release_channel != ReleaseChannel::Default { + let release_channel = + Container::new(Text::new(addon.release_channel.to_string()).size(10)) + .style(style::ChannelBadge) + .padding(3); + + title_row = title_row.push(release_channel); + } + + let mut title_container = Container::new(title_row) + .padding(5) + .height(default_height) + .width(*width) + .center_y(); + if is_addon_expanded && matches!(expand_type, ExpandType::Details(_)) { + title_container = + title_container.style(style::SelectedBrightForegroundContainer); + } else { + title_container = + title_container.style(grin_gui_core::theme::container::Container::HoverableBrightForeground); + } + + row_containers.push((idx, title_container)); + }*/ + + if let Some((idx, width)) = column_config + .iter() + .enumerate() + .filter_map(|(idx, (key, width, hidden))| { + if *key == ColumnKey::Id && !hidden { + Some((idx, width)) + } else { + None + } + }) + .next() + { + let display_id = Text::new(id.clone()).size(DEFAULT_FONT_SIZE); + + let id_container = Container::new(display_id) + .padding(5) + .height(default_height) + .width(*width) + .center_y() + .style(grin_gui_core::theme::ContainerStyle::HoverableForeground); + + row_containers.push((idx, id_container)); + } + + if let Some((idx, width)) = column_config + .iter() + .enumerate() + .filter_map(|(idx, (key, width, hidden))| { + if *key == ColumnKey::CreationTime && !hidden { + Some((idx, width)) + } else { + None + } + }) + .next() + { + let display_creation_time = Text::new(creation_time).size(DEFAULT_FONT_SIZE); + + let display_creation_time_container = Container::new(display_creation_time) + .padding(5) + .height(default_height) + .width(*width) + .center_y() + .style(grin_gui_core::theme::ContainerStyle::HoverableForeground); + + row_containers.push((idx, display_creation_time_container)); + } + + if let Some((idx, width)) = column_config + .iter() + .enumerate() + .filter_map(|(idx, (key, width, hidden))| { + if *key == ColumnKey::ConfirmationTime && !hidden { + Some((idx, width)) + } else { + None + } + }) + .next() + { + let display_confirmation_time = Text::new(confirmation_time).size(DEFAULT_FONT_SIZE); + + let display_confirmation_time_container = Container::new(display_confirmation_time) + .padding(5) + .height(default_height) + .width(*width) + .center_y() + .style(grin_gui_core::theme::ContainerStyle::HoverableForeground); + + row_containers.push((idx, display_confirmation_time_container)); + } + + if let Some((idx, width)) = column_config + .iter() + .enumerate() + .filter_map(|(idx, (key, width, hidden))| { + if *key == ColumnKey::NetDifference && !hidden { + Some((idx, width)) + } else { + None + } + }) + .next() + { + let display_net_difference = Text::new(net_diff).size(DEFAULT_FONT_SIZE); + + let display_net_difference_container = Container::new(display_net_difference) + .padding(5) + .height(default_height) + .width(*width) + .center_y() + .style(grin_gui_core::theme::ContainerStyle::HoverableForeground); + + row_containers.push((idx, display_net_difference_container)); + } + + if let Some((idx, width)) = column_config + .iter() + .enumerate() + .filter_map(|(idx, (key, width, hidden))| { + if *key == ColumnKey::Status && !hidden { + Some((idx, width)) + } else { + None + } + }) + .next() + { + let display_status = Text::new(status).size(DEFAULT_FONT_SIZE); + + let display_status_container = Container::new(display_status) + .padding(5) + .height(default_height) + .width(*width) + .center_y() + .style(grin_gui_core::theme::ContainerStyle::HoverableForeground); + + row_containers.push((idx, display_status_container)); + } + + /*if let Some((idx, width)) = column_config + .iter() + .enumerate() + .filter_map(|(idx, (key, width, hidden))| { + if *key == ColumnKey::Type && !hidden { + Some((idx, width)) + } else { + None + } + }) + .next() + { + let display_type = if let Some(package) = &release_package { + package.version.clone() + } else { + String::from("-") + }; + let remote_version = Text::new(remote_version).size(DEFAULT_FONT_SIZE); + + let mut remote_version_button = + Button::new(&mut addon.remote_version_btn_state, remote_version) + .style(grin_gui_core::theme::button::Button::NormalText); + + if changelog_url.is_some() { + remote_version_button = + remote_version_button.on_press(Interaction::Expand(ExpandType::Changelog { + addon: addon_cloned.clone(), + changelog: None, + })); + } + + let remote_version_button: Element = remote_version_button.into(); + + let remote_version_container = + Container::new(remote_version_button.map(Message::Interaction)) + .height(default_height) + .width(*width) + .center_y() + .style(grin_gui_core::theme::container::Container::HoverableForeground); + + row_containers.push((idx, remote_version_container)); + }*/ + + if let Some((idx, width)) = column_config + .iter() + .enumerate() + .filter_map(|(idx, (key, width, hidden))| { + if *key == ColumnKey::Type && !hidden { + Some((idx, width)) + } else { + None + } + }) + .next() + { + let display_tx_type = Text::new(tx_type.clone()).size(SMALLER_FONT_SIZE); + let display_tx_type_container = Container::new(display_tx_type) + .height(default_height) + .width(*width) + .center_y() + .padding(5) + .style(grin_gui_core::theme::ContainerStyle::HoverableForeground); + + row_containers.push((idx, display_tx_type_container)); + } + + /*if let Some((idx, width)) = column_config + .iter() + .enumerate() + .filter_map(|(idx, (key, width, hidden))| { + if *key == ColumnKey::Author && !hidden { + Some((idx, width)) + } else { + None + } + }) + .next() + { + let author = Text::new(author.as_deref().unwrap_or("-")).size(DEFAULT_FONT_SIZE); + let author_container = Container::new(author) + .height(default_height) + .width(*width) + .center_y() + .padding(5) + .style(grin_gui_core::theme::container::Container::HoverableForeground); + + row_containers.push((idx, author_container)); + }*/ + + /*if let Some((idx, width)) = column_config + .iter() + .enumerate() + .filter_map(|(idx, (key, width, hidden))| { + if *key == ColumnKey::GameVersion && !hidden { + Some((idx, width)) + } else { + None + } + }) + .next() + { + let game_version = + Text::new(game_version.as_deref().unwrap_or("-")).size(DEFAULT_FONT_SIZE); + let game_version_container = Container::new(game_version) + .height(default_height) + .width(*width) + .center_y() + .padding(5) + .style(grin_gui_core::theme::container::Container::HoverableForeground); + + row_containers.push((idx, game_version_container)); + }*/ + + /*if let Some((idx, width)) = column_config + .iter() + .enumerate() + .filter_map(|(idx, (key, width, hidden))| { + if *key == ColumnKey::DateReleased && !hidden { + Some((idx, width)) + } else { + None + } + }) + .next() + { + let release_date_text: String = if let Some(package) = &release_package { + let f = localized_timeago_formatter(); + let now = Local::now(); + + if let Some(time) = package.date_time.as_ref() { + f.convert_chrono(*time, now) + } else { + "".to_string() + } + } else { + "-".to_string() + }; + let release_date_text = Text::new(release_date_text).size(DEFAULT_FONT_SIZE); + let game_version_container = Container::new(release_date_text) + .height(default_height) + .width(*width) + .center_y() + .padding(5) + .style(grin_gui_core::theme::container::Container::HoverableForeground); + + row_containers.push((idx, game_version_container)); + }*/ + + /*if let Some((idx, width)) = column_config + .iter() + .enumerate() + .filter_map(|(idx, (key, width, hidden))| { + if *key == ColumnKey::Source && !hidden { + Some((idx, width)) + } else { + None + } + }) + .next() + { + let source_text = + repository_kind.map_or_else(|| localized_string("unknown"), |a| a.to_string()); + let source = Text::new(source_text).size(DEFAULT_FONT_SIZE); + let source_container = Container::new(source) + .height(default_height) + .width(*width) + .center_y() + .padding(5) + .style(grin_gui_core::theme::container::Container::HoverableForeground); + + row_containers.push((idx, source_container)); + }*/ + + /*if let Some((idx, width)) = column_config + .iter() + .enumerate() + .filter_map(|(idx, (key, width, hidden))| { + if *key == ColumnKey::Summary && !hidden { + Some((idx, width)) + } else { + None + } + }) + .next() + { + let text = addon_cloned.notes().unwrap_or("-"); + let summary = Text::new(text).size(DEFAULT_FONT_SIZE); + let container = Container::new(summary) + .height(default_height) + .width(*width) + .center_y() + .padding(5) + .style(grin_gui_core::theme::container::Container::HoverableForeground); + + row_containers.push((idx, container)); + }*/ + + /*if let Some((idx, width)) = column_config + .iter() + .enumerate() + .filter_map(|(idx, (key, width, hidden))| { + if *key == ColumnKey::Status && !hidden { + Some((idx, width)) + } else { + None + } + }) + .next() + { + let update_button_container = match &addon.state { + AddonState::Idle => Container::new(Text::new("".to_string()).size(DEFAULT_FONT_SIZE)) + .height(default_height) + .width(*width) + .center_y() + .center_x() + .style(grin_gui_core::theme::container::Container::HoverableForeground), + AddonState::Completed => { + Container::new(Text::new(localized_string("completed")).size(DEFAULT_FONT_SIZE)) + .height(default_height) + .width(*width) + .center_y() + .center_x() + .style(grin_gui_core::theme::container::Container::HoverableForeground) + } + AddonState::Error(message) => { + Container::new(Text::new(message).size(DEFAULT_FONT_SIZE)) + .height(default_height) + .width(*width) + .center_y() + .center_x() + .style(grin_gui_core::theme::container::Container::HoverableForeground) + } + AddonState::Updatable | AddonState::Retry => { + let id = addon.primary_folder_id.clone(); + + let text = match addon.state { + AddonState::Updatable => localized_string("update"), + AddonState::Retry => localized_string("retry"), + _ => "".to_owned(), + }; + + let update_wrapper = Container::new(Text::new(text).size(DEFAULT_FONT_SIZE)) + .width(*width) + .center_x() + .align_x(Align::Center); + let update_button: Element = + Button::new(&mut addon.update_btn_state, update_wrapper) + .width(Length::FillPortion(1)) + .style(style::SecondaryButton) + .on_press(Interaction::Update(id)) + .into(); + + Container::new(update_button.map(Message::Interaction)) + .height(default_height) + .width(*width) + .center_y() + .center_x() + .style(grin_gui_core::theme::container::Container::HoverableBrightForeground) + } + AddonState::Downloading => { + Container::new(Text::new(localized_string("downloading")).size(DEFAULT_FONT_SIZE)) + .height(default_height) + .width(*width) + .center_y() + .center_x() + .padding(5) + .style(grin_gui_core::theme::container::Container::HoverableForeground) + } + AddonState::Unpacking => { + Container::new(Text::new(localized_string("unpacking")).size(DEFAULT_FONT_SIZE)) + .height(default_height) + .width(*width) + .center_y() + .center_x() + .padding(5) + .style(grin_gui_core::theme::container::Container::HoverableForeground) + } + AddonState::Fingerprint => { + Container::new(Text::new(localized_string("hashing")).size(DEFAULT_FONT_SIZE)) + .height(default_height) + .width(*width) + .center_y() + .center_x() + .padding(5) + .style(grin_gui_core::theme::container::Container::HoverableForeground) + } + AddonState::Ignored => { + Container::new(Text::new(localized_string("ignored")).size(DEFAULT_FONT_SIZE)) + .height(default_height) + .width(*width) + .center_y() + .center_x() + .padding(5) + .style(grin_gui_core::theme::container::Container::HoverableForeground) + } + AddonState::Unknown => Container::new(Text::new("").size(DEFAULT_FONT_SIZE)) + .height(default_height) + .width(*width) + .center_y() + .center_x() + .padding(5) + .style(grin_gui_core::theme::container::Container::HoverableForeground), + }; + + row_containers.push((idx, update_button_container)); + }*/ + + let left_spacer = Space::new(Length::Fixed(DEFAULT_PADDING), Length::Fixed(0.0)); + let right_spacer = Space::new(Length::Fixed(DEFAULT_PADDING + 5.0), Length::Fixed(0.0)); + + //let mut row = Row::new().push(left_spacer).spacing(1); + let mut row = Row::new().spacing(1); + + // Sort columns and push them into row + row_containers.sort_by(|a, b| a.0.cmp(&b.0)); + for (_, elem) in row_containers.into_iter() { + row = row.push(elem); + } + + row = row.push(right_spacer); + + let mut tx_column = Column::new().push(row); + let mut action_button_row = Row::new(); + + if is_tx_expanded { + match expand_type { + ExpandType::Details(_) => { + let button_width = Length::Fixed(BUTTON_WIDTH); + + // ID + let id_title_text = + Text::new(format!("{}: ", localized_string("tx-id"))).size(DEFAULT_FONT_SIZE); + let id_title_container = Container::new(id_title_text) + .style(grin_gui_core::theme::ContainerStyle::HoverableBrightForeground); + + let id_text = Text::new(id).size(DEFAULT_FONT_SIZE); + let id_text_container = Container::new(id_text) + .style(grin_gui_core::theme::ContainerStyle::HoverableBrightForeground); + + let id_row = Row::new() + .push(id_title_container) + .push(Space::new(Length::Fixed(5.0), Length::Fixed(0.0))) + .push(id_text_container); + + // UUID + let uuid_title_text = Text::new(format!("{}: ", localized_string("tx-shared-id"))) + .size(DEFAULT_FONT_SIZE); + let uuid_title_container = Container::new(uuid_title_text) + .style(grin_gui_core::theme::ContainerStyle::HoverableBrightForeground); + + let uuid_text = Text::new(shared_tx_id).size(DEFAULT_FONT_SIZE); + let uuid_text_container = Container::new(uuid_text) + .style(grin_gui_core::theme::ContainerStyle::HoverableBrightForeground); + + let uuid_row = Row::new() + .push(uuid_title_container) + .push(Space::new(Length::Fixed(5.0), Length::Fixed(0.0))) + .push(uuid_text_container); + + // Transaction type + let type_title_text = + Text::new(format!("{}: ", localized_string("tx-type"))).size(DEFAULT_FONT_SIZE); + let type_title_container = Container::new(type_title_text) + .style(grin_gui_core::theme::ContainerStyle::HoverableBrightForeground); + + let type_text = Text::new(tx_type).size(DEFAULT_FONT_SIZE); + let type_text_container = Container::new(type_text) + .style(grin_gui_core::theme::ContainerStyle::HoverableBrightForeground); + + let type_row = Row::new() + .push(type_title_container) + .push(Space::new(Length::Fixed(5.0), Length::Fixed(0.0))) + .push(type_text_container); + + /*let notes = notes.unwrap_or_else(|| localized_string("no-addon-description")); + let author = author.unwrap_or_else(|| "-".to_string());*/ + let left_spacer = Space::new(Length::Fixed(DEFAULT_PADDING), Length::Fixed(0.0)); + let space = Space::new(Length::Fixed(0.0), Length::Fixed(DEFAULT_PADDING * 2.0)); + let bottom_space = Space::new(Length::Fixed(0.0), Length::Fixed(4.0)); + + let confirmed = tx_cloned.tx.confirmed; + + let tx_details_container = Container::new( + Text::new(localized_string("tx-details")).size(DEFAULT_FONT_SIZE), + ) + .width(button_width) + .align_y(alignment::Vertical::Center) + .align_x(alignment::Horizontal::Center); + + let tx_details_button: Element = Button::new(tx_details_container) + .width(Length::Fixed(BUTTON_WIDTH)) + .style(grin_gui_core::theme::ButtonStyle::Primary) + .on_press(Interaction::WalletOperationHomeViewInteraction( + super::home::LocalViewInteraction::TxDetails(tx_cloned.clone()), + )) + .into(); + + let tx_details_wrap = + Container::new(tx_details_button.map(Message::Interaction)).padding(1.0); + let tx_details_wrap = Container::new(tx_details_wrap) + .style(grin_gui_core::theme::ContainerStyle::Segmented) + .padding(1); + + action_button_row = Row::new() + .push(Space::new( + Length::Fixed(DEFAULT_PADDING * 3.0), + Length::Fixed(0.0), + )) + .push(tx_details_wrap) + .push(Space::with_width(Length::Fixed(DEFAULT_PADDING))); + + // Invoice proof view/copy paste + if config.tx_method == TxMethod::Contracts { + let tx_proof_container = Container::new( + Text::new(localized_string("tx-proof")).size(DEFAULT_FONT_SIZE), + ) + .width(button_width) + .align_y(alignment::Vertical::Center) + .align_x(alignment::Horizontal::Center); + + let tx_proof_button: Element = Button::new(tx_proof_container) + .width(Length::Fixed(BUTTON_WIDTH)) + .style(grin_gui_core::theme::ButtonStyle::Primary) + .on_press(Interaction::WalletOperationHomeViewInteraction( + super::home::LocalViewInteraction::TxProof(tx_cloned), + )) + .into(); + + let tx_proof_wrap = + Container::new(tx_proof_button.map(Message::Interaction)).padding(1.0); + let tx_proof_wrap = Container::new(tx_proof_wrap) + .style(grin_gui_core::theme::ContainerStyle::Segmented) + .padding(1); + + action_button_row = action_button_row + .push(tx_proof_wrap) + .push(Space::with_width(Length::Fixed(DEFAULT_PADDING))); + } + + if !confirmed { + // Re-fetch the slate representing the last saved state + let tx_reload_slate_container = Container::new( + Text::new(localized_string("tx-reload-slate")).size(DEFAULT_FONT_SIZE), + ) + .width(Length::Fixed(BUTTON_WIDTH * 2.0)) + .align_y(alignment::Vertical::Center) + .align_x(alignment::Horizontal::Center); + + let tx_reload_slate_button: Element = + Button::new(tx_reload_slate_container) + .width(Length::Fixed(BUTTON_WIDTH * 2.0)) + .style(grin_gui_core::theme::ButtonStyle::Primary) + .on_press(Interaction::WalletOperationHomeViewInteraction( + super::home::LocalViewInteraction::ReloadTxSlate( + tx_cloned_for_row.tx.tx_slate_id.unwrap().to_string(), + ), + )) + .into(); + + let tx_reload_slate_wrap = + Container::new(tx_reload_slate_button.map(Message::Interaction)).padding(1); + let tx_reload_slate_wrap = Container::new(tx_reload_slate_wrap) + .style(grin_gui_core::theme::ContainerStyle::Segmented) + .padding(1); + + // Present cancel button + let tx_button_cancel_container = Container::new( + Text::new(localized_string("cancel-tx")).size(DEFAULT_FONT_SIZE), + ) + .width(button_width) + .align_y(alignment::Vertical::Center) + .align_x(alignment::Horizontal::Center); + + let mut tx_cancel_button = Button::new(tx_button_cancel_container) + .width(Length::Fixed(BUTTON_WIDTH)) + .style(grin_gui_core::theme::ButtonStyle::Primary); + + if node_synched { + tx_cancel_button = tx_cancel_button.on_press( + Interaction::WalletOperationHomeViewInteraction( + super::home::LocalViewInteraction::CancelTx( + tx_log_entry_wrap.tx.id, + tx_log_entry_wrap.tx.tx_slate_id.unwrap().to_string(), + ), + ), + ); + } + let tx_cancel_button: Element = tx_cancel_button.into(); + + let tx_cancel_wrap = + Container::new(tx_cancel_button.map(Message::Interaction)).padding(1); + let tx_cancel_wrap = Container::new(tx_cancel_wrap) + .style(grin_gui_core::theme::ContainerStyle::Segmented) + .padding(1); + + action_button_row = action_button_row + .push(tx_reload_slate_wrap) + .push(Space::with_width(Length::Fixed(DEFAULT_PADDING))) + .push(tx_cancel_wrap) + } + + /* + let notes_title_text = + Text::new(localized_string("summary")).size(DEFAULT_FONT_SIZE); + let notes_text = Text::new(notes).size(DEFAULT_FONT_SIZE); + let author_text = Text::new(author).size(DEFAULT_FONT_SIZE); + let author_title_text = + Text::new(localized_string("authors")).size(DEFAULT_FONT_SIZE); + let author_title_container = Container::new(author_title_text) + .style(grin_gui_core::theme::container::Container::HoverableBrightForeground); + let notes_title_container = Container::new(notes_title_text) + .style(grin_gui_core::theme::container::Container::HoverableBrightForeground); + + let release_date_text: String = if let Some(package) = &release_package { + let f = localized_timeago_formatter(); + let now = Local::now(); + + if let Some(time) = package.date_time.as_ref() { + f.convert_chrono(*time, now) + } else { + "".to_string() + } + } else { + localized_string("release-channel-no-release") + }; + let release_date_text = Text::new(release_date_text).size(DEFAULT_FONT_SIZE); + let release_date_text_container = Container::new(release_date_text) + .center_y() + .padding(5) + .style(grin_gui_core::theme::container::Container::NormalBackground); + + let release_channel_title = + Text::new(localized_string("remote-release-channel")).size(DEFAULT_FONT_SIZE); + let release_channel_title_container = Container::new(release_channel_title) + .style(grin_gui_core::theme::container::Container::NormalBackground); + let release_channel_list = PickList::new( + &mut addon.pick_release_channel_state, + &ReleaseChannel::ALL[..], + Some(addon.release_channel), + Message::ReleaseChannelSelected, + ) + .text_size(14) + .width(Length::Fixed(100)) + .style(style::PickList); + + let mut website_button = Button::new( + &mut addon.website_btn_state, + Text::new(localized_string("website")).size(DEFAULT_FONT_SIZE), + ) + .style(grin_gui_core::theme::button::Button::Primary); + + if let Some(link) = website_url { + website_button = website_button.on_press(Interaction::OpenLink(link)); + } + + let website_button: Element = website_button.into(); + + let is_ignored = addon.state == AddonState::Ignored; + let ignore_button_text = if is_ignored { + Text::new(localized_string("unignore")).size(DEFAULT_FONT_SIZE) + } else { + Text::new(localized_string("ignore")).size(DEFAULT_FONT_SIZE) + }; + + let mut ignore_button = + Button::new(&mut addon.ignore_btn_state, ignore_button_text) + .on_press(Interaction::Ignore(addon.primary_folder_id.clone())) + .style(grin_gui_core::theme::button::Button::Primary); + + if is_ignored { + ignore_button = ignore_button + .on_press(Interaction::Unignore(addon.primary_folder_id.clone())); + } else { + ignore_button = ignore_button + .on_press(Interaction::Ignore(addon.primary_folder_id.clone())); + } + + let ignore_button: Element = ignore_button.into(); + + let (title, interaction) = if Some(Confirm::DeleteAddon) == *pending_confirmation { + ( + localized_string("confirm-deletion"), + Interaction::ConfirmDeleteAddon(addon.primary_folder_id.clone()), + ) + } else { + let mut vars = HashMap::new(); + vars.insert("addon".to_string(), addon_cloned.title()); + let fmt = localized_string("delete-addon"); + + (strfmt(&fmt, &vars).unwrap(), Interaction::DeleteAddon()) + }; + + let delete_button: Element = Button::new( + &mut addon.delete_btn_state, + Text::new(title).size(DEFAULT_FONT_SIZE), + ) + .on_press(interaction) + .style(style::DefaultDeleteButton) + .into(); + + let (title, interaction) = if Some(Confirm::DeleteSavedVariables) + == *pending_confirmation + { + ( + localized_string("confirm-deletion"), + Interaction::ConfirmDeleteSavedVariables(addon.primary_folder_id.clone()), + ) + } else { + ( + localized_string("delete-addon-saved-variables"), + Interaction::DeleteSavedVariables(), + ) + }; + let delete_savedvariables_button: Element = Button::new( + &mut addon.delete_saved_variables_btn_state, + Text::new(title).size(DEFAULT_FONT_SIZE), + ) + .on_press(interaction) + .style(style::DefaultDeleteButton) + .into(); + + let mut changelog_button = Button::new( + &mut addon.changelog_btn_state, + Text::new(localized_string("changelog")).size(DEFAULT_FONT_SIZE), + ) + .style(grin_gui_core::theme::button::Button::Primary); + + if changelog_url.is_some() { + changelog_button = + changelog_button.on_press(Interaction::Expand(ExpandType::Changelog { + addon: addon_cloned, + changelog: None, + })); + } + + let changelog_button: Element = changelog_button.into();*/ + + /*let test_row = Row::new() + .push(release_channel_list) + .push(release_date_text_container);*/ + + /*let button_row = Row::new() + .push(Space::new(Length::Fill, Length::Fixed(0.0))) + .push(website_button.map(Message::Interaction)) + .push(Space::new(Length::Fixed(5.0), Length::Fixed(0.0))) + .push(changelog_button.map(Message::Interaction)) + .push(Space::new(Length::Fixed(5.0), Length::Fixed(0.0))) + .push(ignore_button.map(Message::Interaction)) + .push(Space::new(Length::Fixed(5.0), Length::Fixed(0.0))) + .push(delete_savedvariables_button.map(Message::Interaction)) + .push(Space::new(Length::Fixed(5.0), Length::Fixed(0.0))) + .push(delete_button.map(Message::Interaction)) + .width(Length::Fill);*/ + let column = Column::new() + .push(id_row) + .push(Space::new(Length::Fixed(0.0), Length::Fixed(3.0))) + .push(uuid_row) + .push(Space::new(Length::Fixed(0.0), Length::Fixed(3.0))) + .push(type_row); + //.push(Space::new(Length::Fixed(0.0), Length::Fixed(3))) + /* .push(notes_title_container) + .push(Space::new(Length::Fixed(0.0), Length::Fixed(3))) + .push(notes_text) + .push(Space::new(Length::Fixed(0.0), Length::Fixed(15))) + .push(release_channel_title_container) + .push(Space::new(Length::Fixed(0.0), Length::Fixed(3))) + .push(test_row) + .push(space) + .push(button_row)*/ + //.push(bottom_space); + let details_container = Container::new(column) + .width(Length::Fill) + .padding(20) + .style(grin_gui_core::theme::ContainerStyle::NormalBackground); + + let row = Row::new() + .push(left_spacer) + .push(details_container) + .push(Space::new( + Length::Fixed(DEFAULT_PADDING + 5.0), + Length::Fixed(0.0), + )) + .spacing(1); + tx_column = tx_column + .push(Space::new(Length::FillPortion(1), Length::Fixed(1.0))) + .push(row); + } + ExpandType::None => {} + } + } + + let mut table_row = TableRow::new(tx_column) + .width(Length::Fill) + .inner_row_height(default_row_height) + .on_press(move |_| { + Message::Interaction(Interaction::WalletOperationTxListInteraction( + LocalViewInteraction::Expand(ExpandType::Details(tx_cloned_for_row.clone())), + )) + }); + + if is_odd == Some(true) { + table_row = table_row.style(grin_gui_core::theme::TableRowStyle::TableRowAlternate) + } else { + table_row = table_row.style(grin_gui_core::theme::TableRowStyle::Default) + } + + // Due to what feels like an iced-rs bug, don't put buttons within the actual row as they appear + // to clear their state between the press down and up event if included within the row itself + // Some kind of fix to the table row widget might rectify this + let mut return_column = Column::new().push(table_row).push(action_button_row); + + if is_tx_expanded { + return_column = return_column.push(Space::new( + Length::Fixed(0.0), + Length::Fixed(DEFAULT_PADDING * 2.0), + )); + } + + let return_container = Container::new(return_column); + + return_container } #[derive(Debug, Clone)] pub enum LocalViewInteraction { - Expand(ExpandType), + Expand(ExpandType), } pub fn handle_message<'a>( - grin_gui: &mut GrinGui, - message: LocalViewInteraction, + grin_gui: &mut GrinGui, + message: LocalViewInteraction, ) -> Result> { - let state = &mut grin_gui - .wallet_state - .operation_state - .home_state - .tx_list_display_state; - match message { - LocalViewInteraction::Expand(expand_type) => match &expand_type { - ExpandType::Details(tx_wrap) => { - log::debug!("Interaction::Expand(Tx({:?}))", &tx_wrap.tx.id,); - let should_close = match &state.expanded_type { - ExpandType::Details(a) => tx_wrap.tx.id == a.tx.id, - _ => false, - }; - - if should_close { - state.expanded_type = ExpandType::None; - } else { - state.expanded_type = expand_type.clone(); - } - } - ExpandType::None => { - log::debug!("Interaction::Expand(ExpandType::None)"); - } - }, - } - Ok(Command::none()) + let state = &mut grin_gui + .wallet_state + .operation_state + .home_state + .tx_list_display_state; + match message { + LocalViewInteraction::Expand(expand_type) => match &expand_type { + ExpandType::Details(tx_wrap) => { + log::debug!("Interaction::Expand(Tx({:?}))", &tx_wrap.tx.id,); + let should_close = match &state.expanded_type { + ExpandType::Details(a) => tx_wrap.tx.id == a.tx.id, + _ => false, + }; + + if should_close { + state.expanded_type = ExpandType::None; + } else { + state.expanded_type = expand_type.clone(); + } + } + ExpandType::None => { + log::debug!("Interaction::Expand(ExpandType::None)"); + } + }, + } + Ok(Command::none()) } diff --git a/src/gui/element/wallet/operation/tx_list_display.rs b/src/gui/element/wallet/operation/tx_list_display.rs index f69efc7..184f5a0 100644 --- a/src/gui/element/wallet/operation/tx_list_display.rs +++ b/src/gui/element/wallet/operation/tx_list_display.rs @@ -3,8 +3,8 @@ use crate::log_error; use async_std::prelude::FutureExt; use chrono::DurationRound; use grin_gui_core::{ - config::Config, - wallet::{TxLogEntry, TxLogEntryType}, + config::Config, + wallet::{TxLogEntry, TxLogEntryType}, }; use grin_gui_widgets::widget::header; use iced_aw::Card; @@ -14,58 +14,58 @@ use std::{borrow::Borrow, path::PathBuf, str::FromStr}; use super::tx_list::{HeaderState, TxList, TxLogEntryWrap}; use { - super::super::super::{ - BUTTON_HEIGHT, BUTTON_WIDTH, DEFAULT_FONT_SIZE, DEFAULT_HEADER_FONT_SIZE, DEFAULT_PADDING, - SMALLER_FONT_SIZE, - }, - crate::gui::{GrinGui, Interaction, Message}, - crate::localization::localized_string, - crate::Result, - anyhow::Context, - grin_gui_core::theme::{ - Button, Column, Container, Element, Header, PickList, Row, Scrollable, TableRow, Text, - TextInput, - }, - grin_gui_core::wallet::{ - InitTxArgs, RetrieveTxQueryArgs, RetrieveTxQuerySortOrder, Slate, StatusMessage, - WalletInfo, WalletInterface, - }, - grin_gui_core::{ - node::amount_to_hr_string, - theme::{ButtonStyle, ColorPalette, ContainerStyle}, - }, - iced::widget::{button, pick_list, scrollable, text_input, Checkbox, Space}, - iced::{alignment, Alignment, Command, Length}, - serde::{Deserialize, Serialize}, - std::sync::{Arc, RwLock}, + super::super::super::{ + BUTTON_HEIGHT, BUTTON_WIDTH, DEFAULT_FONT_SIZE, DEFAULT_HEADER_FONT_SIZE, DEFAULT_PADDING, + SMALLER_FONT_SIZE, + }, + crate::gui::{GrinGui, Interaction, Message}, + crate::localization::localized_string, + crate::Result, + anyhow::Context, + grin_gui_core::theme::{ + Button, Column, Container, Element, Header, PickList, Row, Scrollable, TableRow, Text, + TextInput, + }, + grin_gui_core::wallet::{ + InitTxArgs, RetrieveTxQueryArgs, RetrieveTxQuerySortOrder, Slate, StatusMessage, + WalletInfo, WalletInterface, + }, + grin_gui_core::{ + node::amount_to_hr_string, + theme::{ButtonStyle, ColorPalette, ContainerStyle}, + }, + iced::widget::{button, pick_list, scrollable, text_input, Checkbox, Space}, + iced::{alignment, Alignment, Command, Length}, + serde::{Deserialize, Serialize}, + std::sync::{Arc, RwLock}, }; pub struct StateContainer { - // maintains a list of all confirmed transactions sorted by date - confirmed_txns: Vec, - wallet_txs: TxList, - tx_header_state: HeaderState, - query_args: RetrieveTxQueryArgs, - pub mode: Mode, + // maintains a list of all confirmed transactions sorted by date + confirmed_txns: Vec, + wallet_txs: TxList, + tx_header_state: HeaderState, + query_args: RetrieveTxQueryArgs, + pub mode: Mode, - pub expanded_type: ExpandType, + pub expanded_type: ExpandType, - // balance history for wallet as (date, grin_balance) - pub balance_data: Vec<(chrono::DateTime, f64)>, + // balance history for wallet as (date, grin_balance) + pub balance_data: Vec<(chrono::DateTime, f64)>, } impl Default for StateContainer { - fn default() -> Self { - Self { - wallet_txs: Default::default(), - tx_header_state: Default::default(), - expanded_type: ExpandType::None, - query_args: Default::default(), - mode: Mode::NotInit, - balance_data: vec![], - confirmed_txns: vec![], - } - } + fn default() -> Self { + Self { + wallet_txs: Default::default(), + tx_header_state: Default::default(), + expanded_type: ExpandType::None, + query_args: Default::default(), + mode: Mode::NotInit, + balance_data: vec![], + confirmed_txns: vec![], + } + } } #[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)] @@ -73,371 +73,375 @@ pub enum Action {} #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub enum Mode { - NotInit, - Recent, - Outstanding, + NotInit, + Recent, + Outstanding, } #[derive(Debug, Clone)] pub enum LocalViewInteraction { - SelectMode(Mode), - RefreshList, - TxListUpdateSuccess(bool, Vec), - TxListUpdateFailure(Arc>>), + SelectMode(Mode), + RefreshList, + TxListUpdateSuccess(bool, Vec), + TxListUpdateFailure(Arc>>), } pub fn handle_message<'a>( - grin_gui: &mut GrinGui, - message: LocalViewInteraction, + grin_gui: &mut GrinGui, + message: LocalViewInteraction, ) -> Result> { - let state = &mut grin_gui - .wallet_state - .operation_state - .home_state - .tx_list_display_state; - - match message { - LocalViewInteraction::SelectMode(new_mode) => { - state.query_args = RetrieveTxQueryArgs::default(); - - state.query_args.sort_order = Some(RetrieveTxQuerySortOrder::Desc); - - match new_mode { - Mode::NotInit => {} - Mode::Recent => { - state.query_args.exclude_cancelled = Some(true); - } - Mode::Outstanding => { - state.query_args.exclude_cancelled = Some(true); - state.query_args.include_outstanding_only = Some(true); - } - } - - state.mode = new_mode; - - let fut = move || async {}; - return Ok(Command::perform(fut(), |_| { - return Message::Interaction( - Interaction::WalletOperationHomeTxListDisplayInteraction( - LocalViewInteraction::RefreshList, - ), - ); - })); - } - - LocalViewInteraction::RefreshList => { - let w = grin_gui.wallet_interface.clone(); - - let fut = move || WalletInterface::get_txs(w, Some(state.query_args.clone())); - return Ok(Command::perform(fut(), |tx_list_res| { - if tx_list_res.is_err() { - let e = tx_list_res - .context("Failed to retrieve transaction list") - .unwrap_err(); - return Message::Interaction( - Interaction::WalletOperationHomeTxListDisplayInteraction( - LocalViewInteraction::TxListUpdateFailure(Arc::new(RwLock::new(Some( - e, - )))), - ), - ); - } - let (node_success, txs) = tx_list_res.unwrap(); - Message::Interaction(Interaction::WalletOperationHomeTxListDisplayInteraction( - //LocalViewInteraction::WalletInfoUpdateSuccess(node_success, wallet_info, txs), - LocalViewInteraction::TxListUpdateSuccess(node_success, txs), - )) - })); - } - LocalViewInteraction::TxListUpdateSuccess(node_success, txs) => { - debug!("Update Tx List Summary: {}", node_success); - debug!("Update Wallet Txs Summary: {:?}", txs); - let tx_wrap_list = txs - .iter() - .map(|tx| TxLogEntryWrap::new(tx.clone())) - .collect(); - state.wallet_txs = TxList { txs: tx_wrap_list }; - - let confirmed_txns: Vec<&TxLogEntry> = txs.iter().filter(|tx| tx.confirmed).collect(); - - if !confirmed_txns.is_empty() { - // added new confirmed transactions to state confirmed set? - let mut added = false; - - for tx in confirmed_txns.iter() { - // if tx is not in state confirmed transactions, add it - if state - .confirmed_txns - .iter() - .find(|t| t.id == tx.id) - .is_none() - { - // push to state confirmed transactions - state.confirmed_txns.push(tx.clone().to_owned()); - added = true; - debug!("Confirmed Tx: {:?}", tx); - } - } - - if added { - // sort state transactions by date - state.confirmed_txns.sort_by(|a, b| { - a.confirmation_ts.unwrap().cmp(&b.confirmation_ts.unwrap()) - }); - - let mut datetime_sums = vec![]; - for tx in state.confirmed_txns.iter() { - // trunc transaction date to day - //let datetime = tx.confirmation_ts.unwrap().duration_trunc(chrono::Duration::days(1)).unwrap(); - // this should be the date time above but for dev purposes lets backdate it - let datetime = chrono::DateTime::from_str("2019-01-20T00:00:00Z").unwrap(); - let credits = tx.amount_credited; - let debits = tx.amount_debited; - - datetime_sums.push((datetime, credits as i64 - debits as i64)); - } - - let mut sum = 0; - let mut dt = datetime_sums.first().unwrap().0; - let today = chrono::Utc::now() - .duration_trunc(chrono::Duration::days(1)) - .unwrap(); - - // fill in sum data for days without transactions - let mut balance_history = vec![]; - while dt <= today { - // get all transactions for this date - let txns = datetime_sums.iter().filter(|(date, _)| *date == dt); - - // sum up balance amount - sum = sum + txns.map(|x| x.1).collect::>().iter().sum::(); - - // convert to grin units - let grin_sum = (sum as f64 / grin_gui_core::GRIN_BASE as f64) as f64; - balance_history.push((dt.to_owned(), grin_sum)); - - dt = dt + chrono::Duration::days(1); - } - - // finally we update state with the newly constructed balance history - state.balance_data = balance_history; - } - } - } - LocalViewInteraction::TxListUpdateFailure(err) => { - grin_gui.error = err.write().unwrap().take(); - if let Some(e) = grin_gui.error.as_ref() { - log_error(e); - } - } - } - - Ok(Command::none()) + let state = &mut grin_gui + .wallet_state + .operation_state + .home_state + .tx_list_display_state; + + match message { + LocalViewInteraction::SelectMode(new_mode) => { + state.query_args = RetrieveTxQueryArgs::default(); + + state.query_args.sort_order = Some(RetrieveTxQuerySortOrder::Desc); + + match new_mode { + Mode::NotInit => {} + Mode::Recent => { + state.query_args.exclude_cancelled = Some(true); + } + Mode::Outstanding => { + state.query_args.exclude_cancelled = Some(true); + state.query_args.include_outstanding_only = Some(true); + } + } + + state.mode = new_mode; + + let fut = move || async {}; + return Ok(Command::perform(fut(), |_| { + return Message::Interaction( + Interaction::WalletOperationHomeTxListDisplayInteraction( + LocalViewInteraction::RefreshList, + ), + ); + })); + } + + LocalViewInteraction::RefreshList => { + let w = grin_gui.wallet_interface.clone(); + + let fut = move || WalletInterface::get_txs(w, Some(state.query_args.clone())); + return Ok(Command::perform(fut(), |tx_list_res| { + if tx_list_res.is_err() { + let e = tx_list_res + .context("Failed to retrieve transaction list") + .unwrap_err(); + return Message::Interaction( + Interaction::WalletOperationHomeTxListDisplayInteraction( + LocalViewInteraction::TxListUpdateFailure(Arc::new(RwLock::new(Some( + e, + )))), + ), + ); + } + let (node_success, txs) = tx_list_res.unwrap(); + Message::Interaction(Interaction::WalletOperationHomeTxListDisplayInteraction( + //LocalViewInteraction::WalletInfoUpdateSuccess(node_success, wallet_info, txs), + LocalViewInteraction::TxListUpdateSuccess(node_success, txs), + )) + })); + } + LocalViewInteraction::TxListUpdateSuccess(node_success, txs) => { + debug!("Update Tx List Summary: {}", node_success); + debug!("Update Wallet Txs Summary: {:?}", txs); + let tx_wrap_list = txs + .iter() + .map(|tx| TxLogEntryWrap::new(tx.clone())) + .collect(); + state.wallet_txs = TxList { txs: tx_wrap_list }; + + let confirmed_txns: Vec<&TxLogEntry> = txs.iter().filter(|tx| tx.confirmed).collect(); + + if !confirmed_txns.is_empty() { + // added new confirmed transactions to state confirmed set? + let mut added = false; + + for tx in confirmed_txns.iter() { + // if tx is not in state confirmed transactions, add it + if state + .confirmed_txns + .iter() + .find(|t| t.id == tx.id) + .is_none() + { + // push to state confirmed transactions + state.confirmed_txns.push(tx.clone().to_owned()); + added = true; + debug!("Confirmed Tx: {:?}", tx); + } + } + + if added { + // sort state transactions by date + state.confirmed_txns.sort_by(|a, b| { + a.confirmation_ts.unwrap().cmp(&b.confirmation_ts.unwrap()) + }); + + let mut datetime_sums = vec![]; + for tx in state.confirmed_txns.iter() { + // trunc transaction date to day + //let datetime = tx.confirmation_ts.unwrap().duration_trunc(chrono::Duration::days(1)).unwrap(); + // this should be the date time above but for dev purposes lets backdate it + let datetime = chrono::DateTime::from_str("2019-01-20T00:00:00Z").unwrap(); + let credits = tx.amount_credited; + let debits = tx.amount_debited; + + datetime_sums.push((datetime, credits as i64 - debits as i64)); + } + + let mut sum = 0; + let mut dt = datetime_sums.first().unwrap().0; + let today = chrono::Utc::now() + .duration_trunc(chrono::Duration::days(1)) + .unwrap(); + + // fill in sum data for days without transactions + let mut balance_history = vec![]; + while dt <= today { + // get all transactions for this date + let txns = datetime_sums.iter().filter(|(date, _)| *date == dt); + + // sum up balance amount + sum = sum + txns.map(|x| x.1).collect::>().iter().sum::(); + + // convert to grin units + let grin_sum = (sum as f64 / grin_gui_core::GRIN_BASE as f64) as f64; + balance_history.push((dt.to_owned(), grin_sum)); + + dt = dt + chrono::Duration::days(1); + } + + // finally we update state with the newly constructed balance history + state.balance_data = balance_history; + } + } + } + LocalViewInteraction::TxListUpdateFailure(err) => { + grin_gui.error = err.write().unwrap().take(); + if let Some(e) = grin_gui.error.as_ref() { + log_error(e); + } + } + } + + Ok(Command::none()) } -pub fn data_container<'a>(config: &'a Config, home_state: &'a super::home::StateContainer, state: &'a StateContainer) -> Container<'a, Message> { - let button_height = Length::Fixed(BUTTON_HEIGHT); - let button_width = Length::Fixed(BUTTON_WIDTH); - - let title = Text::new(localized_string("tx-list")).size(DEFAULT_HEADER_FONT_SIZE); - let title_container = Container::new(title) - .style(grin_gui_core::theme::ContainerStyle::BrightBackground) - .padding(iced::Padding::from([ - 0, // top - 0, // right - 0, // bottom - 5, // left - ])); - - let latest_container = - Container::new(Text::new(localized_string("tx-recent")).size(DEFAULT_FONT_SIZE)) - .width(button_width) - .align_y(alignment::Vertical::Center) - .align_x(alignment::Horizontal::Center); - - let latest_button = Button::new(latest_container).width(button_width).on_press( - Interaction::WalletOperationHomeTxListDisplayInteraction(LocalViewInteraction::SelectMode( - Mode::Recent, - )), - ); - - let latest_button = if state.mode == Mode::Recent { - latest_button.style(grin_gui_core::theme::ButtonStyle::Selected) - } else { - latest_button.style(grin_gui_core::theme::ButtonStyle::Primary) - }; - - let latest_button: Element = latest_button.into(); - - // add a nice double border around our buttons - // TODO refactor since many of the buttons around the UI repeat this theme - let latest_container_wrap = Container::new(latest_button.map(Message::Interaction)).padding(1); - let latest_container_wrap = Container::new(latest_container_wrap) - .style(grin_gui_core::theme::ContainerStyle::Segmented) - .padding(1); - - let outstanding_container = - Container::new(Text::new(localized_string("tx-outstanding")).size(DEFAULT_FONT_SIZE)) - .width(button_width) - .align_y(alignment::Vertical::Center) - .align_x(alignment::Horizontal::Center); - - let outstanding_button = Button::new(outstanding_container) - .width(button_width) - .on_press(Interaction::WalletOperationHomeTxListDisplayInteraction( - LocalViewInteraction::SelectMode(Mode::Outstanding), - )); - - let outstanding_button = if state.mode == Mode::Outstanding { - outstanding_button.style(grin_gui_core::theme::ButtonStyle::Selected) - } else { - outstanding_button.style(grin_gui_core::theme::ButtonStyle::Primary) - }; - - let outstanding_button: Element = outstanding_button.into(); - - let outstanding_container_wrap = - Container::new(outstanding_button.map(Message::Interaction)).padding(1); - let outstanding_container_wrap = Container::new(outstanding_container_wrap) - .style(grin_gui_core::theme::ContainerStyle::Segmented) - .padding(1); - - // add additional buttons here - let button_row = Row::new() - .push(latest_container_wrap) - .push(Space::with_width(Length::Fixed(DEFAULT_PADDING))) - .push(outstanding_container_wrap); - - /*let segmented_mode_container = Container::new(button_row).padding(1); - let segmented_mode_control_container = Container::new(segmented_mode_container) - .style(grin_gui_core::theme::ContainerStyle::Segmented) - .padding(1);*/ - - let header_row = Row::new() - .push(title_container) - .push(Space::with_width(Length::Fill)) - .push(button_row) - .align_items(Alignment::Center); - - let header_container = Container::new(header_row).padding(iced::Padding::from([ - 0, // top - 0, // right - DEFAULT_PADDING as u16, // bottom - 0, // left - ])); - - // TRANSACTION HEADER - let column_config = state.tx_header_state.column_config(); - - // Tx row titles is a row of titles above the tx scrollable. - // This is to add titles above each section of the tx row, to let - // the user easily identify what the value is. - let table_header_row = super::tx_list::titles_row_header( - &state.wallet_txs, - &state.tx_header_state.state, - &state.tx_header_state.columns, - state.tx_header_state.previous_column_key, - state.tx_header_state.previous_sort_direction, - ); - - let table_header_container = Container::new(table_header_row).padding(iced::Padding::from([ - 0, // top - DEFAULT_PADDING as u16 * 3, // right - should roughly match width of content scroll bar to align table headers - 0, // bottom - 0, // left - ])); - //.style(grin_gui_core::theme::ContainerStyle::PanelForeground); - - // A scrollable list containing rows. - // Each row holds data about a single tx. - let mut content = Column::new().spacing(1); - //.height(Length::Fill) - //.style(grin_gui_core::theme::ScrollableStyles::Primary); - - let mut has_txs = false; - - // Loops though the txs. - for (idx, tx_wrap) in state.wallet_txs.txs.iter().enumerate() { - has_txs = true; - // If hiding ignored addons, we will skip it. - /*if addon.state == AddonState::Ignored && self.config.hide_ignored_addons { - continue; - }*/ - - // Skip addon if we are filter from query and addon doesn't have fuzzy score - /*if query.is_some() && addon.fuzzy_score.is_none() { - continue; - }*/ - - // Checks if the current tx is expanded. - let is_tx_expanded = match &state.expanded_type { - ExpandType::Details(a) => a.tx.id == tx_wrap.tx.id, - ExpandType::None => false, - }; - - let is_odd = if config.alternating_row_colors { - Some(idx % 2 != 0) - } else { - None - }; - - // A container cell which has all data about the current tx. - // If the tx is expanded, then this is also included in this container. - let tx_data_cell = tx_list::data_row_container( - tx_wrap, - is_tx_expanded, - &state.expanded_type, - config, - &column_config, - is_odd, - &None, - home_state.node_synched, - ); - - // Adds the addon data cell to the scrollable. - content = content.push(tx_data_cell); - } - - let mut tx_list_scrollable = - Scrollable::new(content).style(grin_gui_core::theme::ScrollableStyle::Primary); - - // This column gathers all the tx list elements together. - let mut tx_list_content = Column::new(); - - // Adds the rest of the elements to the content column. - if has_txs { - tx_list_content = tx_list_content.push(tx_list_scrollable); - } else { - let no_txs_label = if state.mode == Mode::NotInit { - Text::new(localized_string("txs-list-loading")).size(DEFAULT_FONT_SIZE) - } else { - Text::new(localized_string("no-txs-list")).size(DEFAULT_FONT_SIZE) - }; - let no_txs_container = Container::new(no_txs_label) - .style(grin_gui_core::theme::ContainerStyle::BrightBackground) - .padding(iced::Padding::from([ - 0, // top - 0, // right - 0, // bottom - 5, // left - ])); - tx_list_content = tx_list_content.push(no_txs_container); - } - - // TRANSACTION LISTING - - let column = Column::new() - .push(header_container) - .push(table_header_container) - .push(tx_list_content); - - // Returns the final container. - Container::new(column) - .padding(iced::Padding::from([ - DEFAULT_PADDING, // top - DEFAULT_PADDING, // right - DEFAULT_PADDING, // bottom - DEFAULT_PADDING, // left - ])) - .style(grin_gui_core::theme::ContainerStyle::PanelBordered) +pub fn data_container<'a>( + config: &'a Config, + home_state: &'a super::home::StateContainer, + state: &'a StateContainer, +) -> Container<'a, Message> { + let button_height = Length::Fixed(BUTTON_HEIGHT); + let button_width = Length::Fixed(BUTTON_WIDTH); + + let title = Text::new(localized_string("tx-list")).size(DEFAULT_HEADER_FONT_SIZE); + let title_container = Container::new(title) + .style(grin_gui_core::theme::ContainerStyle::BrightBackground) + .padding(iced::Padding::from([ + 0, // top + 0, // right + 0, // bottom + 5, // left + ])); + + let latest_container = + Container::new(Text::new(localized_string("tx-recent")).size(DEFAULT_FONT_SIZE)) + .width(button_width) + .align_y(alignment::Vertical::Center) + .align_x(alignment::Horizontal::Center); + + let latest_button = Button::new(latest_container).width(button_width).on_press( + Interaction::WalletOperationHomeTxListDisplayInteraction(LocalViewInteraction::SelectMode( + Mode::Recent, + )), + ); + + let latest_button = if state.mode == Mode::Recent { + latest_button.style(grin_gui_core::theme::ButtonStyle::Selected) + } else { + latest_button.style(grin_gui_core::theme::ButtonStyle::Primary) + }; + + let latest_button: Element = latest_button.into(); + + // add a nice double border around our buttons + // TODO refactor since many of the buttons around the UI repeat this theme + let latest_container_wrap = Container::new(latest_button.map(Message::Interaction)).padding(1); + let latest_container_wrap = Container::new(latest_container_wrap) + .style(grin_gui_core::theme::ContainerStyle::Segmented) + .padding(1); + + let outstanding_container = + Container::new(Text::new(localized_string("tx-outstanding")).size(DEFAULT_FONT_SIZE)) + .width(button_width) + .align_y(alignment::Vertical::Center) + .align_x(alignment::Horizontal::Center); + + let outstanding_button = Button::new(outstanding_container) + .width(button_width) + .on_press(Interaction::WalletOperationHomeTxListDisplayInteraction( + LocalViewInteraction::SelectMode(Mode::Outstanding), + )); + + let outstanding_button = if state.mode == Mode::Outstanding { + outstanding_button.style(grin_gui_core::theme::ButtonStyle::Selected) + } else { + outstanding_button.style(grin_gui_core::theme::ButtonStyle::Primary) + }; + + let outstanding_button: Element = outstanding_button.into(); + + let outstanding_container_wrap = + Container::new(outstanding_button.map(Message::Interaction)).padding(1); + let outstanding_container_wrap = Container::new(outstanding_container_wrap) + .style(grin_gui_core::theme::ContainerStyle::Segmented) + .padding(1); + + // add additional buttons here + let button_row = Row::new() + .push(latest_container_wrap) + .push(Space::with_width(Length::Fixed(DEFAULT_PADDING))) + .push(outstanding_container_wrap); + + /*let segmented_mode_container = Container::new(button_row).padding(1); + let segmented_mode_control_container = Container::new(segmented_mode_container) + .style(grin_gui_core::theme::ContainerStyle::Segmented) + .padding(1);*/ + + let header_row = Row::new() + .push(title_container) + .push(Space::with_width(Length::Fill)) + .push(button_row) + .align_items(Alignment::Center); + + let header_container = Container::new(header_row).padding(iced::Padding::from([ + 0, // top + 0, // right + DEFAULT_PADDING as u16, // bottom + 0, // left + ])); + + // TRANSACTION HEADER + let column_config = state.tx_header_state.column_config(); + + // Tx row titles is a row of titles above the tx scrollable. + // This is to add titles above each section of the tx row, to let + // the user easily identify what the value is. + let table_header_row = super::tx_list::titles_row_header( + &state.wallet_txs, + &state.tx_header_state.state, + &state.tx_header_state.columns, + state.tx_header_state.previous_column_key, + state.tx_header_state.previous_sort_direction, + ); + + let table_header_container = Container::new(table_header_row).padding(iced::Padding::from([ + 0, // top + DEFAULT_PADDING as u16 * 3, // right - should roughly match width of content scroll bar to align table headers + 0, // bottom + 0, // left + ])); + //.style(grin_gui_core::theme::ContainerStyle::PanelForeground); + + // A scrollable list containing rows. + // Each row holds data about a single tx. + let mut content = Column::new().spacing(1); + //.height(Length::Fill) + //.style(grin_gui_core::theme::ScrollableStyles::Primary); + + let mut has_txs = false; + + // Loops though the txs. + for (idx, tx_wrap) in state.wallet_txs.txs.iter().enumerate() { + has_txs = true; + // If hiding ignored addons, we will skip it. + /*if addon.state == AddonState::Ignored && self.config.hide_ignored_addons { + continue; + }*/ + + // Skip addon if we are filter from query and addon doesn't have fuzzy score + /*if query.is_some() && addon.fuzzy_score.is_none() { + continue; + }*/ + + // Checks if the current tx is expanded. + let is_tx_expanded = match &state.expanded_type { + ExpandType::Details(a) => a.tx.id == tx_wrap.tx.id, + ExpandType::None => false, + }; + + let is_odd = if config.alternating_row_colors { + Some(idx % 2 != 0) + } else { + None + }; + + // A container cell which has all data about the current tx. + // If the tx is expanded, then this is also included in this container. + let tx_data_cell = tx_list::data_row_container( + tx_wrap, + is_tx_expanded, + &state.expanded_type, + config, + &column_config, + is_odd, + &None, + home_state.node_synched, + ); + + // Adds the addon data cell to the scrollable. + content = content.push(tx_data_cell); + } + + let mut tx_list_scrollable = + Scrollable::new(content).style(grin_gui_core::theme::ScrollableStyle::Primary); + + // This column gathers all the tx list elements together. + let mut tx_list_content = Column::new(); + + // Adds the rest of the elements to the content column. + if has_txs { + tx_list_content = tx_list_content.push(tx_list_scrollable); + } else { + let no_txs_label = if state.mode == Mode::NotInit { + Text::new(localized_string("txs-list-loading")).size(DEFAULT_FONT_SIZE) + } else { + Text::new(localized_string("no-txs-list")).size(DEFAULT_FONT_SIZE) + }; + let no_txs_container = Container::new(no_txs_label) + .style(grin_gui_core::theme::ContainerStyle::BrightBackground) + .padding(iced::Padding::from([ + 0, // top + 0, // right + 0, // bottom + 5, // left + ])); + tx_list_content = tx_list_content.push(no_txs_container); + } + + // TRANSACTION LISTING + + let column = Column::new() + .push(header_container) + .push(table_header_container) + .push(tx_list_content); + + // Returns the final container. + Container::new(column) + .padding(iced::Padding::from([ + DEFAULT_PADDING, // top + DEFAULT_PADDING, // right + DEFAULT_PADDING, // bottom + DEFAULT_PADDING, // left + ])) + .style(grin_gui_core::theme::ContainerStyle::PanelBordered) } diff --git a/src/gui/element/wallet/operation/tx_proof.rs b/src/gui/element/wallet/operation/tx_proof.rs index 55a90b2..397a233 100644 --- a/src/gui/element/wallet/operation/tx_proof.rs +++ b/src/gui/element/wallet/operation/tx_proof.rs @@ -2,9 +2,9 @@ use super::tx_list::{self, ExpandType}; use crate::log_error; use async_std::prelude::FutureExt; use grin_gui_core::{ - config::Config, - error::GrinWalletInterfaceError, - wallet::{InvoiceProof, SlatepackAddress, TxLogEntry, TxLogEntryType}, + config::Config, + error::GrinWalletInterfaceError, + wallet::{InvoiceProof, SlatepackAddress, TxLogEntry, TxLogEntryType}, }; use grin_gui_widgets::widget::header; use iced_aw::Card; @@ -16,42 +16,42 @@ use std::path::PathBuf; use super::tx_list::{HeaderState, TxList}; use { - super::super::super::{ - BUTTON_HEIGHT, BUTTON_WIDTH, DEFAULT_FONT_SIZE, DEFAULT_HEADER_FONT_SIZE, DEFAULT_PADDING, - SMALLER_FONT_SIZE, - }, - crate::gui::{GrinGui, Interaction, Message}, - crate::localization::localized_string, - crate::Result, - anyhow::Context, - grin_gui_core::theme::{ - Button, Column, Container, Element, Header, PickList, Row, Scrollable, TableRow, Text, - TextInput, - }, - grin_gui_core::wallet::{InitTxArgs, Slate, StatusMessage, WalletInfo, WalletInterface}, - grin_gui_core::{ - node::{amount_from_hr_string, amount_to_hr_string}, - theme::{ButtonStyle, ColorPalette, ContainerStyle}, - }, - iced::widget::{button, pick_list, scrollable, text_input, Checkbox, Space}, - iced::{alignment, Alignment, Command, Length}, - serde::{Deserialize, Serialize}, - std::sync::{Arc, RwLock}, + super::super::super::{ + BUTTON_HEIGHT, BUTTON_WIDTH, DEFAULT_FONT_SIZE, DEFAULT_HEADER_FONT_SIZE, DEFAULT_PADDING, + SMALLER_FONT_SIZE, + }, + crate::gui::{GrinGui, Interaction, Message}, + crate::localization::localized_string, + crate::Result, + anyhow::Context, + grin_gui_core::theme::{ + Button, Column, Container, Element, Header, PickList, Row, Scrollable, TableRow, Text, + TextInput, + }, + grin_gui_core::wallet::{InitTxArgs, Slate, StatusMessage, WalletInfo, WalletInterface}, + grin_gui_core::{ + node::{amount_from_hr_string, amount_to_hr_string}, + theme::{ButtonStyle, ColorPalette, ContainerStyle}, + }, + iced::widget::{button, pick_list, scrollable, text_input, Checkbox, Space}, + iced::{alignment, Alignment, Command, Length}, + serde::{Deserialize, Serialize}, + std::sync::{Arc, RwLock}, }; pub struct StateContainer { - // Transaction that we're viewing - pub current_tx: Option, - pub current_proof: Option, + // Transaction that we're viewing + pub current_tx: Option, + pub current_proof: Option, } impl Default for StateContainer { - fn default() -> Self { - Self { - current_tx: Default::default(), - current_proof: Default::default(), - } - } + fn default() -> Self { + Self { + current_tx: Default::default(), + current_proof: Default::default(), + } + } } #[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)] @@ -59,223 +59,222 @@ pub enum Action {} #[derive(Debug, Clone)] pub enum LocalViewInteraction { - Back, + Back, } pub fn handle_message<'a>( - grin_gui: &mut GrinGui, - message: LocalViewInteraction, + grin_gui: &mut GrinGui, + message: LocalViewInteraction, ) -> Result> { - let state = &mut grin_gui.wallet_state.operation_state.create_tx_state; + let state = &mut grin_gui.wallet_state.operation_state.create_tx_state; - match message { - LocalViewInteraction::Back => { - log::debug!("Interaction::WalletOperationTxProofViewInteraction(Back)"); - grin_gui.wallet_state.operation_state.mode = - crate::gui::element::wallet::operation::Mode::Home; - } - } + match message { + LocalViewInteraction::Back => { + log::debug!("Interaction::WalletOperationTxProofViewInteraction(Back)"); + grin_gui.wallet_state.operation_state.mode = + crate::gui::element::wallet::operation::Mode::Home; + } + } - Ok(Command::none()) + Ok(Command::none()) } pub fn data_container<'a>(config: &'a Config, state: &'a StateContainer) -> Container<'a, Message> { - // Title row - let title = Text::new(localized_string("tx-proof-title")) - .size(DEFAULT_HEADER_FONT_SIZE) - .horizontal_alignment(alignment::Horizontal::Center); - - let title_container = Container::new(title) - .style(grin_gui_core::theme::ContainerStyle::BrightBackground) - .padding(iced::Padding::from([ - 2, // top - 0, // right - 2, // bottom - 5, // left - ])); - - let header_row = Row::new().push(title_container); - - let header_container = Container::new(header_row).padding(iced::Padding::from([ - 0, // top - 0, // right - DEFAULT_PADDING as u16, // bottom - 0, // left - ])); - - let unit_spacing = 15.0; - let row_spacing = 5.0; - - let button_height = Length::Fixed(BUTTON_HEIGHT); - let button_width = Length::Fixed(BUTTON_WIDTH); - - let mut column = Column::new(); - - if let Some(ref proof) = state.current_proof { - // Amount - let pr_amount_label = Text::new(format!("{}: ", localized_string("pr-amount"))) - .size(DEFAULT_FONT_SIZE) - .horizontal_alignment(alignment::Horizontal::Left); - - let pr_amount_label_container = Container::new(pr_amount_label) - .style(grin_gui_core::theme::ContainerStyle::NormalBackground); - - let pr_amount_value = Text::new(format!("{}", amount_to_hr_string(proof.amount, true))) - .size(DEFAULT_FONT_SIZE) - .horizontal_alignment(alignment::Horizontal::Left); - - let pr_amount_value_container = Container::new(pr_amount_value) - .style(grin_gui_core::theme::ContainerStyle::NormalBackground); - - let pr_amount_row = Row::new() - .push(pr_amount_label_container) - .push(pr_amount_value_container); - column = column - .push(pr_amount_row) - .push(Space::new(Length::Fixed(0.0), Length::Fixed(row_spacing))); - - // Timestamp - let pr_timestamp_label = Text::new(format!("{}: ", localized_string("pr-timestamp"))) - .size(DEFAULT_FONT_SIZE) - .horizontal_alignment(alignment::Horizontal::Left); - - let pr_timestamp_label_container = Container::new(pr_timestamp_label) - .style(grin_gui_core::theme::ContainerStyle::NormalBackground); - - // convert i64 timestamp to utc time - let ts_display = chrono::NaiveDateTime::from_timestamp(proof.timestamp, 0) - .format("%Y-%m-%d %H:%M:%S") - .to_string(); - - let pr_timestamp_value = Text::new(format!("{} UTC", ts_display)) - .size(DEFAULT_FONT_SIZE) - .horizontal_alignment(alignment::Horizontal::Left); - - let pr_timestamp_value_container = Container::new(pr_timestamp_value) - .style(grin_gui_core::theme::ContainerStyle::NormalBackground); - - let pr_timestamp_row = Row::new() - .push(pr_timestamp_label_container) - .push(pr_timestamp_value_container); - column = column - .push(pr_timestamp_row) - .push(Space::new(Length::Fixed(0.0), Length::Fixed(row_spacing))); - - // sender address - let pr_sender_address_label = - Text::new(format!("{}: ", localized_string("pr-sender-address"))) - .size(DEFAULT_FONT_SIZE) - .horizontal_alignment(alignment::Horizontal::Left); - - let pr_sender_address_label_container = Container::new(pr_sender_address_label) - .style(grin_gui_core::theme::ContainerStyle::NormalBackground); - - let pr_sender_address_value = - Text::new(format!("{}", SlatepackAddress::new(&proof.sender_address))) - .size(DEFAULT_FONT_SIZE) - .horizontal_alignment(alignment::Horizontal::Left); - - let pr_sender_address_value_container = Container::new(pr_sender_address_value) - .style(grin_gui_core::theme::ContainerStyle::NormalBackground); - - let pr_sender_address_row = Row::new() - .push(pr_sender_address_label_container) - .push(pr_sender_address_value_container); - column = column - .push(pr_sender_address_row) - .push(Space::new(Length::Fixed(0.0), Length::Fixed(row_spacing))) - .push(Space::new(Length::Fixed(0.0), Length::Fixed(row_spacing))); - - let card_contents = format!("{}", serde_json::to_string_pretty(&proof).unwrap()); - - let json_proof_card = Card::new( - Text::new(localized_string("pr-json-proof")).size(DEFAULT_HEADER_FONT_SIZE), - Text::new(card_contents.clone()).size(DEFAULT_FONT_SIZE), - ) - .foot( - Column::new() - .spacing(10) - .padding(5) - .width(Length::Fill) - .align_items(Alignment::Center) - .push( - Button::new( - Text::new(localized_string("copy-to-clipboard")) - .size(SMALLER_FONT_SIZE) - .horizontal_alignment(alignment::Horizontal::Center), - ) - .style(grin_gui_core::theme::ButtonStyle::NormalText) - .on_press(Message::Interaction( - Interaction::WriteToClipboard(card_contents.clone()), - )), - ), - ) - .max_width(400.0) - .style(grin_gui_core::theme::CardStyle::Normal); - - let json_proof_row = Row::new() - .push(json_proof_card); - - column = column - .push(json_proof_row) - .push(Space::new(Length::Fixed(0.0), Length::Fixed(row_spacing))); - } - - let cancel_button_label_container = - Container::new(Text::new(localized_string("back")).size(DEFAULT_FONT_SIZE)) - .width(button_width) - .height(button_height) - .center_x() - .center_y() - .align_x(alignment::Horizontal::Center); - - let cancel_button: Element = Button::new(cancel_button_label_container) - .style(grin_gui_core::theme::ButtonStyle::Primary) - .on_press(Interaction::WalletOperationTxProofViewInteraction( - LocalViewInteraction::Back, - )) - .into(); - - let cancel_container = Container::new(cancel_button.map(Message::Interaction)).padding(1); - let cancel_container = Container::new(cancel_container) - .style(grin_gui_core::theme::ContainerStyle::Segmented) - .padding(1); - - let button_row = Row::new() - .push(cancel_container) - .push(Space::new(Length::Fixed(unit_spacing), Length::Fixed(0.0))); - - column = column.push(button_row); - - let form_container = Container::new(column) - .width(Length::Fill) - .padding(iced::Padding::from([ - 0, // top - 0, // right - 0, // bottom - 5, // left - ])); - - // form container should be scrollable in tiny windows - let scrollable = Scrollable::new(form_container) - .height(Length::Fill) - .style(grin_gui_core::theme::ScrollableStyle::Primary); - - let content = Container::new(scrollable) - .width(Length::Fill) - .height(Length::Shrink) - .style(grin_gui_core::theme::ContainerStyle::NormalBackground); - - let wrapper_column = Column::new() - .height(Length::Fill) - .push(header_container) - .push(content); - - // Returns the final container. - Container::new(wrapper_column).padding(iced::Padding::from([ - DEFAULT_PADDING, // top - DEFAULT_PADDING, // right - DEFAULT_PADDING, // bottom - DEFAULT_PADDING, // left - ])) + // Title row + let title = Text::new(localized_string("tx-proof-title")) + .size(DEFAULT_HEADER_FONT_SIZE) + .horizontal_alignment(alignment::Horizontal::Center); + + let title_container = Container::new(title) + .style(grin_gui_core::theme::ContainerStyle::BrightBackground) + .padding(iced::Padding::from([ + 2, // top + 0, // right + 2, // bottom + 5, // left + ])); + + let header_row = Row::new().push(title_container); + + let header_container = Container::new(header_row).padding(iced::Padding::from([ + 0, // top + 0, // right + DEFAULT_PADDING as u16, // bottom + 0, // left + ])); + + let unit_spacing = 15.0; + let row_spacing = 5.0; + + let button_height = Length::Fixed(BUTTON_HEIGHT); + let button_width = Length::Fixed(BUTTON_WIDTH); + + let mut column = Column::new(); + + if let Some(ref proof) = state.current_proof { + // Amount + let pr_amount_label = Text::new(format!("{}: ", localized_string("pr-amount"))) + .size(DEFAULT_FONT_SIZE) + .horizontal_alignment(alignment::Horizontal::Left); + + let pr_amount_label_container = Container::new(pr_amount_label) + .style(grin_gui_core::theme::ContainerStyle::NormalBackground); + + let pr_amount_value = Text::new(format!("{}", amount_to_hr_string(proof.amount, true))) + .size(DEFAULT_FONT_SIZE) + .horizontal_alignment(alignment::Horizontal::Left); + + let pr_amount_value_container = Container::new(pr_amount_value) + .style(grin_gui_core::theme::ContainerStyle::NormalBackground); + + let pr_amount_row = Row::new() + .push(pr_amount_label_container) + .push(pr_amount_value_container); + column = column + .push(pr_amount_row) + .push(Space::new(Length::Fixed(0.0), Length::Fixed(row_spacing))); + + // Timestamp + let pr_timestamp_label = Text::new(format!("{}: ", localized_string("pr-timestamp"))) + .size(DEFAULT_FONT_SIZE) + .horizontal_alignment(alignment::Horizontal::Left); + + let pr_timestamp_label_container = Container::new(pr_timestamp_label) + .style(grin_gui_core::theme::ContainerStyle::NormalBackground); + + // convert i64 timestamp to utc time + let ts_display = chrono::NaiveDateTime::from_timestamp(proof.timestamp, 0) + .format("%Y-%m-%d %H:%M:%S") + .to_string(); + + let pr_timestamp_value = Text::new(format!("{} UTC", ts_display)) + .size(DEFAULT_FONT_SIZE) + .horizontal_alignment(alignment::Horizontal::Left); + + let pr_timestamp_value_container = Container::new(pr_timestamp_value) + .style(grin_gui_core::theme::ContainerStyle::NormalBackground); + + let pr_timestamp_row = Row::new() + .push(pr_timestamp_label_container) + .push(pr_timestamp_value_container); + column = column + .push(pr_timestamp_row) + .push(Space::new(Length::Fixed(0.0), Length::Fixed(row_spacing))); + + // sender address + let pr_sender_address_label = + Text::new(format!("{}: ", localized_string("pr-sender-address"))) + .size(DEFAULT_FONT_SIZE) + .horizontal_alignment(alignment::Horizontal::Left); + + let pr_sender_address_label_container = Container::new(pr_sender_address_label) + .style(grin_gui_core::theme::ContainerStyle::NormalBackground); + + let pr_sender_address_value = + Text::new(format!("{}", SlatepackAddress::new(&proof.sender_address))) + .size(DEFAULT_FONT_SIZE) + .horizontal_alignment(alignment::Horizontal::Left); + + let pr_sender_address_value_container = Container::new(pr_sender_address_value) + .style(grin_gui_core::theme::ContainerStyle::NormalBackground); + + let pr_sender_address_row = Row::new() + .push(pr_sender_address_label_container) + .push(pr_sender_address_value_container); + column = column + .push(pr_sender_address_row) + .push(Space::new(Length::Fixed(0.0), Length::Fixed(row_spacing))) + .push(Space::new(Length::Fixed(0.0), Length::Fixed(row_spacing))); + + let card_contents = format!("{}", serde_json::to_string_pretty(&proof).unwrap()); + + let json_proof_card = Card::new( + Text::new(localized_string("pr-json-proof")).size(DEFAULT_HEADER_FONT_SIZE), + Text::new(card_contents.clone()).size(DEFAULT_FONT_SIZE), + ) + .foot( + Column::new() + .spacing(10) + .padding(5) + .width(Length::Fill) + .align_items(Alignment::Center) + .push( + Button::new( + Text::new(localized_string("copy-to-clipboard")) + .size(SMALLER_FONT_SIZE) + .horizontal_alignment(alignment::Horizontal::Center), + ) + .style(grin_gui_core::theme::ButtonStyle::NormalText) + .on_press(Message::Interaction(Interaction::WriteToClipboard( + card_contents.clone(), + ))), + ), + ) + .max_width(400.0) + .style(grin_gui_core::theme::CardStyle::Normal); + + let json_proof_row = Row::new().push(json_proof_card); + + column = column + .push(json_proof_row) + .push(Space::new(Length::Fixed(0.0), Length::Fixed(row_spacing))); + } + + let cancel_button_label_container = + Container::new(Text::new(localized_string("back")).size(DEFAULT_FONT_SIZE)) + .width(button_width) + .height(button_height) + .center_x() + .center_y() + .align_x(alignment::Horizontal::Center); + + let cancel_button: Element = Button::new(cancel_button_label_container) + .style(grin_gui_core::theme::ButtonStyle::Primary) + .on_press(Interaction::WalletOperationTxProofViewInteraction( + LocalViewInteraction::Back, + )) + .into(); + + let cancel_container = Container::new(cancel_button.map(Message::Interaction)).padding(1); + let cancel_container = Container::new(cancel_container) + .style(grin_gui_core::theme::ContainerStyle::Segmented) + .padding(1); + + let button_row = Row::new() + .push(cancel_container) + .push(Space::new(Length::Fixed(unit_spacing), Length::Fixed(0.0))); + + column = column.push(button_row); + + let form_container = Container::new(column) + .width(Length::Fill) + .padding(iced::Padding::from([ + 0, // top + 0, // right + 0, // bottom + 5, // left + ])); + + // form container should be scrollable in tiny windows + let scrollable = Scrollable::new(form_container) + .height(Length::Fill) + .style(grin_gui_core::theme::ScrollableStyle::Primary); + + let content = Container::new(scrollable) + .width(Length::Fill) + .height(Length::Shrink) + .style(grin_gui_core::theme::ContainerStyle::NormalBackground); + + let wrapper_column = Column::new() + .height(Length::Fill) + .push(header_container) + .push(content); + + // Returns the final container. + Container::new(wrapper_column).padding(iced::Padding::from([ + DEFAULT_PADDING, // top + DEFAULT_PADDING, // right + DEFAULT_PADDING, // bottom + DEFAULT_PADDING, // left + ])) } diff --git a/src/gui/element/wallet/setup/init.rs b/src/gui/element/wallet/setup/init.rs index e1a32a8..1f71b28 100644 --- a/src/gui/element/wallet/setup/init.rs +++ b/src/gui/element/wallet/setup/init.rs @@ -1,174 +1,172 @@ use { - super::super::super::{DEFAULT_FONT_SIZE, DEFAULT_HEADER_FONT_SIZE}, - crate::gui::{GrinGui, Interaction, Message, element::settings::wallet}, - crate::localization::localized_string, - crate::Result, - grin_gui_core::{ - theme::ColorPalette, - wallet::{create_grin_wallet_path, ChainTypes}, - }, - grin_gui_core::theme::{Column, Element, Container, PickList, Row, Scrollable, Text, TextInput}, - iced::{alignment, Alignment, Command, Length}, - iced::widget::{ - button, pick_list, scrollable, text_input, Button, Checkbox, Space, - }, + super::super::super::{DEFAULT_FONT_SIZE, DEFAULT_HEADER_FONT_SIZE}, + crate::gui::{element::settings::wallet, GrinGui, Interaction, Message}, + crate::localization::localized_string, + crate::Result, + grin_gui_core::theme::{ + Column, Container, Element, PickList, Row, Scrollable, Text, TextInput, + }, + grin_gui_core::{ + theme::ColorPalette, + wallet::{create_grin_wallet_path, ChainTypes}, + }, + iced::widget::{button, pick_list, scrollable, text_input, Button, Checkbox, Space}, + iced::{alignment, Alignment, Command, Length}, }; pub struct StateContainer { - pub setup_wallet_defaults_is_selected: bool, + pub setup_wallet_defaults_is_selected: bool, } impl Default for StateContainer { - fn default() -> Self { - Self { - setup_wallet_defaults_is_selected: true, - } - } + fn default() -> Self { + Self { + setup_wallet_defaults_is_selected: true, + } + } } #[derive(Debug, Clone)] pub enum LocalViewInteraction { - WalletSetup, - WalletList, + WalletSetup, + WalletList, } pub fn handle_message( - grin_gui: &mut GrinGui, - message: LocalViewInteraction, + grin_gui: &mut GrinGui, + message: LocalViewInteraction, ) -> Result> { - let state = &mut grin_gui.wallet_state.setup_state; - match message { - LocalViewInteraction::WalletSetup => { - let config = &grin_gui.config; - let wallet_default_name = localized_string("wallet-default-name"); - let mut wallet_display_name = wallet_default_name.clone(); - let mut i = 1; - - // wallet display name must be unique: i.e. Default 1, Default 2, ... - while let Some(_) = config - .wallets - .iter() - .find(|wallet| wallet.display_name == wallet_display_name) - { - wallet_display_name = format!("{} {}", wallet_default_name, i); - i += 1; - } - - // i.e. default_1, default_2, ... - let wallet_dir: String = str::replace(&wallet_display_name.to_lowercase(), " ", "_"); - - state - .setup_wallet_state - .advanced_options_state - .top_level_directory = create_grin_wallet_path(&ChainTypes::Mainnet, &wallet_dir); - - state.mode = super::Mode::CreateWallet(wallet_display_name); - } - LocalViewInteraction::WalletList => state.mode = super::Mode::ListWallets, - } - Ok(Command::none()) + let state = &mut grin_gui.wallet_state.setup_state; + match message { + LocalViewInteraction::WalletSetup => { + let config = &grin_gui.config; + let wallet_default_name = localized_string("wallet-default-name"); + let mut wallet_display_name = wallet_default_name.clone(); + let mut i = 1; + + // wallet display name must be unique: i.e. Default 1, Default 2, ... + while let Some(_) = config + .wallets + .iter() + .find(|wallet| wallet.display_name == wallet_display_name) + { + wallet_display_name = format!("{} {}", wallet_default_name, i); + i += 1; + } + + // i.e. default_1, default_2, ... + let wallet_dir: String = str::replace(&wallet_display_name.to_lowercase(), " ", "_"); + + state + .setup_wallet_state + .advanced_options_state + .top_level_directory = create_grin_wallet_path(&ChainTypes::Mainnet, &wallet_dir); + + state.mode = super::Mode::CreateWallet(wallet_display_name); + } + LocalViewInteraction::WalletList => state.mode = super::Mode::ListWallets, + } + Ok(Command::none()) } pub fn data_container<'a>() -> Container<'a, Message> { - // Title row - let title = Text::new(localized_string("setup-grin-first-time")) - .size(DEFAULT_HEADER_FONT_SIZE) - .horizontal_alignment(alignment::Horizontal::Center); - - let title_container = - Container::new(title).style(grin_gui_core::theme::ContainerStyle::NormalBackground); - - let title_row = Row::new() - .push(title_container) - .align_items(Alignment::Center) - .padding(6) - .spacing(20); - - let description = Text::new(localized_string("setup-grin-wallet-description")) - .size(DEFAULT_FONT_SIZE) - .horizontal_alignment(alignment::Horizontal::Left); - let description_container = - Container::new(description).style(grin_gui_core::theme::ContainerStyle::NormalBackground); - - let or_text = Text::new(localized_string("or-caps")) - .size(DEFAULT_FONT_SIZE) - .horizontal_alignment(alignment::Horizontal::Center); - - let or_text_container = - Container::new(or_text).style(grin_gui_core::theme::ContainerStyle::NormalBackground); - - let create_default_wallet_button_label_container = Container::new( - Text::new(localized_string("setup-grin-autogenerate-wallet")).size(DEFAULT_FONT_SIZE), - ) - .center_x() - .align_x(alignment::Horizontal::Center); - - let create_default_wallet_button: Element = Button::new( - create_default_wallet_button_label_container, - ) - .style(grin_gui_core::theme::ButtonStyle::Bordered) - .on_press(Interaction::WalletSetupInitViewInteraction( - LocalViewInteraction::WalletSetup, - )) - .into(); - - let select_wallet_button_label_container = - Container::new(Text::new(localized_string("select-wallet-toml")).size(DEFAULT_FONT_SIZE)) - .center_x() - .align_x(alignment::Horizontal::Center); - - let select_wallet_button: Element = Button::new( - select_wallet_button_label_container, - ) - .style(grin_gui_core::theme::ButtonStyle::Bordered) - .on_press(Interaction::WalletSetupInitViewInteraction( - LocalViewInteraction::WalletList, - )) - .into(); - - let select_wallet_button_container = - Container::new(select_wallet_button.map(Message::Interaction)).center_x(); - - //let mut wallet_setup_modal_column = - /*let wallet_setup_select_column = { - let checkbox = Checkbox::new( - state.setup_wallet_defaults_is_selected, - localized_string("setup-grin-autogenerate-wallet"), - Interaction::ToggleCloseToTray, - ) - .style(grin_gui_core::theme::CheckboxStyles::Normal) - .text_size(DEFAULT_FONT_SIZE) - .spacing(5); - - let checkbox: Element = checkbox.into(); - - let checkbox_container = Container::new(checkbox.map(Message::Interaction)) - .style(grin_gui_core::theme::container::Container::NormalBackground); - - Column::new().push(checkbox_container) - };*/ - - let unit_spacing = 15.0; - - let select_column = Column::new() - .push(create_default_wallet_button.map(Message::Interaction)) - .push(Space::new(Length::Fixed(0.0), Length::Fixed(unit_spacing))) - .push(or_text_container) - .push(Space::new(Length::Fixed(0.0), Length::Fixed(unit_spacing))) - .push(select_wallet_button_container) - .align_items(Alignment::Center); - - let column = Column::new() - .push(Space::new(Length::Fixed(0.0), Length::Fixed(20.0))) - .push(title_row) - .push(Space::new(Length::Fixed(0.0), Length::Fixed(unit_spacing))) - .push(description_container) - .push(Space::new(Length::Fixed(0.0), Length::Fixed(unit_spacing))) - .push(select_column) - .align_items(Alignment::Center); - - Container::new(column) - .center_y() - .center_x() - .width(Length::Fill) + // Title row + let title = Text::new(localized_string("setup-grin-first-time")) + .size(DEFAULT_HEADER_FONT_SIZE) + .horizontal_alignment(alignment::Horizontal::Center); + + let title_container = + Container::new(title).style(grin_gui_core::theme::ContainerStyle::NormalBackground); + + let title_row = Row::new() + .push(title_container) + .align_items(Alignment::Center) + .padding(6) + .spacing(20); + + let description = Text::new(localized_string("setup-grin-wallet-description")) + .size(DEFAULT_FONT_SIZE) + .horizontal_alignment(alignment::Horizontal::Left); + let description_container = + Container::new(description).style(grin_gui_core::theme::ContainerStyle::NormalBackground); + + let or_text = Text::new(localized_string("or-caps")) + .size(DEFAULT_FONT_SIZE) + .horizontal_alignment(alignment::Horizontal::Center); + + let or_text_container = + Container::new(or_text).style(grin_gui_core::theme::ContainerStyle::NormalBackground); + + let create_default_wallet_button_label_container = Container::new( + Text::new(localized_string("setup-grin-autogenerate-wallet")).size(DEFAULT_FONT_SIZE), + ) + .center_x() + .align_x(alignment::Horizontal::Center); + + let create_default_wallet_button: Element = + Button::new(create_default_wallet_button_label_container) + .style(grin_gui_core::theme::ButtonStyle::Bordered) + .on_press(Interaction::WalletSetupInitViewInteraction( + LocalViewInteraction::WalletSetup, + )) + .into(); + + let select_wallet_button_label_container = + Container::new(Text::new(localized_string("select-wallet-toml")).size(DEFAULT_FONT_SIZE)) + .center_x() + .align_x(alignment::Horizontal::Center); + + let select_wallet_button: Element = + Button::new(select_wallet_button_label_container) + .style(grin_gui_core::theme::ButtonStyle::Bordered) + .on_press(Interaction::WalletSetupInitViewInteraction( + LocalViewInteraction::WalletList, + )) + .into(); + + let select_wallet_button_container = + Container::new(select_wallet_button.map(Message::Interaction)).center_x(); + + //let mut wallet_setup_modal_column = + /*let wallet_setup_select_column = { + let checkbox = Checkbox::new( + state.setup_wallet_defaults_is_selected, + localized_string("setup-grin-autogenerate-wallet"), + Interaction::ToggleCloseToTray, + ) + .style(grin_gui_core::theme::CheckboxStyles::Normal) + .text_size(DEFAULT_FONT_SIZE) + .spacing(5); + + let checkbox: Element = checkbox.into(); + + let checkbox_container = Container::new(checkbox.map(Message::Interaction)) + .style(grin_gui_core::theme::container::Container::NormalBackground); + + Column::new().push(checkbox_container) + };*/ + + let unit_spacing = 15.0; + + let select_column = Column::new() + .push(create_default_wallet_button.map(Message::Interaction)) + .push(Space::new(Length::Fixed(0.0), Length::Fixed(unit_spacing))) + .push(or_text_container) + .push(Space::new(Length::Fixed(0.0), Length::Fixed(unit_spacing))) + .push(select_wallet_button_container) + .align_items(Alignment::Center); + + let column = Column::new() + .push(Space::new(Length::Fixed(0.0), Length::Fixed(20.0))) + .push(title_row) + .push(Space::new(Length::Fixed(0.0), Length::Fixed(unit_spacing))) + .push(description_container) + .push(Space::new(Length::Fixed(0.0), Length::Fixed(unit_spacing))) + .push(select_column) + .align_items(Alignment::Center); + + Container::new(column) + .center_y() + .center_x() + .width(Length::Fill) } diff --git a/src/gui/element/wallet/setup/mod.rs b/src/gui/element/wallet/setup/mod.rs index cc15e23..c5dfa6f 100644 --- a/src/gui/element/wallet/setup/mod.rs +++ b/src/gui/element/wallet/setup/mod.rs @@ -1,77 +1,73 @@ pub mod init; +pub mod wallet_list; pub mod wallet_setup; pub mod wallet_success; -pub mod wallet_list; use { - crate::gui::{GrinGui, Message}, - crate::Result, - grin_gui_core::theme::ColorPalette, - grin_gui_core::config::Config, - iced::{Command, Length}, - grin_gui_core::theme::{Column, Element, Container, PickList, Row, Scrollable, Text, TextInput}, - iced::widget::{Space} + crate::gui::{GrinGui, Message}, + crate::Result, + grin_gui_core::config::Config, + grin_gui_core::theme::ColorPalette, + grin_gui_core::theme::{ + Column, Container, Element, PickList, Row, Scrollable, Text, TextInput, + }, + iced::widget::Space, + iced::{Command, Length}, }; pub struct StateContainer { - pub mode: Mode, - pub setup_init_state: init::StateContainer, - pub setup_wallet_state: wallet_setup::StateContainer, - pub setup_wallet_success_state: wallet_success::StateContainer, - pub setup_wallet_list_state: wallet_list::StateContainer + pub mode: Mode, + pub setup_init_state: init::StateContainer, + pub setup_wallet_state: wallet_setup::StateContainer, + pub setup_wallet_success_state: wallet_success::StateContainer, + pub setup_wallet_list_state: wallet_list::StateContainer, } #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub enum Mode { - Init, - CreateWallet(String), - ListWallets, - WalletCreateSuccess, + Init, + CreateWallet(String), + ListWallets, + WalletCreateSuccess, } impl Default for StateContainer { - fn default() -> Self { - Self { - mode: Mode::Init, - setup_init_state: Default::default(), - setup_wallet_state: Default::default(), - setup_wallet_success_state: Default::default(), - setup_wallet_list_state: Default::default() - } - } + fn default() -> Self { + Self { + mode: Mode::Init, + setup_init_state: Default::default(), + setup_wallet_state: Default::default(), + setup_wallet_success_state: Default::default(), + setup_wallet_list_state: Default::default(), + } + } } #[derive(Debug, Clone)] pub enum LocalViewInteraction {} pub fn handle_message( - grin_gui: &mut GrinGui, - message: LocalViewInteraction, + grin_gui: &mut GrinGui, + message: LocalViewInteraction, ) -> Result> { - Ok(Command::none()) + Ok(Command::none()) } -pub fn data_container<'a>( - state: &'a StateContainer, - config: &Config, -) -> Container<'a, Message> { - let content = match &state.mode { - Mode::Init => init::data_container(), - Mode::CreateWallet(default_display_name) => { - wallet_setup::data_container(&state.setup_wallet_state, default_display_name) - } - Mode::WalletCreateSuccess => { - wallet_success::data_container(&state.setup_wallet_success_state) - } - Mode::ListWallets => { - wallet_list::data_container(&state.setup_wallet_list_state, - config) - } - }; +pub fn data_container<'a>(state: &'a StateContainer, config: &Config) -> Container<'a, Message> { + let content = match &state.mode { + Mode::Init => init::data_container(), + Mode::CreateWallet(default_display_name) => { + wallet_setup::data_container(&state.setup_wallet_state, default_display_name) + } + Mode::WalletCreateSuccess => { + wallet_success::data_container(&state.setup_wallet_success_state) + } + Mode::ListWallets => wallet_list::data_container(&state.setup_wallet_list_state, config), + }; - Container::new(content) - .center_y() - .center_x() - .width(Length::Fill) - .style(grin_gui_core::theme::ContainerStyle::NormalBackground) + Container::new(content) + .center_y() + .center_x() + .width(Length::Fill) + .style(grin_gui_core::theme::ContainerStyle::NormalBackground) } diff --git a/src/gui/element/wallet/setup/wallet_list.rs b/src/gui/element/wallet/setup/wallet_list.rs index 42055c3..f7339d6 100644 --- a/src/gui/element/wallet/setup/wallet_list.rs +++ b/src/gui/element/wallet/setup/wallet_list.rs @@ -1,23 +1,23 @@ use { - super::super::super::{ - BUTTON_HEIGHT, BUTTON_WIDTH, DEFAULT_FONT_SIZE, DEFAULT_HEADER_FONT_SIZE, DEFAULT_PADDING, - }, - crate::gui::{GrinGui, Interaction, Message}, - crate::localization::localized_string, - crate::Result, - grin_gui_core::config::Config, - grin_gui_core::theme::{ - Button, Column, Container, Element, Header, PickList, Row, Scrollable, TableRow, Text, - TextInput, - }, - grin_gui_core::{ - theme::ColorPalette, - wallet::{create_grin_wallet_path, ChainTypes}, - }, - iced::widget::{button, pick_list, scrollable, text_input, Checkbox, Space}, - iced::{alignment, Alignment, Command, Length}, - native_dialog::FileDialog, - std::path::PathBuf, + super::super::super::{ + BUTTON_HEIGHT, BUTTON_WIDTH, DEFAULT_FONT_SIZE, DEFAULT_HEADER_FONT_SIZE, DEFAULT_PADDING, + }, + crate::gui::{GrinGui, Interaction, Message}, + crate::localization::localized_string, + crate::Result, + grin_gui_core::config::Config, + grin_gui_core::theme::{ + Button, Column, Container, Element, Header, PickList, Row, Scrollable, TableRow, Text, + TextInput, + }, + grin_gui_core::{ + theme::ColorPalette, + wallet::{create_grin_wallet_path, ChainTypes}, + }, + iced::widget::{button, pick_list, scrollable, text_input, Checkbox, Space}, + iced::{alignment, Alignment, Command, Length}, + native_dialog::FileDialog, + std::path::PathBuf, }; use grin_gui_widgets::widget::table_row; @@ -26,382 +26,380 @@ use isahc::head; use crate::gui::element::DEFAULT_SUB_HEADER_FONT_SIZE; pub struct StateContainer { - selected_wallet_index: usize, + selected_wallet_index: usize, } impl Default for StateContainer { - fn default() -> Self { - Self { - selected_wallet_index: 0, - } - } + fn default() -> Self { + Self { + selected_wallet_index: 0, + } + } } #[derive(Debug, Clone)] pub enum LocalViewInteraction { - Back, - WalletRowSelect(bool, usize), - LoadWallet(usize), - LocateWallet, - CreateWallet, + Back, + WalletRowSelect(bool, usize), + LoadWallet(usize), + LocateWallet, + CreateWallet, } pub fn handle_message<'a>( - grin_gui: &mut GrinGui, - message: LocalViewInteraction, + grin_gui: &mut GrinGui, + message: LocalViewInteraction, ) -> Result> { - match message { - LocalViewInteraction::Back => { - grin_gui.wallet_state.setup_state.mode = super::Mode::Init; - } - LocalViewInteraction::WalletRowSelect(is_selected, index) => { - if is_selected { - grin_gui - .wallet_state - .setup_state - .setup_wallet_list_state - .selected_wallet_index = index; - } - } - LocalViewInteraction::LoadWallet(index) => { - grin_gui.config.current_wallet_index = Some(index); - grin_gui.wallet_state.mode = crate::gui::element::wallet::Mode::Operation; - - // If transaction list hasn't been init yet, refresh the list with latest - if grin_gui - .wallet_state - .operation_state - .home_state - .tx_list_display_state - .mode - == crate::gui::element::wallet::operation::tx_list_display::Mode::NotInit - { - let fut = move || async {}; - return Ok(Command::perform(fut(), |_| { - return Message::Interaction( + match message { + LocalViewInteraction::Back => { + grin_gui.wallet_state.setup_state.mode = super::Mode::Init; + } + LocalViewInteraction::WalletRowSelect(is_selected, index) => { + if is_selected { + grin_gui + .wallet_state + .setup_state + .setup_wallet_list_state + .selected_wallet_index = index; + } + } + LocalViewInteraction::LoadWallet(index) => { + grin_gui.config.current_wallet_index = Some(index); + grin_gui.wallet_state.mode = crate::gui::element::wallet::Mode::Operation; + + // If transaction list hasn't been init yet, refresh the list with latest + if grin_gui + .wallet_state + .operation_state + .home_state + .tx_list_display_state + .mode == crate::gui::element::wallet::operation::tx_list_display::Mode::NotInit + { + let fut = move || async {}; + return Ok(Command::perform(fut(), |_| { + return Message::Interaction( Interaction::WalletOperationHomeTxListDisplayInteraction( crate::gui::element::wallet::operation::tx_list_display::LocalViewInteraction::SelectMode( crate::gui::element::wallet::operation::tx_list_display::Mode::Recent ), ), ); - })); - } - - } - LocalViewInteraction::LocateWallet => { - match FileDialog::new().show_open_single_file() { - Ok(path) => { - match path { - Some(d) => { - match validate_directory(d) { - Ok(wallet_was_imported) => {} - Err(err) => { - // tell the user why this directory failed - } - } - } - None => {} - } - } - Err(e) => { - log::debug!("wallet_list.rs::LocalViewInteraction::LocateWallet {}", e); - } - }; - } - LocalViewInteraction::CreateWallet => { - let state = &mut grin_gui.wallet_state.setup_state; - let config = &grin_gui.config; - let wallet_default_name = localized_string("wallet-default-name"); - let mut wallet_display_name = wallet_default_name.clone(); - let mut i = 1; - - // wallet display name must be unique: i.e. Default 1, Default 2, ... - while let Some(_) = config - .wallets - .iter() - .find(|wallet| wallet.display_name == wallet_display_name) - { - wallet_display_name = format!("{} {}", wallet_default_name, i); - i += 1; - } - - // i.e. default_1, default_2, ... - let wallet_dir: String = str::replace(&wallet_display_name.to_lowercase(), " ", "_"); - - state - .setup_wallet_state - .advanced_options_state - .top_level_directory = create_grin_wallet_path(&ChainTypes::Mainnet, &wallet_dir); - - grin_gui.wallet_state.mode = - crate::gui::element::wallet::Mode::CreateWallet(wallet_display_name); - } - } - - Ok(Command::none()) + })); + } + } + LocalViewInteraction::LocateWallet => { + match FileDialog::new().show_open_single_file() { + Ok(path) => { + match path { + Some(d) => { + match validate_directory(d) { + Ok(wallet_was_imported) => {} + Err(err) => { + // tell the user why this directory failed + } + } + } + None => {} + } + } + Err(e) => { + log::debug!("wallet_list.rs::LocalViewInteraction::LocateWallet {}", e); + } + }; + } + LocalViewInteraction::CreateWallet => { + let state = &mut grin_gui.wallet_state.setup_state; + let config = &grin_gui.config; + let wallet_default_name = localized_string("wallet-default-name"); + let mut wallet_display_name = wallet_default_name.clone(); + let mut i = 1; + + // wallet display name must be unique: i.e. Default 1, Default 2, ... + while let Some(_) = config + .wallets + .iter() + .find(|wallet| wallet.display_name == wallet_display_name) + { + wallet_display_name = format!("{} {}", wallet_default_name, i); + i += 1; + } + + // i.e. default_1, default_2, ... + let wallet_dir: String = str::replace(&wallet_display_name.to_lowercase(), " ", "_"); + + state + .setup_wallet_state + .advanced_options_state + .top_level_directory = create_grin_wallet_path(&ChainTypes::Mainnet, &wallet_dir); + + grin_gui.wallet_state.mode = + crate::gui::element::wallet::Mode::CreateWallet(wallet_display_name); + } + } + + Ok(Command::none()) } struct DirectoryValidationError; fn validate_directory(_d: PathBuf) -> Result { - Ok(true) + Ok(true) } pub fn data_container<'a>(state: &'a StateContainer, config: &Config) -> Container<'a, Message> { - let button_height = Length::Fixed(BUTTON_HEIGHT); - let button_width = Length::Fixed(BUTTON_WIDTH); - - let title = Text::new(localized_string("wallet-list")).size(DEFAULT_HEADER_FONT_SIZE); - let title_container = Container::new(title) - .style(grin_gui_core::theme::ContainerStyle::BrightBackground) - .padding(iced::Padding::from([ - 0, // top - 0, // right - 0, // bottom - 5, // left - ])); - - let new_wallet_container = - Container::new(Text::new(localized_string("create-wallet")).size(DEFAULT_FONT_SIZE)) - .align_y(alignment::Vertical::Center) - .align_x(alignment::Horizontal::Center); - - let new_wallet_button: Element = Button::new(new_wallet_container) - .style(grin_gui_core::theme::ButtonStyle::Primary) - .on_press(Interaction::WalletListWalletViewInteraction( - LocalViewInteraction::CreateWallet, - )) - .into(); - - // add additional buttons here - let button_row = Row::new().push(new_wallet_button.map(Message::Interaction)); - - let segmented_mode_container = Container::new(button_row).padding(1); - let segmented_mode_control_container = Container::new(segmented_mode_container) - .style(grin_gui_core::theme::ContainerStyle::Segmented) - .padding(1); - - let header_row = Row::new() - .push(title_container) - .push(Space::with_width(Length::Fill)) - .push(segmented_mode_control_container) - .align_items(Alignment::Center); - - let header_container = Container::new(header_row).padding(iced::Padding::from([ - 0, // top - 0, // right - DEFAULT_PADDING as u16, // bottom - 0, // left - ])); - - let name_header = Text::new(localized_string("name")).size(DEFAULT_FONT_SIZE); - let name_header_container = - Container::new(name_header).style(grin_gui_core::theme::ContainerStyle::BrightForeground); - - let chain_header = Text::new(localized_string("type")).size(DEFAULT_FONT_SIZE); - let chain_header_container = - Container::new(chain_header).style(grin_gui_core::theme::ContainerStyle::BrightForeground); - - let directory_header = Text::new(localized_string("directory")).size(DEFAULT_FONT_SIZE); - let directory_header_container = Container::new(directory_header) - .style(grin_gui_core::theme::ContainerStyle::BrightForeground); - - let table_header_row = Row::new() - .push( - Column::new() - .push(name_header_container) - .width(Length::FillPortion(1)), - ) - .push( - Column::new() - .push(chain_header_container) - .width(Length::FillPortion(1)), - ) - .push( - Column::new() - .push(directory_header_container) - .width(Length::FillPortion(3)), - ); - - let table_header_container = Container::new(table_header_row) - .padding(iced::Padding::from([ - 9, // top - DEFAULT_PADDING as u16, // right - should roughly match width of content scroll bar to align table headers - 9, // bottom - 9, // left - ])) - .style(grin_gui_core::theme::ContainerStyle::PanelForeground); - - let mut wallet_rows: Vec<_> = vec![]; - for (pos, w) in config.wallets.iter().enumerate() { - // si quieres el checkbox - // let checkbox = Checkbox::new(state.selected_wallet_index == pos, "", move |b| { - // Message::Interaction(Interaction::WalletListWalletViewInteraction( - // LocalViewInteraction::WalletRowSelect(b, pos), - // )) - // }) - // .style(grin_gui_core::theme::CheckboxStyles::Normal) - // .text_size(DEFAULT_FONT_SIZE) - // .spacing(10); - - let selected_wallet = state.selected_wallet_index == pos; - let wallet_name = Text::new(w.display_name.clone()).size(DEFAULT_FONT_SIZE); - let chain_name = Text::new(w.chain_type.shortname()).size(DEFAULT_FONT_SIZE); - - let mut wallet_name_container = Container::new(wallet_name) - .style(grin_gui_core::theme::ContainerStyle::HoverableForeground); - - let mut wallet_chain_container = Container::new(chain_name) - .style(grin_gui_core::theme::ContainerStyle::HoverableForeground); - - let tld_string = match &w.tld { - Some(path_buf) => path_buf.display().to_string(), - None => String::from("Unknown"), - }; - let wallet_directory = Text::new(tld_string).size(DEFAULT_FONT_SIZE); - - let mut wallet_directory_container = Container::new(wallet_directory) - .style(grin_gui_core::theme::ContainerStyle::HoverableForeground); - - if selected_wallet { - wallet_name_container = wallet_name_container - .style(grin_gui_core::theme::ContainerStyle::HoverableBrightForeground); - wallet_chain_container = wallet_chain_container - .style(grin_gui_core::theme::ContainerStyle::HoverableBrightForeground); - wallet_directory_container = wallet_directory_container - .style(grin_gui_core::theme::ContainerStyle::HoverableBrightForeground); - } - - let wallet_row = Row::new() - //.push(checkbox) - .push( - Column::new() - .push(wallet_name_container) - .width(Length::FillPortion(1)), - ) - .push( - Column::new() - .push(wallet_chain_container) - .width(Length::FillPortion(1)), - ) - .push( - Column::new() - .push(wallet_directory_container) - .width(Length::FillPortion(3)), - ); - - let mut table_row = TableRow::new(wallet_row) - .padding(iced::Padding::from(9)) - .width(Length::Fill) - .on_press(move |_| { - log::debug!("data_container::table_row::on_press {}", pos); - - Message::Interaction(Interaction::WalletListWalletViewInteraction( - LocalViewInteraction::WalletRowSelect(true, pos), - )) - }); - - if selected_wallet { - // selected wallet should be highlighted - table_row = table_row.style(grin_gui_core::theme::TableRowStyle::TableRowSelected); - } else { - // contrast row styles to spice things up - if pos % 2 == 0 { - table_row = table_row.style(grin_gui_core::theme::TableRowStyle::TableRowLowlife); - } else { - table_row = table_row.style(grin_gui_core::theme::TableRowStyle::TableRowHighlife); - } - } - - wallet_rows.push(table_row.into()); - } - - let wallet_column = Column::new().push(Column::with_children(wallet_rows)); - - let load_wallet_button_container = - Container::new(Text::new(localized_string("load-wallet")).size(DEFAULT_FONT_SIZE)) - .width(button_width) - .height(button_height) - .align_y(alignment::Vertical::Center) - .align_x(alignment::Horizontal::Center); - - let mut load_wallet_button = - Button::new(load_wallet_button_container).style(grin_gui_core::theme::ButtonStyle::Primary); - - // the load wallet button should be disabled if there are no wallets - if !config.wallets.is_empty() { - load_wallet_button = - load_wallet_button.on_press(Interaction::WalletListWalletViewInteraction( - LocalViewInteraction::LoadWallet(state.selected_wallet_index), - )) - } - - let load_wallet_button: Element = load_wallet_button.into(); - - let select_folder_button_container = - Container::new(Text::new(localized_string("select-other")).size(DEFAULT_FONT_SIZE)) - .width(button_width) - .height(button_height) - .align_y(alignment::Vertical::Center) - .align_x(alignment::Horizontal::Center); - - let select_other_button: Element = Button::new(select_folder_button_container) - .style(grin_gui_core::theme::ButtonStyle::Primary) - .on_press(Interaction::WalletListWalletViewInteraction( - LocalViewInteraction::LocateWallet, - )) - .into(); - - // button lipstick - let load_container = Container::new(load_wallet_button.map(Message::Interaction)).padding(1); - let load_container = Container::new(load_container) - .style(grin_gui_core::theme::ContainerStyle::Segmented) - .padding(1); - - let select_container = Container::new(select_other_button.map(Message::Interaction)).padding(1); - let select_container = Container::new(select_container) - .style(grin_gui_core::theme::ContainerStyle::Segmented) - .padding(1); - - let button_row = Row::new() - .push(load_container) - .push(Space::with_width(Length::Fixed(DEFAULT_PADDING))) - .push(select_container) - .height(Length::Shrink); - - let scrollable = - Scrollable::new(wallet_column).style(grin_gui_core::theme::ScrollableStyle::Primary); - - let table_colummn = Column::new().push(table_header_container).push(scrollable); - let table_container = Container::new(table_colummn) - .style(grin_gui_core::theme::ContainerStyle::PanelBordered) - .height(Length::Fill) - .padding(1); - - let row = Row::new().push( - Column::new() - .push(table_container) - .push(Space::with_height(Length::Fixed(DEFAULT_PADDING))) - .push(button_row), - ); - - let content = Container::new(row) - .center_x() - .width(Length::Fill) - .height(Length::Shrink) - .style(grin_gui_core::theme::ContainerStyle::NormalBackground); - - let wrapper_column = Column::new() - .height(Length::Fill) - .push(header_container) - .push(content); - - // Returns the final container. - Container::new(wrapper_column).padding(iced::Padding::from([ - DEFAULT_PADDING, // top - DEFAULT_PADDING, // right - DEFAULT_PADDING, // bottom - DEFAULT_PADDING, // left - ])) + let button_height = Length::Fixed(BUTTON_HEIGHT); + let button_width = Length::Fixed(BUTTON_WIDTH); + + let title = Text::new(localized_string("wallet-list")).size(DEFAULT_HEADER_FONT_SIZE); + let title_container = Container::new(title) + .style(grin_gui_core::theme::ContainerStyle::BrightBackground) + .padding(iced::Padding::from([ + 0, // top + 0, // right + 0, // bottom + 5, // left + ])); + + let new_wallet_container = + Container::new(Text::new(localized_string("create-wallet")).size(DEFAULT_FONT_SIZE)) + .align_y(alignment::Vertical::Center) + .align_x(alignment::Horizontal::Center); + + let new_wallet_button: Element = Button::new(new_wallet_container) + .style(grin_gui_core::theme::ButtonStyle::Primary) + .on_press(Interaction::WalletListWalletViewInteraction( + LocalViewInteraction::CreateWallet, + )) + .into(); + + // add additional buttons here + let button_row = Row::new().push(new_wallet_button.map(Message::Interaction)); + + let segmented_mode_container = Container::new(button_row).padding(1); + let segmented_mode_control_container = Container::new(segmented_mode_container) + .style(grin_gui_core::theme::ContainerStyle::Segmented) + .padding(1); + + let header_row = Row::new() + .push(title_container) + .push(Space::with_width(Length::Fill)) + .push(segmented_mode_control_container) + .align_items(Alignment::Center); + + let header_container = Container::new(header_row).padding(iced::Padding::from([ + 0, // top + 0, // right + DEFAULT_PADDING as u16, // bottom + 0, // left + ])); + + let name_header = Text::new(localized_string("name")).size(DEFAULT_FONT_SIZE); + let name_header_container = + Container::new(name_header).style(grin_gui_core::theme::ContainerStyle::BrightForeground); + + let chain_header = Text::new(localized_string("type")).size(DEFAULT_FONT_SIZE); + let chain_header_container = + Container::new(chain_header).style(grin_gui_core::theme::ContainerStyle::BrightForeground); + + let directory_header = Text::new(localized_string("directory")).size(DEFAULT_FONT_SIZE); + let directory_header_container = Container::new(directory_header) + .style(grin_gui_core::theme::ContainerStyle::BrightForeground); + + let table_header_row = Row::new() + .push( + Column::new() + .push(name_header_container) + .width(Length::FillPortion(1)), + ) + .push( + Column::new() + .push(chain_header_container) + .width(Length::FillPortion(1)), + ) + .push( + Column::new() + .push(directory_header_container) + .width(Length::FillPortion(3)), + ); + + let table_header_container = Container::new(table_header_row) + .padding(iced::Padding::from([ + 9, // top + DEFAULT_PADDING as u16, // right - should roughly match width of content scroll bar to align table headers + 9, // bottom + 9, // left + ])) + .style(grin_gui_core::theme::ContainerStyle::PanelForeground); + + let mut wallet_rows: Vec<_> = vec![]; + for (pos, w) in config.wallets.iter().enumerate() { + // si quieres el checkbox + // let checkbox = Checkbox::new(state.selected_wallet_index == pos, "", move |b| { + // Message::Interaction(Interaction::WalletListWalletViewInteraction( + // LocalViewInteraction::WalletRowSelect(b, pos), + // )) + // }) + // .style(grin_gui_core::theme::CheckboxStyles::Normal) + // .text_size(DEFAULT_FONT_SIZE) + // .spacing(10); + + let selected_wallet = state.selected_wallet_index == pos; + let wallet_name = Text::new(w.display_name.clone()).size(DEFAULT_FONT_SIZE); + let chain_name = Text::new(w.chain_type.shortname()).size(DEFAULT_FONT_SIZE); + + let mut wallet_name_container = Container::new(wallet_name) + .style(grin_gui_core::theme::ContainerStyle::HoverableForeground); + + let mut wallet_chain_container = Container::new(chain_name) + .style(grin_gui_core::theme::ContainerStyle::HoverableForeground); + + let tld_string = match &w.tld { + Some(path_buf) => path_buf.display().to_string(), + None => String::from("Unknown"), + }; + let wallet_directory = Text::new(tld_string).size(DEFAULT_FONT_SIZE); + + let mut wallet_directory_container = Container::new(wallet_directory) + .style(grin_gui_core::theme::ContainerStyle::HoverableForeground); + + if selected_wallet { + wallet_name_container = wallet_name_container + .style(grin_gui_core::theme::ContainerStyle::HoverableBrightForeground); + wallet_chain_container = wallet_chain_container + .style(grin_gui_core::theme::ContainerStyle::HoverableBrightForeground); + wallet_directory_container = wallet_directory_container + .style(grin_gui_core::theme::ContainerStyle::HoverableBrightForeground); + } + + let wallet_row = Row::new() + //.push(checkbox) + .push( + Column::new() + .push(wallet_name_container) + .width(Length::FillPortion(1)), + ) + .push( + Column::new() + .push(wallet_chain_container) + .width(Length::FillPortion(1)), + ) + .push( + Column::new() + .push(wallet_directory_container) + .width(Length::FillPortion(3)), + ); + + let mut table_row = TableRow::new(wallet_row) + .padding(iced::Padding::from(9)) + .width(Length::Fill) + .on_press(move |_| { + log::debug!("data_container::table_row::on_press {}", pos); + + Message::Interaction(Interaction::WalletListWalletViewInteraction( + LocalViewInteraction::WalletRowSelect(true, pos), + )) + }); + + if selected_wallet { + // selected wallet should be highlighted + table_row = table_row.style(grin_gui_core::theme::TableRowStyle::TableRowSelected); + } else { + // contrast row styles to spice things up + if pos % 2 == 0 { + table_row = table_row.style(grin_gui_core::theme::TableRowStyle::TableRowLowlife); + } else { + table_row = table_row.style(grin_gui_core::theme::TableRowStyle::TableRowHighlife); + } + } + + wallet_rows.push(table_row.into()); + } + + let wallet_column = Column::new().push(Column::with_children(wallet_rows)); + + let load_wallet_button_container = + Container::new(Text::new(localized_string("load-wallet")).size(DEFAULT_FONT_SIZE)) + .width(button_width) + .height(button_height) + .align_y(alignment::Vertical::Center) + .align_x(alignment::Horizontal::Center); + + let mut load_wallet_button = + Button::new(load_wallet_button_container).style(grin_gui_core::theme::ButtonStyle::Primary); + + // the load wallet button should be disabled if there are no wallets + if !config.wallets.is_empty() { + load_wallet_button = + load_wallet_button.on_press(Interaction::WalletListWalletViewInteraction( + LocalViewInteraction::LoadWallet(state.selected_wallet_index), + )) + } + + let load_wallet_button: Element = load_wallet_button.into(); + + let select_folder_button_container = + Container::new(Text::new(localized_string("select-other")).size(DEFAULT_FONT_SIZE)) + .width(button_width) + .height(button_height) + .align_y(alignment::Vertical::Center) + .align_x(alignment::Horizontal::Center); + + let select_other_button: Element = Button::new(select_folder_button_container) + .style(grin_gui_core::theme::ButtonStyle::Primary) + .on_press(Interaction::WalletListWalletViewInteraction( + LocalViewInteraction::LocateWallet, + )) + .into(); + + // button lipstick + let load_container = Container::new(load_wallet_button.map(Message::Interaction)).padding(1); + let load_container = Container::new(load_container) + .style(grin_gui_core::theme::ContainerStyle::Segmented) + .padding(1); + + let select_container = Container::new(select_other_button.map(Message::Interaction)).padding(1); + let select_container = Container::new(select_container) + .style(grin_gui_core::theme::ContainerStyle::Segmented) + .padding(1); + + let button_row = Row::new() + .push(load_container) + .push(Space::with_width(Length::Fixed(DEFAULT_PADDING))) + .push(select_container) + .height(Length::Shrink); + + let scrollable = + Scrollable::new(wallet_column).style(grin_gui_core::theme::ScrollableStyle::Primary); + + let table_colummn = Column::new().push(table_header_container).push(scrollable); + let table_container = Container::new(table_colummn) + .style(grin_gui_core::theme::ContainerStyle::PanelBordered) + .height(Length::Fill) + .padding(1); + + let row = Row::new().push( + Column::new() + .push(table_container) + .push(Space::with_height(Length::Fixed(DEFAULT_PADDING))) + .push(button_row), + ); + + let content = Container::new(row) + .center_x() + .width(Length::Fill) + .height(Length::Shrink) + .style(grin_gui_core::theme::ContainerStyle::NormalBackground); + + let wrapper_column = Column::new() + .height(Length::Fill) + .push(header_container) + .push(content); + + // Returns the final container. + Container::new(wrapper_column).padding(iced::Padding::from([ + DEFAULT_PADDING, // top + DEFAULT_PADDING, // right + DEFAULT_PADDING, // bottom + DEFAULT_PADDING, // left + ])) } diff --git a/src/gui/element/wallet/setup/wallet_setup.rs b/src/gui/element/wallet/setup/wallet_setup.rs index d80c7c6..e22087a 100644 --- a/src/gui/element/wallet/setup/wallet_setup.rs +++ b/src/gui/element/wallet/setup/wallet_setup.rs @@ -4,634 +4,634 @@ use native_dialog::FileDialog; use std::path::PathBuf; use { - super::super::super::{ - BUTTON_HEIGHT, BUTTON_WIDTH, DEFAULT_FONT_SIZE, DEFAULT_HEADER_FONT_SIZE, DEFAULT_PADDING, - }, - crate::gui::{GrinGui, Interaction, Message}, - crate::localization::localized_string, - crate::Result, - anyhow::Context, - grin_gui_core::theme::ColorPalette, - grin_gui_core::theme::{ - Button, Column, Container, Element, PickList, Row, Scrollable, Text, TextInput, - }, - grin_gui_core::{ - config::Wallet, - fs::PersistentData, - node::ChainTypes::{self, Mainnet, Testnet}, - wallet::create_grin_wallet_path, - wallet::WalletInterface, - }, - iced::widget::{button, pick_list, scrollable, text_input, Checkbox, Space}, - iced::{alignment, Alignment, Command, Length}, - std::sync::{Arc, RwLock}, + super::super::super::{ + BUTTON_HEIGHT, BUTTON_WIDTH, DEFAULT_FONT_SIZE, DEFAULT_HEADER_FONT_SIZE, DEFAULT_PADDING, + }, + crate::gui::{GrinGui, Interaction, Message}, + crate::localization::localized_string, + crate::Result, + anyhow::Context, + grin_gui_core::theme::ColorPalette, + grin_gui_core::theme::{ + Button, Column, Container, Element, PickList, Row, Scrollable, Text, TextInput, + }, + grin_gui_core::{ + config::Wallet, + fs::PersistentData, + node::ChainTypes::{self, Mainnet, Testnet}, + wallet::create_grin_wallet_path, + wallet::WalletInterface, + }, + iced::widget::{button, pick_list, scrollable, text_input, Checkbox, Space}, + iced::{alignment, Alignment, Command, Length}, + std::sync::{Arc, RwLock}, }; pub struct StateContainer { - pub password_state: PasswordState, - pub restore_from_seed: bool, - pub seed_input_value: String, - pub show_advanced_options: bool, - pub is_testnet: bool, - pub advanced_options_state: AdvancedOptionsState, + pub password_state: PasswordState, + pub restore_from_seed: bool, + pub seed_input_value: String, + pub show_advanced_options: bool, + pub is_testnet: bool, + pub advanced_options_state: AdvancedOptionsState, } impl Default for StateContainer { - fn default() -> Self { - Self { - password_state: Default::default(), - show_advanced_options: false, - is_testnet: false, - restore_from_seed: false, - seed_input_value: Default::default(), - advanced_options_state: Default::default(), - } - } + fn default() -> Self { + Self { + password_state: Default::default(), + show_advanced_options: false, + is_testnet: false, + restore_from_seed: false, + seed_input_value: Default::default(), + advanced_options_state: Default::default(), + } + } } pub struct AdvancedOptionsState { - pub display_name_value: String, - pub top_level_directory: PathBuf, + pub display_name_value: String, + pub top_level_directory: PathBuf, } impl Default for AdvancedOptionsState { - fn default() -> Self { - Self { - display_name_value: Default::default(), - top_level_directory: Default::default(), - } - } + fn default() -> Self { + Self { + display_name_value: Default::default(), + top_level_directory: Default::default(), + } + } } #[derive(Debug, Clone)] pub struct PasswordState { - pub input_value: String, - pub repeat_input_value: String, + pub input_value: String, + pub repeat_input_value: String, } impl Default for PasswordState { - fn default() -> Self { - PasswordState { - input_value: Default::default(), - repeat_input_value: Default::default(), - } - } + fn default() -> Self { + PasswordState { + input_value: Default::default(), + repeat_input_value: Default::default(), + } + } } #[derive(Debug, Clone)] pub enum LocalViewInteraction { - Back, - //TODO: ZeroingString these - PasswordInput(String), - PasswordInputEnterPressed, - PasswordRepeatInput(String), - PasswordRepeatInputEnterPressed, - ToggleRestoreFromSeed(bool), - ToggleAdvancedOptions(bool), - ToggleIsTestnet(bool), - DisplayName(String), - CreateWallet(String, PathBuf), - WalletCreatedOk((String, String, String, ChainTypes)), - WalletCreateError(Arc>>), - SeedInput(String), - ShowFolderPicker, + Back, + //TODO: ZeroingString these + PasswordInput(String), + PasswordInputEnterPressed, + PasswordRepeatInput(String), + PasswordRepeatInputEnterPressed, + ToggleRestoreFromSeed(bool), + ToggleAdvancedOptions(bool), + ToggleIsTestnet(bool), + DisplayName(String), + CreateWallet(String, PathBuf), + WalletCreatedOk((String, String, String, ChainTypes)), + WalletCreateError(Arc>>), + SeedInput(String), + ShowFolderPicker, } pub fn handle_message<'a>( - grin_gui: &mut GrinGui, - message: LocalViewInteraction, + grin_gui: &mut GrinGui, + message: LocalViewInteraction, ) -> Result> { - let state = &mut grin_gui.wallet_state.setup_state.setup_wallet_state; - match message { - LocalViewInteraction::Back => { - // reset user input values - grin_gui.wallet_state.setup_state.setup_wallet_state = Default::default(); - - // return user to proper view - match grin_gui.wallet_state.mode { - // back to init screen - element::wallet::Mode::Init => { - grin_gui.wallet_state.setup_state.mode = super::Mode::Init - } - _ => { - // back to list view - grin_gui.wallet_state.mode = element::wallet::Mode::Init; - grin_gui.wallet_state.setup_state.mode = super::Mode::ListWallets; - } - }; - } - LocalViewInteraction::PasswordInput(password) => { - state.password_state.input_value = password; - } - LocalViewInteraction::PasswordInputEnterPressed => { - // state.password_state.input_state.unfocus(); - // state.password_state.repeat_input_state.focus(); - } - LocalViewInteraction::PasswordRepeatInput(repeat_password) => { - state.password_state.repeat_input_value = repeat_password; - } - LocalViewInteraction::PasswordRepeatInputEnterPressed => { - //state.password_state.repeat_input_state.unfocus(); - } - LocalViewInteraction::ToggleRestoreFromSeed(_) => { - state.restore_from_seed = !state.restore_from_seed - } - LocalViewInteraction::ToggleAdvancedOptions(_) => { - state.show_advanced_options = !state.show_advanced_options - } - LocalViewInteraction::ToggleIsTestnet(_) => { - state.is_testnet = !state.is_testnet; - let current_tld = state.advanced_options_state.top_level_directory.clone(); - let directory = current_tld.file_name().unwrap().to_str().unwrap(); - - if state.is_testnet { - let default_path = create_grin_wallet_path(&Mainnet, directory); - // Only change if nobody's modified the default path - if default_path == current_tld { - state.advanced_options_state.top_level_directory = - create_grin_wallet_path(&Testnet, directory); - } - } else { - let default_path = create_grin_wallet_path(&Testnet, directory); - // Only change if nobody's modified the default path - if default_path == current_tld { - state.advanced_options_state.top_level_directory = - create_grin_wallet_path(&Mainnet, directory); - } - } - } - LocalViewInteraction::DisplayName(display_name_value) => { - state.advanced_options_state.display_name_value = display_name_value; - } - LocalViewInteraction::ShowFolderPicker => { - match FileDialog::new().show_open_single_dir() { - Ok(path) => match path { - Some(d) => { - state.advanced_options_state.top_level_directory = d; - } - None => {} - }, - Err(e) => { - log::debug!( - "wallet_setup.rs::LocalViewInteraction::ShowFolderPicker {}", - e - ); - } - }; - } - LocalViewInteraction::CreateWallet(display_name, top_level_directory) => { - grin_gui.error.take(); - - log::debug!( - "setup::wallet::LocalViewInteraction::CreateWallet {}", - display_name, - ); - - 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()) - } else { - None - }; - - let fut = move || { - WalletInterface::init( - w, - password.clone(), - top_level_directory, - display_name, - chain_type, - recovery_phrase, - ) - }; - - return Ok(Command::perform(fut(), |r| { - match r.context("Failed to Create Wallet") { - Ok(ret) => Message::Interaction(Interaction::WalletSetupWalletViewInteraction( - LocalViewInteraction::WalletCreatedOk(ret), - )), - Err(e) => Message::Interaction(Interaction::WalletSetupWalletViewInteraction( - LocalViewInteraction::WalletCreateError(Arc::new(RwLock::new(Some(e)))), - )), - } - })); - } - LocalViewInteraction::WalletCreatedOk((tld, mnemonic, display_name, chain_type)) => { - let tld = Some(PathBuf::from(&tld)); - let saved_wallet = Wallet::new(tld, display_name, chain_type); - - let index = grin_gui.config.add_wallet(saved_wallet); - grin_gui.config.current_wallet_index = Some(index); - grin_gui.wallet_state.clear_config_missing(); - grin_gui - .wallet_state - .setup_state - .setup_wallet_success_state - .recovery_phrase = mnemonic; - - // reset user input values - grin_gui.wallet_state.setup_state.setup_wallet_state = Default::default(); - - let _ = grin_gui.config.save(); - - grin_gui.wallet_state.setup_state.mode = - crate::gui::element::wallet::setup::Mode::WalletCreateSuccess; - - if grin_gui.wallet_state.mode != element::wallet::Mode::Init { - // set init state - grin_gui.wallet_state.mode = element::wallet::Mode::Init; - } - } - LocalViewInteraction::WalletCreateError(err) => { - grin_gui.error = err.write().unwrap().take(); - if let Some(e) = grin_gui.error.as_ref() { - log_error(e); - } - } - LocalViewInteraction::SeedInput(seed) => { - state.seed_input_value = seed; - } - } - - Ok(Command::none()) + let state = &mut grin_gui.wallet_state.setup_state.setup_wallet_state; + match message { + LocalViewInteraction::Back => { + // reset user input values + grin_gui.wallet_state.setup_state.setup_wallet_state = Default::default(); + + // return user to proper view + match grin_gui.wallet_state.mode { + // back to init screen + element::wallet::Mode::Init => { + grin_gui.wallet_state.setup_state.mode = super::Mode::Init + } + _ => { + // back to list view + grin_gui.wallet_state.mode = element::wallet::Mode::Init; + grin_gui.wallet_state.setup_state.mode = super::Mode::ListWallets; + } + }; + } + LocalViewInteraction::PasswordInput(password) => { + state.password_state.input_value = password; + } + LocalViewInteraction::PasswordInputEnterPressed => { + // state.password_state.input_state.unfocus(); + // state.password_state.repeat_input_state.focus(); + } + LocalViewInteraction::PasswordRepeatInput(repeat_password) => { + state.password_state.repeat_input_value = repeat_password; + } + LocalViewInteraction::PasswordRepeatInputEnterPressed => { + //state.password_state.repeat_input_state.unfocus(); + } + LocalViewInteraction::ToggleRestoreFromSeed(_) => { + state.restore_from_seed = !state.restore_from_seed + } + LocalViewInteraction::ToggleAdvancedOptions(_) => { + state.show_advanced_options = !state.show_advanced_options + } + LocalViewInteraction::ToggleIsTestnet(_) => { + state.is_testnet = !state.is_testnet; + let current_tld = state.advanced_options_state.top_level_directory.clone(); + let directory = current_tld.file_name().unwrap().to_str().unwrap(); + + if state.is_testnet { + let default_path = create_grin_wallet_path(&Mainnet, directory); + // Only change if nobody's modified the default path + if default_path == current_tld { + state.advanced_options_state.top_level_directory = + create_grin_wallet_path(&Testnet, directory); + } + } else { + let default_path = create_grin_wallet_path(&Testnet, directory); + // Only change if nobody's modified the default path + if default_path == current_tld { + state.advanced_options_state.top_level_directory = + create_grin_wallet_path(&Mainnet, directory); + } + } + } + LocalViewInteraction::DisplayName(display_name_value) => { + state.advanced_options_state.display_name_value = display_name_value; + } + LocalViewInteraction::ShowFolderPicker => { + match FileDialog::new().show_open_single_dir() { + Ok(path) => match path { + Some(d) => { + state.advanced_options_state.top_level_directory = d; + } + None => {} + }, + Err(e) => { + log::debug!( + "wallet_setup.rs::LocalViewInteraction::ShowFolderPicker {}", + e + ); + } + }; + } + LocalViewInteraction::CreateWallet(display_name, top_level_directory) => { + grin_gui.error.take(); + + log::debug!( + "setup::wallet::LocalViewInteraction::CreateWallet {}", + display_name, + ); + + 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()) + } else { + None + }; + + let fut = move || { + WalletInterface::init( + w, + password.clone(), + top_level_directory, + display_name, + chain_type, + recovery_phrase, + ) + }; + + return Ok(Command::perform(fut(), |r| { + match r.context("Failed to Create Wallet") { + Ok(ret) => Message::Interaction(Interaction::WalletSetupWalletViewInteraction( + LocalViewInteraction::WalletCreatedOk(ret), + )), + Err(e) => Message::Interaction(Interaction::WalletSetupWalletViewInteraction( + LocalViewInteraction::WalletCreateError(Arc::new(RwLock::new(Some(e)))), + )), + } + })); + } + LocalViewInteraction::WalletCreatedOk((tld, mnemonic, display_name, chain_type)) => { + let tld = Some(PathBuf::from(&tld)); + let saved_wallet = Wallet::new(tld, display_name, chain_type); + + let index = grin_gui.config.add_wallet(saved_wallet); + grin_gui.config.current_wallet_index = Some(index); + grin_gui.wallet_state.clear_config_missing(); + grin_gui + .wallet_state + .setup_state + .setup_wallet_success_state + .recovery_phrase = mnemonic; + + // reset user input values + grin_gui.wallet_state.setup_state.setup_wallet_state = Default::default(); + + let _ = grin_gui.config.save(); + + grin_gui.wallet_state.setup_state.mode = + crate::gui::element::wallet::setup::Mode::WalletCreateSuccess; + + if grin_gui.wallet_state.mode != element::wallet::Mode::Init { + // set init state + grin_gui.wallet_state.mode = element::wallet::Mode::Init; + } + } + LocalViewInteraction::WalletCreateError(err) => { + grin_gui.error = err.write().unwrap().take(); + if let Some(e) = grin_gui.error.as_ref() { + log_error(e); + } + } + LocalViewInteraction::SeedInput(seed) => { + state.seed_input_value = seed; + } + } + + Ok(Command::none()) } pub fn data_container<'a>( - state: &'a StateContainer, - default_display_name: &str, + state: &'a StateContainer, + default_display_name: &str, ) -> Container<'a, Message> { - let check_password = || { - state.password_state.input_value == state.password_state.repeat_input_value - && !state.password_state.input_value.is_empty() - }; - - let disp_password_status = || { - !state.password_state.input_value.is_empty() - && !state.password_state.repeat_input_value.is_empty() - }; - - let title = Text::new(localized_string("setup-grin-wallet-title")) - .size(DEFAULT_HEADER_FONT_SIZE) - .horizontal_alignment(alignment::Horizontal::Center); - - // we need 2 pts of padding here to match the position with other views: i.e. wallet list, settings. - // otherwise this title container will look like it shifts up slightly when the user toggles - // between views with buttons on the header row. - let title_container = Container::new(title) - .style(grin_gui_core::theme::ContainerStyle::BrightBackground) - .padding(iced::Padding::from([ - 2, // top - 0, // right - 2, // bottom - 5, // left - ])); - - // push more items on to header here: e.g. other buttons, things that belong on the header - let header_row = Row::new().push(title_container); - - let header_container = Container::new(header_row).padding(iced::Padding::from([ - 0, // top - 0, // right - DEFAULT_PADDING as u16, // bottom - 0, // left - ])); - - let password_column = { - let password_input = TextInput::new( - &localized_string("password")[..], - &state.password_state.input_value, - ) - .on_input(|s| { - Interaction::WalletSetupWalletViewInteraction(LocalViewInteraction::PasswordInput(s)) - }) - .on_submit(Interaction::WalletSetupWalletViewInteraction( - LocalViewInteraction::PasswordInputEnterPressed, - )) - .size(DEFAULT_FONT_SIZE) - .padding(6) - .width(Length::Fixed(200.0)) - .style(grin_gui_core::theme::TextInputStyle::AddonsQuery) - .password(); - - let password_input: Element = password_input.into(); - - let repeat_password_input = TextInput::new( - &localized_string("password-repeat")[..], - &state.password_state.repeat_input_value, - ) - .on_input(|s| { - Interaction::WalletSetupWalletViewInteraction( - LocalViewInteraction::PasswordRepeatInput(s), - ) - }) - .on_submit(Interaction::WalletSetupWalletViewInteraction( - LocalViewInteraction::PasswordRepeatInputEnterPressed, - )) - .size(DEFAULT_FONT_SIZE) - .padding(6) - .width(Length::Fixed(200.0)) - .style(grin_gui_core::theme::TextInputStyle::AddonsQuery) - .password(); - - let repeat_password_input: Element = repeat_password_input.into(); - - let mut password_entry_value = localized_string("setup-grin-passwords-dont-match"); - if check_password() { - password_entry_value = localized_string("setup-grin-passwords-okay") - } - let password_entry_status = Text::new(password_entry_value) - .size(DEFAULT_FONT_SIZE) - .horizontal_alignment(alignment::Horizontal::Left); - let mut password_entry_status_container = Container::new(password_entry_status) - //.width(Length::Fill) - .style(grin_gui_core::theme::ContainerStyle::ErrorForeground); - - let mut password_input_col = Column::new() - .push(password_input.map(Message::Interaction)) - .push(repeat_password_input.map(Message::Interaction)) - .spacing(DEFAULT_PADDING) - .align_items(Alignment::Start); - - if !check_password() && disp_password_status() { - password_input_col = password_input_col.push(password_entry_status_container) - } else if check_password() { - password_entry_status_container = password_entry_status_container - .style(grin_gui_core::theme::ContainerStyle::SuccessBackground); - password_input_col = password_input_col.push(password_entry_status_container) - } - Column::new().push(password_input_col) - }; - - let description = Text::new(localized_string("setup-grin-wallet-enter-password")) - .size(DEFAULT_FONT_SIZE) - .horizontal_alignment(alignment::Horizontal::Center); - let description_container = - Container::new(description).style(grin_gui_core::theme::ContainerStyle::NormalBackground); - - let mut restore_from_seed_column = { - let checkbox = Checkbox::new( - localized_string("restore-from-seed"), - state.restore_from_seed, - |b| { - Interaction::WalletSetupWalletViewInteraction( - LocalViewInteraction::ToggleRestoreFromSeed(b), - ) - }, - ) - .style(grin_gui_core::theme::CheckboxStyle::Normal) - .text_size(DEFAULT_FONT_SIZE) - .spacing(10); - - let checkbox: Element = checkbox.into(); - - let checkbox_container = Container::new(checkbox.map(Message::Interaction)) - .style(grin_gui_core::theme::ContainerStyle::NormalBackground); - Column::new().push(checkbox_container) - }; - - let show_advanced_options_column = { - let checkbox = Checkbox::new( - localized_string("show-advanced-options"), - state.show_advanced_options, - |b| { - Interaction::WalletSetupWalletViewInteraction( - LocalViewInteraction::ToggleAdvancedOptions(b), - ) - }, - ) - .style(grin_gui_core::theme::CheckboxStyle::Normal) - .text_size(DEFAULT_FONT_SIZE) - .spacing(10); - - let checkbox: Element = checkbox.into(); - - let checkbox_container = Container::new(checkbox.map(Message::Interaction)) - .style(grin_gui_core::theme::ContainerStyle::NormalBackground); - Column::new().push(checkbox_container) - }; - - // ** 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_column = Column::with_children(vec![seed_input.map(Message::Interaction)]); - - if state.restore_from_seed { - restore_from_seed_column = restore_from_seed_column - .push(Space::with_height(Length::Fixed(DEFAULT_PADDING))) - .push(seed_column); - } - - // ** end hideable restore - - // ** start hideable advanced options - //let display_name_label = - let display_name = Text::new(localized_string("display-name")) - .size(DEFAULT_FONT_SIZE) - .horizontal_alignment(alignment::Horizontal::Left); - - let display_name_container = - Container::new(display_name).style(grin_gui_core::theme::ContainerStyle::NormalBackground); - - let display_name_input = TextInput::new( - default_display_name, - &state.advanced_options_state.display_name_value, - ) - .on_input(|s| { - Interaction::WalletSetupWalletViewInteraction(LocalViewInteraction::DisplayName(s)) - }) - .size(DEFAULT_FONT_SIZE) - .padding(6) - .width(Length::Fixed(200.0)) - .style(grin_gui_core::theme::TextInputStyle::AddonsQuery); - - let tld = Text::new(localized_string("top-level-domain")) - .size(DEFAULT_FONT_SIZE) - .horizontal_alignment(alignment::Horizontal::Left); - - let tld_container = - Container::new(tld).style(grin_gui_core::theme::ContainerStyle::NormalBackground); - - let folder_select_button_container = - Container::new(Text::new(localized_string("select-directory")).size(DEFAULT_FONT_SIZE)); - let folder_select_button = Button::new(folder_select_button_container) - .style(grin_gui_core::theme::ButtonStyle::Bordered) - .on_press(Interaction::WalletSetupWalletViewInteraction( - LocalViewInteraction::ShowFolderPicker, - )); - let folder_select_button: Element = folder_select_button.into(); - - let tld_string = state - .advanced_options_state - .top_level_directory - .to_str() - .unwrap(); - let current_tld = Text::new(tld_string).size(DEFAULT_FONT_SIZE); - - let current_tld_container = - Container::new(current_tld).style(grin_gui_core::theme::ContainerStyle::NormalBackground); - - let current_tld_column = Column::new() - .push(Space::new(Length::Fixed(0.0), Length::Fixed(5.0))) - .push(current_tld_container); - - let folder_select_row = Row::new() - .push(folder_select_button.map(Message::Interaction)) - .push(Space::new( - Length::Fixed(DEFAULT_PADDING), - Length::Fixed(0.0), - )) - .push(current_tld_column); - - let display_name_input: Element = display_name_input.into(); - - let is_testnet_checkbox = - Checkbox::new(localized_string("use-testnet"), state.is_testnet, |b| { - Interaction::WalletSetupWalletViewInteraction(LocalViewInteraction::ToggleIsTestnet(b)) - }) - .style(grin_gui_core::theme::CheckboxStyle::Normal) - .text_size(DEFAULT_FONT_SIZE) - .spacing(10); - - let is_testnet_checkbox: Element = is_testnet_checkbox.into(); - - let is_testnet_row = Row::new().push(is_testnet_checkbox.map(Message::Interaction)); - - let advanced_options_column = Column::new() - .push(display_name_container) - .push(display_name_input.map(Message::Interaction)) - .push(Space::new(Length::Fixed(0.0), Length::Fixed(5.0))) - .push(tld_container) - .spacing(DEFAULT_PADDING) - .push(folder_select_row) - .spacing(DEFAULT_PADDING) - .push(Space::new(Length::Fixed(0.0), Length::Fixed(5.0))) - .push(is_testnet_row) - .push(restore_from_seed_column) - .align_items(Alignment::Start); - - // ** end hideable advanced options - - let button_height = Length::Fixed(BUTTON_HEIGHT); - let button_width = Length::Fixed(BUTTON_WIDTH); - - let submit_button_label_container = Container::new( - Text::new(localized_string("setup-grin-create-wallet")).size(DEFAULT_FONT_SIZE), - ) - .width(button_width) - .height(button_height) - .center_x() - .center_y() - .align_x(alignment::Horizontal::Center); - - let mut submit_button = Button::new(submit_button_label_container) - .style(grin_gui_core::theme::ButtonStyle::Primary); - if check_password() { - let top_level_directory = state.advanced_options_state.top_level_directory.clone(); - let display_name = if state.advanced_options_state.display_name_value.is_empty() { - default_display_name.to_string() - } else { - state.advanced_options_state.display_name_value.clone() - }; - - submit_button = submit_button.on_press(Interaction::WalletSetupWalletViewInteraction( - LocalViewInteraction::CreateWallet(display_name, top_level_directory), - )); - } - - let submit_button: Element = submit_button.into(); - - let cancel_button_label_container = - Container::new(Text::new(localized_string("cancel")).size(DEFAULT_FONT_SIZE)) - .width(button_width) - .height(button_height) - .center_x() - .center_y() - .align_x(alignment::Horizontal::Center); - - let cancel_button: Element = Button::new(cancel_button_label_container) - .style(grin_gui_core::theme::ButtonStyle::Primary) - .on_press(Interaction::WalletSetupWalletViewInteraction( - LocalViewInteraction::Back, - )) - .into(); - - let submit_container = Container::new(submit_button.map(Message::Interaction)).padding(1); - let submit_container = Container::new(submit_container) - .style(grin_gui_core::theme::ContainerStyle::Segmented) - .padding(1); - - let cancel_container = Container::new(cancel_button.map(Message::Interaction)).padding(1); - let cancel_container = Container::new(cancel_container) - .style(grin_gui_core::theme::ContainerStyle::Segmented) - .padding(1); - - let unit_spacing = 15.0; - let button_row = Row::new() - .push(submit_container) - .push(Space::new(Length::Fixed(unit_spacing), Length::Fixed(0.0))) - .push(cancel_container); - - let mut column = Column::new() - .push(Space::new(Length::Fixed(0.0), Length::Fixed(unit_spacing))) - .push(description_container) - .push(Space::new(Length::Fixed(0.0), Length::Fixed(unit_spacing))) - .push(password_column) - .push(Space::new(Length::Fixed(0.0), Length::Fixed(unit_spacing))) - .push(show_advanced_options_column) - .push(Space::new( - Length::Fixed(0.0), - Length::Fixed(unit_spacing + 10.0), - )); - - if state.show_advanced_options { - column = column.push(advanced_options_column).push(Space::new( - Length::Fixed(0.0), - Length::Fixed(unit_spacing + 10.0), - )); - } - - column = column.push(button_row).align_items(Alignment::Start); - let form_container = Container::new(column) - .width(Length::Fill) - .padding(iced::Padding::from([ - 0, // top - 0, // right - 0, // bottom - 5, // left - ])); - - // form container should be scrollable in tiny windows - let scrollable = Scrollable::new(form_container) - .height(Length::Fill) - .style(grin_gui_core::theme::ScrollableStyle::Primary); - - let content = Container::new(scrollable) - .width(Length::Fill) - .height(Length::Shrink) - .style(grin_gui_core::theme::ContainerStyle::NormalBackground); - - let wrapper_column = Column::new() - .height(Length::Fill) - .push(header_container) - .push(content); - - // Returns the final container. - Container::new(wrapper_column).padding(iced::Padding::from([ - DEFAULT_PADDING, // top - DEFAULT_PADDING, // right - DEFAULT_PADDING, // bottom - DEFAULT_PADDING, // left - ])) + let check_password = || { + state.password_state.input_value == state.password_state.repeat_input_value + && !state.password_state.input_value.is_empty() + }; + + let disp_password_status = || { + !state.password_state.input_value.is_empty() + && !state.password_state.repeat_input_value.is_empty() + }; + + let title = Text::new(localized_string("setup-grin-wallet-title")) + .size(DEFAULT_HEADER_FONT_SIZE) + .horizontal_alignment(alignment::Horizontal::Center); + + // we need 2 pts of padding here to match the position with other views: i.e. wallet list, settings. + // otherwise this title container will look like it shifts up slightly when the user toggles + // between views with buttons on the header row. + let title_container = Container::new(title) + .style(grin_gui_core::theme::ContainerStyle::BrightBackground) + .padding(iced::Padding::from([ + 2, // top + 0, // right + 2, // bottom + 5, // left + ])); + + // push more items on to header here: e.g. other buttons, things that belong on the header + let header_row = Row::new().push(title_container); + + let header_container = Container::new(header_row).padding(iced::Padding::from([ + 0, // top + 0, // right + DEFAULT_PADDING as u16, // bottom + 0, // left + ])); + + let password_column = { + let password_input = TextInput::new( + &localized_string("password")[..], + &state.password_state.input_value, + ) + .on_input(|s| { + Interaction::WalletSetupWalletViewInteraction(LocalViewInteraction::PasswordInput(s)) + }) + .on_submit(Interaction::WalletSetupWalletViewInteraction( + LocalViewInteraction::PasswordInputEnterPressed, + )) + .size(DEFAULT_FONT_SIZE) + .padding(6) + .width(Length::Fixed(200.0)) + .style(grin_gui_core::theme::TextInputStyle::AddonsQuery) + .password(); + + let password_input: Element = password_input.into(); + + let repeat_password_input = TextInput::new( + &localized_string("password-repeat")[..], + &state.password_state.repeat_input_value, + ) + .on_input(|s| { + Interaction::WalletSetupWalletViewInteraction( + LocalViewInteraction::PasswordRepeatInput(s), + ) + }) + .on_submit(Interaction::WalletSetupWalletViewInteraction( + LocalViewInteraction::PasswordRepeatInputEnterPressed, + )) + .size(DEFAULT_FONT_SIZE) + .padding(6) + .width(Length::Fixed(200.0)) + .style(grin_gui_core::theme::TextInputStyle::AddonsQuery) + .password(); + + let repeat_password_input: Element = repeat_password_input.into(); + + let mut password_entry_value = localized_string("setup-grin-passwords-dont-match"); + if check_password() { + password_entry_value = localized_string("setup-grin-passwords-okay") + } + let password_entry_status = Text::new(password_entry_value) + .size(DEFAULT_FONT_SIZE) + .horizontal_alignment(alignment::Horizontal::Left); + let mut password_entry_status_container = Container::new(password_entry_status) + //.width(Length::Fill) + .style(grin_gui_core::theme::ContainerStyle::ErrorForeground); + + let mut password_input_col = Column::new() + .push(password_input.map(Message::Interaction)) + .push(repeat_password_input.map(Message::Interaction)) + .spacing(DEFAULT_PADDING) + .align_items(Alignment::Start); + + if !check_password() && disp_password_status() { + password_input_col = password_input_col.push(password_entry_status_container) + } else if check_password() { + password_entry_status_container = password_entry_status_container + .style(grin_gui_core::theme::ContainerStyle::SuccessBackground); + password_input_col = password_input_col.push(password_entry_status_container) + } + Column::new().push(password_input_col) + }; + + let description = Text::new(localized_string("setup-grin-wallet-enter-password")) + .size(DEFAULT_FONT_SIZE) + .horizontal_alignment(alignment::Horizontal::Center); + let description_container = + Container::new(description).style(grin_gui_core::theme::ContainerStyle::NormalBackground); + + let mut restore_from_seed_column = { + let checkbox = Checkbox::new( + localized_string("restore-from-seed"), + state.restore_from_seed, + |b| { + Interaction::WalletSetupWalletViewInteraction( + LocalViewInteraction::ToggleRestoreFromSeed(b), + ) + }, + ) + .style(grin_gui_core::theme::CheckboxStyle::Normal) + .text_size(DEFAULT_FONT_SIZE) + .spacing(10); + + let checkbox: Element = checkbox.into(); + + let checkbox_container = Container::new(checkbox.map(Message::Interaction)) + .style(grin_gui_core::theme::ContainerStyle::NormalBackground); + Column::new().push(checkbox_container) + }; + + let show_advanced_options_column = { + let checkbox = Checkbox::new( + localized_string("show-advanced-options"), + state.show_advanced_options, + |b| { + Interaction::WalletSetupWalletViewInteraction( + LocalViewInteraction::ToggleAdvancedOptions(b), + ) + }, + ) + .style(grin_gui_core::theme::CheckboxStyle::Normal) + .text_size(DEFAULT_FONT_SIZE) + .spacing(10); + + let checkbox: Element = checkbox.into(); + + let checkbox_container = Container::new(checkbox.map(Message::Interaction)) + .style(grin_gui_core::theme::ContainerStyle::NormalBackground); + Column::new().push(checkbox_container) + }; + + // ** 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_column = Column::with_children(vec![seed_input.map(Message::Interaction)]); + + if state.restore_from_seed { + restore_from_seed_column = restore_from_seed_column + .push(Space::with_height(Length::Fixed(DEFAULT_PADDING))) + .push(seed_column); + } + + // ** end hideable restore + + // ** start hideable advanced options + //let display_name_label = + let display_name = Text::new(localized_string("display-name")) + .size(DEFAULT_FONT_SIZE) + .horizontal_alignment(alignment::Horizontal::Left); + + let display_name_container = + Container::new(display_name).style(grin_gui_core::theme::ContainerStyle::NormalBackground); + + let display_name_input = TextInput::new( + default_display_name, + &state.advanced_options_state.display_name_value, + ) + .on_input(|s| { + Interaction::WalletSetupWalletViewInteraction(LocalViewInteraction::DisplayName(s)) + }) + .size(DEFAULT_FONT_SIZE) + .padding(6) + .width(Length::Fixed(200.0)) + .style(grin_gui_core::theme::TextInputStyle::AddonsQuery); + + let tld = Text::new(localized_string("top-level-domain")) + .size(DEFAULT_FONT_SIZE) + .horizontal_alignment(alignment::Horizontal::Left); + + let tld_container = + Container::new(tld).style(grin_gui_core::theme::ContainerStyle::NormalBackground); + + let folder_select_button_container = + Container::new(Text::new(localized_string("select-directory")).size(DEFAULT_FONT_SIZE)); + let folder_select_button = Button::new(folder_select_button_container) + .style(grin_gui_core::theme::ButtonStyle::Bordered) + .on_press(Interaction::WalletSetupWalletViewInteraction( + LocalViewInteraction::ShowFolderPicker, + )); + let folder_select_button: Element = folder_select_button.into(); + + let tld_string = state + .advanced_options_state + .top_level_directory + .to_str() + .unwrap(); + let current_tld = Text::new(tld_string).size(DEFAULT_FONT_SIZE); + + let current_tld_container = + Container::new(current_tld).style(grin_gui_core::theme::ContainerStyle::NormalBackground); + + let current_tld_column = Column::new() + .push(Space::new(Length::Fixed(0.0), Length::Fixed(5.0))) + .push(current_tld_container); + + let folder_select_row = Row::new() + .push(folder_select_button.map(Message::Interaction)) + .push(Space::new( + Length::Fixed(DEFAULT_PADDING), + Length::Fixed(0.0), + )) + .push(current_tld_column); + + let display_name_input: Element = display_name_input.into(); + + let is_testnet_checkbox = + Checkbox::new(localized_string("use-testnet"), state.is_testnet, |b| { + Interaction::WalletSetupWalletViewInteraction(LocalViewInteraction::ToggleIsTestnet(b)) + }) + .style(grin_gui_core::theme::CheckboxStyle::Normal) + .text_size(DEFAULT_FONT_SIZE) + .spacing(10); + + let is_testnet_checkbox: Element = is_testnet_checkbox.into(); + + let is_testnet_row = Row::new().push(is_testnet_checkbox.map(Message::Interaction)); + + let advanced_options_column = Column::new() + .push(display_name_container) + .push(display_name_input.map(Message::Interaction)) + .push(Space::new(Length::Fixed(0.0), Length::Fixed(5.0))) + .push(tld_container) + .spacing(DEFAULT_PADDING) + .push(folder_select_row) + .spacing(DEFAULT_PADDING) + .push(Space::new(Length::Fixed(0.0), Length::Fixed(5.0))) + .push(is_testnet_row) + .push(restore_from_seed_column) + .align_items(Alignment::Start); + + // ** end hideable advanced options + + let button_height = Length::Fixed(BUTTON_HEIGHT); + let button_width = Length::Fixed(BUTTON_WIDTH); + + let submit_button_label_container = Container::new( + Text::new(localized_string("setup-grin-create-wallet")).size(DEFAULT_FONT_SIZE), + ) + .width(button_width) + .height(button_height) + .center_x() + .center_y() + .align_x(alignment::Horizontal::Center); + + let mut submit_button = Button::new(submit_button_label_container) + .style(grin_gui_core::theme::ButtonStyle::Primary); + if check_password() { + let top_level_directory = state.advanced_options_state.top_level_directory.clone(); + let display_name = if state.advanced_options_state.display_name_value.is_empty() { + default_display_name.to_string() + } else { + state.advanced_options_state.display_name_value.clone() + }; + + submit_button = submit_button.on_press(Interaction::WalletSetupWalletViewInteraction( + LocalViewInteraction::CreateWallet(display_name, top_level_directory), + )); + } + + let submit_button: Element = submit_button.into(); + + let cancel_button_label_container = + Container::new(Text::new(localized_string("cancel")).size(DEFAULT_FONT_SIZE)) + .width(button_width) + .height(button_height) + .center_x() + .center_y() + .align_x(alignment::Horizontal::Center); + + let cancel_button: Element = Button::new(cancel_button_label_container) + .style(grin_gui_core::theme::ButtonStyle::Primary) + .on_press(Interaction::WalletSetupWalletViewInteraction( + LocalViewInteraction::Back, + )) + .into(); + + let submit_container = Container::new(submit_button.map(Message::Interaction)).padding(1); + let submit_container = Container::new(submit_container) + .style(grin_gui_core::theme::ContainerStyle::Segmented) + .padding(1); + + let cancel_container = Container::new(cancel_button.map(Message::Interaction)).padding(1); + let cancel_container = Container::new(cancel_container) + .style(grin_gui_core::theme::ContainerStyle::Segmented) + .padding(1); + + let unit_spacing = 15.0; + let button_row = Row::new() + .push(submit_container) + .push(Space::new(Length::Fixed(unit_spacing), Length::Fixed(0.0))) + .push(cancel_container); + + let mut column = Column::new() + .push(Space::new(Length::Fixed(0.0), Length::Fixed(unit_spacing))) + .push(description_container) + .push(Space::new(Length::Fixed(0.0), Length::Fixed(unit_spacing))) + .push(password_column) + .push(Space::new(Length::Fixed(0.0), Length::Fixed(unit_spacing))) + .push(show_advanced_options_column) + .push(Space::new( + Length::Fixed(0.0), + Length::Fixed(unit_spacing + 10.0), + )); + + if state.show_advanced_options { + column = column.push(advanced_options_column).push(Space::new( + Length::Fixed(0.0), + Length::Fixed(unit_spacing + 10.0), + )); + } + + column = column.push(button_row).align_items(Alignment::Start); + let form_container = Container::new(column) + .width(Length::Fill) + .padding(iced::Padding::from([ + 0, // top + 0, // right + 0, // bottom + 5, // left + ])); + + // form container should be scrollable in tiny windows + let scrollable = Scrollable::new(form_container) + .height(Length::Fill) + .style(grin_gui_core::theme::ScrollableStyle::Primary); + + let content = Container::new(scrollable) + .width(Length::Fill) + .height(Length::Shrink) + .style(grin_gui_core::theme::ContainerStyle::NormalBackground); + + let wrapper_column = Column::new() + .height(Length::Fill) + .push(header_container) + .push(content); + + // Returns the final container. + Container::new(wrapper_column).padding(iced::Padding::from([ + DEFAULT_PADDING, // top + DEFAULT_PADDING, // right + DEFAULT_PADDING, // bottom + DEFAULT_PADDING, // left + ])) } diff --git a/src/gui/element/wallet/setup/wallet_success.rs b/src/gui/element/wallet/setup/wallet_success.rs index c99fae5..b74de02 100644 --- a/src/gui/element/wallet/setup/wallet_success.rs +++ b/src/gui/element/wallet/setup/wallet_success.rs @@ -1,132 +1,132 @@ use { - super::super::super::{DEFAULT_FONT_SIZE, DEFAULT_HEADER_FONT_SIZE, SMALLER_FONT_SIZE}, - crate::gui::{GrinGui, Interaction, Message}, - crate::localization::localized_string, - crate::Result, - grin_gui_core::theme::ColorPalette, - iced::{alignment, Alignment, Command, Length}, - grin_gui_core::theme::{Column, Element, Container, PickList, Row, Scrollable, Text, TextInput}, - iced::widget::{ - button, pick_list, scrollable, text_input, Button, Checkbox, Space, - }, - iced_aw::Card, + super::super::super::{DEFAULT_FONT_SIZE, DEFAULT_HEADER_FONT_SIZE, SMALLER_FONT_SIZE}, + crate::gui::{GrinGui, Interaction, Message}, + crate::localization::localized_string, + crate::Result, + grin_gui_core::theme::ColorPalette, + grin_gui_core::theme::{ + Column, Container, Element, PickList, Row, Scrollable, Text, TextInput, + }, + iced::widget::{button, pick_list, scrollable, text_input, Button, Checkbox, Space}, + iced::{alignment, Alignment, Command, Length}, + iced_aw::Card, }; pub struct StateContainer { - // TODO: ZeroingString this - pub recovery_phrase: String, + // TODO: ZeroingString this + pub recovery_phrase: String, } impl Default for StateContainer { - fn default() -> Self { - Self { - recovery_phrase: Default::default(), - } - } + fn default() -> Self { + Self { + recovery_phrase: Default::default(), + } + } } #[derive(Debug, Clone)] pub enum LocalViewInteraction { - Submit, + Submit, } pub fn handle_message( - grin_gui: &mut GrinGui, - message: LocalViewInteraction, + grin_gui: &mut GrinGui, + message: LocalViewInteraction, ) -> Result> { - let state = &mut grin_gui.wallet_state.setup_state.setup_wallet_state; - match message { - LocalViewInteraction::Submit => { - grin_gui.wallet_state.mode = super::super::Mode::Operation; - grin_gui.wallet_state.setup_state.mode = crate::gui::element::wallet::setup::Mode::Init; - } - } - Ok(Command::none()) + let state = &mut grin_gui.wallet_state.setup_state.setup_wallet_state; + match message { + LocalViewInteraction::Submit => { + grin_gui.wallet_state.mode = super::super::Mode::Operation; + grin_gui.wallet_state.setup_state.mode = crate::gui::element::wallet::setup::Mode::Init; + } + } + Ok(Command::none()) } -pub fn data_container<'a>( - state: &'a StateContainer, -) -> Container<'a, Message> { - // Title row - let title = Text::new(localized_string("setup-grin-wallet-success")) - .size(DEFAULT_HEADER_FONT_SIZE) - .horizontal_alignment(alignment::Horizontal::Left); +pub fn data_container<'a>(state: &'a StateContainer) -> Container<'a, Message> { + // Title row + let title = Text::new(localized_string("setup-grin-wallet-success")) + .size(DEFAULT_HEADER_FONT_SIZE) + .horizontal_alignment(alignment::Horizontal::Left); - let title_container = - Container::new(title).style(grin_gui_core::theme::ContainerStyle::NormalBackground); + let title_container = + Container::new(title).style(grin_gui_core::theme::ContainerStyle::NormalBackground); - let title_row = Row::new() - .push(title_container) - .align_items(Alignment::Center) - .spacing(20); + let title_row = Row::new() + .push(title_container) + .align_items(Alignment::Center) + .spacing(20); - let description = Text::new(localized_string("setup-grin-wallet-recovery-phrase")) - .size(DEFAULT_FONT_SIZE) - .horizontal_alignment(alignment::Horizontal::Center); - let description_container = - Container::new(description).style(grin_gui_core::theme::ContainerStyle::NormalBackground); + let description = Text::new(localized_string("setup-grin-wallet-recovery-phrase")) + .size(DEFAULT_FONT_SIZE) + .horizontal_alignment(alignment::Horizontal::Center); + let description_container = + Container::new(description).style(grin_gui_core::theme::ContainerStyle::NormalBackground); - let recovery_phrase_card = Card::new( - Text::new(localized_string("setup-grin-wallet-recovery-phrase-title")).size(DEFAULT_HEADER_FONT_SIZE), - Text::new(&state.recovery_phrase).size(DEFAULT_FONT_SIZE), - ) - .foot( - Column::new() - .spacing(10) - .padding(5) - .width(Length::Fill) - .align_items(Alignment::Center) - .push( - Button::new( - Text::new(localized_string("copy-to-clipboard")) - .size(SMALLER_FONT_SIZE) - .horizontal_alignment(alignment::Horizontal::Center), - ) - .style(grin_gui_core::theme::ButtonStyle::NormalText) - .on_press(Message::Interaction(Interaction::WriteToClipboard( - state.recovery_phrase.clone(), - ))), - ), - ) - .max_width(400.0) - .style(grin_gui_core::theme::CardStyle::Normal); + let recovery_phrase_card = Card::new( + Text::new(localized_string("setup-grin-wallet-recovery-phrase-title")) + .size(DEFAULT_HEADER_FONT_SIZE), + Text::new(&state.recovery_phrase).size(DEFAULT_FONT_SIZE), + ) + .foot( + Column::new() + .spacing(10) + .padding(5) + .width(Length::Fill) + .align_items(Alignment::Center) + .push( + Button::new( + Text::new(localized_string("copy-to-clipboard")) + .size(SMALLER_FONT_SIZE) + .horizontal_alignment(alignment::Horizontal::Center), + ) + .style(grin_gui_core::theme::ButtonStyle::NormalText) + .on_press(Message::Interaction(Interaction::WriteToClipboard( + state.recovery_phrase.clone(), + ))), + ), + ) + .max_width(400.0) + .style(grin_gui_core::theme::CardStyle::Normal); - let submit_button_label_container = - Container::new(Text::new(localized_string("setup-grin-wallet-done")).size(DEFAULT_FONT_SIZE)) - .center_x() - .align_x(alignment::Horizontal::Center); + let submit_button_label_container = Container::new( + Text::new(localized_string("setup-grin-wallet-done")).size(DEFAULT_FONT_SIZE), + ) + .center_x() + .align_x(alignment::Horizontal::Center); - let next_button = Button::new(submit_button_label_container) - .style(grin_gui_core::theme::ButtonStyle::Bordered) - .on_press(Interaction::WalletSetupWalletSuccessViewInteraction( - LocalViewInteraction::Submit, - )); + let next_button = Button::new(submit_button_label_container) + .style(grin_gui_core::theme::ButtonStyle::Bordered) + .on_press(Interaction::WalletSetupWalletSuccessViewInteraction( + LocalViewInteraction::Submit, + )); - let next_button: Element = next_button.into(); + let next_button: Element = next_button.into(); - let unit_spacing = 15.0; + let unit_spacing = 15.0; - let colum = Column::new() - .push(title_row) - .push(Space::new( - Length::Fixed(0.0), - Length::Fixed(unit_spacing + 5.0), - )) - .push(description_container) - .push(Space::new( - Length::Fixed(0.0), - Length::Fixed(unit_spacing + 5.0), - )) - .push(recovery_phrase_card) - .push(Space::new( - Length::Fixed(0.0), - Length::Fixed(unit_spacing + 10.0), - )) - .push(next_button.map(Message::Interaction)) - .align_items(Alignment::Center); + let colum = Column::new() + .push(title_row) + .push(Space::new( + Length::Fixed(0.0), + Length::Fixed(unit_spacing + 5.0), + )) + .push(description_container) + .push(Space::new( + Length::Fixed(0.0), + Length::Fixed(unit_spacing + 5.0), + )) + .push(recovery_phrase_card) + .push(Space::new( + Length::Fixed(0.0), + Length::Fixed(unit_spacing + 10.0), + )) + .push(next_button.map(Message::Interaction)) + .align_items(Alignment::Center); - Container::new(colum) - .center_y() - .center_x() - .width(Length::Fill) + Container::new(colum) + .center_y() + .center_x() + .width(Length::Fill) } diff --git a/src/gui/mod.rs b/src/gui/mod.rs index 99dbff7..b827290 100644 --- a/src/gui/mod.rs +++ b/src/gui/mod.rs @@ -1,24 +1,27 @@ mod element; //mod style; -mod update; mod time; +mod update; use crate::cli::Opts; use crate::error_cause_string; -use crate::localization::{localized_string, LANG}; use crate::gui::element::{DEFAULT_FONT_SIZE, SMALLER_FONT_SIZE}; +use crate::localization::{localized_string, LANG}; use grin_gui_core::theme::Element; use grin_gui_core::{ - config::Config, - fs::PersistentData, - theme::{Theme, Container, Column, ColorPalette, Button, PickList, Row, Scrollable, Text}, - wallet::{WalletInterfaceHttpNodeClient, HTTPNodeClient, global, get_grin_wallet_default_path}, - node::{NodeInterface, subscriber::{self, UIMessage}, ChainTypes}, + config::Config, + fs::PersistentData, + node::{ + subscriber::{self, UIMessage}, + ChainTypes, NodeInterface, + }, + theme::{Button, ColorPalette, Column, Container, PickList, Row, Scrollable, Text, Theme}, + wallet::{get_grin_wallet_default_path, global, HTTPNodeClient, WalletInterfaceHttpNodeClient}, }; -use iced::{alignment, font, Alignment, Application, Command, Length, Subscription, Settings, window}; -use iced::widget::{ - button, pick_list, scrollable, text_input, Checkbox, Space, TextInput, +use iced::widget::{button, pick_list, scrollable, text_input, Checkbox, Space, TextInput}; +use iced::{ + alignment, font, window, Alignment, Application, Command, Length, Settings, Subscription, }; use iced_aw::{modal, Card, Modal}; @@ -31,238 +34,246 @@ use std::borrow::BorrowMut; //use std::collections::HashMap; use std::sync::{Arc, RwLock}; -use element::{DEFAULT_HEADER_FONT_SIZE}; +use element::DEFAULT_HEADER_FONT_SIZE; static WINDOW_ICON: &[u8] = include_bytes!("../../resources/windows/ajour.ico"); pub struct GrinGui { - /// Wallet Interface - wallet_interface: Arc>, + /// Wallet Interface + wallet_interface: Arc>, - /// Node Interface - node_interface: Arc>, + /// Node Interface + node_interface: Arc>, - error: Option, - mode: Mode, - config: Config, + error: Option, + mode: Mode, + config: Config, - /// Main menu state - menu_state: element::menu::StateContainer, + /// Main menu state + menu_state: element::menu::StateContainer, - /// Top-Level Wallet area state - wallet_state: element::wallet::StateContainer, + /// Top-Level Wallet area state + wallet_state: element::wallet::StateContainer, - /// Top-Level Node area state - node_state: element::node::StateContainer, + /// Top-Level Node area state + node_state: element::node::StateContainer, - /// Settings screen + sub-screens states - settings_state: element::settings::StateContainer, - wallet_settings_state: element::settings::wallet::StateContainer, - node_settings_state: element::settings::node::StateContainer, - general_settings_state: element::settings::general::StateContainer, + /// Settings screen + sub-screens states + settings_state: element::settings::StateContainer, + wallet_settings_state: element::settings::wallet::StateContainer, + node_settings_state: element::settings::node::StateContainer, + general_settings_state: element::settings::general::StateContainer, - /// About screen state - about_state: element::about::StateContainer, + /// About screen state + about_state: element::about::StateContainer, - show_modal: bool, - modal_type: ModalType, - exit: bool, - theme: Theme, + show_modal: bool, + modal_type: ModalType, + exit: bool, + theme: Theme, } impl GrinGui { - pub fn show_exit (&mut self, show: bool) { - self.show_modal = show; - if show { - self.modal_type = ModalType::Exit; - } else { - self.modal_type = ModalType::Error; - } - } - - pub fn safe_exit (&mut self) { - let mut node = self.node_interface.write().unwrap(); - node.shutdown_server(true); - } + pub fn show_exit(&mut self, show: bool) { + self.show_modal = show; + if show { + self.modal_type = ModalType::Exit; + } else { + self.modal_type = ModalType::Error; + } + } + + pub fn safe_exit(&mut self) { + let mut node = self.node_interface.write().unwrap(); + node.shutdown_server(true); + } } -impl GrinGui{ - fn from_config(config: &Config) -> Self { - - // Instantiate wallet node client - // TODO: Fill out - let node_url = "http://localhost:8080"; - let node_client = HTTPNodeClient::new(node_url, None).unwrap(); - - // restore theme from config - let name = config.theme.clone().unwrap_or("Alliance".to_string()); - let theme = Theme::all().iter().find(|t| t.0 == name).unwrap().1.clone(); - - Self { - wallet_interface: Arc::new(RwLock::new(WalletInterfaceHttpNodeClient::new(node_client))), - node_interface: Arc::new(RwLock::new(NodeInterface::new())), - error: None, - mode: Mode::Catalog, - config: Config::default(), - menu_state: Default::default(), - wallet_state: Default::default(), - node_state: Default::default(), - settings_state: Default::default(), - wallet_settings_state: Default::default(), - node_settings_state: Default::default(), - general_settings_state: Default::default(), - about_state: Default::default(), - show_modal: false, - modal_type: ModalType::Error, - exit: false, - theme, - } - } +impl GrinGui { + fn from_config(config: &Config) -> Self { + // Instantiate wallet node client + // TODO: Fill out + let node_url = "http://localhost:8080"; + let node_client = HTTPNodeClient::new(node_url, None).unwrap(); + + // restore theme from config + let name = config.theme.clone().unwrap_or("Alliance".to_string()); + let theme = Theme::all().iter().find(|t| t.0 == name).unwrap().1.clone(); + + Self { + wallet_interface: Arc::new(RwLock::new(WalletInterfaceHttpNodeClient::new( + node_client, + ))), + node_interface: Arc::new(RwLock::new(NodeInterface::new())), + error: None, + mode: Mode::Catalog, + config: Config::default(), + menu_state: Default::default(), + wallet_state: Default::default(), + node_state: Default::default(), + settings_state: Default::default(), + wallet_settings_state: Default::default(), + node_settings_state: Default::default(), + general_settings_state: Default::default(), + about_state: Default::default(), + show_modal: false, + modal_type: ModalType::Error, + exit: false, + theme, + } + } } #[derive(Clone, Debug)] #[allow(clippy::large_enum_variant)] pub enum Message { - Error(Arc>>), - SendNodeMessage((usize, UIMessage, Option>)), - Interaction(Interaction), - Tick(chrono::DateTime), - RuntimeEvent(iced_core::Event), - FontLoaded(Result<(), font::Error>), - None(()), + Error(Arc>>), + SendNodeMessage((usize, UIMessage, Option>)), + Interaction(Interaction), + Tick(chrono::DateTime), + RuntimeEvent(iced_core::Event), + FontLoaded(Result<(), font::Error>), + None(()), } pub enum ModalType { - Exit, - Error, + Exit, + Error, } impl Application for GrinGui { - type Executor = iced::executor::Default; - type Message = Message; - type Flags = Config; - type Theme = Theme; - - fn theme(&self) -> Theme { - self.theme.clone() - } - - fn new(config: Config) -> (Self, Command) { - let mut grin_gui = GrinGui::from_config(&config); - - // default Mainnet - global::set_local_chain_type(ChainTypes::Mainnet); - - if let Some(wallet_index) = config.current_wallet_index { - let wallet = config.wallets[wallet_index].clone(); - global::set_local_chain_type(wallet.chain_type); - } - - // Check initial wallet status - /*if !config.wallet.toml_file_path.is_some() - || !w.config_exists( - config - .wallet - .toml_file_path - .as_ref() - .unwrap() - .to_str() - .unwrap(), - ) - { - grin_gui.menu_state.mode = element::menu::Mode::Wallet; - }*/ - - apply_config(&mut grin_gui, config); - let load_font_reg = iced::font::load(include_bytes!("../../fonts/notosans-regular.ttf").as_slice()).map(Message::FontLoaded); - let load_font_bold = iced::font::load(include_bytes!("../../fonts/notosans-bold.ttf").as_slice()).map(Message::FontLoaded); - (grin_gui, Command::batch(vec![load_font_reg, load_font_bold])) - } - - fn title(&self) -> String { - String::from("Grin") - } - - fn scale_factor(&self) -> f64 { - self.general_settings_state.scale_state.scale - } - - /*#[cfg(target_os = "windows")] - fn mode(&self) -> iced::window::Mode { - use crate::tray::GUI_VISIBLE; - use iced::window::Mode; - use std::sync::atomic::Ordering; - - if GUI_VISIBLE.load(Ordering::Relaxed) { - Mode::Windowed - } else { - Mode::Hidden - } - }*/ - - fn subscription(&self) -> Subscription { - let runtime_subscription = iced_futures::subscription::events().map(Message::RuntimeEvent); - let tick_subscription = time::every(std::time::Duration::from_millis(1000)).map(Message::Tick); - let node_subscription = subscriber::subscriber(0).map(|e| - Message::SendNodeMessage(e) - ); - - iced::Subscription::batch(vec![runtime_subscription, tick_subscription, node_subscription]) - } - - fn update(&mut self, message: Message) -> Command { - match update::handle_message(self, message) { - Ok(x) => x, - Err(e) => Command::perform(async { Arc::new(RwLock::new(Some(e))) }, Message::Error), - } - } - - fn view(&self) -> Element { - let menu_state = self.menu_state.clone(); - - let mut content = Column::new().push(element::menu::data_container( - &self.menu_state, - &self.error, - )); - - // Spacer between menu and content. - //content = content.push(Space::new(Length::Fixed(0.0), Length::Fixed(DEFAULT_PADDING))); - match menu_state.mode { - element::menu::Mode::Wallet => { - let setup_container = element::wallet::data_container( - &self.wallet_state, - &self.config - ); - content = content.push(setup_container) - } - element::menu::Mode::Node => { - let chain_type = self.node_interface.read().unwrap().chain_type.unwrap_or_else( || ChainTypes::Mainnet); - let node_container = element::node::data_container( - &self.node_state, - chain_type, - ); - content = content.push(node_container) - } - element::menu::Mode::About => { - let about_container = - element::about::data_container(&None, &self.about_state); - content = content.push(about_container) - } - element::menu::Mode::Settings => { - content = content.push(element::settings::data_container( - &self.settings_state, - &self.config, - &self.wallet_settings_state, - &self.node_settings_state, - &self.general_settings_state, - )) - /*if let Some(settings_container) = views.get_mut(settings_view_index) { - content = content.push(settings_container.view.data_container) - }*/ - } - } - - let underlay: Element = + type Executor = iced::executor::Default; + type Message = Message; + type Flags = Config; + type Theme = Theme; + + fn theme(&self) -> Theme { + self.theme.clone() + } + + fn new(config: Config) -> (Self, Command) { + let mut grin_gui = GrinGui::from_config(&config); + + // default Mainnet + global::set_local_chain_type(ChainTypes::Mainnet); + + if let Some(wallet_index) = config.current_wallet_index { + let wallet = config.wallets[wallet_index].clone(); + global::set_local_chain_type(wallet.chain_type); + } + + // Check initial wallet status + /*if !config.wallet.toml_file_path.is_some() + || !w.config_exists( + config + .wallet + .toml_file_path + .as_ref() + .unwrap() + .to_str() + .unwrap(), + ) + { + grin_gui.menu_state.mode = element::menu::Mode::Wallet; + }*/ + + apply_config(&mut grin_gui, config); + let load_font_reg = + iced::font::load(include_bytes!("../../fonts/notosans-regular.ttf").as_slice()) + .map(Message::FontLoaded); + let load_font_bold = + iced::font::load(include_bytes!("../../fonts/notosans-bold.ttf").as_slice()) + .map(Message::FontLoaded); + ( + grin_gui, + Command::batch(vec![load_font_reg, load_font_bold]), + ) + } + + fn title(&self) -> String { + String::from("Grin") + } + + fn scale_factor(&self) -> f64 { + self.general_settings_state.scale_state.scale + } + + /*#[cfg(target_os = "windows")] + fn mode(&self) -> iced::window::Mode { + use crate::tray::GUI_VISIBLE; + use iced::window::Mode; + use std::sync::atomic::Ordering; + + if GUI_VISIBLE.load(Ordering::Relaxed) { + Mode::Windowed + } else { + Mode::Hidden + } + }*/ + + fn subscription(&self) -> Subscription { + let runtime_subscription = iced_futures::subscription::events().map(Message::RuntimeEvent); + let tick_subscription = + time::every(std::time::Duration::from_millis(1000)).map(Message::Tick); + let node_subscription = subscriber::subscriber(0).map(|e| Message::SendNodeMessage(e)); + + iced::Subscription::batch(vec![ + runtime_subscription, + tick_subscription, + node_subscription, + ]) + } + + fn update(&mut self, message: Message) -> Command { + match update::handle_message(self, message) { + Ok(x) => x, + Err(e) => Command::perform(async { Arc::new(RwLock::new(Some(e))) }, Message::Error), + } + } + + fn view(&self) -> Element { + let menu_state = self.menu_state.clone(); + + let mut content = + Column::new().push(element::menu::data_container(&self.menu_state, &self.error)); + + // Spacer between menu and content. + //content = content.push(Space::new(Length::Fixed(0.0), Length::Fixed(DEFAULT_PADDING))); + match menu_state.mode { + element::menu::Mode::Wallet => { + let setup_container = + element::wallet::data_container(&self.wallet_state, &self.config); + content = content.push(setup_container) + } + element::menu::Mode::Node => { + let chain_type = self + .node_interface + .read() + .unwrap() + .chain_type + .unwrap_or_else(|| ChainTypes::Mainnet); + let node_container = element::node::data_container(&self.node_state, chain_type); + content = content.push(node_container) + } + element::menu::Mode::About => { + let about_container = element::about::data_container(&None, &self.about_state); + content = content.push(about_container) + } + element::menu::Mode::Settings => { + content = content.push(element::settings::data_container( + &self.settings_state, + &self.config, + &self.wallet_settings_state, + &self.node_settings_state, + &self.general_settings_state, + )) + /*if let Some(settings_container) = views.get_mut(settings_view_index) { + content = content.push(settings_container.view.data_container) + }*/ + } + } + + let underlay: Element = // Wraps everything in a container. Container::new(content) .width(Length::Fill) @@ -270,438 +281,457 @@ impl Application for GrinGui { .style(grin_gui_core::theme::ContainerStyle::NormalBackground) .into(); - let content: Element = - match self.modal_type { - ModalType::Exit => element::modal::exit_card().into(), - ModalType::Error => { - let error_cause = self.error - .as_ref() - .map_or_else(|| "unknown error".to_owned(), |e| error_cause_string(e)); - - element::modal::error_card(error_cause.clone()).into() - } - }; - - Modal::new(self.show_modal, underlay, content) - .on_esc(Message::Interaction(Interaction::CloseErrorModal)) - .style(grin_gui_core::theme::ModalStyle::Normal) - .into() - - } + let content: Element = match self.modal_type { + ModalType::Exit => element::modal::exit_card().into(), + ModalType::Error => { + let error_cause = self + .error + .as_ref() + .map_or_else(|| "unknown error".to_owned(), |e| error_cause_string(e)); + + element::modal::error_card(error_cause.clone()).into() + } + }; + + Modal::new(self.show_modal, underlay, content) + .on_esc(Message::Interaction(Interaction::CloseErrorModal)) + .style(grin_gui_core::theme::ModalStyle::Normal) + .into() + } } /// Starts the GUI. /// This function does not return. pub fn run(opts: Opts, config: Config) { - // Set LANG using config (defaults to "en_US") - LANG.set(RwLock::new(config.language.language_code())) - .expect("setting LANG from config"); - - log::debug!("config loaded:\n{:#?}", &config); - - let mut settings = Settings::default(); - settings.window.size = config.window_size.unwrap_or((900, 620)); - - #[cfg(target_os = "macos")] - { - // false needed for Application shutdown - settings.exit_on_close_request = false; - } - - #[cfg(target_os = "windows")] - { - settings.exit_on_close_request = false; - } - - #[cfg(not(target_os = "linux"))] - // TODO (casperstorm): Due to an upstream bug, min_size causes the window to become unresizable - // on Linux. - // @see: https://github.com/ajour/ajour/issues/427 - { - settings.window.min_size = Some((600, 300)); - } - - #[cfg(feature = "wgpu")] - { - let antialiasing = opts.antialiasing.unwrap_or(true); - log::debug!("antialiasing: {}", antialiasing); - settings.antialiasing = antialiasing; - } - - #[cfg(feature = "opengl")] - { - let antialiasing = opts.antialiasing.unwrap_or(false); - log::debug!("antialiasing: {}", antialiasing); - settings.antialiasing = antialiasing; - } - - // Sets the Window icon. - let image = image::load_from_memory_with_format(WINDOW_ICON, ImageFormat::Ico) - .expect("loading icon") - .to_rgba8(); - let (width, height) = image.dimensions(); - let icon = iced_core::window::icon::from_rgba(image.into_raw(), width, height); - settings.window.icon = Some(icon.unwrap()); - - settings.flags = config; - - // Runs the GUI. - GrinGui::run(settings).expect("running Grin gui"); + // Set LANG using config (defaults to "en_US") + LANG.set(RwLock::new(config.language.language_code())) + .expect("setting LANG from config"); + + log::debug!("config loaded:\n{:#?}", &config); + + let mut settings = Settings::default(); + settings.window.size = config.window_size.unwrap_or((900, 620)); + + #[cfg(target_os = "macos")] + { + // false needed for Application shutdown + settings.exit_on_close_request = false; + } + + #[cfg(target_os = "windows")] + { + settings.exit_on_close_request = false; + } + + #[cfg(not(target_os = "linux"))] + // TODO (casperstorm): Due to an upstream bug, min_size causes the window to become unresizable + // on Linux. + // @see: https://github.com/ajour/ajour/issues/427 + { + settings.window.min_size = Some((600, 300)); + } + + #[cfg(feature = "wgpu")] + { + let antialiasing = opts.antialiasing.unwrap_or(true); + log::debug!("antialiasing: {}", antialiasing); + settings.antialiasing = antialiasing; + } + + #[cfg(feature = "opengl")] + { + let antialiasing = opts.antialiasing.unwrap_or(false); + log::debug!("antialiasing: {}", antialiasing); + settings.antialiasing = antialiasing; + } + + // Sets the Window icon. + let image = image::load_from_memory_with_format(WINDOW_ICON, ImageFormat::Ico) + .expect("loading icon") + .to_rgba8(); + let (width, height) = image.dimensions(); + let icon = iced_core::window::icon::from_rgba(image.into_raw(), width, height); + settings.window.icon = Some(icon.unwrap()); + + settings.flags = config; + + // Runs the GUI. + GrinGui::run(settings).expect("running Grin gui"); } #[derive(Debug)] pub enum State { - Ready, - Loading, - Error(anyhow::Error), + Ready, + Loading, + Error(anyhow::Error), } impl Default for State { - fn default() -> Self { - State::Ready - } + fn default() -> Self { + State::Ready + } } #[derive(Debug, Clone, Copy)] pub enum SelfUpdateStatus { - InProgress, - Failed, + InProgress, + Failed, } impl std::fmt::Display for SelfUpdateStatus { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - let s = match self { - SelfUpdateStatus::InProgress => localized_string("updating"), - SelfUpdateStatus::Failed => localized_string("failed"), - }; - write!(f, "{}", s) - } + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + let s = match self { + SelfUpdateStatus::InProgress => localized_string("updating"), + SelfUpdateStatus::Failed => localized_string("failed"), + }; + write!(f, "{}", s) + } } #[derive(Default, Debug)] pub struct SelfUpdateState { - status: Option, + status: Option, } #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub enum Mode { - Catalog, - Install, - Settings, - About, + Catalog, + Install, + Settings, + About, } #[derive(Debug, Clone)] #[allow(clippy::large_enum_variant)] pub enum Interaction { - /// Error modal - OpenErrorModal, - CloseErrorModal, - /// Clipboard copy - WriteToClipboard(String), - ReadSlatepackFromClipboard, - /// View interactions - MenuViewInteraction(element::menu::LocalViewInteraction), - SettingsViewInteraction(element::settings::LocalViewInteraction), - WalletSettingsViewInteraction(element::settings::wallet::LocalViewInteraction), - NodeSettingsViewInteraction(element::settings::node::LocalViewInteraction), - GeneralSettingsViewInteraction(element::settings::general::LocalViewInteraction), - GeneralSettingsViewImportTheme, - WalletSetupViewInteraction(element::wallet::setup::LocalViewInteraction), - WalletSetupInitViewInteraction(element::wallet::setup::init::LocalViewInteraction), - WalletSetupWalletViewInteraction(element::wallet::setup::wallet_setup::LocalViewInteraction), - WalletListWalletViewInteraction(element::wallet::setup::wallet_list::LocalViewInteraction), - WalletSetupWalletSuccessViewInteraction(element::wallet::setup::wallet_success::LocalViewInteraction), - WalletOperationOpenViewInteraction(element::wallet::operation::open::LocalViewInteraction), - WalletOperationHomeViewInteraction(element::wallet::operation::home::LocalViewInteraction), - WalletOperationTxListInteraction(element::wallet::operation::tx_list::LocalViewInteraction), - WalletOperationHomeTxListDisplayInteraction(element::wallet::operation::tx_list_display::LocalViewInteraction), - WalletOperationHomeActionMenuViewInteraction(element::wallet::operation::action_menu::LocalViewInteraction), - WalletOperationCreateTxViewInteraction(element::wallet::operation::create_tx::LocalViewInteraction), - WalletOperationApplyTxViewInteraction(element::wallet::operation::apply_tx::LocalViewInteraction), - WalletOperationApplyTxConfirmViewInteraction(element::wallet::operation::apply_tx_confirm::LocalViewInteraction), - WalletOperationShowSlatepackViewInteraction(element::wallet::operation::show_slatepack::LocalViewInteraction), - WalletOperationTxDetailViewInteraction(element::wallet::operation::tx_detail::LocalViewInteraction), - WalletOperationTxProofViewInteraction(element::wallet::operation::tx_proof::LocalViewInteraction), - WalletOperationTxDoneViewInteraction(element::wallet::operation::tx_done::LocalViewInteraction), - WalletOperationCreateTxContractsViewInteraction(element::wallet::operation::create_tx_contracts::LocalViewInteraction), - ViewInteraction(String, String), - ModeSelected(Mode), - ModeSelectedSettings(element::settings::Mode), - //Expand(ExpandType), - Ignore(String), - SelectBackupDirectory(), - OpenLink(String), - Unignore(String), - Update(String), - ScaleUp, - ScaleDown, - SortCatalogColumn(element::wallet::operation::tx_list::ColumnKey), - Backup, - ToggleHideIgnoredAddons(bool), - CatalogQuery(String), - InstallScmQuery(String), - InstallScmUrl, - UpdateGrin, - AlternatingRowColorToggled(bool), - KeybindingsToggle(bool), - #[cfg(target_os = "windows")] - ToggleCloseToTray(bool), - #[cfg(target_os = "windows")] - ToggleAutoStart(bool), - #[cfg(target_os = "windows")] - ToggleStartClosedToTray(bool), - - /// Application shutdown - Exit, - ExitCancel + /// Error modal + OpenErrorModal, + CloseErrorModal, + /// Clipboard copy + WriteToClipboard(String), + ReadSlatepackFromClipboard, + /// View interactions + MenuViewInteraction(element::menu::LocalViewInteraction), + SettingsViewInteraction(element::settings::LocalViewInteraction), + WalletSettingsViewInteraction(element::settings::wallet::LocalViewInteraction), + NodeSettingsViewInteraction(element::settings::node::LocalViewInteraction), + GeneralSettingsViewInteraction(element::settings::general::LocalViewInteraction), + GeneralSettingsViewImportTheme, + WalletSetupViewInteraction(element::wallet::setup::LocalViewInteraction), + WalletSetupInitViewInteraction(element::wallet::setup::init::LocalViewInteraction), + WalletSetupWalletViewInteraction(element::wallet::setup::wallet_setup::LocalViewInteraction), + WalletListWalletViewInteraction(element::wallet::setup::wallet_list::LocalViewInteraction), + WalletSetupWalletSuccessViewInteraction( + element::wallet::setup::wallet_success::LocalViewInteraction, + ), + WalletOperationOpenViewInteraction(element::wallet::operation::open::LocalViewInteraction), + WalletOperationHomeViewInteraction(element::wallet::operation::home::LocalViewInteraction), + WalletOperationTxListInteraction(element::wallet::operation::tx_list::LocalViewInteraction), + WalletOperationHomeTxListDisplayInteraction( + element::wallet::operation::tx_list_display::LocalViewInteraction, + ), + WalletOperationHomeActionMenuViewInteraction( + element::wallet::operation::action_menu::LocalViewInteraction, + ), + WalletOperationCreateTxViewInteraction( + element::wallet::operation::create_tx::LocalViewInteraction, + ), + WalletOperationApplyTxViewInteraction( + element::wallet::operation::apply_tx::LocalViewInteraction, + ), + WalletOperationApplyTxConfirmViewInteraction( + element::wallet::operation::apply_tx_confirm::LocalViewInteraction, + ), + WalletOperationShowSlatepackViewInteraction( + element::wallet::operation::show_slatepack::LocalViewInteraction, + ), + WalletOperationTxDetailViewInteraction( + element::wallet::operation::tx_detail::LocalViewInteraction, + ), + WalletOperationTxProofViewInteraction( + element::wallet::operation::tx_proof::LocalViewInteraction, + ), + WalletOperationTxDoneViewInteraction(element::wallet::operation::tx_done::LocalViewInteraction), + WalletOperationCreateTxContractsViewInteraction( + element::wallet::operation::create_tx_contracts::LocalViewInteraction, + ), + ViewInteraction(String, String), + ModeSelected(Mode), + ModeSelectedSettings(element::settings::Mode), + //Expand(ExpandType), + Ignore(String), + SelectBackupDirectory(), + OpenLink(String), + Unignore(String), + Update(String), + ScaleUp, + ScaleDown, + SortCatalogColumn(element::wallet::operation::tx_list::ColumnKey), + Backup, + ToggleHideIgnoredAddons(bool), + CatalogQuery(String), + InstallScmQuery(String), + InstallScmUrl, + UpdateGrin, + AlternatingRowColorToggled(bool), + KeybindingsToggle(bool), + #[cfg(target_os = "windows")] + ToggleCloseToTray(bool), + #[cfg(target_os = "windows")] + ToggleAutoStart(bool), + #[cfg(target_os = "windows")] + ToggleStartClosedToTray(bool), + + /// Application shutdown + Exit, + ExitCancel, } pub struct ThemeState { - themes: Vec<(String, Theme)>, - current_theme_name: String, - // pick_list_state: pick_list::State, - // input_state: text_input::State, - input_url: String, + themes: Vec<(String, Theme)>, + current_theme_name: String, + // pick_list_state: pick_list::State, + // input_state: text_input::State, + input_url: String, } impl Default for ThemeState { - fn default() -> Self { - let themes = Theme::all(); - - ThemeState { - themes, - current_theme_name: "Dark".to_string(), - input_url: Default::default(), - } - } + fn default() -> Self { + let themes = Theme::all(); + + ThemeState { + themes, + current_theme_name: "Dark".to_string(), + input_url: Default::default(), + } + } } fn apply_config(grin_gui: &mut GrinGui, mut config: Config) { - // Set column widths from the config - /*match &config.column_config { - ColumnConfig::V1 { - local_version_width, - remote_version_width, - status_width, - } => { - grin_gui - .header_state - .columns - .get_mut(1) - .as_mut() - .unwrap() - .width = Length::Fixed(*local_version_width); - grin_gui - .header_state - .columns - .get_mut(2) - .as_mut() - .unwrap() - .width = Length::Fixed(*remote_version_width); - grin_gui - .header_state - .columns - .get_mut(3) - .as_mut() - .unwrap() - .width = Length::Fixed(*status_width); - } - ColumnConfig::V2 { columns } => { - grin_gui.header_state.columns.iter_mut().for_each(|a| { - if let Some((idx, column)) = columns - .iter() - .enumerate() - .filter_map(|(idx, column)| { - if column.key == a.key.as_string() { - Some((idx, column)) - } else { - None - } - }) - .next() - { - a.width = column.width.map_or(Length::Fill, Length::Fixed); - a.hidden = column.hidden; - a.order = idx; - } - }); - - grin_gui.column_settings.columns.iter_mut().for_each(|a| { - if let Some(idx) = columns - .iter() - .enumerate() - .filter_map(|(idx, column)| { - if column.key == a.key.as_string() { - Some(idx) - } else { - None - } - }) - .next() - { - a.order = idx; - } - }); - - // My Addons - grin_gui.header_state.columns.sort_by_key(|c| c.order); - grin_gui.column_settings.columns.sort_by_key(|c| c.order); - } - ColumnConfig::V3 { - my_addons_columns, - catalog_columns, - aura_columns, - } => { - grin_gui.header_state.columns.iter_mut().for_each(|a| { - if let Some((idx, column)) = my_addons_columns - .iter() - .enumerate() - .filter_map(|(idx, column)| { - if column.key == a.key.as_string() { - Some((idx, column)) - } else { - None - } - }) - .next() - { - // Always force "Title" column as Length::Fill - // - // Shouldn't be an issue here, as it was for catalog column fix - // below, but will cover things in case anyone accidently manually - // modifies their config and sets a fixed width on this column. - a.width = if a.key == ColumnKey::Title { - Length::Fill - } else { - column.width.map_or(Length::Fill, Length::Fixed) - }; - - a.hidden = column.hidden; - a.order = idx; - } - }); - - grin_gui.column_settings.columns.iter_mut().for_each(|a| { - if let Some(idx) = my_addons_columns - .iter() - .enumerate() - .filter_map(|(idx, column)| { - if column.key == a.key.as_string() { - Some(idx) - } else { - None - } - }) - .next() - { - a.order = idx; - } - }); - - grin_gui - .catalog_column_settings - .columns - .iter_mut() - .for_each(|a| { - if let Some(idx) = catalog_columns - .iter() - .enumerate() - .filter_map(|(idx, column)| { - if column.key == a.key.as_string() { - Some(idx) - } else { - None - } - }) - .next() - { - a.order = idx; - } - }); - - grin_gui.catalog_header_state.columns.iter_mut().for_each(|a| { - if let Some((idx, column)) = catalog_columns - .iter() - .enumerate() - .filter_map(|(idx, column)| { - if column.key == a.key.as_string() { - Some((idx, column)) - } else { - None - } - }) - .next() - { - // Always force "Title" column as Length::Fill - // - // An older version of ajour used a different column as the fill - // column and some users have migration issues when updating to - // a newer version, causing NO columns to be set as Fill and - // making resizing columns work incorrectly - a.width = if a.key == CatalogColumnKey::Title { - Length::Fill - } else { - column.width.map_or(Length::Fill, Length::Fixed) - }; - - a.hidden = column.hidden; - a.order = idx; - } - }); - - grin_gui.aura_header_state.columns.iter_mut().for_each(|a| { - if let Some((_idx, column)) = aura_columns - .iter() - .enumerate() - .filter_map(|(idx, column)| { - if column.key == a.key.as_string() { - Some((idx, column)) - } else { - None - } - }) - .next() - { - // Always force "Title" column as Length::Fill - // - // An older version of ajour used a different column as the fill - // column and some users have migration issues when updating to - // a newer version, causing NO columns to be set as Fill and - // making resizing columns work incorrectly - a.width = if a.key == AuraColumnKey::Title { - Length::Fill - } else { - column.width.map_or(Length::Fill, Length::Fixed) - }; - } - }); - - // My Addons - grin_gui.header_state.columns.sort_by_key(|c| c.order); - grin_gui.column_settings.columns.sort_by_key(|c| c.order); - - // Catalog - grin_gui.catalog_header_state.columns.sort_by_key(|c| c.order); - grin_gui - .catalog_column_settings - .columns - .sort_by_key(|c| c.order); - - // No sorting on Aura columns currently - } - }*/ - - // Use theme from config. Set to "Dark" if not defined. - grin_gui - .general_settings_state - .theme_state - .current_theme_name = config.theme.as_deref().unwrap_or("Dark").to_string(); - - // Use scale from config. Set to 1.0 if not defined. - grin_gui.general_settings_state.scale_state.scale = config.scale.unwrap_or(1.0); - - grin_gui.config = config; - - let _ = &grin_gui.config.save(); + // Set column widths from the config + /*match &config.column_config { + ColumnConfig::V1 { + local_version_width, + remote_version_width, + status_width, + } => { + grin_gui + .header_state + .columns + .get_mut(1) + .as_mut() + .unwrap() + .width = Length::Fixed(*local_version_width); + grin_gui + .header_state + .columns + .get_mut(2) + .as_mut() + .unwrap() + .width = Length::Fixed(*remote_version_width); + grin_gui + .header_state + .columns + .get_mut(3) + .as_mut() + .unwrap() + .width = Length::Fixed(*status_width); + } + ColumnConfig::V2 { columns } => { + grin_gui.header_state.columns.iter_mut().for_each(|a| { + if let Some((idx, column)) = columns + .iter() + .enumerate() + .filter_map(|(idx, column)| { + if column.key == a.key.as_string() { + Some((idx, column)) + } else { + None + } + }) + .next() + { + a.width = column.width.map_or(Length::Fill, Length::Fixed); + a.hidden = column.hidden; + a.order = idx; + } + }); + + grin_gui.column_settings.columns.iter_mut().for_each(|a| { + if let Some(idx) = columns + .iter() + .enumerate() + .filter_map(|(idx, column)| { + if column.key == a.key.as_string() { + Some(idx) + } else { + None + } + }) + .next() + { + a.order = idx; + } + }); + + // My Addons + grin_gui.header_state.columns.sort_by_key(|c| c.order); + grin_gui.column_settings.columns.sort_by_key(|c| c.order); + } + ColumnConfig::V3 { + my_addons_columns, + catalog_columns, + aura_columns, + } => { + grin_gui.header_state.columns.iter_mut().for_each(|a| { + if let Some((idx, column)) = my_addons_columns + .iter() + .enumerate() + .filter_map(|(idx, column)| { + if column.key == a.key.as_string() { + Some((idx, column)) + } else { + None + } + }) + .next() + { + // Always force "Title" column as Length::Fill + // + // Shouldn't be an issue here, as it was for catalog column fix + // below, but will cover things in case anyone accidently manually + // modifies their config and sets a fixed width on this column. + a.width = if a.key == ColumnKey::Title { + Length::Fill + } else { + column.width.map_or(Length::Fill, Length::Fixed) + }; + + a.hidden = column.hidden; + a.order = idx; + } + }); + + grin_gui.column_settings.columns.iter_mut().for_each(|a| { + if let Some(idx) = my_addons_columns + .iter() + .enumerate() + .filter_map(|(idx, column)| { + if column.key == a.key.as_string() { + Some(idx) + } else { + None + } + }) + .next() + { + a.order = idx; + } + }); + + grin_gui + .catalog_column_settings + .columns + .iter_mut() + .for_each(|a| { + if let Some(idx) = catalog_columns + .iter() + .enumerate() + .filter_map(|(idx, column)| { + if column.key == a.key.as_string() { + Some(idx) + } else { + None + } + }) + .next() + { + a.order = idx; + } + }); + + grin_gui.catalog_header_state.columns.iter_mut().for_each(|a| { + if let Some((idx, column)) = catalog_columns + .iter() + .enumerate() + .filter_map(|(idx, column)| { + if column.key == a.key.as_string() { + Some((idx, column)) + } else { + None + } + }) + .next() + { + // Always force "Title" column as Length::Fill + // + // An older version of ajour used a different column as the fill + // column and some users have migration issues when updating to + // a newer version, causing NO columns to be set as Fill and + // making resizing columns work incorrectly + a.width = if a.key == CatalogColumnKey::Title { + Length::Fill + } else { + column.width.map_or(Length::Fill, Length::Fixed) + }; + + a.hidden = column.hidden; + a.order = idx; + } + }); + + grin_gui.aura_header_state.columns.iter_mut().for_each(|a| { + if let Some((_idx, column)) = aura_columns + .iter() + .enumerate() + .filter_map(|(idx, column)| { + if column.key == a.key.as_string() { + Some((idx, column)) + } else { + None + } + }) + .next() + { + // Always force "Title" column as Length::Fill + // + // An older version of ajour used a different column as the fill + // column and some users have migration issues when updating to + // a newer version, causing NO columns to be set as Fill and + // making resizing columns work incorrectly + a.width = if a.key == AuraColumnKey::Title { + Length::Fill + } else { + column.width.map_or(Length::Fill, Length::Fixed) + }; + } + }); + + // My Addons + grin_gui.header_state.columns.sort_by_key(|c| c.order); + grin_gui.column_settings.columns.sort_by_key(|c| c.order); + + // Catalog + grin_gui.catalog_header_state.columns.sort_by_key(|c| c.order); + grin_gui + .catalog_column_settings + .columns + .sort_by_key(|c| c.order); + + // No sorting on Aura columns currently + } + }*/ + + // Use theme from config. Set to "Dark" if not defined. + grin_gui + .general_settings_state + .theme_state + .current_theme_name = config.theme.as_deref().unwrap_or("Dark").to_string(); + + // Use scale from config. Set to 1.0 if not defined. + grin_gui.general_settings_state.scale_state.scale = config.scale.unwrap_or(1.0); + + grin_gui.config = config; + + let _ = &grin_gui.config.save(); } diff --git a/src/gui/time.rs b/src/gui/time.rs index 59587fc..aafc7ff 100644 --- a/src/gui/time.rs +++ b/src/gui/time.rs @@ -1,36 +1,32 @@ -use iced_futures::{ - self, - subscription -}; +use iced_futures::{self, subscription}; use iced_core::Hasher; use std::hash::Hash; pub fn every(duration: std::time::Duration) -> iced::Subscription> { - iced::Subscription::from_recipe(Every(duration)) + iced::Subscription::from_recipe(Every(duration)) } struct Every(std::time::Duration); -impl iced_futures::subscription::Recipe for Every -{ - type Output = chrono::DateTime; +impl iced_futures::subscription::Recipe for Every { + type Output = chrono::DateTime; - fn hash(&self, state: &mut Hasher) { - use std::hash::Hash; + fn hash(&self, state: &mut Hasher) { + use std::hash::Hash; - std::any::TypeId::of::().hash(state); - self.0.hash(state); - } + std::any::TypeId::of::().hash(state); + self.0.hash(state); + } - fn stream( - self: Box, - _input: subscription::EventStream, - ) -> futures::stream::BoxStream<'static, Self::Output> { - use futures::stream::StreamExt; + fn stream( + self: Box, + _input: subscription::EventStream, + ) -> futures::stream::BoxStream<'static, Self::Output> { + use futures::stream::StreamExt; - async_std::stream::interval(self.0) - .map(|_| chrono::Local::now()) - .boxed() - } + async_std::stream::interval(self.0) + .map(|_| chrono::Local::now()) + .boxed() + } } diff --git a/src/gui/update.rs b/src/gui/update.rs index 21b6eee..949ca11 100644 --- a/src/gui/update.rs +++ b/src/gui/update.rs @@ -1,13 +1,13 @@ use { - super::{GrinGui, Interaction, Message, Mode}, - crate::{gui::element, log_error, Result}, - grin_gui_core::{ - fs::PersistentData, node::subscriber::UIMessage, node::ChainTypes::Mainnet, - node::ChainTypes::Testnet, - }, - iced::{clipboard, Command}, - //grin_gui_widgets::header::ResizeEvent, - std::path::PathBuf, + super::{GrinGui, Interaction, Message, Mode}, + crate::{gui::element, log_error, Result}, + grin_gui_core::{ + fs::PersistentData, node::subscriber::UIMessage, node::ChainTypes::Mainnet, + node::ChainTypes::Testnet, + }, + iced::{clipboard, Command}, + //grin_gui_widgets::header::ResizeEvent, + std::path::PathBuf, }; use iced::window; @@ -18,445 +18,445 @@ use crate::tray::{TrayMessage, SHOULD_EXIT, TRAY_SENDER}; use std::sync::atomic::Ordering; pub fn handle_message(grin_gui: &mut GrinGui, message: Message) -> Result> { - if let Some(index) = grin_gui.config.current_wallet_index { - // Take opportunity to check if we don't have a wallet config file for some reason - if !grin_gui.wallet_state.config_missing() { - match &grin_gui.config.wallets[index].tld { - Some(t) => { - let wallet_interface = grin_gui.wallet_interface.clone(); - let r = wallet_interface.read(); - if let Ok(w) = r { - if !w.config_exists(t.to_str().unwrap()) { - grin_gui.wallet_state.set_config_missing(); - } - } - } - None => { - grin_gui.wallet_state.set_config_missing(); - } - } - } - - // Check if password needs entering in wallet mode - if !grin_gui.wallet_state.config_missing() - && !grin_gui.wallet_state.operation_state.wallet_not_open() - { - let wallet_interface = grin_gui.wallet_interface.clone(); - let r = wallet_interface.read(); - if let Ok(w) = r { - if !w.wallet_is_open() { - grin_gui.wallet_state.operation_state.set_wallet_not_open() - } - } - } - // Check if embedded node needs starting - if grin_gui.config.wallets[index].use_embedded_node { - let (node_started, has_ui_sender) = { - let n = grin_gui.node_interface.read().unwrap(); - (n.node_started, n.ui_sender.is_some()) - }; - - if !node_started && has_ui_sender { - let mut node = grin_gui.node_interface.write().unwrap(); - //let is_testnet = grin_gui.config.wallets[index].is_testnet; - let wallet_chain_type = grin_gui.config.wallets[index].chain_type; - - if !node_started { - node.start_server(wallet_chain_type); - } else { - let running_chain_type = { - let node = grin_gui.node_interface.read().unwrap(); - node.chain_type - } - .unwrap(); - - if running_chain_type != wallet_chain_type { - node.restart_server(wallet_chain_type); - } - } - } - } - } else { - if !grin_gui.wallet_state.config_missing() { - grin_gui.wallet_state.set_config_missing(); - } - } - - // Clear errors when necessary - match message { - Message::Interaction(Interaction::OpenErrorModal) => {} - Message::Interaction(Interaction::CloseErrorModal) => {} - Message::Interaction(Interaction::WriteToClipboard(_)) => {} - Message::Interaction(Interaction::ReadSlatepackFromClipboard) => {} - Message::Interaction(Interaction::WalletOperationHomeViewInteraction(ref i)) => match i { - element::wallet::operation::home::LocalViewInteraction::WalletInfoUpdateSuccess( - _, - _, - ) => {} - _ => { - grin_gui.error.take(); - () - } - }, - Message::Interaction(_) => { - grin_gui.error.take(); - } - _ => {} - } - - match message { - Message::FontLoaded(f) => { - debug!("Font Loaded: {:?}", f) - } - // Ticks, for stuff that happens frequently, like checking wallet status - Message::Tick(time) => { - // Call all views 'registered' for ticks - return element::wallet::operation::home::handle_tick(grin_gui, time); - } - // Update from embedded node server - Message::SendNodeMessage((_id, msg, sender)) => match sender { - Some(sender) => { - let mut n = grin_gui.node_interface.write().unwrap(); - n.set_ui_sender(sender); - return Ok(Command::none()); - } - None => { - match msg { - UIMessage::None => {} - UIMessage::UpdateStatus(stats) => { - grin_gui - .wallet_state - .operation_state - .home_state - .update_node_status(&stats); - grin_gui.node_state.embedded_state.server_stats = Some(stats); - } - } - return Ok(Command::none()); - } - }, - // Error modal state - Message::Interaction(Interaction::OpenErrorModal) => grin_gui.show_modal = true, - Message::Interaction(Interaction::CloseErrorModal) => grin_gui.show_modal = false, - // Clipboard messages - Message::Interaction(Interaction::WriteToClipboard(contents)) => { - return Ok(clipboard::write::(contents)); - } - Message::Interaction(Interaction::ReadSlatepackFromClipboard) => { - return Ok(clipboard::read::(|value| { - match value { + if let Some(index) = grin_gui.config.current_wallet_index { + // Take opportunity to check if we don't have a wallet config file for some reason + if !grin_gui.wallet_state.config_missing() { + match &grin_gui.config.wallets[index].tld { + Some(t) => { + let wallet_interface = grin_gui.wallet_interface.clone(); + let r = wallet_interface.read(); + if let Ok(w) = r { + if !w.config_exists(t.to_str().unwrap()) { + grin_gui.wallet_state.set_config_missing(); + } + } + } + None => { + grin_gui.wallet_state.set_config_missing(); + } + } + } + + // Check if password needs entering in wallet mode + if !grin_gui.wallet_state.config_missing() + && !grin_gui.wallet_state.operation_state.wallet_not_open() + { + let wallet_interface = grin_gui.wallet_interface.clone(); + let r = wallet_interface.read(); + if let Ok(w) = r { + if !w.wallet_is_open() { + grin_gui.wallet_state.operation_state.set_wallet_not_open() + } + } + } + // Check if embedded node needs starting + if grin_gui.config.wallets[index].use_embedded_node { + let (node_started, has_ui_sender) = { + let n = grin_gui.node_interface.read().unwrap(); + (n.node_started, n.ui_sender.is_some()) + }; + + if !node_started && has_ui_sender { + let mut node = grin_gui.node_interface.write().unwrap(); + //let is_testnet = grin_gui.config.wallets[index].is_testnet; + let wallet_chain_type = grin_gui.config.wallets[index].chain_type; + + if !node_started { + node.start_server(wallet_chain_type); + } else { + let running_chain_type = { + let node = grin_gui.node_interface.read().unwrap(); + node.chain_type + } + .unwrap(); + + if running_chain_type != wallet_chain_type { + node.restart_server(wallet_chain_type); + } + } + } + } + } else { + if !grin_gui.wallet_state.config_missing() { + grin_gui.wallet_state.set_config_missing(); + } + } + + // Clear errors when necessary + match message { + Message::Interaction(Interaction::OpenErrorModal) => {} + Message::Interaction(Interaction::CloseErrorModal) => {} + Message::Interaction(Interaction::WriteToClipboard(_)) => {} + Message::Interaction(Interaction::ReadSlatepackFromClipboard) => {} + Message::Interaction(Interaction::WalletOperationHomeViewInteraction(ref i)) => match i { + element::wallet::operation::home::LocalViewInteraction::WalletInfoUpdateSuccess( + _, + _, + ) => {} + _ => { + grin_gui.error.take(); + () + } + }, + Message::Interaction(_) => { + grin_gui.error.take(); + } + _ => {} + } + + match message { + Message::FontLoaded(f) => { + debug!("Font Loaded: {:?}", f) + } + // Ticks, for stuff that happens frequently, like checking wallet status + Message::Tick(time) => { + // Call all views 'registered' for ticks + return element::wallet::operation::home::handle_tick(grin_gui, time); + } + // Update from embedded node server + Message::SendNodeMessage((_id, msg, sender)) => match sender { + Some(sender) => { + let mut n = grin_gui.node_interface.write().unwrap(); + n.set_ui_sender(sender); + return Ok(Command::none()); + } + None => { + match msg { + UIMessage::None => {} + UIMessage::UpdateStatus(stats) => { + grin_gui + .wallet_state + .operation_state + .home_state + .update_node_status(&stats); + grin_gui.node_state.embedded_state.server_stats = Some(stats); + } + } + return Ok(Command::none()); + } + }, + // Error modal state + Message::Interaction(Interaction::OpenErrorModal) => grin_gui.show_modal = true, + Message::Interaction(Interaction::CloseErrorModal) => grin_gui.show_modal = false, + // Clipboard messages + Message::Interaction(Interaction::WriteToClipboard(contents)) => { + return Ok(clipboard::write::(contents)); + } + Message::Interaction(Interaction::ReadSlatepackFromClipboard) => { + return Ok(clipboard::read::(|value| { + match value { Some(v) => return Message::Interaction(Interaction::WalletOperationApplyTxViewInteraction(element::wallet::operation::apply_tx::LocalViewInteraction::ReadFromClipboardSuccess(v))), None => return Message::Interaction(Interaction::WalletOperationApplyTxViewInteraction(element::wallet::operation::apply_tx::LocalViewInteraction::ReadFromClipboardFailure)) } - })) - } // Top level menu - Message::Interaction(Interaction::MenuViewInteraction(l)) => { - let _ = element::menu::handle_message(grin_gui, l); - } - // Top level settings view - Message::Interaction(Interaction::SettingsViewInteraction(l)) => { - element::settings::handle_message(grin_gui, l); - } - // Settings -> Wallet Settings - Message::Interaction(Interaction::WalletSettingsViewInteraction(l)) => { - element::settings::wallet::handle_message(grin_gui, l); - } - // Settings -> Node Settings - Message::Interaction(Interaction::NodeSettingsViewInteraction(l)) => { - element::settings::node::handle_message(grin_gui, l); - } - - // Settings -> General Settings - Message::Interaction(Interaction::GeneralSettingsViewInteraction(l)) => { - return element::settings::general::handle_message(grin_gui, l); - } - // Setup Top Level - Message::Interaction(Interaction::WalletSetupViewInteraction(l)) => { - return element::wallet::setup::handle_message(grin_gui, l); - } - // Setup -> Initial View (To appear when no wallet toml file is set) - Message::Interaction(Interaction::WalletSetupInitViewInteraction(l)) => { - return element::wallet::setup::init::handle_message(grin_gui, l); - } - // Setup -> Wallet Init Settings - Message::Interaction(Interaction::WalletSetupWalletViewInteraction(l)) => { - return element::wallet::setup::wallet_setup::handle_message(grin_gui, l); - } - // Setup -> Wallet List - Message::Interaction(Interaction::WalletListWalletViewInteraction(l)) => { - return element::wallet::setup::wallet_list::handle_message(grin_gui, l); - } - // Setup -> Wallet Success Settings - Message::Interaction(Interaction::WalletSetupWalletSuccessViewInteraction(l)) => { - return element::wallet::setup::wallet_success::handle_message(grin_gui, l); - } - // Wallet -> Operation -> Open Settings - Message::Interaction(Interaction::WalletOperationOpenViewInteraction(l)) => { - return element::wallet::operation::open::handle_message(grin_gui, l); - } - // Wallet -> Operation -> Home Settings - Message::Interaction(Interaction::WalletOperationHomeViewInteraction(l)) => { - return element::wallet::operation::home::handle_message(grin_gui, l); - } - // Wallet -> Operation -> Home -> TxListDisplay Settings - Message::Interaction(Interaction::WalletOperationHomeTxListDisplayInteraction(l)) => { - return element::wallet::operation::tx_list_display::handle_message(grin_gui, l); - } - // Wallet -> Operation -> TxList - Message::Interaction(Interaction::WalletOperationTxListInteraction(l)) => { - return element::wallet::operation::tx_list::handle_message(grin_gui, l); - } - // Wallet -> Operation -> CreateTx - Message::Interaction(Interaction::WalletOperationCreateTxViewInteraction(l)) => { - return element::wallet::operation::create_tx::handle_message(grin_gui, l); - } - // Wallet -> Operation -> CreateTxSuccess - Message::Interaction(Interaction::WalletOperationShowSlatepackViewInteraction(l)) => { - return element::wallet::operation::show_slatepack::handle_message(grin_gui, l); - } - // Wallet -> Operation -> Home -> Action - Message::Interaction(Interaction::WalletOperationApplyTxViewInteraction(l)) => { - return element::wallet::operation::apply_tx::handle_message(grin_gui, l); - } - // Wallet -> Operation -> Home -> Action - Message::Interaction(Interaction::WalletOperationApplyTxConfirmViewInteraction(l)) => { - return element::wallet::operation::apply_tx_confirm::handle_message(grin_gui, l); - } - // Wallet -> Operation -> Home -> Action - Message::Interaction(Interaction::WalletOperationTxDetailViewInteraction(l)) => { - return element::wallet::operation::tx_detail::handle_message(grin_gui, l); - } - // Wallet -> Operation -> Proof -> Action - Message::Interaction(Interaction::WalletOperationTxProofViewInteraction(l)) => { - return element::wallet::operation::tx_proof::handle_message(grin_gui, l); - } - // Wallet -> Operation -> Home -> Action - Message::Interaction(Interaction::WalletOperationHomeActionMenuViewInteraction(l)) => { - return element::wallet::operation::action_menu::handle_message(grin_gui, l); - } - // Wallet -> Operation -> Home -> Action - Message::Interaction(Interaction::WalletOperationTxDoneViewInteraction(l)) => { - return element::wallet::operation::tx_done::handle_message(grin_gui, l); - } - // Wallet -> Operation -> CreateTxContract - Message::Interaction(Interaction::WalletOperationCreateTxContractsViewInteraction(l)) => { - return element::wallet::operation::create_tx_contracts::handle_message(grin_gui, l); - } - Message::Interaction(Interaction::ModeSelected(mode)) => { - log::debug!("Interaction::ModeSelected({:?})", mode); - // Set Mode - grin_gui.mode = mode; - } - /*Message::MessageInteraction(m) => { - m.handle_message() - }*/ - Message::Interaction(Interaction::ModeSelectedSettings(mode)) => { - log::debug!("Interaction::ModeSelectedSettings({:?})", mode); - // Set Mode - //grin_gui.settings_state.mode = mode; - } - Message::Error(error) => { - let mut e = error.write().unwrap(); - let err = e.take(); - if let Some(ref e) = err { - log_error(e); - } - grin_gui.error = err; - } - Message::RuntimeEvent(iced_core::Event::Window(iced_core::window::Event::Resized { - width, - height, - })) => { - let width = (width as f64 * grin_gui.general_settings_state.scale_state.scale) as u32; - let height = (height as f64 * grin_gui.general_settings_state.scale_state.scale) as u32; - - // Minimizing Grin GUI on Windows will call this function with 0, 0. - // We don't want to save that in config, because then it will start with zero size. - if width > 0 && height > 0 { - grin_gui.config.window_size = Some((width, height)); - let _ = grin_gui.config.save(); - } - } - - #[cfg(target_os = "macos")] - // Application shutdown - Message::RuntimeEvent(iced_core::Event::Window( - iced_core::window::Event::CloseRequested, - )) => { - log::debug!("Message::RuntimeEvent(CloseRequested)"); - grin_gui.show_exit(true); - } - - #[cfg(target_os = "windows")] - Message::RuntimeEvent(iced_core::Event::Window( - iced_core::window::Event::CloseRequested, - )) => { - log::debug!("Message::RuntimeEvent(CloseRequested)"); - - if let Some(sender) = TRAY_SENDER.get() { - if grin_gui.config.close_to_tray { - let _ = sender.try_send(TrayMessage::CloseToTray); - } else { - return Ok(window::close()); - } - } - } - Message::RuntimeEvent(iced_core::Event::Keyboard( - iced_core::keyboard::Event::KeyReleased { - key_code, - 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() - { - return Ok(Command::none()); - } - - match key_code { - iced::keyboard::KeyCode::A => {} - iced::keyboard::KeyCode::C => { - grin_gui.mode = Mode::Catalog; - } - iced::keyboard::KeyCode::R => {} - iced::keyboard::KeyCode::S => { - grin_gui.mode = Mode::Settings; - } - iced::keyboard::KeyCode::U => {} - iced::keyboard::KeyCode::W => {} - iced::keyboard::KeyCode::I => { - grin_gui.mode = Mode::Install; - } - iced::keyboard::KeyCode::Escape => match grin_gui.mode { - _ => (), - }, - _ => (), - } - } - #[cfg(target_os = "windows")] - Message::Interaction(Interaction::ToggleCloseToTray(enable)) => { - log::debug!("Interaction::ToggleCloseToTray({})", enable); - - grin_gui.config.close_to_tray = enable; - - // Remove start closed to tray if we are disabling - if !enable { - grin_gui.config.start_closed_to_tray = false; - } - - let _ = grin_gui.config.save(); - - if let Some(sender) = TRAY_SENDER.get() { - let msg = if enable { - TrayMessage::Enable - } else { - TrayMessage::Disable - }; - - let _ = sender.try_send(msg); - } - } - #[cfg(target_os = "windows")] - Message::Interaction(Interaction::ToggleAutoStart(enable)) => { - log::debug!("Interaction::ToggleAutoStart({})", enable); - - grin_gui.config.autostart = enable; - - let _ = grin_gui.config.save(); - - if let Some(sender) = TRAY_SENDER.get() { - let _ = sender.try_send(TrayMessage::ToggleAutoStart(enable)); - } - } - #[cfg(target_os = "windows")] - Message::Interaction(Interaction::ToggleStartClosedToTray(enable)) => { - log::debug!("Interaction::ToggleStartClosedToTray({})", enable); - - grin_gui.config.start_closed_to_tray = enable; - - // Enable tray if this feature is enabled - if enable && !grin_gui.config.close_to_tray { - grin_gui.config.close_to_tray = true; - - if let Some(sender) = TRAY_SENDER.get() { - let _ = sender.try_send(TrayMessage::Enable); - } - } - - let _ = grin_gui.config.save(); - } - Message::Interaction(Interaction::OpenLink(link)) => { - log::debug!("Interaction::OpenLink({})", &link); - - return Ok(Command::perform( - async { - let _ = opener::open(link); - }, - Message::None, - )); - } - // Application shutdown - Message::Interaction(Interaction::Exit) => { - grin_gui.safe_exit(); - return Ok(window::close()); - } - Message::Interaction(Interaction::ExitCancel) => { - grin_gui.show_exit(false); - } - Message::Interaction(_) => {} - Message::RuntimeEvent(_) => {} - Message::None(_) => {} - } - - #[cfg(target_os = "windows")] - if SHOULD_EXIT.load(Ordering::Relaxed) { - return Ok(window::close()); - } - - Ok(Command::none()) + })) + } // Top level menu + Message::Interaction(Interaction::MenuViewInteraction(l)) => { + let _ = element::menu::handle_message(grin_gui, l); + } + // Top level settings view + Message::Interaction(Interaction::SettingsViewInteraction(l)) => { + element::settings::handle_message(grin_gui, l); + } + // Settings -> Wallet Settings + Message::Interaction(Interaction::WalletSettingsViewInteraction(l)) => { + element::settings::wallet::handle_message(grin_gui, l); + } + // Settings -> Node Settings + Message::Interaction(Interaction::NodeSettingsViewInteraction(l)) => { + element::settings::node::handle_message(grin_gui, l); + } + + // Settings -> General Settings + Message::Interaction(Interaction::GeneralSettingsViewInteraction(l)) => { + return element::settings::general::handle_message(grin_gui, l); + } + // Setup Top Level + Message::Interaction(Interaction::WalletSetupViewInteraction(l)) => { + return element::wallet::setup::handle_message(grin_gui, l); + } + // Setup -> Initial View (To appear when no wallet toml file is set) + Message::Interaction(Interaction::WalletSetupInitViewInteraction(l)) => { + return element::wallet::setup::init::handle_message(grin_gui, l); + } + // Setup -> Wallet Init Settings + Message::Interaction(Interaction::WalletSetupWalletViewInteraction(l)) => { + return element::wallet::setup::wallet_setup::handle_message(grin_gui, l); + } + // Setup -> Wallet List + Message::Interaction(Interaction::WalletListWalletViewInteraction(l)) => { + return element::wallet::setup::wallet_list::handle_message(grin_gui, l); + } + // Setup -> Wallet Success Settings + Message::Interaction(Interaction::WalletSetupWalletSuccessViewInteraction(l)) => { + return element::wallet::setup::wallet_success::handle_message(grin_gui, l); + } + // Wallet -> Operation -> Open Settings + Message::Interaction(Interaction::WalletOperationOpenViewInteraction(l)) => { + return element::wallet::operation::open::handle_message(grin_gui, l); + } + // Wallet -> Operation -> Home Settings + Message::Interaction(Interaction::WalletOperationHomeViewInteraction(l)) => { + return element::wallet::operation::home::handle_message(grin_gui, l); + } + // Wallet -> Operation -> Home -> TxListDisplay Settings + Message::Interaction(Interaction::WalletOperationHomeTxListDisplayInteraction(l)) => { + return element::wallet::operation::tx_list_display::handle_message(grin_gui, l); + } + // Wallet -> Operation -> TxList + Message::Interaction(Interaction::WalletOperationTxListInteraction(l)) => { + return element::wallet::operation::tx_list::handle_message(grin_gui, l); + } + // Wallet -> Operation -> CreateTx + Message::Interaction(Interaction::WalletOperationCreateTxViewInteraction(l)) => { + return element::wallet::operation::create_tx::handle_message(grin_gui, l); + } + // Wallet -> Operation -> CreateTxSuccess + Message::Interaction(Interaction::WalletOperationShowSlatepackViewInteraction(l)) => { + return element::wallet::operation::show_slatepack::handle_message(grin_gui, l); + } + // Wallet -> Operation -> Home -> Action + Message::Interaction(Interaction::WalletOperationApplyTxViewInteraction(l)) => { + return element::wallet::operation::apply_tx::handle_message(grin_gui, l); + } + // Wallet -> Operation -> Home -> Action + Message::Interaction(Interaction::WalletOperationApplyTxConfirmViewInteraction(l)) => { + return element::wallet::operation::apply_tx_confirm::handle_message(grin_gui, l); + } + // Wallet -> Operation -> Home -> Action + Message::Interaction(Interaction::WalletOperationTxDetailViewInteraction(l)) => { + return element::wallet::operation::tx_detail::handle_message(grin_gui, l); + } + // Wallet -> Operation -> Proof -> Action + Message::Interaction(Interaction::WalletOperationTxProofViewInteraction(l)) => { + return element::wallet::operation::tx_proof::handle_message(grin_gui, l); + } + // Wallet -> Operation -> Home -> Action + Message::Interaction(Interaction::WalletOperationHomeActionMenuViewInteraction(l)) => { + return element::wallet::operation::action_menu::handle_message(grin_gui, l); + } + // Wallet -> Operation -> Home -> Action + Message::Interaction(Interaction::WalletOperationTxDoneViewInteraction(l)) => { + return element::wallet::operation::tx_done::handle_message(grin_gui, l); + } + // Wallet -> Operation -> CreateTxContract + Message::Interaction(Interaction::WalletOperationCreateTxContractsViewInteraction(l)) => { + return element::wallet::operation::create_tx_contracts::handle_message(grin_gui, l); + } + Message::Interaction(Interaction::ModeSelected(mode)) => { + log::debug!("Interaction::ModeSelected({:?})", mode); + // Set Mode + grin_gui.mode = mode; + } + /*Message::MessageInteraction(m) => { + m.handle_message() + }*/ + Message::Interaction(Interaction::ModeSelectedSettings(mode)) => { + log::debug!("Interaction::ModeSelectedSettings({:?})", mode); + // Set Mode + //grin_gui.settings_state.mode = mode; + } + Message::Error(error) => { + let mut e = error.write().unwrap(); + let err = e.take(); + if let Some(ref e) = err { + log_error(e); + } + grin_gui.error = err; + } + Message::RuntimeEvent(iced_core::Event::Window(iced_core::window::Event::Resized { + width, + height, + })) => { + let width = (width as f64 * grin_gui.general_settings_state.scale_state.scale) as u32; + let height = (height as f64 * grin_gui.general_settings_state.scale_state.scale) as u32; + + // Minimizing Grin GUI on Windows will call this function with 0, 0. + // We don't want to save that in config, because then it will start with zero size. + if width > 0 && height > 0 { + grin_gui.config.window_size = Some((width, height)); + let _ = grin_gui.config.save(); + } + } + + #[cfg(target_os = "macos")] + // Application shutdown + Message::RuntimeEvent(iced_core::Event::Window( + iced_core::window::Event::CloseRequested, + )) => { + log::debug!("Message::RuntimeEvent(CloseRequested)"); + grin_gui.show_exit(true); + } + + #[cfg(target_os = "windows")] + Message::RuntimeEvent(iced_core::Event::Window( + iced_core::window::Event::CloseRequested, + )) => { + log::debug!("Message::RuntimeEvent(CloseRequested)"); + + if let Some(sender) = TRAY_SENDER.get() { + if grin_gui.config.close_to_tray { + let _ = sender.try_send(TrayMessage::CloseToTray); + } else { + return Ok(window::close()); + } + } + } + Message::RuntimeEvent(iced_core::Event::Keyboard( + iced_core::keyboard::Event::KeyReleased { + key_code, + 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() + { + return Ok(Command::none()); + } + + match key_code { + iced::keyboard::KeyCode::A => {} + iced::keyboard::KeyCode::C => { + grin_gui.mode = Mode::Catalog; + } + iced::keyboard::KeyCode::R => {} + iced::keyboard::KeyCode::S => { + grin_gui.mode = Mode::Settings; + } + iced::keyboard::KeyCode::U => {} + iced::keyboard::KeyCode::W => {} + iced::keyboard::KeyCode::I => { + grin_gui.mode = Mode::Install; + } + iced::keyboard::KeyCode::Escape => match grin_gui.mode { + _ => (), + }, + _ => (), + } + } + #[cfg(target_os = "windows")] + Message::Interaction(Interaction::ToggleCloseToTray(enable)) => { + log::debug!("Interaction::ToggleCloseToTray({})", enable); + + grin_gui.config.close_to_tray = enable; + + // Remove start closed to tray if we are disabling + if !enable { + grin_gui.config.start_closed_to_tray = false; + } + + let _ = grin_gui.config.save(); + + if let Some(sender) = TRAY_SENDER.get() { + let msg = if enable { + TrayMessage::Enable + } else { + TrayMessage::Disable + }; + + let _ = sender.try_send(msg); + } + } + #[cfg(target_os = "windows")] + Message::Interaction(Interaction::ToggleAutoStart(enable)) => { + log::debug!("Interaction::ToggleAutoStart({})", enable); + + grin_gui.config.autostart = enable; + + let _ = grin_gui.config.save(); + + if let Some(sender) = TRAY_SENDER.get() { + let _ = sender.try_send(TrayMessage::ToggleAutoStart(enable)); + } + } + #[cfg(target_os = "windows")] + Message::Interaction(Interaction::ToggleStartClosedToTray(enable)) => { + log::debug!("Interaction::ToggleStartClosedToTray({})", enable); + + grin_gui.config.start_closed_to_tray = enable; + + // Enable tray if this feature is enabled + if enable && !grin_gui.config.close_to_tray { + grin_gui.config.close_to_tray = true; + + if let Some(sender) = TRAY_SENDER.get() { + let _ = sender.try_send(TrayMessage::Enable); + } + } + + let _ = grin_gui.config.save(); + } + Message::Interaction(Interaction::OpenLink(link)) => { + log::debug!("Interaction::OpenLink({})", &link); + + return Ok(Command::perform( + async { + let _ = opener::open(link); + }, + Message::None, + )); + } + // Application shutdown + Message::Interaction(Interaction::Exit) => { + grin_gui.safe_exit(); + return Ok(window::close()); + } + Message::Interaction(Interaction::ExitCancel) => { + grin_gui.show_exit(false); + } + Message::Interaction(_) => {} + Message::RuntimeEvent(_) => {} + Message::None(_) => {} + } + + #[cfg(target_os = "windows")] + if SHOULD_EXIT.load(Ordering::Relaxed) { + return Ok(window::close()); + } + + Ok(Command::none()) } #[cfg(not(target_os = "linux"))] async fn select_directory() -> Option { - use rfd::AsyncFileDialog; + use rfd::AsyncFileDialog; - let dialog = AsyncFileDialog::new(); - if let Some(show) = dialog.pick_folder().await { - return Some(show.path().to_path_buf()); - } + let dialog = AsyncFileDialog::new(); + if let Some(show) = dialog.pick_folder().await { + return Some(show.path().to_path_buf()); + } - None + None } #[cfg(target_os = "linux")] async fn select_directory() -> Option { - use native_dialog::FileDialog; + use native_dialog::FileDialog; - let dialog = FileDialog::new(); - if let Ok(Some(show)) = dialog.show_open_single_dir() { - return Some(show); - } + let dialog = FileDialog::new(); + if let Ok(Some(show)) = dialog.show_open_single_dir() { + return Some(show); + } - None + None } /// Hardcoded binary names for each compilation target /// that gets published to the Github Release const fn bin_name() -> &'static str { - #[cfg(target_os = "windows")] - { - "grin-gui.exe" - } - - #[cfg(target_os = "macos")] - { - "grin-gui" - } - - #[cfg(target_os = "linux")] - { - "grin-gui.AppImage" - } + #[cfg(target_os = "windows")] + { + "grin-gui.exe" + } + + #[cfg(target_os = "macos")] + { + "grin-gui" + } + + #[cfg(target_os = "linux")] + { + "grin-gui.AppImage" + } } diff --git a/src/localization.rs b/src/localization.rs index 387e4b2..fa39289 100644 --- a/src/localization.rs +++ b/src/localization.rs @@ -4,44 +4,44 @@ use once_cell::sync::{Lazy, OnceCell}; use std::sync::RwLock; pub static LOCALIZATION_CTX: Lazy> = Lazy::new(|| { - static_json_gettext_build!( - "en_US", - "en_US", - "locale/en.json", - "de_DE", - "locale/de.json" - ) - .unwrap() + static_json_gettext_build!( + "en_US", + "en_US", + "locale/en.json", + "de_DE", + "locale/de.json" + ) + .unwrap() }); pub static LANG: OnceCell> = OnceCell::new(); pub fn localized_string(key: &str) -> String { - let lang = LANG.get().expect("LANG not set").read().unwrap(); + let lang = LANG.get().expect("LANG not set").read().unwrap(); - if let Some(text) = get_text!(LOCALIZATION_CTX, *lang, key) { - let text = text.to_string(); - if text.is_empty() { - key.to_owned() - } else { - text - } - } else { - key.to_owned() - } + if let Some(text) = get_text!(LOCALIZATION_CTX, *lang, key) { + let text = text.to_string(); + if text.is_empty() { + key.to_owned() + } else { + text + } + } else { + key.to_owned() + } } /// Returns a localized `timeago::Formatter`. /// If user has chosen a language whic his not supported by `timeago` we fallback to english. pub fn localized_timeago_formatter() -> timeago::Formatter> { - let lang = LANG.get().expect("LANG not set").read().unwrap(); - let isolang = isolang::Language::from_locale(&lang).unwrap(); + let lang = LANG.get().expect("LANG not set").read().unwrap(); + let isolang = isolang::Language::from_locale(&lang).unwrap(); - // this step might fail if timeago does not support the chosen language. - // In that case we fallback to `en_US`. - if let Some(timeago_lang) = timeago::from_isolang(isolang) { - timeago::Formatter::with_language(timeago_lang) - } else { - timeago::Formatter::with_language(Box::new(timeago::English)) - } + // this step might fail if timeago does not support the chosen language. + // In that case we fallback to `en_US`. + if let Some(timeago_lang) = timeago::from_isolang(isolang) { + timeago::Formatter::with_language(timeago_lang) + } else { + timeago::Formatter::with_language(Box::new(timeago::English)) + } } diff --git a/src/process.rs b/src/process.rs index c77b5b1..185558e 100644 --- a/src/process.rs +++ b/src/process.rs @@ -4,93 +4,93 @@ use std::path::PathBuf; use grin_gui_core::fs::PersistentData; use serde::{Deserialize, Serialize}; use winapi::{ - shared::winerror::WAIT_TIMEOUT, - um::{ - processthreadsapi::{GetCurrentProcess, GetCurrentProcessId, OpenProcess}, - synchapi::WaitForSingleObject, - winbase::QueryFullProcessImageNameW, - winnt::{PROCESS_QUERY_LIMITED_INFORMATION, SYNCHRONIZE}, - }, + shared::winerror::WAIT_TIMEOUT, + um::{ + processthreadsapi::{GetCurrentProcess, GetCurrentProcessId, OpenProcess}, + synchapi::WaitForSingleObject, + winbase::QueryFullProcessImageNameW, + winnt::{PROCESS_QUERY_LIMITED_INFORMATION, SYNCHRONIZE}, + }, }; #[derive(Debug, Serialize, Deserialize)] struct Process { - pid: u32, - name: String, + pid: u32, + name: String, } impl PersistentData for Process { - fn relative_path() -> PathBuf { - PathBuf::from("pid") - } + fn relative_path() -> PathBuf { + PathBuf::from("pid") + } } pub fn avoid_multiple_instances() { - if process_already_running() { - log::info!("Another instance of Grin GUI is already running. Exiting..."); - std::process::exit(0); - } else { - // Otherwise this is the only instance. Save info about this process to the - // pid file so future launches of Grin GUI can detect this running process. - save_current_process_file(); - } + if process_already_running() { + log::info!("Another instance of Grin GUI is already running. Exiting..."); + std::process::exit(0); + } else { + // Otherwise this is the only instance. Save info about this process to the + // pid file so future launches of Grin GUI can detect this running process. + save_current_process_file(); + } } fn process_already_running() -> bool { - let old_process = if let Ok(process) = Process::load() { - process - } else { - return false; - }; - - unsafe { - let current_pid = GetCurrentProcessId(); - - // In case new process somehow got recycled PID of old process - if current_pid == old_process.pid { - return false; - } - - let handle = OpenProcess( - SYNCHRONIZE | PROCESS_QUERY_LIMITED_INFORMATION, - 0, - old_process.pid, - ); - - if let Some(name) = get_process_name(handle) { - if name == old_process.name { - let status = WaitForSingleObject(handle, 0); - - return status == WAIT_TIMEOUT; - } - } - } - - false + let old_process = if let Ok(process) = Process::load() { + process + } else { + return false; + }; + + unsafe { + let current_pid = GetCurrentProcessId(); + + // In case new process somehow got recycled PID of old process + if current_pid == old_process.pid { + return false; + } + + let handle = OpenProcess( + SYNCHRONIZE | PROCESS_QUERY_LIMITED_INFORMATION, + 0, + old_process.pid, + ); + + if let Some(name) = get_process_name(handle) { + if name == old_process.name { + let status = WaitForSingleObject(handle, 0); + + return status == WAIT_TIMEOUT; + } + } + } + + false } fn save_current_process_file() { - unsafe { - let handle = GetCurrentProcess(); - let pid = GetCurrentProcessId(); + unsafe { + let handle = GetCurrentProcess(); + let pid = GetCurrentProcessId(); - if let Some(name) = get_process_name(handle) { - let process = Process { pid, name }; + if let Some(name) = get_process_name(handle) { + let process = Process { pid, name }; - let _ = process.save(); - } - } + let _ = process.save(); + } + } } unsafe fn get_process_name(handle: *mut c_void) -> Option { - let mut size = 256; - let mut buffer = [0u16; 256]; + let mut size = 256; + let mut buffer = [0u16; 256]; - let status = QueryFullProcessImageNameW(handle, 0, buffer.as_mut_ptr(), &mut size); + let status = QueryFullProcessImageNameW(handle, 0, buffer.as_mut_ptr(), &mut size); - if status != 0 { - String::from_utf16(&buffer[..(size as usize).min(buffer.len())]).ok() - } else { - None - } + if status != 0 { + String::from_utf16(&buffer[..(size as usize).min(buffer.len())]).ok() + } else { + None + } } diff --git a/src/tray/autostart.rs b/src/tray/autostart.rs index 3d584b0..08f4415 100644 --- a/src/tray/autostart.rs +++ b/src/tray/autostart.rs @@ -3,8 +3,8 @@ use std::fs; use std::mem; use std::ptr; -use grin_gui_core::fs::CONFIG_DIR; use anyhow::Error; +use grin_gui_core::fs::CONFIG_DIR; use winapi::shared::minwindef::HKEY; use winapi::um::winnt::{KEY_SET_VALUE, REG_OPTION_NON_VOLATILE, REG_SZ}; use winapi::um::winreg::{RegCreateKeyExW, RegDeleteKeyValueW, RegSetValueExW, HKEY_CURRENT_USER}; @@ -12,50 +12,50 @@ use winapi::um::winreg::{RegCreateKeyExW, RegDeleteKeyValueW, RegSetValueExW, HK use crate::str_to_wide; pub unsafe fn toggle_autostart(enabled: bool) -> Result<(), Error> { - let mut app_path = CONFIG_DIR.lock().unwrap().to_owned(); - app_path.push("grin-gui.exe"); - - // Copy Grin GUI to config directory so we can autostart it from there - let current_path = env::current_exe()?; - if current_path != app_path && enabled { - fs::copy(current_path, &app_path)?; - } - - let app_path = str_to_wide!(app_path.to_str().unwrap_or_default()); - let mut key_name = str_to_wide!("Software\\Microsoft\\Windows\\CurrentVersion\\Run"); - let mut value_name = str_to_wide!("grin-gui"); - - let mut key: HKEY = mem::zeroed(); - - if enabled { - if RegCreateKeyExW( - HKEY_CURRENT_USER, - key_name.as_mut_ptr(), - 0, - ptr::null_mut(), - REG_OPTION_NON_VOLATILE, - KEY_SET_VALUE, - ptr::null_mut(), - &mut key, - ptr::null_mut(), - ) == 0 - { - RegSetValueExW( - key, - value_name.as_mut_ptr(), - 0, - REG_SZ, - app_path.as_ptr() as _, - app_path.len() as u32 * 2, - ); - } - } else { - RegDeleteKeyValueW( - HKEY_CURRENT_USER, - key_name.as_mut_ptr(), - value_name.as_mut_ptr(), - ); - } - - Ok(()) + let mut app_path = CONFIG_DIR.lock().unwrap().to_owned(); + app_path.push("grin-gui.exe"); + + // Copy Grin GUI to config directory so we can autostart it from there + let current_path = env::current_exe()?; + if current_path != app_path && enabled { + fs::copy(current_path, &app_path)?; + } + + let app_path = str_to_wide!(app_path.to_str().unwrap_or_default()); + let mut key_name = str_to_wide!("Software\\Microsoft\\Windows\\CurrentVersion\\Run"); + let mut value_name = str_to_wide!("grin-gui"); + + let mut key: HKEY = mem::zeroed(); + + if enabled { + if RegCreateKeyExW( + HKEY_CURRENT_USER, + key_name.as_mut_ptr(), + 0, + ptr::null_mut(), + REG_OPTION_NON_VOLATILE, + KEY_SET_VALUE, + ptr::null_mut(), + &mut key, + ptr::null_mut(), + ) == 0 + { + RegSetValueExW( + key, + value_name.as_mut_ptr(), + 0, + REG_SZ, + app_path.as_ptr() as _, + app_path.len() as u32 * 2, + ); + } + } else { + RegDeleteKeyValueW( + HKEY_CURRENT_USER, + key_name.as_mut_ptr(), + value_name.as_mut_ptr(), + ); + } + + Ok(()) } diff --git a/src/tray/mod.rs b/src/tray/mod.rs index b419402..e9cfa07 100644 --- a/src/tray/mod.rs +++ b/src/tray/mod.rs @@ -8,24 +8,24 @@ use once_cell::sync::OnceCell; use winapi::shared::windef::{HWND, POINT}; use winapi::um::libloaderapi::GetModuleHandleW; use winapi::um::shellapi::{ - Shell_NotifyIconW, NIF_ICON, NIF_INFO, NIF_MESSAGE, NIF_TIP, NIIF_NONE, NIIF_NOSOUND, NIM_ADD, - NIM_DELETE, NIM_MODIFY, NOTIFYICONDATAW, + Shell_NotifyIconW, NIF_ICON, NIF_INFO, NIF_MESSAGE, NIF_TIP, NIIF_NONE, NIIF_NOSOUND, NIM_ADD, + NIM_DELETE, NIM_MODIFY, NOTIFYICONDATAW, }; use winapi::um::wingdi::{CreateSolidBrush, RGB}; use winapi::um::winuser::{ - CreatePopupMenu, CreateWindowExW, DefWindowProcW, DestroyMenu, DestroyWindow, DispatchMessageW, - EnumWindows, GetCursorPos, GetMessageW, GetWindowLongPtrW, GetWindowTextW, - GetWindowThreadProcessId, InsertMenuW, LoadIconW, MessageBoxW, PostMessageW, PostQuitMessage, - RegisterClassExW, SendMessageW, SetFocus, SetForegroundWindow, SetMenuDefaultItem, - SetWindowLongPtrW, ShowWindow, TrackPopupMenu, TranslateMessage, CREATESTRUCTW, GWLP_USERDATA, - MAKEINTRESOURCEW, MB_ICONINFORMATION, MB_OK, MF_BYPOSITION, MF_GRAYED, MF_SEPARATOR, MF_STRING, - SW_HIDE, TPM_LEFTALIGN, TPM_NONOTIFY, TPM_RETURNCMD, TPM_RIGHTBUTTON, WM_APP, WM_CLOSE, - WM_COMMAND, WM_CREATE, WM_DESTROY, WM_INITMENUPOPUP, WM_LBUTTONDBLCLK, WM_RBUTTONUP, - WNDCLASSEXW, WS_EX_NOACTIVATE, + CreatePopupMenu, CreateWindowExW, DefWindowProcW, DestroyMenu, DestroyWindow, DispatchMessageW, + EnumWindows, GetCursorPos, GetMessageW, GetWindowLongPtrW, GetWindowTextW, + GetWindowThreadProcessId, InsertMenuW, LoadIconW, MessageBoxW, PostMessageW, PostQuitMessage, + RegisterClassExW, SendMessageW, SetFocus, SetForegroundWindow, SetMenuDefaultItem, + SetWindowLongPtrW, ShowWindow, TrackPopupMenu, TranslateMessage, CREATESTRUCTW, GWLP_USERDATA, + MAKEINTRESOURCEW, MB_ICONINFORMATION, MB_OK, MF_BYPOSITION, MF_GRAYED, MF_SEPARATOR, MF_STRING, + SW_HIDE, TPM_LEFTALIGN, TPM_NONOTIFY, TPM_RETURNCMD, TPM_RIGHTBUTTON, WM_APP, WM_CLOSE, + WM_COMMAND, WM_CREATE, WM_DESTROY, WM_INITMENUPOPUP, WM_LBUTTONDBLCLK, WM_RBUTTONUP, + WNDCLASSEXW, WS_EX_NOACTIVATE, }; use winapi::{ - shared::minwindef::{BOOL, LOWORD, LPARAM, LRESULT, UINT, WPARAM}, - um::winuser::SW_SHOW, + shared::minwindef::{BOOL, LOWORD, LPARAM, LRESULT, UINT, WPARAM}, + um::winuser::SW_SHOW, }; use crate::localization::localized_string; @@ -43,20 +43,20 @@ const ID_EXIT: u16 = 2002; const WM_HIDE_GUI: u32 = WM_APP + 1; pub enum TrayMessage { - Enable, - Disable, - CloseToTray, - TrayCreated(WindowHandle), - ToggleAutoStart(bool), + Enable, + Disable, + CloseToTray, + TrayCreated(WindowHandle), + ToggleAutoStart(bool), } #[derive(Debug)] struct TrayState { - gui_handle: Option, - gui_hidden: bool, - about_shown: bool, - close_gui: bool, - show_balloon: bool, + gui_handle: Option, + gui_hidden: bool, + about_shown: bool, + close_gui: bool, + show_balloon: bool, } unsafe impl Send for TrayState {} @@ -69,377 +69,377 @@ unsafe impl Sync for WindowHandle {} #[macro_export] macro_rules! str_to_wide { - ($str:expr) => {{ - $str.encode_utf16() - .chain(std::iter::once(0)) - .collect::>() - }}; + ($str:expr) => {{ + $str.encode_utf16() + .chain(std::iter::once(0)) + .collect::>() + }}; } pub fn spawn_sys_tray(enabled: bool, start_closed_to_tray: bool) { - thread::spawn(move || { - let (sender, receiver) = sync_channel(1); - let _ = TRAY_SENDER.set(sender); - - // Stores the window handle so we can post messages to its queue - let mut window: Option = None; - - // Spawn tray initially if enabled - if enabled { - unsafe { create_window(false, start_closed_to_tray) }; - } - - // Make GUI visible if we don't start to tray - if !start_closed_to_tray { - GUI_VISIBLE.store(true, Ordering::Relaxed); - } - - while let Ok(msg) = receiver.recv() { - match msg { - TrayMessage::Enable => unsafe { - if window.is_none() { - create_window(true, false); - } - }, - TrayMessage::Disable => unsafe { - if let Some(window) = window.take() { - PostMessageW(window.0, WM_CLOSE, 1, 0); - } - }, - TrayMessage::CloseToTray => unsafe { - if let Some(window) = window.as_ref() { - PostMessageW(window.0, WM_HIDE_GUI, 0, 0); - } - }, - TrayMessage::TrayCreated(win) => { - window = Some(win); - } - TrayMessage::ToggleAutoStart(enabled) => unsafe { - if let Err(e) = autostart::toggle_autostart(enabled) { - log_error(&e); - } - }, - } - } - }); + thread::spawn(move || { + let (sender, receiver) = sync_channel(1); + let _ = TRAY_SENDER.set(sender); + + // Stores the window handle so we can post messages to its queue + let mut window: Option = None; + + // Spawn tray initially if enabled + if enabled { + unsafe { create_window(false, start_closed_to_tray) }; + } + + // Make GUI visible if we don't start to tray + if !start_closed_to_tray { + GUI_VISIBLE.store(true, Ordering::Relaxed); + } + + while let Ok(msg) = receiver.recv() { + match msg { + TrayMessage::Enable => unsafe { + if window.is_none() { + create_window(true, false); + } + }, + TrayMessage::Disable => unsafe { + if let Some(window) = window.take() { + PostMessageW(window.0, WM_CLOSE, 1, 0); + } + }, + TrayMessage::CloseToTray => unsafe { + if let Some(window) = window.as_ref() { + PostMessageW(window.0, WM_HIDE_GUI, 0, 0); + } + }, + TrayMessage::TrayCreated(win) => { + window = Some(win); + } + TrayMessage::ToggleAutoStart(enabled) => unsafe { + if let Err(e) = autostart::toggle_autostart(enabled) { + log_error(&e); + } + }, + } + } + }); } unsafe fn create_window(show_balloon: bool, gui_hidden: bool) { - thread::spawn(move || { - let mut tray_state = TrayState { - gui_handle: None, - gui_hidden, - about_shown: false, - close_gui: false, - show_balloon, - }; - - // Keep searching for window handle until its found - while tray_state.gui_handle.is_none() { - EnumWindows(Some(enum_proc), &mut tray_state as *mut _ as LPARAM); - } - - let h_instance = GetModuleHandleW(ptr::null()); - - let class_name = str_to_wide!("Grin GUI Tray"); - - let mut class = mem::zeroed::(); - class.cbSize = mem::size_of::() as u32; - class.lpfnWndProc = Some(window_proc); - class.hInstance = h_instance; - class.lpszClassName = class_name.as_ptr(); - class.hbrBackground = CreateSolidBrush(RGB(0, 77, 128)); - - RegisterClassExW(&class); - - let hwnd = CreateWindowExW( - WS_EX_NOACTIVATE, - class_name.as_ptr(), - ptr::null(), - 0, - 0, - 0, - 0, - 0, - ptr::null_mut(), - ptr::null_mut(), - h_instance, - &mut tray_state as *mut _ as *mut std::ffi::c_void, - ); - - // Send window handle back to main loop so we can post messages to it - let _ = TRAY_SENDER - .get() - .unwrap() - .try_send(TrayMessage::TrayCreated(WindowHandle(hwnd))); - - let mut msg = mem::zeroed(); - while GetMessageW(&mut msg, ptr::null_mut(), 0, 0) != 0 { - TranslateMessage(&msg); - DispatchMessageW(&msg); - } - - if tray_state.close_gui { - // WM_QUIT was sent, which was triggered by the Exit button. Close entire program. - SHOULD_EXIT.store(true, Ordering::Relaxed); - - // Activate window to force event loop to run / see that it should now close - SetForegroundWindow(tray_state.gui_handle.unwrap()); - } - }); + thread::spawn(move || { + let mut tray_state = TrayState { + gui_handle: None, + gui_hidden, + about_shown: false, + close_gui: false, + show_balloon, + }; + + // Keep searching for window handle until its found + while tray_state.gui_handle.is_none() { + EnumWindows(Some(enum_proc), &mut tray_state as *mut _ as LPARAM); + } + + let h_instance = GetModuleHandleW(ptr::null()); + + let class_name = str_to_wide!("Grin GUI Tray"); + + let mut class = mem::zeroed::(); + class.cbSize = mem::size_of::() as u32; + class.lpfnWndProc = Some(window_proc); + class.hInstance = h_instance; + class.lpszClassName = class_name.as_ptr(); + class.hbrBackground = CreateSolidBrush(RGB(0, 77, 128)); + + RegisterClassExW(&class); + + let hwnd = CreateWindowExW( + WS_EX_NOACTIVATE, + class_name.as_ptr(), + ptr::null(), + 0, + 0, + 0, + 0, + 0, + ptr::null_mut(), + ptr::null_mut(), + h_instance, + &mut tray_state as *mut _ as *mut std::ffi::c_void, + ); + + // Send window handle back to main loop so we can post messages to it + let _ = TRAY_SENDER + .get() + .unwrap() + .try_send(TrayMessage::TrayCreated(WindowHandle(hwnd))); + + let mut msg = mem::zeroed(); + while GetMessageW(&mut msg, ptr::null_mut(), 0, 0) != 0 { + TranslateMessage(&msg); + DispatchMessageW(&msg); + } + + if tray_state.close_gui { + // WM_QUIT was sent, which was triggered by the Exit button. Close entire program. + SHOULD_EXIT.store(true, Ordering::Relaxed); + + // Activate window to force event loop to run / see that it should now close + SetForegroundWindow(tray_state.gui_handle.unwrap()); + } + }); } unsafe fn add_icon(hwnd: HWND) { - let h_instance = GetModuleHandleW(ptr::null()); - - let icon_handle = LoadIconW(h_instance, MAKEINTRESOURCEW(0x101)); - - let mut tooltip_array = [0u16; 128]; - let tooltip = "Grin GUI"; - let mut tooltip = tooltip.encode_utf16().collect::>(); - tooltip.extend(vec![0; 128 - tooltip.len()]); - tooltip_array.swap_with_slice(&mut tooltip[..]); - - let mut icon_data: NOTIFYICONDATAW = mem::zeroed(); - icon_data.cbSize = mem::size_of::() as u32; - icon_data.hWnd = hwnd; - icon_data.uID = 1; - icon_data.uCallbackMessage = WM_APP; - icon_data.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP; - icon_data.hIcon = icon_handle; - icon_data.szTip = tooltip_array; - - Shell_NotifyIconW(NIM_ADD, &mut icon_data); + let h_instance = GetModuleHandleW(ptr::null()); + + let icon_handle = LoadIconW(h_instance, MAKEINTRESOURCEW(0x101)); + + let mut tooltip_array = [0u16; 128]; + let tooltip = "Grin GUI"; + let mut tooltip = tooltip.encode_utf16().collect::>(); + tooltip.extend(vec![0; 128 - tooltip.len()]); + tooltip_array.swap_with_slice(&mut tooltip[..]); + + let mut icon_data: NOTIFYICONDATAW = mem::zeroed(); + icon_data.cbSize = mem::size_of::() as u32; + icon_data.hWnd = hwnd; + icon_data.uID = 1; + icon_data.uCallbackMessage = WM_APP; + icon_data.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP; + icon_data.hIcon = icon_handle; + icon_data.szTip = tooltip_array; + + Shell_NotifyIconW(NIM_ADD, &mut icon_data); } unsafe fn display_balloon_message(hwnd: HWND, message: &str) { - let mut info = [0u16; 256]; - let message = str_to_wide!(message); - - for (idx, b) in message[0..message.len().min(255)].iter().enumerate() { - info[idx] = *b; - } - - let mut icon_data: NOTIFYICONDATAW = mem::zeroed(); - icon_data.cbSize = mem::size_of::() as u32; - icon_data.hWnd = hwnd; - icon_data.uID = 1; - icon_data.uFlags = NIF_INFO; - icon_data.szInfo = info; - icon_data.dwInfoFlags = NIIF_NONE | NIIF_NOSOUND; - - Shell_NotifyIconW(NIM_MODIFY, &mut icon_data); + let mut info = [0u16; 256]; + let message = str_to_wide!(message); + + for (idx, b) in message[0..message.len().min(255)].iter().enumerate() { + info[idx] = *b; + } + + let mut icon_data: NOTIFYICONDATAW = mem::zeroed(); + icon_data.cbSize = mem::size_of::() as u32; + icon_data.hWnd = hwnd; + icon_data.uID = 1; + icon_data.uFlags = NIF_INFO; + icon_data.szInfo = info; + icon_data.dwInfoFlags = NIIF_NONE | NIIF_NOSOUND; + + Shell_NotifyIconW(NIM_MODIFY, &mut icon_data); } unsafe fn remove_icon(hwnd: HWND) { - let mut icon_data: NOTIFYICONDATAW = mem::zeroed(); - icon_data.cbSize = mem::size_of::() as u32; - icon_data.hWnd = hwnd; - icon_data.uID = 1; + let mut icon_data: NOTIFYICONDATAW = mem::zeroed(); + icon_data.cbSize = mem::size_of::() as u32; + icon_data.hWnd = hwnd; + icon_data.uID = 1; - Shell_NotifyIconW(NIM_DELETE, &mut icon_data); + Shell_NotifyIconW(NIM_DELETE, &mut icon_data); } unsafe fn show_popup_menu(hwnd: HWND, state: &TrayState) { - let menu = CreatePopupMenu(); - - let hidden = state.gui_hidden; - - let mut about = str_to_wide!(localized_string("about")); - let mut toggle = str_to_wide!(if hidden { - localized_string("open-grin-gui") - } else { - localized_string("hide-grin-gui") - }); - let mut exit = str_to_wide!(localized_string("exit")); - - InsertMenuW( - menu, - 0, - MF_BYPOSITION | MF_STRING, - ID_TOGGLE_WINDOW as usize, - toggle.as_mut_ptr(), - ); - - InsertMenuW( - menu, - 1, - MF_BYPOSITION | MF_STRING, - ID_ABOUT as usize, - about.as_mut_ptr(), - ); - - InsertMenuW(menu, 2, MF_SEPARATOR | MF_GRAYED, 0, ptr::null_mut()); - - InsertMenuW( - menu, - 3, - MF_BYPOSITION | MF_STRING, - ID_EXIT as usize, - exit.as_mut_ptr(), - ); - - SetMenuDefaultItem(menu, ID_TOGGLE_WINDOW as u32, 0); - SetFocus(hwnd); - SendMessageW(hwnd, WM_INITMENUPOPUP, menu as usize, 0); - - let mut point: POINT = mem::zeroed(); - GetCursorPos(&mut point); - - let cmd = TrackPopupMenu( - menu, - TPM_LEFTALIGN | TPM_RIGHTBUTTON | TPM_RETURNCMD | TPM_NONOTIFY, - point.x, - point.y, - 0, - hwnd, - ptr::null_mut(), - ); - - SendMessageW(hwnd, WM_COMMAND, cmd as usize, 0); - - DestroyMenu(menu); + let menu = CreatePopupMenu(); + + let hidden = state.gui_hidden; + + let mut about = str_to_wide!(localized_string("about")); + let mut toggle = str_to_wide!(if hidden { + localized_string("open-grin-gui") + } else { + localized_string("hide-grin-gui") + }); + let mut exit = str_to_wide!(localized_string("exit")); + + InsertMenuW( + menu, + 0, + MF_BYPOSITION | MF_STRING, + ID_TOGGLE_WINDOW as usize, + toggle.as_mut_ptr(), + ); + + InsertMenuW( + menu, + 1, + MF_BYPOSITION | MF_STRING, + ID_ABOUT as usize, + about.as_mut_ptr(), + ); + + InsertMenuW(menu, 2, MF_SEPARATOR | MF_GRAYED, 0, ptr::null_mut()); + + InsertMenuW( + menu, + 3, + MF_BYPOSITION | MF_STRING, + ID_EXIT as usize, + exit.as_mut_ptr(), + ); + + SetMenuDefaultItem(menu, ID_TOGGLE_WINDOW as u32, 0); + SetFocus(hwnd); + SendMessageW(hwnd, WM_INITMENUPOPUP, menu as usize, 0); + + let mut point: POINT = mem::zeroed(); + GetCursorPos(&mut point); + + let cmd = TrackPopupMenu( + menu, + TPM_LEFTALIGN | TPM_RIGHTBUTTON | TPM_RETURNCMD | TPM_NONOTIFY, + point.x, + point.y, + 0, + hwnd, + ptr::null_mut(), + ); + + SendMessageW(hwnd, WM_COMMAND, cmd as usize, 0); + + DestroyMenu(menu); } unsafe fn show_about() { - let mut title = str_to_wide!("About"); + let mut title = str_to_wide!("About"); - let msg = format!( - "Grin GUI - {}\n\nCopyright © 2016-2022 The Grin Developers", - env!("CARGO_PKG_VERSION") - ); + let msg = format!( + "Grin GUI - {}\n\nCopyright © 2016-2022 The Grin Developers", + env!("CARGO_PKG_VERSION") + ); - let mut msg = str_to_wide!(msg); + let mut msg = str_to_wide!(msg); - MessageBoxW( - ptr::null_mut(), - msg.as_mut_ptr(), - title.as_mut_ptr(), - MB_ICONINFORMATION | MB_OK, - ); + MessageBoxW( + ptr::null_mut(), + msg.as_mut_ptr(), + title.as_mut_ptr(), + MB_ICONINFORMATION | MB_OK, + ); } unsafe extern "system" fn window_proc( - hwnd: HWND, - msg: UINT, - wparam: WPARAM, - lparam: LPARAM, + hwnd: HWND, + msg: UINT, + wparam: WPARAM, + lparam: LPARAM, ) -> LRESULT { - let mut state: &mut TrayState; - - if msg == WM_CREATE { - let create_struct = &*(lparam as *const CREATESTRUCTW); - state = &mut *(create_struct.lpCreateParams as *mut TrayState); - SetWindowLongPtrW(hwnd, GWLP_USERDATA, state as *mut _ as LPARAM); - - add_icon(hwnd); - - if state.show_balloon { - display_balloon_message(hwnd, "Running from Tray..."); - } - - return 0; - } else { - let ptr = GetWindowLongPtrW(hwnd, GWLP_USERDATA); - state = &mut *(ptr as *mut TrayState); - } - - match msg { - WM_CLOSE => { - // We send wparam as 1 when disabling tray from gui, and we don't want - // to shut down gui. Otherwise tray is closing because we selected Exit - // from tray icon - if wparam == 0 { - state.close_gui = true; - } - - remove_icon(hwnd); - - DestroyWindow(hwnd); - } - WM_DESTROY => { - PostQuitMessage(0); - } - WM_COMMAND => { - match LOWORD(wparam as u32) { - ID_ABOUT => { - // Don't show if already up - if !state.about_shown { - state.about_shown = true; - - show_about(); - - state.about_shown = false; - - return 0; - } - } - ID_TOGGLE_WINDOW => { - state.gui_hidden = !state.gui_hidden; - ShowWindow( - *state.gui_handle.as_ref().unwrap(), - if state.gui_hidden { SW_HIDE } else { SW_SHOW }, - ); - SetForegroundWindow(*state.gui_handle.as_ref().unwrap()); - - return 0; - } - ID_EXIT => { - PostMessageW(hwnd, WM_CLOSE, 0, 0); - return 0; - } - _ => {} - } - } - WM_APP => match lparam as u32 { - WM_LBUTTONDBLCLK => { - state.gui_hidden = !state.gui_hidden; - ShowWindow( - *state.gui_handle.as_ref().unwrap(), - if state.gui_hidden { SW_HIDE } else { SW_SHOW }, - ); - SetForegroundWindow(*state.gui_handle.as_ref().unwrap()); - - return 0; - } - WM_RBUTTONUP => { - SetForegroundWindow(hwnd); - show_popup_menu(hwnd, state); - - return 0; - } - _ => {} - }, - WM_HIDE_GUI => { - state.gui_hidden = true; - ShowWindow(*state.gui_handle.as_ref().unwrap(), SW_HIDE); - SetForegroundWindow(*state.gui_handle.as_ref().unwrap()); - - return 0; - } - _ => {} - } - - DefWindowProcW(hwnd, msg, wparam, lparam) + let mut state: &mut TrayState; + + if msg == WM_CREATE { + let create_struct = &*(lparam as *const CREATESTRUCTW); + state = &mut *(create_struct.lpCreateParams as *mut TrayState); + SetWindowLongPtrW(hwnd, GWLP_USERDATA, state as *mut _ as LPARAM); + + add_icon(hwnd); + + if state.show_balloon { + display_balloon_message(hwnd, "Running from Tray..."); + } + + return 0; + } else { + let ptr = GetWindowLongPtrW(hwnd, GWLP_USERDATA); + state = &mut *(ptr as *mut TrayState); + } + + match msg { + WM_CLOSE => { + // We send wparam as 1 when disabling tray from gui, and we don't want + // to shut down gui. Otherwise tray is closing because we selected Exit + // from tray icon + if wparam == 0 { + state.close_gui = true; + } + + remove_icon(hwnd); + + DestroyWindow(hwnd); + } + WM_DESTROY => { + PostQuitMessage(0); + } + WM_COMMAND => { + match LOWORD(wparam as u32) { + ID_ABOUT => { + // Don't show if already up + if !state.about_shown { + state.about_shown = true; + + show_about(); + + state.about_shown = false; + + return 0; + } + } + ID_TOGGLE_WINDOW => { + state.gui_hidden = !state.gui_hidden; + ShowWindow( + *state.gui_handle.as_ref().unwrap(), + if state.gui_hidden { SW_HIDE } else { SW_SHOW }, + ); + SetForegroundWindow(*state.gui_handle.as_ref().unwrap()); + + return 0; + } + ID_EXIT => { + PostMessageW(hwnd, WM_CLOSE, 0, 0); + return 0; + } + _ => {} + } + } + WM_APP => match lparam as u32 { + WM_LBUTTONDBLCLK => { + state.gui_hidden = !state.gui_hidden; + ShowWindow( + *state.gui_handle.as_ref().unwrap(), + if state.gui_hidden { SW_HIDE } else { SW_SHOW }, + ); + SetForegroundWindow(*state.gui_handle.as_ref().unwrap()); + + return 0; + } + WM_RBUTTONUP => { + SetForegroundWindow(hwnd); + show_popup_menu(hwnd, state); + + return 0; + } + _ => {} + }, + WM_HIDE_GUI => { + state.gui_hidden = true; + ShowWindow(*state.gui_handle.as_ref().unwrap(), SW_HIDE); + SetForegroundWindow(*state.gui_handle.as_ref().unwrap()); + + return 0; + } + _ => {} + } + + DefWindowProcW(hwnd, msg, wparam, lparam) } unsafe extern "system" fn enum_proc(hwnd: HWND, lparam: LPARAM) -> BOOL { - let mut state = &mut *(lparam as *mut TrayState); + let mut state = &mut *(lparam as *mut TrayState); - let mut id = mem::zeroed(); - GetWindowThreadProcessId(hwnd, &mut id); + let mut id = mem::zeroed(); + GetWindowThreadProcessId(hwnd, &mut id); - if id == std::process::id() { - let mut title = [0u16; 12]; - let read_len = GetWindowTextW(hwnd, title.as_mut_ptr(), 12); - let title = String::from_utf16_lossy(&title[0..read_len.min(12) as usize]); + if id == std::process::id() { + let mut title = [0u16; 12]; + let read_len = GetWindowTextW(hwnd, title.as_mut_ptr(), 12); + let title = String::from_utf16_lossy(&title[0..read_len.min(12) as usize]); - if title == "Grin" { - state.gui_handle = Some(hwnd); + if title == "Grin" { + state.gui_handle = Some(hwnd); - return 0; - } - } + return 0; + } + } - 1 + 1 } From d1ae8c90dbda370a42a1d58d3e6d5343a8d91ee3 Mon Sep 17 00:00:00 2001 From: Yeastplume Date: Wed, 17 Jan 2024 09:53:59 +0000 Subject: [PATCH 4/5] rename logos --- resources/linux/ajour.desktop | 7 ------- resources/logo/1024x1024/ajour.png | Bin 270117 -> 0 bytes resources/logo/1024x1024/ajour_macos.png | Bin 551628 -> 0 bytes resources/logo/128x128/ajour.png | Bin 19607 -> 0 bytes resources/logo/16x16/ajour.png | Bin 705 -> 0 bytes resources/logo/24x24/ajour.png | Bin 1378 -> 0 bytes resources/logo/256x256/ajour.png | Bin 54664 -> 0 bytes resources/logo/32x32/ajour.png | Bin 2081 -> 0 bytes resources/logo/48x48/ajour.png | Bin 4121 -> 0 bytes resources/logo/512x512/ajour.png | Bin 140631 -> 0 bytes resources/logo/64x64/ajour.png | Bin 6318 -> 0 bytes resources/windows/ajour.ico | Bin 349782 -> 0 bytes resources/windows/res.rc | 2 +- src/gui/mod.rs | 2 +- 14 files changed, 2 insertions(+), 9 deletions(-) delete mode 100644 resources/linux/ajour.desktop delete mode 100644 resources/logo/1024x1024/ajour.png delete mode 100644 resources/logo/1024x1024/ajour_macos.png delete mode 100644 resources/logo/128x128/ajour.png delete mode 100644 resources/logo/16x16/ajour.png delete mode 100644 resources/logo/24x24/ajour.png delete mode 100644 resources/logo/256x256/ajour.png delete mode 100644 resources/logo/32x32/ajour.png delete mode 100644 resources/logo/48x48/ajour.png delete mode 100644 resources/logo/512x512/ajour.png delete mode 100644 resources/logo/64x64/ajour.png delete mode 100644 resources/windows/ajour.ico diff --git a/resources/linux/ajour.desktop b/resources/linux/ajour.desktop deleted file mode 100644 index 0650a9b..0000000 --- a/resources/linux/ajour.desktop +++ /dev/null @@ -1,7 +0,0 @@ -[Desktop Entry] -Type=Application -Terminal=false -Exec=ajour -Name=ajour -Icon=ajour -Categories=Game; diff --git a/resources/logo/1024x1024/ajour.png b/resources/logo/1024x1024/ajour.png deleted file mode 100644 index 7af46b34c034a150923b7e1f3b56c5307af38022..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 270117 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

_S?8c)<94Kpu0r>M;Kusz4{+J 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

0Vms)xS@jm>$H(>^Ig2D6hwD;o+@fyY9`id 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 {LU(BXmJp3 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

X9r{Dppr%Mbht?@F|6jV35`kE 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�awR3=bLf4S4m4ObJ$l^oe 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%0DmJ5uY6GeH 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 diff --git a/resources/logo/128x128/ajour.png b/resources/logo/128x128/ajour.png deleted file mode 100644 index b88883b310ac264208d1437d64f56adb4f9d0c5c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 19607 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 diff --git a/resources/logo/24x24/ajour.png b/resources/logo/24x24/ajour.png deleted file mode 100644 index d804457f3c4ae9ffcd5bf0a2bf0ca22af9e9cde4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1378 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 B%LM=c diff --git a/resources/logo/32x32/ajour.png b/resources/logo/32x32/ajour.png deleted file mode 100644 index 9684364ab27bfbe288a4ac126f5a92c7c31e97f6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2081 zcmV++2;TRJP)0<_1Z1?8aiFybVxc-XLYXOJl>!yeiaf>wGt3Ce z$V*XC2!-J(kFmCpYAX=Z+R!w8ha^pJZr(R{@7=q1@9v&;(iR7jX!<|?W_EV>?C$w~ z&hPg<=Pdt^&wWUf6R_i?eUGF_%q0=562dqQS0TNd*a;t#ORcKtCJfh1QkUrl>OezRmsk& zk|k_Qc4akS`Ogl10sp{dMqhvBvADs|ei@J{D;1Yklq)|8&aF6FSXS|t+7Z|%OIfe# zk&q-=LiL4%0cmTjfbB_r27uz(Hj--I7>OD;Mg4OS<0*VKA&6u+yz?J4H^ZL32ISB} zwCP-=wO{B%O|< z4G$dW7p{w{xcDT&l}p3K&t1o(_rz#xe}G z=tHgXK+)+)DPxM(v;ft0eh8Htl!SQV{$u>PWg#n;M@e*dk=7lAu*r-LqqrHmdf>o5 z9bt}Oo4Mn&rN3_g*AiU2s+Q;8Ig`gW_Cqv+VZ}}@1DAZYm_=7tRHnz1{QOtNG@MgL z|Dk;h_77s`4N^k`^f^vDoV(Idip2;zs^fSNK1y@EJ8%7%$hJ2FNoqnS79yY9bjk|yN zHZi4>_dbx3@=3CpG)7j(%w(Bck!LIu;*~$?T)f10@y*xFj?4&f&Z5AVu$|bZS1qE& zE}?<~!l4LREs3ecdB07eu4p&U-2WmZqA(C))34v;jJY4PvonNaj3V+maBPH?qqt1v z56@fpeQwRQ%fpLj1n3$z7N9{-LZT?BsEtF2qNMY&uQA>ypmMq|z>( zotg3(0fgm9!i9+y)UhpOTcf?ZfRK{lxm(+a=2SSGX6-K=wj8eEosVl-bDsl;(nNC} zHr?J%#5X{DZ-{V#2O%c*69t5e5bhKoP624`%nnt~Q7MW^2wTwAr*lsA5#C(ClM-FQ z-kssfyJddUI-liB{4D#5mnYw^W5rzxR(qOaP3DdDZG5?5fW)Z8*w6^E7(_w}^;L3W zMu7T4X+H%}Ug4l=dE!Z%m8T!1Dr%zd&T_+(3a|Foap__orf!kfZI*s9z+aA4asA^m z>0JiZF`FyqbaJ3~h|?O*W8QojogDtGI6PTTncPt1it$U972fFa2Yt=WE{N0pEF zAcTaW2{N`s>j907<}ka`M?M89OD8#W8k-;5`}{XHXsagcP1%eZi{Z!)ty}rt02?2! zAzb8dr=nnoWbF_p5IK`^KyD-#|ujvLIj1s)^+cG-;S!-Gk%<{R+t1k>>wTGLpGrTi)h#; zTxcR(ok+-_p-QD=e~RnZS98{6G4pn>dW@X7`%89YjsXe7_vI)N-q-h5Bzid!0Z`VNVMFYJM;7#_uO-BSSw zcp;y)@fIuCB1FgIAM*QK^8D=a^JzUA;`P6!=uhZa!bDchiN7Z-$7XQY;O!QTU5O~S zKC+14t+UztR2!}tL@rXu8DhE$O!a{6LTOYgMlxw^^uTD0@#YV?ZCNEhcz*$Ze6f}- z+s5ci=tx%XxQm4+h&LQy_4*jsealZ^a4*T{kI_^=3nqR@@;NGFQpqU+>>h!qx0>5L zF6U-5uH*^GBBO;ETpJhFixTP$*VNRkSvD)cXo$Y#iKJE+0WpW%;4%H32afg)>=sU0 zeMk-tnB;Oo4u>T9<@fSirUUqIzL>~Y;is-AVnR(S^-y_90~a*Sp{b-qin&M(4T;gt zZaP}_^TDV?|A}t@v+RCS=G4h`$C(L0I(bZAw3Fcj7L}anZRar9|Lf(?YJJ9wQ%dm3 zNCEH3^QS-f1k5T7LV4+ln{WokjN{KeCr3Ql@DtxzGY#r<7{I>)T(5xZTu??N00000 LNkvXXu0mjf6CMhu diff --git a/resources/logo/48x48/ajour.png b/resources/logo/48x48/ajour.png deleted file mode 100644 index e942e6babf93b48a79848752aeabb0d19a9cd28e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4121 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 X<{O=k3d{=200000NkvXXu0mjfb=M#d diff --git a/resources/logo/512x512/ajour.png b/resources/logo/512x512/ajour.png deleted file mode 100644 index 2d7a8840be119e8cef13a61267c50e3fd101e768..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 140631 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