From 4b9d23cc3a4bcd9910936d6bd453990e558748f0 Mon Sep 17 00:00:00 2001 From: veeso Date: Thu, 30 Sep 2021 09:33:34 +0200 Subject: [PATCH] Reuse mounts --- src/ui/activities/auth/view.rs | 152 +++++++++++----------- src/ui/activities/setup/view/mod.rs | 156 +++++++++++++++-------- src/ui/activities/setup/view/setup.rs | 140 +++++++------------- src/ui/activities/setup/view/ssh_keys.rs | 21 +-- 4 files changed, 235 insertions(+), 234 deletions(-) diff --git a/src/ui/activities/auth/view.rs b/src/ui/activities/auth/view.rs index d41f933..21c22b4 100644 --- a/src/ui/activities/auth/view.rs +++ b/src/ui/activities/auth/view.rs @@ -99,100 +99,63 @@ impl AuthActivity { // Get default protocol let default_protocol: FileTransferProtocol = self.context().config().get_default_protocol(); // Protocol - self.view.mount( + self.mount_radio( super::COMPONENT_RADIO_PROTOCOL, - Box::new(Radio::new( - RadioPropsBuilder::default() - .with_color(protocol_color) - .with_inverted_color(Color::Black) - .with_borders(Borders::ALL, BorderType::Rounded, protocol_color) - .with_title("Protocol", Alignment::Left) - .with_options(&["SFTP", "SCP", "FTP", "FTPS", "AWS S3"]) - .with_value(Self::protocol_enum_to_opt(default_protocol)) - .rewind(true) - .build(), - )), + "Protocol", + &["SFTP", "SCP", "FTP", "FTPS", "AWS S3"], + Self::protocol_enum_to_opt(default_protocol), + protocol_color, ); // Address - self.view.mount( + self.mount_input( super::COMPONENT_INPUT_ADDR, - Box::new(Input::new( - InputPropsBuilder::default() - .with_foreground(addr_color) - .with_borders(Borders::ALL, BorderType::Rounded, addr_color) - .with_label("Remote host", Alignment::Left) - .build(), - )), + "Remote host", + addr_color, + InputType::Text, ); // Port - self.view.mount( + self.mount_input_ex( super::COMPONENT_INPUT_PORT, - Box::new(Input::new( - InputPropsBuilder::default() - .with_foreground(port_color) - .with_borders(Borders::ALL, BorderType::Rounded, port_color) - .with_label("Port number", Alignment::Left) - .with_input(InputType::Number) - .with_input_len(5) - .with_value(Self::get_default_port_for_protocol(default_protocol).to_string()) - .build(), - )), + "Port number", + port_color, + InputType::Number, + Some(5), + Some(Self::get_default_port_for_protocol(default_protocol).to_string()), ); // Username - self.view.mount( + self.mount_input( super::COMPONENT_INPUT_USERNAME, - Box::new(Input::new( - InputPropsBuilder::default() - .with_foreground(username_color) - .with_borders(Borders::ALL, BorderType::Rounded, username_color) - .with_label("Username", Alignment::Left) - .build(), - )), + "Username", + username_color, + InputType::Text, ); // Password - self.view.mount( + self.mount_input( super::COMPONENT_INPUT_PASSWORD, - Box::new(Input::new( - InputPropsBuilder::default() - .with_foreground(password_color) - .with_borders(Borders::ALL, BorderType::Rounded, password_color) - .with_label("Password", Alignment::Left) - .with_input(InputType::Password) - .build(), - )), + "Password", + password_color, + InputType::Password, ); // Bucket - self.view.mount( + self.mount_input( super::COMPONENT_INPUT_S3_BUCKET, - Box::new(Input::new( - InputPropsBuilder::default() - .with_foreground(addr_color) - .with_borders(Borders::ALL, BorderType::Rounded, addr_color) - .with_label("Bucket name", Alignment::Left) - .build(), - )), + "Bucket name", + addr_color, + InputType::Text, ); // Region - self.view.mount( + self.mount_input( super::COMPONENT_INPUT_S3_REGION, - Box::new(Input::new( - InputPropsBuilder::default() - .with_foreground(port_color) - .with_borders(Borders::ALL, BorderType::Rounded, port_color) - .with_label("Region", Alignment::Left) - .build(), - )), + "Region", + port_color, + InputType::Text, ); // Profile - self.view.mount( + self.mount_input( super::COMPONENT_INPUT_S3_PROFILE, - Box::new(Input::new( - InputPropsBuilder::default() - .with_foreground(username_color) - .with_borders(Borders::ALL, BorderType::Rounded, username_color) - .with_label("Profile", Alignment::Left) - .build(), - )), + "Profile", + username_color, + InputType::Text, ); // Version notice if let Some(version) = self @@ -995,4 +958,49 @@ impl AuthActivity { // Active self.view.active(id); } + + fn mount_radio(&mut self, id: &str, text: &str, opts: &[&str], default: usize, color: Color) { + self.view.mount( + id, + Box::new(Radio::new( + RadioPropsBuilder::default() + .with_color(color) + .with_inverted_color(Color::Black) + .with_borders(Borders::ALL, BorderType::Rounded, color) + .with_title(text, Alignment::Left) + .with_options(opts) + .with_value(default) + .rewind(true) + .build(), + )), + ); + } + + fn mount_input(&mut self, id: &str, label: &str, fg: Color, typ: InputType) { + self.mount_input_ex(id, label, fg, typ, None, None); + } + + fn mount_input_ex( + &mut self, + id: &str, + label: &str, + fg: Color, + typ: InputType, + len: Option, + value: Option, + ) { + let mut props = InputPropsBuilder::default(); + props + .with_foreground(fg) + .with_borders(Borders::ALL, BorderType::Rounded, fg) + .with_label(label, Alignment::Left) + .with_input(typ); + if let Some(len) = len { + props.with_input_len(len); + } + if let Some(value) = value { + props.with_value(value); + } + self.view.mount(id, Box::new(Input::new(props.build()))); + } } diff --git a/src/ui/activities/setup/view/mod.rs b/src/ui/activities/setup/view/mod.rs index d43eb91..f3452be 100644 --- a/src/ui/activities/setup/view/mod.rs +++ b/src/ui/activities/setup/view/mod.rs @@ -36,10 +36,10 @@ pub use ssh_keys::*; pub use theme::*; // Ext use tui_realm_stdlib::{ - List, ListPropsBuilder, Paragraph, ParagraphPropsBuilder, Radio, RadioPropsBuilder, Span, - SpanPropsBuilder, + Input, InputPropsBuilder, List, ListPropsBuilder, Paragraph, ParagraphPropsBuilder, Radio, + RadioPropsBuilder, Span, SpanPropsBuilder, }; -use tuirealm::props::{Alignment, PropsBuilder, TableBuilder, TextSpan}; +use tuirealm::props::{Alignment, InputType, PropsBuilder, TableBuilder, TextSpan}; use tuirealm::tui::{ style::Color, widgets::{BorderType, Borders}, @@ -74,21 +74,7 @@ impl SetupActivity { /// /// Mount error box pub(super) fn mount_error(&mut self, text: &str) { - // Mount - self.view.mount( - super::COMPONENT_TEXT_ERROR, - Box::new(Paragraph::new( - ParagraphPropsBuilder::default() - .with_foreground(Color::Red) - .bold() - .with_borders(Borders::ALL, BorderType::Rounded, Color::Red) - .with_texts(vec![TextSpan::from(text)]) - .with_text_alignment(Alignment::Center) - .build(), - )), - ); - // Give focus to error - self.view.active(super::COMPONENT_TEXT_ERROR); + self.mount_text_dialog(super::COMPONENT_TEXT_ERROR, text, Color::Red); } /// ### umount_error @@ -102,28 +88,13 @@ impl SetupActivity { /// /// Mount quit popup pub(super) fn mount_quit(&mut self) { - self.view.mount( + self.mount_radio_dialog( super::COMPONENT_RADIO_QUIT, - Box::new(Radio::new( - RadioPropsBuilder::default() - .with_color(Color::LightRed) - .with_inverted_color(Color::Black) - .with_borders(Borders::ALL, BorderType::Rounded, Color::LightRed) - .with_title( - "There are unsaved changes! Save changes before leaving?", - Alignment::Center, - ) - .with_options(&[ - String::from("Save"), - String::from("Don't save"), - String::from("Cancel"), - ]) - .rewind(true) - .build(), - )), + "There are unsaved changes! Save changes before leaving?", + &["Save", "Don't save", "Cancel"], + 0, + Color::LightRed, ); - // Active - self.view.active(super::COMPONENT_RADIO_QUIT); } /// ### umount_quit @@ -137,21 +108,13 @@ impl SetupActivity { /// /// Mount save popup pub(super) fn mount_save_popup(&mut self) { - self.view.mount( + self.mount_radio_dialog( super::COMPONENT_RADIO_SAVE, - Box::new(Radio::new( - RadioPropsBuilder::default() - .with_color(Color::LightYellow) - .with_inverted_color(Color::Black) - .with_borders(Borders::ALL, BorderType::Rounded, Color::LightYellow) - .with_title("Save changes?", Alignment::Center) - .with_options(&[String::from("Yes"), String::from("No")]) - .rewind(true) - .build(), - )), + "Save changes?", + &["Yes", "No"], + 0, + Color::LightYellow, ); - // Active - self.view.active(super::COMPONENT_RADIO_SAVE); } /// ### umount_quit @@ -253,4 +216,95 @@ impl SetupActivity { pub(super) fn umount_help(&mut self) { self.view.umount(super::COMPONENT_TEXT_HELP); } + + // -- mount helpers + + fn mount_text_dialog(&mut self, id: &str, text: &str, color: Color) { + // Mount + self.view.mount( + id, + Box::new(Paragraph::new( + ParagraphPropsBuilder::default() + .with_borders(Borders::ALL, BorderType::Thick, color) + .with_foreground(color) + .bold() + .with_text_alignment(Alignment::Center) + .with_texts(vec![TextSpan::from(text)]) + .build(), + )), + ); + // Give focus to error + self.view.active(id); + } + + fn mount_radio_dialog( + &mut self, + id: &str, + text: &str, + opts: &[&str], + default: usize, + color: Color, + ) { + self.view.mount( + id, + Box::new(Radio::new( + RadioPropsBuilder::default() + .with_color(color) + .with_inverted_color(Color::Black) + .with_borders(Borders::ALL, BorderType::Rounded, color) + .with_title(text, Alignment::Center) + .with_options(opts) + .with_value(default) + .rewind(true) + .build(), + )), + ); + // Active + self.view.active(id); + } + + fn mount_radio(&mut self, id: &str, text: &str, opts: &[&str], default: usize, color: Color) { + self.view.mount( + id, + Box::new(Radio::new( + RadioPropsBuilder::default() + .with_color(color) + .with_inverted_color(Color::Black) + .with_borders(Borders::ALL, BorderType::Rounded, color) + .with_title(text, Alignment::Left) + .with_options(opts) + .with_value(default) + .rewind(true) + .build(), + )), + ); + } + + fn mount_input(&mut self, id: &str, label: &str, fg: Color, typ: InputType) { + self.mount_input_ex(id, label, fg, typ, None, None); + } + + fn mount_input_ex( + &mut self, + id: &str, + label: &str, + fg: Color, + typ: InputType, + len: Option, + value: Option, + ) { + let mut props = InputPropsBuilder::default(); + props + .with_foreground(fg) + .with_borders(Borders::ALL, BorderType::Rounded, fg) + .with_label(label, Alignment::Left) + .with_input(typ); + if let Some(len) = len { + props.with_input_len(len); + } + if let Some(value) = value { + props.with_value(value); + } + self.view.mount(id, Box::new(Input::new(props.build()))); + } } diff --git a/src/ui/activities/setup/view/setup.rs b/src/ui/activities/setup/view/setup.rs index 20fb80c..618aab8 100644 --- a/src/ui/activities/setup/view/setup.rs +++ b/src/ui/activities/setup/view/setup.rs @@ -27,14 +27,14 @@ * SOFTWARE. */ // Locals -use super::{Context, SetupActivity}; +use super::{Context, InputType, SetupActivity}; use crate::filetransfer::FileTransferProtocol; use crate::fs::explorer::GroupDirs; use crate::ui::components::bytes::{Bytes, BytesPropsBuilder}; use crate::utils::ui::draw_area_in; // Ext use std::path::PathBuf; -use tui_realm_stdlib::{Input, InputPropsBuilder, Radio, RadioPropsBuilder}; +use tui_realm_stdlib::{InputPropsBuilder, RadioPropsBuilder}; use tuirealm::tui::{ layout::{Constraint, Direction, Layout}, style::Color, @@ -60,118 +60,66 @@ impl SetupActivity { // Footer self.mount_footer(); // Input fields - self.view.mount( + self.mount_input( super::COMPONENT_INPUT_TEXT_EDITOR, - Box::new(Input::new( - InputPropsBuilder::default() - .with_foreground(Color::LightGreen) - .with_borders(Borders::ALL, BorderType::Rounded, Color::LightGreen) - .with_label("Text editor", Alignment::Left) - .build(), - )), + "Text editor", + Color::LightGreen, + InputType::Text, ); self.view.active(super::COMPONENT_INPUT_TEXT_EDITOR); // <-- Focus - self.view.mount( + self.mount_radio( super::COMPONENT_RADIO_DEFAULT_PROTOCOL, - Box::new(Radio::new( - RadioPropsBuilder::default() - .with_color(Color::LightCyan) - .with_inverted_color(Color::Black) - .with_borders(Borders::ALL, BorderType::Rounded, Color::LightCyan) - .with_title("Default file transfer protocol", Alignment::Left) - .with_options(&["SFTP", "SCP", "FTP", "FTPS", "AWS S3"]) - .rewind(true) - .build(), - )), + "Default protocol", + &["SFTP", "SCP", "FTP", "FTPS", "AWS S3"], + 0, + Color::LightCyan, ); - self.view.mount( + self.mount_radio( super::COMPONENT_RADIO_HIDDEN_FILES, - Box::new(Radio::new( - RadioPropsBuilder::default() - .with_color(Color::LightRed) - .with_inverted_color(Color::Black) - .with_borders(Borders::ALL, BorderType::Rounded, Color::LightRed) - .with_title("Show hidden files (by default)?", Alignment::Left) - .with_options(&[String::from("Yes"), String::from("No")]) - .rewind(true) - .build(), - )), + "Show hidden files (by default)?", + &["Yes", "No"], + 0, + Color::LightRed, ); - self.view.mount( + self.mount_radio( super::COMPONENT_RADIO_UPDATES, - Box::new(Radio::new( - RadioPropsBuilder::default() - .with_color(Color::LightYellow) - .with_inverted_color(Color::Black) - .with_borders(Borders::ALL, BorderType::Rounded, Color::LightYellow) - .with_title("Check for updates?", Alignment::Left) - .with_options(&[String::from("Yes"), String::from("No")]) - .rewind(true) - .build(), - )), + "Check for updates?", + &["Yes", "No"], + 0, + Color::LightYellow, ); - self.view.mount( + self.mount_radio( super::COMPONENT_RADIO_PROMPT_ON_FILE_REPLACE, - Box::new(Radio::new( - RadioPropsBuilder::default() - .with_color(Color::LightCyan) - .with_inverted_color(Color::Black) - .with_borders(Borders::ALL, BorderType::Rounded, Color::LightCyan) - .with_title("Prompt when replacing existing files?", Alignment::Left) - .with_options(&[String::from("Yes"), String::from("No")]) - .rewind(true) - .build(), - )), + "Prompt when replacing existing files?", + &["Yes", "No"], + 0, + Color::LightCyan, ); - self.view.mount( + self.mount_radio( super::COMPONENT_RADIO_GROUP_DIRS, - Box::new(Radio::new( - RadioPropsBuilder::default() - .with_color(Color::LightMagenta) - .with_inverted_color(Color::Black) - .with_borders(Borders::ALL, BorderType::Rounded, Color::LightMagenta) - .with_title("Group directories", Alignment::Left) - .with_options(&[ - String::from("Display first"), - String::from("Display Last"), - String::from("No"), - ]) - .rewind(true) - .build(), - )), + "Group directories", + &["Display first", "Display last", "No"], + 0, + Color::LightMagenta, ); - self.view.mount( + self.mount_input( super::COMPONENT_INPUT_LOCAL_FILE_FMT, - Box::new(Input::new( - InputPropsBuilder::default() - .with_foreground(Color::LightGreen) - .with_borders(Borders::ALL, BorderType::Rounded, Color::LightGreen) - .with_label("File formatter syntax (local)", Alignment::Left) - .build(), - )), + "File formatter syntax (local)", + Color::LightGreen, + InputType::Text, ); - self.view.mount( + self.mount_input( super::COMPONENT_INPUT_REMOTE_FILE_FMT, - Box::new(Input::new( - InputPropsBuilder::default() - .with_foreground(Color::LightCyan) - .with_borders(Borders::ALL, BorderType::Rounded, Color::LightCyan) - .with_label("File formatter syntax (remote)", Alignment::Left) - .build(), - )), + "File formatter syntax (remote)", + Color::LightCyan, + InputType::Text, ); - self.view.mount( + self.mount_radio( super::COMPONENT_RADIO_NOTIFICATIONS_ENABLED, - Box::new(Radio::new( - RadioPropsBuilder::default() - .with_color(Color::LightRed) - .with_inverted_color(Color::Black) - .with_borders(Borders::ALL, BorderType::Rounded, Color::LightRed) - .with_title("Enable notifications?", Alignment::Left) - .with_options(&[String::from("Yes"), String::from("No")]) - .rewind(true) - .build(), - )), + "Enable notifications?", + &["Yes", "No"], + 0, + Color::LightRed, ); self.view.mount( super::COMPONENT_INPUT_NOTIFICATIONS_THRESHOLD, diff --git a/src/ui/activities/setup/view/ssh_keys.rs b/src/ui/activities/setup/view/ssh_keys.rs index c99393a..b7ddca9 100644 --- a/src/ui/activities/setup/view/ssh_keys.rs +++ b/src/ui/activities/setup/view/ssh_keys.rs @@ -31,7 +31,7 @@ use super::{Context, SetupActivity}; use crate::ui::components::bookmark_list::{BookmarkList, BookmarkListPropsBuilder}; use crate::utils::ui::draw_area_in; // Ext -use tui_realm_stdlib::{Input, InputPropsBuilder, Radio, RadioPropsBuilder}; +use tui_realm_stdlib::{Input, InputPropsBuilder}; use tuirealm::tui::{ layout::{Constraint, Direction, Layout}, style::Color, @@ -169,22 +169,13 @@ impl SetupActivity { /// /// Mount delete ssh key component pub(crate) fn mount_del_ssh_key(&mut self) { - self.view.mount( + self.mount_radio_dialog( super::COMPONENT_RADIO_DEL_SSH_KEY, - Box::new(Radio::new( - RadioPropsBuilder::default() - .with_color(Color::LightRed) - .with_inverted_color(Color::Black) - .with_borders(Borders::ALL, BorderType::Rounded, Color::LightRed) - .with_title("Delete key?", Alignment::Center) - .with_options(&[String::from("Yes"), String::from("No")]) - .with_value(1) // Default: No - .rewind(true) - .build(), - )), + "Delete key?", + &["Yes", "No"], + 1, + Color::LightRed, ); - // Active - self.view.active(super::COMPONENT_RADIO_DEL_SSH_KEY); } /// ### umount_del_ssh_key