mirror of
https://github.com/veeso/termscp.git
synced 2026-09-27 22:41:19 -07:00
Migrated termscp to tui-realm 1.x
This commit is contained in:
committed by
Christian Visintin
parent
30851a78e8
commit
54b5583d1a
+186
-197
@@ -31,18 +31,15 @@ pub mod ssh_keys;
|
||||
pub mod theme;
|
||||
|
||||
use super::*;
|
||||
use crate::utils::ui::draw_area_in;
|
||||
pub use setup::*;
|
||||
pub use ssh_keys::*;
|
||||
pub use theme::*;
|
||||
// Ext
|
||||
use tui_realm_stdlib::{
|
||||
Input, InputPropsBuilder, List, ListPropsBuilder, Paragraph, ParagraphPropsBuilder, Radio,
|
||||
RadioPropsBuilder, Span, SpanPropsBuilder,
|
||||
};
|
||||
use tuirealm::props::{Alignment, InputType, PropsBuilder, TableBuilder, TextSpan};
|
||||
use tuirealm::tui::{
|
||||
style::Color,
|
||||
widgets::{BorderType, Borders},
|
||||
|
||||
use tuirealm::tui::widgets::Clear;
|
||||
use tuirealm::{
|
||||
event::{Key, KeyEvent, KeyModifiers},
|
||||
Frame, Sub, SubClause, SubEventClause,
|
||||
};
|
||||
|
||||
impl SetupActivity {
|
||||
@@ -61,6 +58,7 @@ impl SetupActivity {
|
||||
///
|
||||
/// View gui
|
||||
pub(super) fn view(&mut self) {
|
||||
self.redraw = false;
|
||||
match self.layout {
|
||||
ViewLayout::SetupForm => self.view_setup(),
|
||||
ViewLayout::SshKeys => self.view_ssh_keys(),
|
||||
@@ -73,238 +71,229 @@ impl SetupActivity {
|
||||
/// ### mount_error
|
||||
///
|
||||
/// Mount error box
|
||||
pub(super) fn mount_error(&mut self, text: &str) {
|
||||
self.mount_text_dialog(super::COMPONENT_TEXT_ERROR, text, Color::Red);
|
||||
pub(super) fn mount_error<S: AsRef<str>>(&mut self, text: S) {
|
||||
assert!(self
|
||||
.app
|
||||
.remount(
|
||||
Id::Common(IdCommon::ErrorPopup),
|
||||
Box::new(components::ErrorPopup::new(text)),
|
||||
vec![],
|
||||
)
|
||||
.is_ok());
|
||||
assert!(self.app.active(&Id::Common(IdCommon::ErrorPopup)).is_ok());
|
||||
}
|
||||
|
||||
/// ### umount_error
|
||||
///
|
||||
/// Umount error message
|
||||
pub(super) fn umount_error(&mut self) {
|
||||
self.view.umount(super::COMPONENT_TEXT_ERROR);
|
||||
let _ = self.app.umount(&Id::Common(IdCommon::ErrorPopup));
|
||||
}
|
||||
|
||||
/// ### mount_quit
|
||||
///
|
||||
/// Mount quit popup
|
||||
pub(super) fn mount_quit(&mut self) {
|
||||
self.mount_radio_dialog(
|
||||
super::COMPONENT_RADIO_QUIT,
|
||||
"There are unsaved changes! Save changes before leaving?",
|
||||
&["Save", "Don't save", "Cancel"],
|
||||
0,
|
||||
Color::LightRed,
|
||||
);
|
||||
assert!(self
|
||||
.app
|
||||
.remount(
|
||||
Id::Common(IdCommon::QuitPopup),
|
||||
Box::new(components::QuitPopup::default()),
|
||||
vec![],
|
||||
)
|
||||
.is_ok());
|
||||
assert!(self.app.active(&Id::Common(IdCommon::QuitPopup)).is_ok());
|
||||
}
|
||||
|
||||
/// ### umount_quit
|
||||
///
|
||||
/// Umount quit
|
||||
pub(super) fn umount_quit(&mut self) {
|
||||
self.view.umount(super::COMPONENT_RADIO_QUIT);
|
||||
let _ = self.app.umount(&Id::Common(IdCommon::QuitPopup));
|
||||
}
|
||||
|
||||
/// ### mount_save_popup
|
||||
///
|
||||
/// Mount save popup
|
||||
pub(super) fn mount_save_popup(&mut self) {
|
||||
self.mount_radio_dialog(
|
||||
super::COMPONENT_RADIO_SAVE,
|
||||
"Save changes?",
|
||||
&["Yes", "No"],
|
||||
0,
|
||||
Color::LightYellow,
|
||||
);
|
||||
assert!(self
|
||||
.app
|
||||
.remount(
|
||||
Id::Common(IdCommon::SavePopup),
|
||||
Box::new(components::SavePopup::default()),
|
||||
vec![],
|
||||
)
|
||||
.is_ok());
|
||||
assert!(self.app.active(&Id::Common(IdCommon::SavePopup)).is_ok());
|
||||
}
|
||||
|
||||
/// ### umount_quit
|
||||
///
|
||||
/// Umount quit
|
||||
pub(super) fn umount_save_popup(&mut self) {
|
||||
self.view.umount(super::COMPONENT_RADIO_SAVE);
|
||||
}
|
||||
|
||||
pub(self) fn mount_header_tab(&mut self, idx: usize) {
|
||||
self.view.mount(
|
||||
super::COMPONENT_RADIO_TAB,
|
||||
Box::new(Radio::new(
|
||||
RadioPropsBuilder::default()
|
||||
.with_color(Color::LightYellow)
|
||||
.with_inverted_color(Color::Black)
|
||||
.with_borders(Borders::BOTTOM, BorderType::Thick, Color::White)
|
||||
.with_options(&[
|
||||
String::from("User Interface"),
|
||||
String::from("SSH Keys"),
|
||||
String::from("Theme"),
|
||||
])
|
||||
.with_value(idx)
|
||||
.rewind(true)
|
||||
.build(),
|
||||
)),
|
||||
);
|
||||
}
|
||||
|
||||
pub(self) fn mount_footer(&mut self) {
|
||||
self.view.mount(
|
||||
super::COMPONENT_TEXT_FOOTER,
|
||||
Box::new(Span::new(
|
||||
SpanPropsBuilder::default()
|
||||
.with_spans(vec![
|
||||
TextSpan::new("Press ").bold(),
|
||||
TextSpan::new("<CTRL+H>").bold().fg(Color::Cyan),
|
||||
TextSpan::new(" to show keybindings").bold(),
|
||||
])
|
||||
.build(),
|
||||
)),
|
||||
);
|
||||
let _ = self.app.umount(&Id::Common(IdCommon::SavePopup));
|
||||
}
|
||||
|
||||
/// ### mount_help
|
||||
///
|
||||
/// Mount help
|
||||
pub(super) fn mount_help(&mut self) {
|
||||
self.view.mount(
|
||||
super::COMPONENT_TEXT_HELP,
|
||||
Box::new(List::new(
|
||||
ListPropsBuilder::default()
|
||||
.with_borders(Borders::ALL, BorderType::Rounded, Color::White)
|
||||
.with_highlighted_str(Some("?"))
|
||||
.with_max_scroll_step(8)
|
||||
.bold()
|
||||
.with_title("Help", Alignment::Center)
|
||||
.scrollable(true)
|
||||
.with_rows(
|
||||
TableBuilder::default()
|
||||
.add_col(TextSpan::new("<ESC>").bold().fg(Color::Cyan))
|
||||
.add_col(TextSpan::from(" Exit setup"))
|
||||
.add_row()
|
||||
.add_col(TextSpan::new("<TAB>").bold().fg(Color::Cyan))
|
||||
.add_col(TextSpan::from(" Change setup page"))
|
||||
.add_row()
|
||||
.add_col(TextSpan::new("<RIGHT/LEFT>").bold().fg(Color::Cyan))
|
||||
.add_col(TextSpan::from(" Change cursor"))
|
||||
.add_row()
|
||||
.add_col(TextSpan::new("<UP/DOWN>").bold().fg(Color::Cyan))
|
||||
.add_col(TextSpan::from(" Change input field"))
|
||||
.add_row()
|
||||
.add_col(TextSpan::new("<ENTER>").bold().fg(Color::Cyan))
|
||||
.add_col(TextSpan::from(" Select / Dismiss popup"))
|
||||
.add_row()
|
||||
.add_col(TextSpan::new("<DEL|E>").bold().fg(Color::Cyan))
|
||||
.add_col(TextSpan::from(" Delete SSH key"))
|
||||
.add_row()
|
||||
.add_col(TextSpan::new("<CTRL+N>").bold().fg(Color::Cyan))
|
||||
.add_col(TextSpan::from(" New SSH key"))
|
||||
.add_row()
|
||||
.add_col(TextSpan::new("<CTRL+R>").bold().fg(Color::Cyan))
|
||||
.add_col(TextSpan::from(" Revert changes"))
|
||||
.add_row()
|
||||
.add_col(TextSpan::new("<CTRL+S>").bold().fg(Color::Cyan))
|
||||
.add_col(TextSpan::from(" Save configuration"))
|
||||
.build(),
|
||||
)
|
||||
.build(),
|
||||
)),
|
||||
);
|
||||
// Active help
|
||||
self.view.active(super::COMPONENT_TEXT_HELP);
|
||||
assert!(self
|
||||
.app
|
||||
.remount(
|
||||
Id::Common(IdCommon::Keybindings),
|
||||
Box::new(components::Keybindings::default()),
|
||||
vec![],
|
||||
)
|
||||
.is_ok());
|
||||
assert!(self.app.active(&Id::Common(IdCommon::Keybindings)).is_ok());
|
||||
}
|
||||
|
||||
/// ### umount_help
|
||||
///
|
||||
/// Umount help
|
||||
pub(super) fn umount_help(&mut self) {
|
||||
self.view.umount(super::COMPONENT_TEXT_HELP);
|
||||
let _ = self.app.umount(&Id::Common(IdCommon::Keybindings));
|
||||
}
|
||||
|
||||
// -- 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<usize>,
|
||||
value: Option<String>,
|
||||
) {
|
||||
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);
|
||||
pub(super) fn view_popups(&mut self, f: &mut Frame) {
|
||||
if self.app.mounted(&Id::Common(IdCommon::ErrorPopup)) {
|
||||
let popup = draw_area_in(f.size(), 50, 10);
|
||||
f.render_widget(Clear, popup);
|
||||
// make popup
|
||||
self.app.view(&Id::Common(IdCommon::ErrorPopup), f, popup);
|
||||
} else if self.app.mounted(&Id::Common(IdCommon::QuitPopup)) {
|
||||
// make popup
|
||||
let popup = draw_area_in(f.size(), 40, 10);
|
||||
f.render_widget(Clear, popup);
|
||||
self.app.view(&Id::Common(IdCommon::QuitPopup), f, popup);
|
||||
} else if self.app.mounted(&Id::Common(IdCommon::Keybindings)) {
|
||||
// make popup
|
||||
let popup = draw_area_in(f.size(), 50, 70);
|
||||
f.render_widget(Clear, popup);
|
||||
self.app.view(&Id::Common(IdCommon::Keybindings), f, popup);
|
||||
} else if self.app.mounted(&Id::Common(IdCommon::SavePopup)) {
|
||||
// make popup
|
||||
let popup = draw_area_in(f.size(), 30, 10);
|
||||
f.render_widget(Clear, popup);
|
||||
self.app.view(&Id::Common(IdCommon::SavePopup), f, popup);
|
||||
}
|
||||
if let Some(value) = value {
|
||||
props.with_value(value);
|
||||
}
|
||||
self.view.mount(id, Box::new(Input::new(props.build())));
|
||||
}
|
||||
|
||||
/// ### new_app
|
||||
///
|
||||
/// Clean app up and remount common components and global listener
|
||||
fn new_app(&mut self, layout: ViewLayout) {
|
||||
self.app.umount_all();
|
||||
self.mount_global_listener();
|
||||
self.mount_commons(layout);
|
||||
}
|
||||
|
||||
/// ### mount_commons
|
||||
///
|
||||
/// Mount common components
|
||||
fn mount_commons(&mut self, layout: ViewLayout) {
|
||||
// Radio tab
|
||||
assert!(self
|
||||
.app
|
||||
.remount(
|
||||
Id::Common(IdCommon::Header),
|
||||
Box::new(components::Header::new(layout)),
|
||||
vec![],
|
||||
)
|
||||
.is_ok());
|
||||
// Footer
|
||||
assert!(self
|
||||
.app
|
||||
.remount(
|
||||
Id::Common(IdCommon::Footer),
|
||||
Box::new(components::Footer::default()),
|
||||
vec![],
|
||||
)
|
||||
.is_ok());
|
||||
}
|
||||
|
||||
/// ### mount_global_listener
|
||||
///
|
||||
/// Mount global listener
|
||||
fn mount_global_listener(&mut self) {
|
||||
assert!(self
|
||||
.app
|
||||
.mount(
|
||||
Id::Common(IdCommon::GlobalListener),
|
||||
Box::new(components::GlobalListener::default()),
|
||||
vec![
|
||||
Sub::new(
|
||||
SubEventClause::Keyboard(KeyEvent {
|
||||
code: Key::Esc,
|
||||
modifiers: KeyModifiers::NONE,
|
||||
}),
|
||||
Self::no_popup_mounted_clause(),
|
||||
),
|
||||
Sub::new(
|
||||
SubEventClause::Keyboard(KeyEvent {
|
||||
code: Key::Tab,
|
||||
modifiers: KeyModifiers::NONE,
|
||||
}),
|
||||
Self::no_popup_mounted_clause(),
|
||||
),
|
||||
Sub::new(
|
||||
SubEventClause::Keyboard(KeyEvent {
|
||||
code: Key::Char('h'),
|
||||
modifiers: KeyModifiers::CONTROL,
|
||||
}),
|
||||
Self::no_popup_mounted_clause(),
|
||||
),
|
||||
Sub::new(
|
||||
SubEventClause::Keyboard(KeyEvent {
|
||||
code: Key::Char('r'),
|
||||
modifiers: KeyModifiers::CONTROL,
|
||||
}),
|
||||
Self::no_popup_mounted_clause(),
|
||||
),
|
||||
Sub::new(
|
||||
SubEventClause::Keyboard(KeyEvent {
|
||||
code: Key::Char('s'),
|
||||
modifiers: KeyModifiers::CONTROL,
|
||||
}),
|
||||
Self::no_popup_mounted_clause(),
|
||||
),
|
||||
]
|
||||
)
|
||||
.is_ok());
|
||||
}
|
||||
|
||||
/// ### no_popup_mounted_clause
|
||||
///
|
||||
/// Returns a sub clause which requires that no popup is mounted in order to be satisfied
|
||||
fn no_popup_mounted_clause() -> SubClause<Id> {
|
||||
SubClause::And(
|
||||
Box::new(SubClause::Not(Box::new(SubClause::IsMounted(Id::Common(
|
||||
IdCommon::ErrorPopup,
|
||||
))))),
|
||||
Box::new(SubClause::And(
|
||||
Box::new(SubClause::Not(Box::new(SubClause::IsMounted(Id::Common(
|
||||
IdCommon::Keybindings,
|
||||
))))),
|
||||
Box::new(SubClause::And(
|
||||
Box::new(SubClause::Not(Box::new(SubClause::IsMounted(Id::Common(
|
||||
IdCommon::QuitPopup,
|
||||
))))),
|
||||
Box::new(SubClause::And(
|
||||
Box::new(SubClause::Not(Box::new(SubClause::IsMounted(Id::Common(
|
||||
IdCommon::SavePopup,
|
||||
))))),
|
||||
Box::new(SubClause::And(
|
||||
Box::new(SubClause::Not(Box::new(SubClause::IsMounted(Id::Ssh(
|
||||
IdSsh::DelSshKeyPopup,
|
||||
))))),
|
||||
Box::new(SubClause::Not(Box::new(SubClause::IsMounted(Id::Ssh(
|
||||
IdSsh::SshHost,
|
||||
))))),
|
||||
)),
|
||||
)),
|
||||
)),
|
||||
)),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,23 +27,15 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
// Locals
|
||||
use super::{Context, InputType, SetupActivity};
|
||||
use super::{components, Context, Id, IdCommon, IdConfig, SetupActivity, ViewLayout};
|
||||
use crate::filetransfer::FileTransferProtocol;
|
||||
use crate::fs::explorer::GroupDirs;
|
||||
use crate::ui::components::bytes::{Bytes, BytesPropsBuilder};
|
||||
use crate::utils::ui::draw_area_in;
|
||||
use crate::utils::fmt::fmt_bytes;
|
||||
|
||||
// Ext
|
||||
use std::path::PathBuf;
|
||||
use tui_realm_stdlib::{InputPropsBuilder, RadioPropsBuilder};
|
||||
use tuirealm::tui::{
|
||||
layout::{Constraint, Direction, Layout},
|
||||
style::Color,
|
||||
widgets::{BorderType, Borders, Clear},
|
||||
};
|
||||
use tuirealm::{
|
||||
props::{Alignment, PropsBuilder},
|
||||
Payload, Value, View,
|
||||
};
|
||||
use tuirealm::tui::layout::{Constraint, Direction, Layout};
|
||||
use tuirealm::{State, StateValue};
|
||||
|
||||
impl SetupActivity {
|
||||
// -- view
|
||||
@@ -52,92 +44,17 @@ impl SetupActivity {
|
||||
///
|
||||
/// Initialize setup view
|
||||
pub(super) fn init_setup(&mut self) {
|
||||
// Init view
|
||||
self.view = View::init();
|
||||
// Common stuff
|
||||
// Radio tab
|
||||
self.mount_header_tab(0);
|
||||
// Footer
|
||||
self.mount_footer();
|
||||
// Input fields
|
||||
self.mount_input(
|
||||
super::COMPONENT_INPUT_TEXT_EDITOR,
|
||||
"Text editor",
|
||||
Color::LightGreen,
|
||||
InputType::Text,
|
||||
);
|
||||
self.view.active(super::COMPONENT_INPUT_TEXT_EDITOR); // <-- Focus
|
||||
self.mount_radio(
|
||||
super::COMPONENT_RADIO_DEFAULT_PROTOCOL,
|
||||
"Default protocol",
|
||||
&["SFTP", "SCP", "FTP", "FTPS", "AWS S3"],
|
||||
0,
|
||||
Color::LightCyan,
|
||||
);
|
||||
self.mount_radio(
|
||||
super::COMPONENT_RADIO_HIDDEN_FILES,
|
||||
"Show hidden files (by default)?",
|
||||
&["Yes", "No"],
|
||||
0,
|
||||
Color::LightRed,
|
||||
);
|
||||
self.mount_radio(
|
||||
super::COMPONENT_RADIO_UPDATES,
|
||||
"Check for updates?",
|
||||
&["Yes", "No"],
|
||||
0,
|
||||
Color::LightYellow,
|
||||
);
|
||||
self.mount_radio(
|
||||
super::COMPONENT_RADIO_PROMPT_ON_FILE_REPLACE,
|
||||
"Prompt when replacing existing files?",
|
||||
&["Yes", "No"],
|
||||
0,
|
||||
Color::LightCyan,
|
||||
);
|
||||
self.mount_radio(
|
||||
super::COMPONENT_RADIO_GROUP_DIRS,
|
||||
"Group directories",
|
||||
&["Display first", "Display last", "No"],
|
||||
0,
|
||||
Color::LightMagenta,
|
||||
);
|
||||
self.mount_input(
|
||||
super::COMPONENT_INPUT_LOCAL_FILE_FMT,
|
||||
"File formatter syntax (local)",
|
||||
Color::LightGreen,
|
||||
InputType::Text,
|
||||
);
|
||||
self.mount_input(
|
||||
super::COMPONENT_INPUT_REMOTE_FILE_FMT,
|
||||
"File formatter syntax (remote)",
|
||||
Color::LightCyan,
|
||||
InputType::Text,
|
||||
);
|
||||
self.mount_radio(
|
||||
super::COMPONENT_RADIO_NOTIFICATIONS_ENABLED,
|
||||
"Enable notifications?",
|
||||
&["Yes", "No"],
|
||||
0,
|
||||
Color::LightRed,
|
||||
);
|
||||
self.view.mount(
|
||||
super::COMPONENT_INPUT_NOTIFICATIONS_THRESHOLD,
|
||||
Box::new(Bytes::new(
|
||||
BytesPropsBuilder::default()
|
||||
.with_foreground(Color::LightYellow)
|
||||
.with_borders(Borders::ALL, BorderType::Rounded, Color::LightYellow)
|
||||
.with_label("Notifications: minimum transfer size", Alignment::Left)
|
||||
.build(),
|
||||
)),
|
||||
);
|
||||
// Init view (and mount commons)
|
||||
self.new_app(ViewLayout::SetupForm);
|
||||
// Load values
|
||||
self.load_input_values();
|
||||
// Active text editor
|
||||
assert!(self.app.active(&Id::Config(IdConfig::TextEditor)).is_ok());
|
||||
}
|
||||
|
||||
pub(super) fn view_setup(&mut self) {
|
||||
let mut ctx: Context = self.context.take().unwrap();
|
||||
let _ = ctx.terminal().draw(|f| {
|
||||
let _ = ctx.terminal().raw_mut().draw(|f| {
|
||||
// Prepare main chunks
|
||||
let chunks = Layout::default()
|
||||
.direction(Direction::Vertical)
|
||||
@@ -152,8 +69,8 @@ impl SetupActivity {
|
||||
)
|
||||
.split(f.size());
|
||||
// Render common widget
|
||||
self.view.render(super::COMPONENT_RADIO_TAB, f, chunks[0]);
|
||||
self.view.render(super::COMPONENT_TEXT_FOOTER, f, chunks[2]);
|
||||
self.app.view(&Id::Common(IdCommon::Header), f, chunks[0]);
|
||||
self.app.view(&Id::Common(IdCommon::Footer), f, chunks[2]);
|
||||
// Make chunks (two columns)
|
||||
let ui_cfg_chunks = Layout::default()
|
||||
.direction(Direction::Horizontal)
|
||||
@@ -174,27 +91,27 @@ impl SetupActivity {
|
||||
.as_ref(),
|
||||
)
|
||||
.split(ui_cfg_chunks[0]);
|
||||
self.view
|
||||
.render(super::COMPONENT_INPUT_TEXT_EDITOR, f, ui_cfg_chunks_col1[0]);
|
||||
self.view.render(
|
||||
super::COMPONENT_RADIO_DEFAULT_PROTOCOL,
|
||||
self.app
|
||||
.view(&Id::Config(IdConfig::TextEditor), f, ui_cfg_chunks_col1[0]);
|
||||
self.app.view(
|
||||
&Id::Config(IdConfig::DefaultProtocol),
|
||||
f,
|
||||
ui_cfg_chunks_col1[1],
|
||||
);
|
||||
self.view.render(
|
||||
super::COMPONENT_RADIO_HIDDEN_FILES,
|
||||
self.app
|
||||
.view(&Id::Config(IdConfig::HiddenFiles), f, ui_cfg_chunks_col1[2]);
|
||||
self.app.view(
|
||||
&Id::Config(IdConfig::CheckUpdates),
|
||||
f,
|
||||
ui_cfg_chunks_col1[2],
|
||||
ui_cfg_chunks_col1[3],
|
||||
);
|
||||
self.view
|
||||
.render(super::COMPONENT_RADIO_UPDATES, f, ui_cfg_chunks_col1[3]);
|
||||
self.view.render(
|
||||
super::COMPONENT_RADIO_PROMPT_ON_FILE_REPLACE,
|
||||
self.app.view(
|
||||
&Id::Config(IdConfig::PromptOnFileReplace),
|
||||
f,
|
||||
ui_cfg_chunks_col1[4],
|
||||
);
|
||||
self.view
|
||||
.render(super::COMPONENT_RADIO_GROUP_DIRS, f, ui_cfg_chunks_col1[5]);
|
||||
self.app
|
||||
.view(&Id::Config(IdConfig::GroupDirs), f, ui_cfg_chunks_col1[5]);
|
||||
// Column 2
|
||||
let ui_cfg_chunks_col2 = Layout::default()
|
||||
.direction(Direction::Vertical)
|
||||
@@ -209,59 +126,28 @@ impl SetupActivity {
|
||||
.as_ref(),
|
||||
)
|
||||
.split(ui_cfg_chunks[1]);
|
||||
self.view.render(
|
||||
super::COMPONENT_INPUT_LOCAL_FILE_FMT,
|
||||
self.app.view(
|
||||
&Id::Config(IdConfig::LocalFileFmt),
|
||||
f,
|
||||
ui_cfg_chunks_col2[0],
|
||||
);
|
||||
self.view.render(
|
||||
super::COMPONENT_INPUT_REMOTE_FILE_FMT,
|
||||
self.app.view(
|
||||
&Id::Config(IdConfig::RemoteFileFmt),
|
||||
f,
|
||||
ui_cfg_chunks_col2[1],
|
||||
);
|
||||
self.view.render(
|
||||
super::COMPONENT_RADIO_NOTIFICATIONS_ENABLED,
|
||||
self.app.view(
|
||||
&Id::Config(IdConfig::NotificationsEnabled),
|
||||
f,
|
||||
ui_cfg_chunks_col2[2],
|
||||
);
|
||||
self.view.render(
|
||||
super::COMPONENT_INPUT_NOTIFICATIONS_THRESHOLD,
|
||||
self.app.view(
|
||||
&Id::Config(IdConfig::NotificationsThreshold),
|
||||
f,
|
||||
ui_cfg_chunks_col2[3],
|
||||
);
|
||||
// Popups
|
||||
if let Some(props) = self.view.get_props(super::COMPONENT_TEXT_ERROR) {
|
||||
if props.visible {
|
||||
let popup = draw_area_in(f.size(), 50, 10);
|
||||
f.render_widget(Clear, popup);
|
||||
// make popup
|
||||
self.view.render(super::COMPONENT_TEXT_ERROR, f, popup);
|
||||
}
|
||||
}
|
||||
if let Some(props) = self.view.get_props(super::COMPONENT_RADIO_QUIT) {
|
||||
if props.visible {
|
||||
// make popup
|
||||
let popup = draw_area_in(f.size(), 40, 10);
|
||||
f.render_widget(Clear, popup);
|
||||
self.view.render(super::COMPONENT_RADIO_QUIT, f, popup);
|
||||
}
|
||||
}
|
||||
if let Some(props) = self.view.get_props(super::COMPONENT_TEXT_HELP) {
|
||||
if props.visible {
|
||||
// make popup
|
||||
let popup = draw_area_in(f.size(), 50, 70);
|
||||
f.render_widget(Clear, popup);
|
||||
self.view.render(super::COMPONENT_TEXT_HELP, f, popup);
|
||||
}
|
||||
}
|
||||
if let Some(props) = self.view.get_props(super::COMPONENT_RADIO_SAVE) {
|
||||
if props.visible {
|
||||
// make popup
|
||||
let popup = draw_area_in(f.size(), 30, 10);
|
||||
f.render_widget(Clear, popup);
|
||||
self.view.render(super::COMPONENT_RADIO_SAVE, f, popup);
|
||||
}
|
||||
}
|
||||
self.view_popups(f);
|
||||
});
|
||||
// Put context back to context
|
||||
self.context = Some(ctx);
|
||||
@@ -272,125 +158,127 @@ impl SetupActivity {
|
||||
/// Load values from configuration into input fields
|
||||
pub(crate) fn load_input_values(&mut self) {
|
||||
// Text editor
|
||||
if let Some(props) = self.view.get_props(super::COMPONENT_INPUT_TEXT_EDITOR) {
|
||||
let text_editor: String =
|
||||
String::from(self.config().get_text_editor().as_path().to_string_lossy());
|
||||
let props = InputPropsBuilder::from(props)
|
||||
.with_value(text_editor)
|
||||
.build();
|
||||
let _ = self.view.update(super::COMPONENT_INPUT_TEXT_EDITOR, props);
|
||||
}
|
||||
let text_editor: String =
|
||||
String::from(self.config().get_text_editor().as_path().to_string_lossy());
|
||||
assert!(self
|
||||
.app
|
||||
.remount(
|
||||
Id::Config(IdConfig::TextEditor),
|
||||
Box::new(components::TextEditor::new(text_editor.as_str())),
|
||||
vec![]
|
||||
)
|
||||
.is_ok());
|
||||
// Protocol
|
||||
if let Some(props) = self.view.get_props(super::COMPONENT_RADIO_DEFAULT_PROTOCOL) {
|
||||
let protocol: usize = match self.config().get_default_protocol() {
|
||||
FileTransferProtocol::Sftp => 0,
|
||||
FileTransferProtocol::Scp => 1,
|
||||
FileTransferProtocol::Ftp(false) => 2,
|
||||
FileTransferProtocol::Ftp(true) => 3,
|
||||
FileTransferProtocol::AwsS3 => 4,
|
||||
};
|
||||
let props = RadioPropsBuilder::from(props).with_value(protocol).build();
|
||||
let _ = self
|
||||
.view
|
||||
.update(super::COMPONENT_RADIO_DEFAULT_PROTOCOL, props);
|
||||
}
|
||||
assert!(self
|
||||
.app
|
||||
.remount(
|
||||
Id::Config(IdConfig::DefaultProtocol),
|
||||
Box::new(components::DefaultProtocol::new(
|
||||
self.config().get_default_protocol()
|
||||
)),
|
||||
vec![]
|
||||
)
|
||||
.is_ok());
|
||||
// Hidden files
|
||||
if let Some(props) = self.view.get_props(super::COMPONENT_RADIO_HIDDEN_FILES) {
|
||||
let hidden: usize = match self.config().get_show_hidden_files() {
|
||||
true => 0,
|
||||
false => 1,
|
||||
};
|
||||
let props = RadioPropsBuilder::from(props).with_value(hidden).build();
|
||||
let _ = self.view.update(super::COMPONENT_RADIO_HIDDEN_FILES, props);
|
||||
}
|
||||
assert!(self
|
||||
.app
|
||||
.remount(
|
||||
Id::Config(IdConfig::HiddenFiles),
|
||||
Box::new(components::HiddenFiles::new(
|
||||
self.config().get_show_hidden_files()
|
||||
)),
|
||||
vec![]
|
||||
)
|
||||
.is_ok());
|
||||
// Updates
|
||||
if let Some(props) = self.view.get_props(super::COMPONENT_RADIO_UPDATES) {
|
||||
let updates: usize = match self.config().get_check_for_updates() {
|
||||
true => 0,
|
||||
false => 1,
|
||||
};
|
||||
let props = RadioPropsBuilder::from(props).with_value(updates).build();
|
||||
let _ = self.view.update(super::COMPONENT_RADIO_UPDATES, props);
|
||||
}
|
||||
assert!(self
|
||||
.app
|
||||
.remount(
|
||||
Id::Config(IdConfig::CheckUpdates),
|
||||
Box::new(components::CheckUpdates::new(
|
||||
self.config().get_check_for_updates()
|
||||
)),
|
||||
vec![]
|
||||
)
|
||||
.is_ok());
|
||||
// File replace
|
||||
if let Some(props) = self
|
||||
.view
|
||||
.get_props(super::COMPONENT_RADIO_PROMPT_ON_FILE_REPLACE)
|
||||
{
|
||||
let updates: usize = match self.config().get_prompt_on_file_replace() {
|
||||
true => 0,
|
||||
false => 1,
|
||||
};
|
||||
let props = RadioPropsBuilder::from(props).with_value(updates).build();
|
||||
let _ = self
|
||||
.view
|
||||
.update(super::COMPONENT_RADIO_PROMPT_ON_FILE_REPLACE, props);
|
||||
}
|
||||
assert!(self
|
||||
.app
|
||||
.remount(
|
||||
Id::Config(IdConfig::PromptOnFileReplace),
|
||||
Box::new(components::PromptOnFileReplace::new(
|
||||
self.config().get_prompt_on_file_replace()
|
||||
)),
|
||||
vec![]
|
||||
)
|
||||
.is_ok());
|
||||
// Group dirs
|
||||
if let Some(props) = self.view.get_props(super::COMPONENT_RADIO_GROUP_DIRS) {
|
||||
let dirs: usize = match self.config().get_group_dirs() {
|
||||
Some(GroupDirs::First) => 0,
|
||||
Some(GroupDirs::Last) => 1,
|
||||
None => 2,
|
||||
};
|
||||
let props = RadioPropsBuilder::from(props).with_value(dirs).build();
|
||||
let _ = self.view.update(super::COMPONENT_RADIO_GROUP_DIRS, props);
|
||||
}
|
||||
assert!(self
|
||||
.app
|
||||
.remount(
|
||||
Id::Config(IdConfig::GroupDirs),
|
||||
Box::new(components::GroupDirs::new(self.config().get_group_dirs())),
|
||||
vec![]
|
||||
)
|
||||
.is_ok());
|
||||
// Local File Fmt
|
||||
if let Some(props) = self.view.get_props(super::COMPONENT_INPUT_LOCAL_FILE_FMT) {
|
||||
let file_fmt: String = self.config().get_local_file_fmt().unwrap_or_default();
|
||||
let props = InputPropsBuilder::from(props).with_value(file_fmt).build();
|
||||
let _ = self
|
||||
.view
|
||||
.update(super::COMPONENT_INPUT_LOCAL_FILE_FMT, props);
|
||||
}
|
||||
assert!(self
|
||||
.app
|
||||
.remount(
|
||||
Id::Config(IdConfig::LocalFileFmt),
|
||||
Box::new(components::LocalFileFmt::new(
|
||||
&self.config().get_local_file_fmt().unwrap_or_default()
|
||||
)),
|
||||
vec![]
|
||||
)
|
||||
.is_ok());
|
||||
// Remote File Fmt
|
||||
if let Some(props) = self.view.get_props(super::COMPONENT_INPUT_REMOTE_FILE_FMT) {
|
||||
let file_fmt: String = self.config().get_remote_file_fmt().unwrap_or_default();
|
||||
let props = InputPropsBuilder::from(props).with_value(file_fmt).build();
|
||||
let _ = self
|
||||
.view
|
||||
.update(super::COMPONENT_INPUT_REMOTE_FILE_FMT, props);
|
||||
}
|
||||
assert!(self
|
||||
.app
|
||||
.remount(
|
||||
Id::Config(IdConfig::RemoteFileFmt),
|
||||
Box::new(components::RemoteFileFmt::new(
|
||||
&self.config().get_remote_file_fmt().unwrap_or_default()
|
||||
)),
|
||||
vec![]
|
||||
)
|
||||
.is_ok());
|
||||
// Notifications enabled
|
||||
if let Some(props) = self
|
||||
.view
|
||||
.get_props(super::COMPONENT_RADIO_NOTIFICATIONS_ENABLED)
|
||||
{
|
||||
let enabled: usize = match self.config().get_notifications() {
|
||||
true => 0,
|
||||
false => 1,
|
||||
};
|
||||
let props = RadioPropsBuilder::from(props).with_value(enabled).build();
|
||||
let _ = self
|
||||
.view
|
||||
.update(super::COMPONENT_RADIO_NOTIFICATIONS_ENABLED, props);
|
||||
}
|
||||
assert!(self
|
||||
.app
|
||||
.remount(
|
||||
Id::Config(IdConfig::NotificationsEnabled),
|
||||
Box::new(components::NotificationsEnabled::new(
|
||||
self.config().get_notifications()
|
||||
)),
|
||||
vec![]
|
||||
)
|
||||
.is_ok());
|
||||
// Notifications threshold
|
||||
if let Some(props) = self
|
||||
.view
|
||||
.get_props(super::COMPONENT_INPUT_NOTIFICATIONS_THRESHOLD)
|
||||
{
|
||||
let value: u64 = self.config().get_notification_threshold();
|
||||
let props = BytesPropsBuilder::from(props).with_value(value).build();
|
||||
let _ = self
|
||||
.view
|
||||
.update(super::COMPONENT_INPUT_NOTIFICATIONS_THRESHOLD, props);
|
||||
}
|
||||
assert!(self
|
||||
.app
|
||||
.remount(
|
||||
Id::Config(IdConfig::NotificationsThreshold),
|
||||
Box::new(components::NotificationsThreshold::new(&fmt_bytes(
|
||||
self.config().get_notification_threshold()
|
||||
))),
|
||||
vec![]
|
||||
)
|
||||
.is_ok());
|
||||
}
|
||||
|
||||
/// ### collect_input_values
|
||||
///
|
||||
/// Collect values from input and put them into the configuration
|
||||
pub(crate) fn collect_input_values(&mut self) {
|
||||
if let Some(Payload::One(Value::Str(editor))) =
|
||||
self.view.get_state(super::COMPONENT_INPUT_TEXT_EDITOR)
|
||||
if let Ok(State::One(StateValue::String(editor))) =
|
||||
self.app.state(&Id::Config(IdConfig::TextEditor))
|
||||
{
|
||||
self.config_mut()
|
||||
.set_text_editor(PathBuf::from(editor.as_str()));
|
||||
}
|
||||
if let Some(Payload::One(Value::Usize(protocol))) =
|
||||
self.view.get_state(super::COMPONENT_RADIO_DEFAULT_PROTOCOL)
|
||||
if let Ok(State::One(StateValue::Usize(protocol))) =
|
||||
self.app.state(&Id::Config(IdConfig::DefaultProtocol))
|
||||
{
|
||||
let protocol: FileTransferProtocol = match protocol {
|
||||
1 => FileTransferProtocol::Scp,
|
||||
@@ -401,37 +289,36 @@ impl SetupActivity {
|
||||
};
|
||||
self.config_mut().set_default_protocol(protocol);
|
||||
}
|
||||
if let Some(Payload::One(Value::Usize(opt))) =
|
||||
self.view.get_state(super::COMPONENT_RADIO_HIDDEN_FILES)
|
||||
if let Ok(State::One(StateValue::Usize(opt))) =
|
||||
self.app.state(&Id::Config(IdConfig::HiddenFiles))
|
||||
{
|
||||
let show: bool = matches!(opt, 0);
|
||||
self.config_mut().set_show_hidden_files(show);
|
||||
}
|
||||
if let Some(Payload::One(Value::Usize(opt))) =
|
||||
self.view.get_state(super::COMPONENT_RADIO_UPDATES)
|
||||
if let Ok(State::One(StateValue::Usize(opt))) =
|
||||
self.app.state(&Id::Config(IdConfig::CheckUpdates))
|
||||
{
|
||||
let check: bool = matches!(opt, 0);
|
||||
self.config_mut().set_check_for_updates(check);
|
||||
}
|
||||
if let Some(Payload::One(Value::Usize(opt))) = self
|
||||
.view
|
||||
.get_state(super::COMPONENT_RADIO_PROMPT_ON_FILE_REPLACE)
|
||||
if let Ok(State::One(StateValue::Usize(opt))) =
|
||||
self.app.state(&Id::Config(IdConfig::PromptOnFileReplace))
|
||||
{
|
||||
let check: bool = matches!(opt, 0);
|
||||
self.config_mut().set_prompt_on_file_replace(check);
|
||||
}
|
||||
if let Some(Payload::One(Value::Str(fmt))) =
|
||||
self.view.get_state(super::COMPONENT_INPUT_LOCAL_FILE_FMT)
|
||||
if let Ok(State::One(StateValue::String(fmt))) =
|
||||
self.app.state(&Id::Config(IdConfig::LocalFileFmt))
|
||||
{
|
||||
self.config_mut().set_local_file_fmt(fmt);
|
||||
}
|
||||
if let Some(Payload::One(Value::Str(fmt))) =
|
||||
self.view.get_state(super::COMPONENT_INPUT_REMOTE_FILE_FMT)
|
||||
if let Ok(State::One(StateValue::String(fmt))) =
|
||||
self.app.state(&Id::Config(IdConfig::RemoteFileFmt))
|
||||
{
|
||||
self.config_mut().set_remote_file_fmt(fmt);
|
||||
}
|
||||
if let Some(Payload::One(Value::Usize(opt))) =
|
||||
self.view.get_state(super::COMPONENT_RADIO_GROUP_DIRS)
|
||||
if let Ok(State::One(StateValue::Usize(opt))) =
|
||||
self.app.state(&Id::Config(IdConfig::GroupDirs))
|
||||
{
|
||||
let dirs: Option<GroupDirs> = match opt {
|
||||
0 => Some(GroupDirs::First),
|
||||
@@ -440,15 +327,14 @@ impl SetupActivity {
|
||||
};
|
||||
self.config_mut().set_group_dirs(dirs);
|
||||
}
|
||||
if let Some(Payload::One(Value::Usize(opt))) = self
|
||||
.view
|
||||
.get_state(super::COMPONENT_RADIO_NOTIFICATIONS_ENABLED)
|
||||
if let Ok(State::One(StateValue::Usize(opt))) =
|
||||
self.app.state(&Id::Config(IdConfig::NotificationsEnabled))
|
||||
{
|
||||
self.config_mut().set_notifications(opt == 0);
|
||||
}
|
||||
if let Some(Payload::One(Value::U64(bytes))) = self
|
||||
.view
|
||||
.get_state(super::COMPONENT_INPUT_NOTIFICATIONS_THRESHOLD)
|
||||
if let Ok(State::One(StateValue::U64(bytes))) = self
|
||||
.app
|
||||
.state(&Id::Config(IdConfig::NotificationsThreshold))
|
||||
{
|
||||
self.config_mut().set_notification_threshold(bytes);
|
||||
}
|
||||
|
||||
@@ -27,20 +27,12 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
// Locals
|
||||
use super::{Context, SetupActivity};
|
||||
use crate::ui::components::bookmark_list::{BookmarkList, BookmarkListPropsBuilder};
|
||||
use super::{components, Context, Id, IdCommon, IdSsh, SetupActivity, ViewLayout};
|
||||
use crate::utils::ui::draw_area_in;
|
||||
|
||||
// Ext
|
||||
use tui_realm_stdlib::{Input, InputPropsBuilder};
|
||||
use tuirealm::tui::{
|
||||
layout::{Constraint, Direction, Layout},
|
||||
style::Color,
|
||||
widgets::{BorderType, Borders, Clear},
|
||||
};
|
||||
use tuirealm::{
|
||||
props::{Alignment, PropsBuilder},
|
||||
View,
|
||||
};
|
||||
use tuirealm::tui::layout::{Constraint, Direction, Layout};
|
||||
use tuirealm::tui::widgets::Clear;
|
||||
|
||||
impl SetupActivity {
|
||||
// -- view
|
||||
@@ -49,34 +41,17 @@ impl SetupActivity {
|
||||
///
|
||||
/// Initialize ssh keys view
|
||||
pub(super) fn init_ssh_keys(&mut self) {
|
||||
// Init view
|
||||
self.view = View::init();
|
||||
// Common stuff
|
||||
// Radio tab
|
||||
// Radio tab
|
||||
self.mount_header_tab(1);
|
||||
// Footer
|
||||
self.mount_footer();
|
||||
self.view.mount(
|
||||
super::COMPONENT_LIST_SSH_KEYS,
|
||||
Box::new(BookmarkList::new(
|
||||
BookmarkListPropsBuilder::default()
|
||||
.with_title("SSH keys", Alignment::Left)
|
||||
.with_borders(Borders::ALL, BorderType::Plain, Color::LightGreen)
|
||||
.with_background(Color::LightGreen)
|
||||
.with_foreground(Color::Black)
|
||||
.build(),
|
||||
)),
|
||||
);
|
||||
// Give focus
|
||||
self.view.active(super::COMPONENT_LIST_SSH_KEYS);
|
||||
// Init view (and mount commons)
|
||||
self.new_app(ViewLayout::SshKeys);
|
||||
// Load keys
|
||||
self.reload_ssh_keys();
|
||||
// Give focus
|
||||
assert!(self.app.active(&Id::Ssh(IdSsh::SshKeys)).is_ok());
|
||||
}
|
||||
|
||||
pub(crate) fn view_ssh_keys(&mut self) {
|
||||
let mut ctx: Context = self.context.take().unwrap();
|
||||
let _ = ctx.terminal().draw(|f| {
|
||||
let _ = ctx.terminal().raw_mut().draw(|f| {
|
||||
// Prepare main chunks
|
||||
let chunks = Layout::default()
|
||||
.direction(Direction::Vertical)
|
||||
@@ -91,72 +66,31 @@ impl SetupActivity {
|
||||
)
|
||||
.split(f.size());
|
||||
// Render common widget
|
||||
self.view.render(super::COMPONENT_RADIO_TAB, f, chunks[0]);
|
||||
self.view.render(super::COMPONENT_TEXT_FOOTER, f, chunks[2]);
|
||||
self.view
|
||||
.render(super::COMPONENT_LIST_SSH_KEYS, f, chunks[1]);
|
||||
self.app.view(&Id::Common(IdCommon::Header), f, chunks[0]);
|
||||
self.app.view(&Id::Common(IdCommon::Footer), f, chunks[2]);
|
||||
self.app.view(&Id::Ssh(IdSsh::SshKeys), f, chunks[1]);
|
||||
// Popups
|
||||
if let Some(props) = self.view.get_props(super::COMPONENT_TEXT_ERROR) {
|
||||
if props.visible {
|
||||
let popup = draw_area_in(f.size(), 50, 10);
|
||||
f.render_widget(Clear, popup);
|
||||
// make popup
|
||||
self.view.render(super::COMPONENT_TEXT_ERROR, f, popup);
|
||||
}
|
||||
}
|
||||
if let Some(props) = self.view.get_props(super::COMPONENT_RADIO_QUIT) {
|
||||
if props.visible {
|
||||
// make popup
|
||||
let popup = draw_area_in(f.size(), 40, 10);
|
||||
f.render_widget(Clear, popup);
|
||||
self.view.render(super::COMPONENT_RADIO_QUIT, f, popup);
|
||||
}
|
||||
}
|
||||
if let Some(props) = self.view.get_props(super::COMPONENT_TEXT_HELP) {
|
||||
if props.visible {
|
||||
// make popup
|
||||
let popup = draw_area_in(f.size(), 50, 70);
|
||||
f.render_widget(Clear, popup);
|
||||
self.view.render(super::COMPONENT_TEXT_HELP, f, popup);
|
||||
}
|
||||
}
|
||||
if let Some(props) = self.view.get_props(super::COMPONENT_RADIO_SAVE) {
|
||||
if props.visible {
|
||||
// make popup
|
||||
let popup = draw_area_in(f.size(), 30, 10);
|
||||
f.render_widget(Clear, popup);
|
||||
self.view.render(super::COMPONENT_RADIO_SAVE, f, popup);
|
||||
}
|
||||
}
|
||||
if let Some(props) = self.view.get_props(super::COMPONENT_RADIO_DEL_SSH_KEY) {
|
||||
if props.visible {
|
||||
// make popup
|
||||
let popup = draw_area_in(f.size(), 30, 10);
|
||||
f.render_widget(Clear, popup);
|
||||
self.view
|
||||
.render(super::COMPONENT_RADIO_DEL_SSH_KEY, f, popup);
|
||||
}
|
||||
}
|
||||
if let Some(props) = self.view.get_props(super::COMPONENT_INPUT_SSH_HOST) {
|
||||
if props.visible {
|
||||
// make popup
|
||||
let popup = draw_area_in(f.size(), 50, 20);
|
||||
f.render_widget(Clear, popup);
|
||||
let popup_chunks = Layout::default()
|
||||
.direction(Direction::Vertical)
|
||||
.constraints(
|
||||
[
|
||||
Constraint::Length(3), // Host
|
||||
Constraint::Length(3), // Username
|
||||
]
|
||||
.as_ref(),
|
||||
)
|
||||
.split(popup);
|
||||
self.view
|
||||
.render(super::COMPONENT_INPUT_SSH_HOST, f, popup_chunks[0]);
|
||||
self.view
|
||||
.render(super::COMPONENT_INPUT_SSH_USERNAME, f, popup_chunks[1]);
|
||||
}
|
||||
self.view_popups(f);
|
||||
if self.app.mounted(&Id::Ssh(IdSsh::DelSshKeyPopup)) {
|
||||
let popup = draw_area_in(f.size(), 30, 10);
|
||||
f.render_widget(Clear, popup);
|
||||
self.app.view(&Id::Ssh(IdSsh::DelSshKeyPopup), f, popup);
|
||||
} else if self.app.mounted(&Id::Ssh(IdSsh::SshHost)) {
|
||||
let popup = draw_area_in(f.size(), 50, 20);
|
||||
f.render_widget(Clear, popup);
|
||||
let popup_chunks = Layout::default()
|
||||
.direction(Direction::Vertical)
|
||||
.constraints(
|
||||
[
|
||||
Constraint::Length(3), // Host
|
||||
Constraint::Length(3), // Username
|
||||
]
|
||||
.as_ref(),
|
||||
)
|
||||
.split(popup);
|
||||
self.app.view(&Id::Ssh(IdSsh::SshHost), f, popup_chunks[0]);
|
||||
self.app
|
||||
.view(&Id::Ssh(IdSsh::SshUsername), f, popup_chunks[1]);
|
||||
}
|
||||
});
|
||||
// Put context back to context
|
||||
@@ -169,82 +103,74 @@ impl SetupActivity {
|
||||
///
|
||||
/// Mount delete ssh key component
|
||||
pub(crate) fn mount_del_ssh_key(&mut self) {
|
||||
self.mount_radio_dialog(
|
||||
super::COMPONENT_RADIO_DEL_SSH_KEY,
|
||||
"Delete key?",
|
||||
&["Yes", "No"],
|
||||
1,
|
||||
Color::LightRed,
|
||||
);
|
||||
assert!(self
|
||||
.app
|
||||
.remount(
|
||||
Id::Ssh(IdSsh::DelSshKeyPopup),
|
||||
Box::new(components::DelSshKeyPopup::default()),
|
||||
vec![]
|
||||
)
|
||||
.is_ok());
|
||||
assert!(self.app.active(&Id::Ssh(IdSsh::DelSshKeyPopup)).is_ok());
|
||||
}
|
||||
|
||||
/// ### umount_del_ssh_key
|
||||
///
|
||||
/// Umount delete ssh key
|
||||
pub(crate) fn umount_del_ssh_key(&mut self) {
|
||||
self.view.umount(super::COMPONENT_RADIO_DEL_SSH_KEY);
|
||||
let _ = self.app.umount(&Id::Ssh(IdSsh::DelSshKeyPopup));
|
||||
}
|
||||
|
||||
/// ### mount_new_ssh_key
|
||||
///
|
||||
/// Mount new ssh key prompt
|
||||
pub(crate) fn mount_new_ssh_key(&mut self) {
|
||||
self.view.mount(
|
||||
super::COMPONENT_INPUT_SSH_HOST,
|
||||
Box::new(Input::new(
|
||||
InputPropsBuilder::default()
|
||||
.with_label("Hostname or address", Alignment::Center)
|
||||
.with_borders(
|
||||
Borders::TOP | Borders::RIGHT | Borders::LEFT,
|
||||
BorderType::Plain,
|
||||
Color::Reset,
|
||||
)
|
||||
.build(),
|
||||
)),
|
||||
);
|
||||
self.view.mount(
|
||||
super::COMPONENT_INPUT_SSH_USERNAME,
|
||||
Box::new(Input::new(
|
||||
InputPropsBuilder::default()
|
||||
.with_label("Username", Alignment::Center)
|
||||
.with_borders(
|
||||
Borders::BOTTOM | Borders::RIGHT | Borders::LEFT,
|
||||
BorderType::Plain,
|
||||
Color::Reset,
|
||||
)
|
||||
.build(),
|
||||
)),
|
||||
);
|
||||
self.view.active(super::COMPONENT_INPUT_SSH_HOST);
|
||||
assert!(self
|
||||
.app
|
||||
.remount(
|
||||
Id::Ssh(IdSsh::SshHost),
|
||||
Box::new(components::SshHost::default()),
|
||||
vec![]
|
||||
)
|
||||
.is_ok());
|
||||
assert!(self
|
||||
.app
|
||||
.remount(
|
||||
Id::Ssh(IdSsh::SshUsername),
|
||||
Box::new(components::SshUsername::default()),
|
||||
vec![]
|
||||
)
|
||||
.is_ok());
|
||||
assert!(self.app.active(&Id::Ssh(IdSsh::SshHost)).is_ok());
|
||||
}
|
||||
|
||||
/// ### umount_new_ssh_key
|
||||
///
|
||||
/// Umount new ssh key prompt
|
||||
pub(crate) fn umount_new_ssh_key(&mut self) {
|
||||
self.view.umount(super::COMPONENT_INPUT_SSH_HOST);
|
||||
self.view.umount(super::COMPONENT_INPUT_SSH_USERNAME);
|
||||
let _ = self.app.umount(&Id::Ssh(IdSsh::SshUsername));
|
||||
let _ = self.app.umount(&Id::Ssh(IdSsh::SshHost));
|
||||
}
|
||||
|
||||
/// ### reload_ssh_keys
|
||||
///
|
||||
/// Reload ssh keys
|
||||
pub(crate) fn reload_ssh_keys(&mut self) {
|
||||
// get props
|
||||
if let Some(props) = self.view.get_props(super::COMPONENT_LIST_SSH_KEYS) {
|
||||
// Create texts
|
||||
let keys: Vec<String> = self
|
||||
.config()
|
||||
.iter_ssh_keys()
|
||||
.map(|x| {
|
||||
let (addr, username, _) = self.config().get_ssh_key(x).ok().unwrap().unwrap();
|
||||
format!("{} at {}", addr, username)
|
||||
})
|
||||
.collect();
|
||||
let props = BookmarkListPropsBuilder::from(props)
|
||||
.with_bookmarks(keys)
|
||||
.build();
|
||||
self.view.update(super::COMPONENT_LIST_SSH_KEYS, props);
|
||||
}
|
||||
let keys: Vec<String> = self
|
||||
.config()
|
||||
.iter_ssh_keys()
|
||||
.map(|x| {
|
||||
let (addr, username, _) = self.config().get_ssh_key(x).ok().unwrap().unwrap();
|
||||
format!("{} at {}", addr, username)
|
||||
})
|
||||
.collect();
|
||||
assert!(self
|
||||
.app
|
||||
.remount(
|
||||
Id::Ssh(IdSsh::SshKeys),
|
||||
Box::new(components::SshKeys::new(&keys)),
|
||||
vec![]
|
||||
)
|
||||
.is_ok());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,22 +27,10 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
// Locals
|
||||
use super::{Context, SetupActivity};
|
||||
use crate::config::themes::Theme;
|
||||
use crate::ui::components::color_picker::{ColorPicker, ColorPickerPropsBuilder};
|
||||
use crate::utils::parser::parse_color;
|
||||
use crate::utils::ui::draw_area_in;
|
||||
use super::{components, Context, Id, IdCommon, IdTheme, SetupActivity, Theme, ViewLayout};
|
||||
|
||||
// Ext
|
||||
use tui_realm_stdlib::{Label, LabelPropsBuilder};
|
||||
use tuirealm::tui::{
|
||||
layout::{Constraint, Direction, Layout},
|
||||
style::Color,
|
||||
widgets::{BorderType, Borders, Clear},
|
||||
};
|
||||
use tuirealm::{
|
||||
props::{Alignment, PropsBuilder},
|
||||
Payload, Value, View,
|
||||
};
|
||||
use tuirealm::tui::layout::{Constraint, Direction, Layout};
|
||||
|
||||
impl SetupActivity {
|
||||
// -- view
|
||||
@@ -51,96 +39,19 @@ impl SetupActivity {
|
||||
///
|
||||
/// Initialize thene view
|
||||
pub(super) fn init_theme(&mut self) {
|
||||
// Init view
|
||||
self.view = View::init();
|
||||
// Common stuff
|
||||
// Radio tab
|
||||
self.mount_header_tab(2);
|
||||
// Footer
|
||||
self.mount_footer();
|
||||
// auth colors
|
||||
self.mount_title(super::COMPONENT_COLOR_AUTH_TITLE, "Authentication styles");
|
||||
self.mount_color_picker(super::COMPONENT_COLOR_AUTH_PROTOCOL, "Protocol");
|
||||
self.mount_color_picker(super::COMPONENT_COLOR_AUTH_ADDR, "Ip address");
|
||||
self.mount_color_picker(super::COMPONENT_COLOR_AUTH_PORT, "Port");
|
||||
self.mount_color_picker(super::COMPONENT_COLOR_AUTH_USERNAME, "Username");
|
||||
self.mount_color_picker(super::COMPONENT_COLOR_AUTH_PASSWORD, "Password");
|
||||
self.mount_color_picker(super::COMPONENT_COLOR_AUTH_BOOKMARKS, "Bookmarks");
|
||||
self.mount_color_picker(super::COMPONENT_COLOR_AUTH_RECENTS, "Recent connections");
|
||||
// Misc
|
||||
self.mount_title(super::COMPONENT_COLOR_MISC_TITLE, "Misc styles");
|
||||
self.mount_color_picker(super::COMPONENT_COLOR_MISC_ERROR, "Error");
|
||||
self.mount_color_picker(super::COMPONENT_COLOR_MISC_INFO, "Info dialogs");
|
||||
self.mount_color_picker(super::COMPONENT_COLOR_MISC_INPUT, "Input fields");
|
||||
self.mount_color_picker(super::COMPONENT_COLOR_MISC_KEYS, "Key strokes");
|
||||
self.mount_color_picker(super::COMPONENT_COLOR_MISC_QUIT, "Quit dialogs");
|
||||
self.mount_color_picker(super::COMPONENT_COLOR_MISC_SAVE, "Save confirmations");
|
||||
self.mount_color_picker(super::COMPONENT_COLOR_MISC_WARN, "Warnings");
|
||||
// Transfer (1)
|
||||
self.mount_title(super::COMPONENT_COLOR_TRANSFER_TITLE, "Transfer styles");
|
||||
self.mount_color_picker(
|
||||
super::COMPONENT_COLOR_TRANSFER_EXPLORER_LOCAL_BG,
|
||||
"Local explorer background",
|
||||
);
|
||||
self.mount_color_picker(
|
||||
super::COMPONENT_COLOR_TRANSFER_EXPLORER_LOCAL_FG,
|
||||
"Local explorer foreground",
|
||||
);
|
||||
self.mount_color_picker(
|
||||
super::COMPONENT_COLOR_TRANSFER_EXPLORER_LOCAL_HG,
|
||||
"Local explorer highlighted",
|
||||
);
|
||||
self.mount_color_picker(
|
||||
super::COMPONENT_COLOR_TRANSFER_EXPLORER_REMOTE_BG,
|
||||
"Remote explorer background",
|
||||
);
|
||||
self.mount_color_picker(
|
||||
super::COMPONENT_COLOR_TRANSFER_EXPLORER_REMOTE_FG,
|
||||
"Remote explorer foreground",
|
||||
);
|
||||
self.mount_color_picker(
|
||||
super::COMPONENT_COLOR_TRANSFER_EXPLORER_REMOTE_HG,
|
||||
"Remote explorer highlighted",
|
||||
);
|
||||
self.mount_color_picker(
|
||||
super::COMPONENT_COLOR_TRANSFER_PROG_BAR_FULL,
|
||||
"'Full transfer' Progress bar",
|
||||
);
|
||||
self.mount_color_picker(
|
||||
super::COMPONENT_COLOR_TRANSFER_PROG_BAR_PARTIAL,
|
||||
"'Partial transfer' Progress bar",
|
||||
);
|
||||
// Transfer (2)
|
||||
self.mount_title(
|
||||
super::COMPONENT_COLOR_TRANSFER_TITLE_2,
|
||||
"Transfer styles (2)",
|
||||
);
|
||||
self.mount_color_picker(
|
||||
super::COMPONENT_COLOR_TRANSFER_LOG_BG,
|
||||
"Log window background",
|
||||
);
|
||||
self.mount_color_picker(super::COMPONENT_COLOR_TRANSFER_LOG_WIN, "Log window");
|
||||
self.mount_color_picker(
|
||||
super::COMPONENT_COLOR_TRANSFER_STATUS_SORTING,
|
||||
"File sorting",
|
||||
);
|
||||
self.mount_color_picker(
|
||||
super::COMPONENT_COLOR_TRANSFER_STATUS_HIDDEN,
|
||||
"Hidden files",
|
||||
);
|
||||
self.mount_color_picker(
|
||||
super::COMPONENT_COLOR_TRANSFER_STATUS_SYNC,
|
||||
"Synchronized browsing",
|
||||
);
|
||||
// Init view (and mount commons)
|
||||
self.new_app(ViewLayout::Theme);
|
||||
// Mount titles
|
||||
self.load_titles();
|
||||
// Load styles
|
||||
self.load_styles();
|
||||
// Active first field
|
||||
self.view.active(super::COMPONENT_COLOR_AUTH_PROTOCOL);
|
||||
assert!(self.app.active(&Id::Theme(IdTheme::AuthProtocol)).is_ok());
|
||||
}
|
||||
|
||||
pub(super) fn view_theme(&mut self) {
|
||||
let mut ctx: Context = self.context.take().unwrap();
|
||||
let _ = ctx.terminal().draw(|f| {
|
||||
let _ = ctx.terminal().raw_mut().draw(|f| {
|
||||
// Prepare main chunks
|
||||
let chunks = Layout::default()
|
||||
.direction(Direction::Vertical)
|
||||
@@ -155,8 +66,8 @@ impl SetupActivity {
|
||||
)
|
||||
.split(f.size());
|
||||
// Render common widget
|
||||
self.view.render(super::COMPONENT_RADIO_TAB, f, chunks[0]);
|
||||
self.view.render(super::COMPONENT_TEXT_FOOTER, f, chunks[2]);
|
||||
self.app.view(&Id::Common(IdCommon::Header), f, chunks[0]);
|
||||
self.app.view(&Id::Common(IdCommon::Footer), f, chunks[2]);
|
||||
// Make chunks
|
||||
let colors_layout = Layout::default()
|
||||
.direction(Direction::Horizontal)
|
||||
@@ -186,34 +97,22 @@ impl SetupActivity {
|
||||
.as_ref(),
|
||||
)
|
||||
.split(colors_layout[0]);
|
||||
self.view
|
||||
.render(super::COMPONENT_COLOR_AUTH_TITLE, f, auth_colors_layout[0]);
|
||||
self.view.render(
|
||||
super::COMPONENT_COLOR_AUTH_PROTOCOL,
|
||||
f,
|
||||
auth_colors_layout[1],
|
||||
);
|
||||
self.view
|
||||
.render(super::COMPONENT_COLOR_AUTH_ADDR, f, auth_colors_layout[2]);
|
||||
self.view
|
||||
.render(super::COMPONENT_COLOR_AUTH_PORT, f, auth_colors_layout[3]);
|
||||
self.view.render(
|
||||
super::COMPONENT_COLOR_AUTH_USERNAME,
|
||||
f,
|
||||
auth_colors_layout[4],
|
||||
);
|
||||
self.view.render(
|
||||
super::COMPONENT_COLOR_AUTH_PASSWORD,
|
||||
f,
|
||||
auth_colors_layout[5],
|
||||
);
|
||||
self.view.render(
|
||||
super::COMPONENT_COLOR_AUTH_BOOKMARKS,
|
||||
f,
|
||||
auth_colors_layout[6],
|
||||
);
|
||||
self.view.render(
|
||||
super::COMPONENT_COLOR_AUTH_RECENTS,
|
||||
self.app
|
||||
.view(&Id::Theme(IdTheme::AuthTitle), f, auth_colors_layout[0]);
|
||||
self.app
|
||||
.view(&Id::Theme(IdTheme::AuthProtocol), f, auth_colors_layout[1]);
|
||||
self.app
|
||||
.view(&Id::Theme(IdTheme::AuthAddress), f, auth_colors_layout[2]);
|
||||
self.app
|
||||
.view(&Id::Theme(IdTheme::AuthPort), f, auth_colors_layout[3]);
|
||||
self.app
|
||||
.view(&Id::Theme(IdTheme::AuthUsername), f, auth_colors_layout[4]);
|
||||
self.app
|
||||
.view(&Id::Theme(IdTheme::AuthPassword), f, auth_colors_layout[5]);
|
||||
self.app
|
||||
.view(&Id::Theme(IdTheme::AuthBookmarks), f, auth_colors_layout[6]);
|
||||
self.app.view(
|
||||
&Id::Theme(IdTheme::AuthRecentHosts),
|
||||
f,
|
||||
auth_colors_layout[7],
|
||||
);
|
||||
@@ -233,22 +132,22 @@ impl SetupActivity {
|
||||
.as_ref(),
|
||||
)
|
||||
.split(colors_layout[1]);
|
||||
self.view
|
||||
.render(super::COMPONENT_COLOR_MISC_TITLE, f, misc_colors_layout[0]);
|
||||
self.view
|
||||
.render(super::COMPONENT_COLOR_MISC_ERROR, f, misc_colors_layout[1]);
|
||||
self.view
|
||||
.render(super::COMPONENT_COLOR_MISC_INFO, f, misc_colors_layout[2]);
|
||||
self.view
|
||||
.render(super::COMPONENT_COLOR_MISC_INPUT, f, misc_colors_layout[3]);
|
||||
self.view
|
||||
.render(super::COMPONENT_COLOR_MISC_KEYS, f, misc_colors_layout[4]);
|
||||
self.view
|
||||
.render(super::COMPONENT_COLOR_MISC_QUIT, f, misc_colors_layout[5]);
|
||||
self.view
|
||||
.render(super::COMPONENT_COLOR_MISC_SAVE, f, misc_colors_layout[6]);
|
||||
self.view
|
||||
.render(super::COMPONENT_COLOR_MISC_WARN, f, misc_colors_layout[7]);
|
||||
self.app
|
||||
.view(&Id::Theme(IdTheme::MiscTitle), f, misc_colors_layout[0]);
|
||||
self.app
|
||||
.view(&Id::Theme(IdTheme::MiscError), f, misc_colors_layout[1]);
|
||||
self.app
|
||||
.view(&Id::Theme(IdTheme::MiscInfo), f, misc_colors_layout[2]);
|
||||
self.app
|
||||
.view(&Id::Theme(IdTheme::MiscInput), f, misc_colors_layout[3]);
|
||||
self.app
|
||||
.view(&Id::Theme(IdTheme::MiscKeys), f, misc_colors_layout[4]);
|
||||
self.app
|
||||
.view(&Id::Theme(IdTheme::MiscQuit), f, misc_colors_layout[5]);
|
||||
self.app
|
||||
.view(&Id::Theme(IdTheme::MiscSave), f, misc_colors_layout[6]);
|
||||
self.app
|
||||
.view(&Id::Theme(IdTheme::MiscWarn), f, misc_colors_layout[7]);
|
||||
|
||||
let transfer_colors_layout_col1 = Layout::default()
|
||||
.direction(Direction::Vertical)
|
||||
@@ -266,38 +165,38 @@ impl SetupActivity {
|
||||
.as_ref(),
|
||||
)
|
||||
.split(colors_layout[2]);
|
||||
self.view.render(
|
||||
super::COMPONENT_COLOR_TRANSFER_TITLE,
|
||||
self.app.view(
|
||||
&Id::Theme(IdTheme::TransferTitle),
|
||||
f,
|
||||
transfer_colors_layout_col1[0],
|
||||
);
|
||||
self.view.render(
|
||||
super::COMPONENT_COLOR_TRANSFER_EXPLORER_LOCAL_BG,
|
||||
self.app.view(
|
||||
&Id::Theme(IdTheme::ExplorerLocalBg),
|
||||
f,
|
||||
transfer_colors_layout_col1[1],
|
||||
);
|
||||
self.view.render(
|
||||
super::COMPONENT_COLOR_TRANSFER_EXPLORER_LOCAL_FG,
|
||||
self.app.view(
|
||||
&Id::Theme(IdTheme::ExplorerLocalFg),
|
||||
f,
|
||||
transfer_colors_layout_col1[2],
|
||||
);
|
||||
self.view.render(
|
||||
super::COMPONENT_COLOR_TRANSFER_EXPLORER_LOCAL_HG,
|
||||
self.app.view(
|
||||
&Id::Theme(IdTheme::ExplorerLocalHg),
|
||||
f,
|
||||
transfer_colors_layout_col1[3],
|
||||
);
|
||||
self.view.render(
|
||||
super::COMPONENT_COLOR_TRANSFER_EXPLORER_REMOTE_BG,
|
||||
self.app.view(
|
||||
&Id::Theme(IdTheme::ExplorerRemoteBg),
|
||||
f,
|
||||
transfer_colors_layout_col1[4],
|
||||
);
|
||||
self.view.render(
|
||||
super::COMPONENT_COLOR_TRANSFER_EXPLORER_REMOTE_FG,
|
||||
self.app.view(
|
||||
&Id::Theme(IdTheme::ExplorerRemoteFg),
|
||||
f,
|
||||
transfer_colors_layout_col1[5],
|
||||
);
|
||||
self.view.render(
|
||||
super::COMPONENT_COLOR_TRANSFER_EXPLORER_REMOTE_HG,
|
||||
self.app.view(
|
||||
&Id::Theme(IdTheme::ExplorerRemoteHg),
|
||||
f,
|
||||
transfer_colors_layout_col1[6],
|
||||
);
|
||||
@@ -317,332 +216,328 @@ impl SetupActivity {
|
||||
.as_ref(),
|
||||
)
|
||||
.split(colors_layout[3]);
|
||||
self.view.render(
|
||||
super::COMPONENT_COLOR_TRANSFER_TITLE_2,
|
||||
self.app.view(
|
||||
&Id::Theme(IdTheme::TransferTitle2),
|
||||
f,
|
||||
transfer_colors_layout_col2[0],
|
||||
);
|
||||
self.view.render(
|
||||
super::COMPONENT_COLOR_TRANSFER_PROG_BAR_FULL,
|
||||
self.app.view(
|
||||
&Id::Theme(IdTheme::ProgBarFull),
|
||||
f,
|
||||
transfer_colors_layout_col2[1],
|
||||
);
|
||||
self.view.render(
|
||||
super::COMPONENT_COLOR_TRANSFER_PROG_BAR_PARTIAL,
|
||||
self.app.view(
|
||||
&Id::Theme(IdTheme::ProgBarPartial),
|
||||
f,
|
||||
transfer_colors_layout_col2[2],
|
||||
);
|
||||
self.view.render(
|
||||
super::COMPONENT_COLOR_TRANSFER_LOG_BG,
|
||||
self.app.view(
|
||||
&Id::Theme(IdTheme::LogBg),
|
||||
f,
|
||||
transfer_colors_layout_col2[3],
|
||||
);
|
||||
self.view.render(
|
||||
super::COMPONENT_COLOR_TRANSFER_LOG_WIN,
|
||||
self.app.view(
|
||||
&Id::Theme(IdTheme::LogWindow),
|
||||
f,
|
||||
transfer_colors_layout_col2[4],
|
||||
);
|
||||
self.view.render(
|
||||
super::COMPONENT_COLOR_TRANSFER_STATUS_SORTING,
|
||||
self.app.view(
|
||||
&Id::Theme(IdTheme::StatusSorting),
|
||||
f,
|
||||
transfer_colors_layout_col2[5],
|
||||
);
|
||||
self.view.render(
|
||||
super::COMPONENT_COLOR_TRANSFER_STATUS_HIDDEN,
|
||||
self.app.view(
|
||||
&Id::Theme(IdTheme::StatusHidden),
|
||||
f,
|
||||
transfer_colors_layout_col2[6],
|
||||
);
|
||||
self.view.render(
|
||||
super::COMPONENT_COLOR_TRANSFER_STATUS_SYNC,
|
||||
self.app.view(
|
||||
&Id::Theme(IdTheme::StatusSync),
|
||||
f,
|
||||
transfer_colors_layout_col2[7],
|
||||
);
|
||||
// Popups
|
||||
if let Some(props) = self.view.get_props(super::COMPONENT_TEXT_ERROR) {
|
||||
if props.visible {
|
||||
let popup = draw_area_in(f.size(), 50, 10);
|
||||
f.render_widget(Clear, popup);
|
||||
// make popup
|
||||
self.view.render(super::COMPONENT_TEXT_ERROR, f, popup);
|
||||
}
|
||||
}
|
||||
if let Some(props) = self.view.get_props(super::COMPONENT_RADIO_QUIT) {
|
||||
if props.visible {
|
||||
// make popup
|
||||
let popup = draw_area_in(f.size(), 40, 10);
|
||||
f.render_widget(Clear, popup);
|
||||
self.view.render(super::COMPONENT_RADIO_QUIT, f, popup);
|
||||
}
|
||||
}
|
||||
if let Some(props) = self.view.get_props(super::COMPONENT_TEXT_HELP) {
|
||||
if props.visible {
|
||||
// make popup
|
||||
let popup = draw_area_in(f.size(), 50, 70);
|
||||
f.render_widget(Clear, popup);
|
||||
self.view.render(super::COMPONENT_TEXT_HELP, f, popup);
|
||||
}
|
||||
}
|
||||
if let Some(props) = self.view.get_props(super::COMPONENT_RADIO_SAVE) {
|
||||
if props.visible {
|
||||
// make popup
|
||||
let popup = draw_area_in(f.size(), 30, 10);
|
||||
f.render_widget(Clear, popup);
|
||||
self.view.render(super::COMPONENT_RADIO_SAVE, f, popup);
|
||||
}
|
||||
}
|
||||
self.view_popups(f);
|
||||
});
|
||||
// Put context back to context
|
||||
self.context = Some(ctx);
|
||||
}
|
||||
|
||||
fn load_titles(&mut self) {
|
||||
assert!(self
|
||||
.app
|
||||
.remount(
|
||||
Id::Theme(IdTheme::AuthTitle),
|
||||
Box::new(components::AuthTitle::default()),
|
||||
vec![]
|
||||
)
|
||||
.is_ok());
|
||||
assert!(self
|
||||
.app
|
||||
.remount(
|
||||
Id::Theme(IdTheme::MiscTitle),
|
||||
Box::new(components::MiscTitle::default()),
|
||||
vec![]
|
||||
)
|
||||
.is_ok());
|
||||
assert!(self
|
||||
.app
|
||||
.remount(
|
||||
Id::Theme(IdTheme::TransferTitle),
|
||||
Box::new(components::TransferTitle::default()),
|
||||
vec![]
|
||||
)
|
||||
.is_ok());
|
||||
assert!(self
|
||||
.app
|
||||
.remount(
|
||||
Id::Theme(IdTheme::TransferTitle2),
|
||||
Box::new(components::TransferTitle2::default()),
|
||||
vec![]
|
||||
)
|
||||
.is_ok());
|
||||
}
|
||||
|
||||
/// ### load_styles
|
||||
///
|
||||
/// Load values from theme into input fields
|
||||
pub(crate) fn load_styles(&mut self) {
|
||||
let theme: Theme = self.theme().clone();
|
||||
self.update_color(super::COMPONENT_COLOR_AUTH_ADDR, theme.auth_address);
|
||||
self.update_color(super::COMPONENT_COLOR_AUTH_BOOKMARKS, theme.auth_bookmarks);
|
||||
self.update_color(super::COMPONENT_COLOR_AUTH_PASSWORD, theme.auth_password);
|
||||
self.update_color(super::COMPONENT_COLOR_AUTH_PORT, theme.auth_port);
|
||||
self.update_color(super::COMPONENT_COLOR_AUTH_PROTOCOL, theme.auth_protocol);
|
||||
self.update_color(super::COMPONENT_COLOR_AUTH_RECENTS, theme.auth_recents);
|
||||
self.update_color(super::COMPONENT_COLOR_AUTH_USERNAME, theme.auth_username);
|
||||
self.update_color(super::COMPONENT_COLOR_MISC_ERROR, theme.misc_error_dialog);
|
||||
self.update_color(super::COMPONENT_COLOR_MISC_INFO, theme.misc_info_dialog);
|
||||
self.update_color(super::COMPONENT_COLOR_MISC_INPUT, theme.misc_input_dialog);
|
||||
self.update_color(super::COMPONENT_COLOR_MISC_KEYS, theme.misc_keys);
|
||||
self.update_color(super::COMPONENT_COLOR_MISC_QUIT, theme.misc_quit_dialog);
|
||||
self.update_color(super::COMPONENT_COLOR_MISC_SAVE, theme.misc_save_dialog);
|
||||
self.update_color(super::COMPONENT_COLOR_MISC_WARN, theme.misc_warn_dialog);
|
||||
self.update_color(
|
||||
super::COMPONENT_COLOR_TRANSFER_EXPLORER_LOCAL_BG,
|
||||
theme.transfer_local_explorer_background,
|
||||
);
|
||||
self.update_color(
|
||||
super::COMPONENT_COLOR_TRANSFER_EXPLORER_LOCAL_FG,
|
||||
theme.transfer_local_explorer_foreground,
|
||||
);
|
||||
self.update_color(
|
||||
super::COMPONENT_COLOR_TRANSFER_EXPLORER_LOCAL_HG,
|
||||
theme.transfer_local_explorer_highlighted,
|
||||
);
|
||||
self.update_color(
|
||||
super::COMPONENT_COLOR_TRANSFER_EXPLORER_REMOTE_BG,
|
||||
theme.transfer_remote_explorer_background,
|
||||
);
|
||||
self.update_color(
|
||||
super::COMPONENT_COLOR_TRANSFER_EXPLORER_REMOTE_FG,
|
||||
theme.transfer_remote_explorer_foreground,
|
||||
);
|
||||
self.update_color(
|
||||
super::COMPONENT_COLOR_TRANSFER_EXPLORER_REMOTE_HG,
|
||||
theme.transfer_remote_explorer_highlighted,
|
||||
);
|
||||
self.update_color(
|
||||
super::COMPONENT_COLOR_TRANSFER_PROG_BAR_FULL,
|
||||
theme.transfer_progress_bar_full,
|
||||
);
|
||||
self.update_color(
|
||||
super::COMPONENT_COLOR_TRANSFER_PROG_BAR_PARTIAL,
|
||||
theme.transfer_progress_bar_partial,
|
||||
);
|
||||
self.update_color(
|
||||
super::COMPONENT_COLOR_TRANSFER_LOG_BG,
|
||||
theme.transfer_log_background,
|
||||
);
|
||||
self.update_color(
|
||||
super::COMPONENT_COLOR_TRANSFER_LOG_WIN,
|
||||
theme.transfer_log_window,
|
||||
);
|
||||
self.update_color(
|
||||
super::COMPONENT_COLOR_TRANSFER_STATUS_SORTING,
|
||||
theme.transfer_status_sorting,
|
||||
);
|
||||
self.update_color(
|
||||
super::COMPONENT_COLOR_TRANSFER_STATUS_HIDDEN,
|
||||
theme.transfer_status_hidden,
|
||||
);
|
||||
self.update_color(
|
||||
super::COMPONENT_COLOR_TRANSFER_STATUS_SYNC,
|
||||
theme.transfer_status_sync_browsing,
|
||||
);
|
||||
}
|
||||
|
||||
/// ### collect_styles
|
||||
///
|
||||
/// Collect values from input and put them into the theme.
|
||||
/// If a component has an invalid color, returns Err(component_id)
|
||||
pub(crate) fn collect_styles(&mut self) -> Result<(), &'static str> {
|
||||
// auth
|
||||
let auth_address: Color = self
|
||||
.get_color(super::COMPONENT_COLOR_AUTH_ADDR)
|
||||
.map_err(|_| super::COMPONENT_COLOR_AUTH_ADDR)?;
|
||||
let auth_bookmarks: Color = self
|
||||
.get_color(super::COMPONENT_COLOR_AUTH_BOOKMARKS)
|
||||
.map_err(|_| super::COMPONENT_COLOR_AUTH_BOOKMARKS)?;
|
||||
let auth_password: Color = self
|
||||
.get_color(super::COMPONENT_COLOR_AUTH_PASSWORD)
|
||||
.map_err(|_| super::COMPONENT_COLOR_AUTH_PASSWORD)?;
|
||||
let auth_port: Color = self
|
||||
.get_color(super::COMPONENT_COLOR_AUTH_PORT)
|
||||
.map_err(|_| super::COMPONENT_COLOR_AUTH_PORT)?;
|
||||
let auth_protocol: Color = self
|
||||
.get_color(super::COMPONENT_COLOR_AUTH_PROTOCOL)
|
||||
.map_err(|_| super::COMPONENT_COLOR_AUTH_PROTOCOL)?;
|
||||
let auth_recents: Color = self
|
||||
.get_color(super::COMPONENT_COLOR_AUTH_RECENTS)
|
||||
.map_err(|_| super::COMPONENT_COLOR_AUTH_RECENTS)?;
|
||||
let auth_username: Color = self
|
||||
.get_color(super::COMPONENT_COLOR_AUTH_USERNAME)
|
||||
.map_err(|_| super::COMPONENT_COLOR_AUTH_USERNAME)?;
|
||||
// misc
|
||||
let misc_error_dialog: Color = self
|
||||
.get_color(super::COMPONENT_COLOR_MISC_ERROR)
|
||||
.map_err(|_| super::COMPONENT_COLOR_MISC_ERROR)?;
|
||||
let misc_info_dialog: Color = self
|
||||
.get_color(super::COMPONENT_COLOR_MISC_INFO)
|
||||
.map_err(|_| super::COMPONENT_COLOR_MISC_INFO)?;
|
||||
let misc_input_dialog: Color = self
|
||||
.get_color(super::COMPONENT_COLOR_MISC_INPUT)
|
||||
.map_err(|_| super::COMPONENT_COLOR_MISC_INPUT)?;
|
||||
let misc_keys: Color = self
|
||||
.get_color(super::COMPONENT_COLOR_MISC_KEYS)
|
||||
.map_err(|_| super::COMPONENT_COLOR_MISC_KEYS)?;
|
||||
let misc_quit_dialog: Color = self
|
||||
.get_color(super::COMPONENT_COLOR_MISC_QUIT)
|
||||
.map_err(|_| super::COMPONENT_COLOR_MISC_QUIT)?;
|
||||
let misc_save_dialog: Color = self
|
||||
.get_color(super::COMPONENT_COLOR_MISC_SAVE)
|
||||
.map_err(|_| super::COMPONENT_COLOR_MISC_SAVE)?;
|
||||
let misc_warn_dialog: Color = self
|
||||
.get_color(super::COMPONENT_COLOR_MISC_WARN)
|
||||
.map_err(|_| super::COMPONENT_COLOR_MISC_WARN)?;
|
||||
// transfer
|
||||
let transfer_local_explorer_background: Color = self
|
||||
.get_color(super::COMPONENT_COLOR_TRANSFER_EXPLORER_LOCAL_BG)
|
||||
.map_err(|_| super::COMPONENT_COLOR_TRANSFER_EXPLORER_LOCAL_BG)?;
|
||||
let transfer_local_explorer_foreground: Color = self
|
||||
.get_color(super::COMPONENT_COLOR_TRANSFER_EXPLORER_LOCAL_FG)
|
||||
.map_err(|_| super::COMPONENT_COLOR_TRANSFER_EXPLORER_LOCAL_FG)?;
|
||||
let transfer_local_explorer_highlighted: Color = self
|
||||
.get_color(super::COMPONENT_COLOR_TRANSFER_EXPLORER_LOCAL_HG)
|
||||
.map_err(|_| super::COMPONENT_COLOR_TRANSFER_EXPLORER_LOCAL_HG)?;
|
||||
let transfer_remote_explorer_background: Color = self
|
||||
.get_color(super::COMPONENT_COLOR_TRANSFER_EXPLORER_REMOTE_BG)
|
||||
.map_err(|_| super::COMPONENT_COLOR_TRANSFER_EXPLORER_REMOTE_BG)?;
|
||||
let transfer_remote_explorer_foreground: Color = self
|
||||
.get_color(super::COMPONENT_COLOR_TRANSFER_EXPLORER_REMOTE_FG)
|
||||
.map_err(|_| super::COMPONENT_COLOR_TRANSFER_EXPLORER_REMOTE_FG)?;
|
||||
let transfer_remote_explorer_highlighted: Color = self
|
||||
.get_color(super::COMPONENT_COLOR_TRANSFER_EXPLORER_REMOTE_HG)
|
||||
.map_err(|_| super::COMPONENT_COLOR_TRANSFER_EXPLORER_REMOTE_HG)?;
|
||||
let transfer_log_background: Color = self
|
||||
.get_color(super::COMPONENT_COLOR_TRANSFER_LOG_BG)
|
||||
.map_err(|_| super::COMPONENT_COLOR_TRANSFER_LOG_BG)?;
|
||||
let transfer_log_window: Color = self
|
||||
.get_color(super::COMPONENT_COLOR_TRANSFER_LOG_WIN)
|
||||
.map_err(|_| super::COMPONENT_COLOR_TRANSFER_LOG_WIN)?;
|
||||
let transfer_progress_bar_full: Color = self
|
||||
.get_color(super::COMPONENT_COLOR_TRANSFER_PROG_BAR_FULL)
|
||||
.map_err(|_| super::COMPONENT_COLOR_TRANSFER_PROG_BAR_FULL)?;
|
||||
let transfer_progress_bar_partial: Color = self
|
||||
.get_color(super::COMPONENT_COLOR_TRANSFER_PROG_BAR_PARTIAL)
|
||||
.map_err(|_| super::COMPONENT_COLOR_TRANSFER_PROG_BAR_PARTIAL)?;
|
||||
let transfer_status_hidden: Color = self
|
||||
.get_color(super::COMPONENT_COLOR_TRANSFER_STATUS_HIDDEN)
|
||||
.map_err(|_| super::COMPONENT_COLOR_TRANSFER_STATUS_HIDDEN)?;
|
||||
let transfer_status_sorting: Color = self
|
||||
.get_color(super::COMPONENT_COLOR_TRANSFER_STATUS_SORTING)
|
||||
.map_err(|_| super::COMPONENT_COLOR_TRANSFER_STATUS_SORTING)?;
|
||||
let transfer_status_sync_browsing: Color = self
|
||||
.get_color(super::COMPONENT_COLOR_TRANSFER_STATUS_SYNC)
|
||||
.map_err(|_| super::COMPONENT_COLOR_TRANSFER_STATUS_SYNC)?;
|
||||
// Update theme
|
||||
let mut theme: &mut Theme = self.theme_mut();
|
||||
theme.auth_address = auth_address;
|
||||
theme.auth_bookmarks = auth_bookmarks;
|
||||
theme.auth_password = auth_password;
|
||||
theme.auth_port = auth_port;
|
||||
theme.auth_protocol = auth_protocol;
|
||||
theme.auth_recents = auth_recents;
|
||||
theme.auth_username = auth_username;
|
||||
theme.misc_error_dialog = misc_error_dialog;
|
||||
theme.misc_info_dialog = misc_info_dialog;
|
||||
theme.misc_input_dialog = misc_input_dialog;
|
||||
theme.misc_keys = misc_keys;
|
||||
theme.misc_quit_dialog = misc_quit_dialog;
|
||||
theme.misc_save_dialog = misc_save_dialog;
|
||||
theme.misc_warn_dialog = misc_warn_dialog;
|
||||
theme.transfer_local_explorer_background = transfer_local_explorer_background;
|
||||
theme.transfer_local_explorer_foreground = transfer_local_explorer_foreground;
|
||||
theme.transfer_local_explorer_highlighted = transfer_local_explorer_highlighted;
|
||||
theme.transfer_remote_explorer_background = transfer_remote_explorer_background;
|
||||
theme.transfer_remote_explorer_foreground = transfer_remote_explorer_foreground;
|
||||
theme.transfer_remote_explorer_highlighted = transfer_remote_explorer_highlighted;
|
||||
theme.transfer_log_background = transfer_log_background;
|
||||
theme.transfer_log_window = transfer_log_window;
|
||||
theme.transfer_progress_bar_full = transfer_progress_bar_full;
|
||||
theme.transfer_progress_bar_partial = transfer_progress_bar_partial;
|
||||
theme.transfer_status_hidden = transfer_status_hidden;
|
||||
theme.transfer_status_sorting = transfer_status_sorting;
|
||||
theme.transfer_status_sync_browsing = transfer_status_sync_browsing;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// ### update_color
|
||||
///
|
||||
/// Update color for provided component
|
||||
fn update_color(&mut self, component: &str, color: Color) {
|
||||
if let Some(props) = self.view.get_props(component) {
|
||||
self.view.update(
|
||||
component,
|
||||
ColorPickerPropsBuilder::from(props)
|
||||
.with_color(&color)
|
||||
.build(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// ### get_color
|
||||
///
|
||||
/// Get color from component
|
||||
fn get_color(&self, component: &str) -> Result<Color, ()> {
|
||||
match self.view.get_state(component) {
|
||||
Some(Payload::One(Value::Str(color))) => match parse_color(color.as_str()) {
|
||||
Some(c) => Ok(c),
|
||||
None => Err(()),
|
||||
},
|
||||
_ => Err(()),
|
||||
}
|
||||
}
|
||||
|
||||
/// ### mount_color_picker
|
||||
///
|
||||
/// Mount color picker with provided data
|
||||
fn mount_color_picker(&mut self, id: &str, label: &str) {
|
||||
self.view.mount(
|
||||
id,
|
||||
Box::new(ColorPicker::new(
|
||||
ColorPickerPropsBuilder::default()
|
||||
.with_borders(Borders::ALL, BorderType::Rounded, Color::Reset)
|
||||
.with_label(label.to_string(), Alignment::Left)
|
||||
.build(),
|
||||
)),
|
||||
);
|
||||
}
|
||||
|
||||
/// ### mount_title
|
||||
///
|
||||
/// Mount title
|
||||
fn mount_title(&mut self, id: &str, text: &str) {
|
||||
self.view.mount(
|
||||
id,
|
||||
Box::new(Label::new(
|
||||
LabelPropsBuilder::default()
|
||||
.bold()
|
||||
.with_text(text.to_string())
|
||||
.build(),
|
||||
)),
|
||||
);
|
||||
assert!(self
|
||||
.app
|
||||
.remount(
|
||||
Id::Theme(IdTheme::AuthAddress),
|
||||
Box::new(components::AuthAddress::new(theme.auth_address)),
|
||||
vec![]
|
||||
)
|
||||
.is_ok());
|
||||
assert!(self
|
||||
.app
|
||||
.remount(
|
||||
Id::Theme(IdTheme::AuthBookmarks),
|
||||
Box::new(components::AuthBookmarks::new(theme.auth_bookmarks)),
|
||||
vec![]
|
||||
)
|
||||
.is_ok());
|
||||
assert!(self
|
||||
.app
|
||||
.remount(
|
||||
Id::Theme(IdTheme::AuthPassword),
|
||||
Box::new(components::AuthPassword::new(theme.auth_password)),
|
||||
vec![]
|
||||
)
|
||||
.is_ok());
|
||||
assert!(self
|
||||
.app
|
||||
.remount(
|
||||
Id::Theme(IdTheme::AuthPort),
|
||||
Box::new(components::AuthPort::new(theme.auth_port)),
|
||||
vec![]
|
||||
)
|
||||
.is_ok());
|
||||
assert!(self
|
||||
.app
|
||||
.remount(
|
||||
Id::Theme(IdTheme::AuthProtocol),
|
||||
Box::new(components::AuthProtocol::new(theme.auth_protocol)),
|
||||
vec![]
|
||||
)
|
||||
.is_ok());
|
||||
assert!(self
|
||||
.app
|
||||
.remount(
|
||||
Id::Theme(IdTheme::AuthRecentHosts),
|
||||
Box::new(components::AuthRecentHosts::new(theme.auth_recents)),
|
||||
vec![]
|
||||
)
|
||||
.is_ok());
|
||||
assert!(self
|
||||
.app
|
||||
.remount(
|
||||
Id::Theme(IdTheme::AuthUsername),
|
||||
Box::new(components::AuthUsername::new(theme.auth_username)),
|
||||
vec![]
|
||||
)
|
||||
.is_ok());
|
||||
assert!(self
|
||||
.app
|
||||
.remount(
|
||||
Id::Theme(IdTheme::MiscError),
|
||||
Box::new(components::MiscError::new(theme.misc_error_dialog)),
|
||||
vec![]
|
||||
)
|
||||
.is_ok());
|
||||
assert!(self
|
||||
.app
|
||||
.remount(
|
||||
Id::Theme(IdTheme::MiscInfo),
|
||||
Box::new(components::MiscInfo::new(theme.misc_info_dialog)),
|
||||
vec![]
|
||||
)
|
||||
.is_ok());
|
||||
assert!(self
|
||||
.app
|
||||
.remount(
|
||||
Id::Theme(IdTheme::MiscInput),
|
||||
Box::new(components::MiscInput::new(theme.misc_input_dialog)),
|
||||
vec![]
|
||||
)
|
||||
.is_ok());
|
||||
assert!(self
|
||||
.app
|
||||
.remount(
|
||||
Id::Theme(IdTheme::MiscKeys),
|
||||
Box::new(components::MiscKeys::new(theme.misc_keys)),
|
||||
vec![]
|
||||
)
|
||||
.is_ok());
|
||||
assert!(self
|
||||
.app
|
||||
.remount(
|
||||
Id::Theme(IdTheme::MiscQuit),
|
||||
Box::new(components::MiscQuit::new(theme.misc_quit_dialog)),
|
||||
vec![]
|
||||
)
|
||||
.is_ok());
|
||||
assert!(self
|
||||
.app
|
||||
.remount(
|
||||
Id::Theme(IdTheme::MiscSave),
|
||||
Box::new(components::MiscSave::new(theme.misc_save_dialog)),
|
||||
vec![]
|
||||
)
|
||||
.is_ok());
|
||||
assert!(self
|
||||
.app
|
||||
.remount(
|
||||
Id::Theme(IdTheme::MiscWarn),
|
||||
Box::new(components::MiscWarn::new(theme.misc_warn_dialog)),
|
||||
vec![]
|
||||
)
|
||||
.is_ok());
|
||||
assert!(self
|
||||
.app
|
||||
.remount(
|
||||
Id::Theme(IdTheme::ExplorerLocalBg),
|
||||
Box::new(components::ExplorerLocalBg::new(
|
||||
theme.transfer_local_explorer_background
|
||||
)),
|
||||
vec![]
|
||||
)
|
||||
.is_ok());
|
||||
assert!(self
|
||||
.app
|
||||
.remount(
|
||||
Id::Theme(IdTheme::ExplorerLocalFg),
|
||||
Box::new(components::ExplorerLocalFg::new(
|
||||
theme.transfer_local_explorer_foreground
|
||||
)),
|
||||
vec![]
|
||||
)
|
||||
.is_ok());
|
||||
assert!(self
|
||||
.app
|
||||
.remount(
|
||||
Id::Theme(IdTheme::ExplorerLocalHg),
|
||||
Box::new(components::ExplorerLocalHg::new(
|
||||
theme.transfer_local_explorer_highlighted
|
||||
)),
|
||||
vec![]
|
||||
)
|
||||
.is_ok());
|
||||
assert!(self
|
||||
.app
|
||||
.remount(
|
||||
Id::Theme(IdTheme::ExplorerRemoteBg),
|
||||
Box::new(components::ExplorerRemoteBg::new(
|
||||
theme.transfer_remote_explorer_background
|
||||
)),
|
||||
vec![]
|
||||
)
|
||||
.is_ok());
|
||||
assert!(self
|
||||
.app
|
||||
.remount(
|
||||
Id::Theme(IdTheme::ExplorerRemoteFg),
|
||||
Box::new(components::ExplorerRemoteFg::new(
|
||||
theme.transfer_remote_explorer_foreground
|
||||
)),
|
||||
vec![]
|
||||
)
|
||||
.is_ok());
|
||||
assert!(self
|
||||
.app
|
||||
.remount(
|
||||
Id::Theme(IdTheme::ExplorerRemoteHg),
|
||||
Box::new(components::ExplorerRemoteHg::new(
|
||||
theme.transfer_remote_explorer_highlighted
|
||||
)),
|
||||
vec![]
|
||||
)
|
||||
.is_ok());
|
||||
assert!(self
|
||||
.app
|
||||
.remount(
|
||||
Id::Theme(IdTheme::ProgBarFull),
|
||||
Box::new(components::ProgBarFull::new(
|
||||
theme.transfer_progress_bar_full
|
||||
)),
|
||||
vec![]
|
||||
)
|
||||
.is_ok());
|
||||
assert!(self
|
||||
.app
|
||||
.remount(
|
||||
Id::Theme(IdTheme::ProgBarPartial),
|
||||
Box::new(components::ProgBarPartial::new(
|
||||
theme.transfer_progress_bar_partial
|
||||
)),
|
||||
vec![]
|
||||
)
|
||||
.is_ok());
|
||||
assert!(self
|
||||
.app
|
||||
.remount(
|
||||
Id::Theme(IdTheme::LogBg),
|
||||
Box::new(components::LogBg::new(theme.transfer_log_background)),
|
||||
vec![]
|
||||
)
|
||||
.is_ok());
|
||||
assert!(self
|
||||
.app
|
||||
.remount(
|
||||
Id::Theme(IdTheme::LogWindow),
|
||||
Box::new(components::LogWindow::new(theme.transfer_log_window)),
|
||||
vec![]
|
||||
)
|
||||
.is_ok());
|
||||
assert!(self
|
||||
.app
|
||||
.remount(
|
||||
Id::Theme(IdTheme::StatusSorting),
|
||||
Box::new(components::StatusSorting::new(
|
||||
theme.transfer_status_sorting
|
||||
)),
|
||||
vec![]
|
||||
)
|
||||
.is_ok());
|
||||
assert!(self
|
||||
.app
|
||||
.remount(
|
||||
Id::Theme(IdTheme::StatusHidden),
|
||||
Box::new(components::StatusHidden::new(theme.transfer_status_hidden)),
|
||||
vec![]
|
||||
)
|
||||
.is_ok());
|
||||
assert!(self
|
||||
.app
|
||||
.remount(
|
||||
Id::Theme(IdTheme::StatusSync),
|
||||
Box::new(components::StatusSync::new(
|
||||
theme.transfer_status_sync_browsing
|
||||
)),
|
||||
vec![]
|
||||
)
|
||||
.is_ok());
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user