mirror of
https://github.com/veeso/termscp.git
synced 2026-04-06 02:01:34 -07:00
Notifications
This commit is contained in:
@@ -58,6 +58,8 @@ const COMPONENT_RADIO_PROMPT_ON_FILE_REPLACE: &str = "RADIO_PROMPT_ON_FILE_REPLA
|
||||
const COMPONENT_RADIO_GROUP_DIRS: &str = "RADIO_GROUP_DIRS";
|
||||
const COMPONENT_INPUT_LOCAL_FILE_FMT: &str = "INPUT_LOCAL_FILE_FMT";
|
||||
const COMPONENT_INPUT_REMOTE_FILE_FMT: &str = "INPUT_REMOTE_FILE_FMT";
|
||||
const COMPONENT_RADIO_NOTIFICATIONS_ENABLED: &str = "RADIO_NOTIFICATIONS_ENABLED";
|
||||
const COMPONENT_INPUT_NOTIFICATIONS_THRESHOLD: &str = "INPUT_NOTIFICATIONS_THRESHOLD";
|
||||
// -- ssh keys
|
||||
const COMPONENT_LIST_SSH_KEYS: &str = "LIST_SSH_KEYS";
|
||||
const COMPONENT_INPUT_SSH_HOST: &str = "INPUT_SSH_HOST";
|
||||
|
||||
@@ -40,11 +40,13 @@ use super::{
|
||||
COMPONENT_COLOR_TRANSFER_PROG_BAR_FULL, COMPONENT_COLOR_TRANSFER_PROG_BAR_PARTIAL,
|
||||
COMPONENT_COLOR_TRANSFER_STATUS_HIDDEN, COMPONENT_COLOR_TRANSFER_STATUS_SORTING,
|
||||
COMPONENT_COLOR_TRANSFER_STATUS_SYNC, COMPONENT_INPUT_LOCAL_FILE_FMT,
|
||||
COMPONENT_INPUT_REMOTE_FILE_FMT, COMPONENT_INPUT_SSH_HOST, COMPONENT_INPUT_SSH_USERNAME,
|
||||
COMPONENT_INPUT_TEXT_EDITOR, COMPONENT_LIST_SSH_KEYS, COMPONENT_RADIO_DEFAULT_PROTOCOL,
|
||||
COMPONENT_RADIO_DEL_SSH_KEY, COMPONENT_RADIO_GROUP_DIRS, COMPONENT_RADIO_HIDDEN_FILES,
|
||||
COMPONENT_RADIO_PROMPT_ON_FILE_REPLACE, COMPONENT_RADIO_QUIT, COMPONENT_RADIO_SAVE,
|
||||
COMPONENT_RADIO_UPDATES, COMPONENT_TEXT_ERROR, COMPONENT_TEXT_HELP,
|
||||
COMPONENT_INPUT_NOTIFICATIONS_THRESHOLD, COMPONENT_INPUT_REMOTE_FILE_FMT,
|
||||
COMPONENT_INPUT_SSH_HOST, COMPONENT_INPUT_SSH_USERNAME, COMPONENT_INPUT_TEXT_EDITOR,
|
||||
COMPONENT_LIST_SSH_KEYS, COMPONENT_RADIO_DEFAULT_PROTOCOL, COMPONENT_RADIO_DEL_SSH_KEY,
|
||||
COMPONENT_RADIO_GROUP_DIRS, COMPONENT_RADIO_HIDDEN_FILES,
|
||||
COMPONENT_RADIO_NOTIFICATIONS_ENABLED, COMPONENT_RADIO_PROMPT_ON_FILE_REPLACE,
|
||||
COMPONENT_RADIO_QUIT, COMPONENT_RADIO_SAVE, COMPONENT_RADIO_UPDATES, COMPONENT_TEXT_ERROR,
|
||||
COMPONENT_TEXT_HELP,
|
||||
};
|
||||
use crate::ui::keymap::*;
|
||||
use crate::utils::parser::parse_color;
|
||||
@@ -103,10 +105,26 @@ impl SetupActivity {
|
||||
None
|
||||
}
|
||||
(COMPONENT_INPUT_REMOTE_FILE_FMT, key) if key == &MSG_KEY_DOWN => {
|
||||
self.view.active(COMPONENT_RADIO_NOTIFICATIONS_ENABLED);
|
||||
None
|
||||
}
|
||||
(COMPONENT_RADIO_NOTIFICATIONS_ENABLED, key) if key == &MSG_KEY_DOWN => {
|
||||
self.view.active(COMPONENT_INPUT_NOTIFICATIONS_THRESHOLD);
|
||||
None
|
||||
}
|
||||
(COMPONENT_INPUT_NOTIFICATIONS_THRESHOLD, key) if key == &MSG_KEY_DOWN => {
|
||||
self.view.active(COMPONENT_INPUT_TEXT_EDITOR);
|
||||
None
|
||||
}
|
||||
// Input field <UP>
|
||||
(COMPONENT_INPUT_NOTIFICATIONS_THRESHOLD, key) if key == &MSG_KEY_UP => {
|
||||
self.view.active(COMPONENT_RADIO_NOTIFICATIONS_ENABLED);
|
||||
None
|
||||
}
|
||||
(COMPONENT_RADIO_NOTIFICATIONS_ENABLED, key) if key == &MSG_KEY_UP => {
|
||||
self.view.active(COMPONENT_INPUT_REMOTE_FILE_FMT);
|
||||
None
|
||||
}
|
||||
(COMPONENT_INPUT_REMOTE_FILE_FMT, key) if key == &MSG_KEY_UP => {
|
||||
self.view.active(COMPONENT_INPUT_LOCAL_FILE_FMT);
|
||||
None
|
||||
@@ -136,7 +154,7 @@ impl SetupActivity {
|
||||
None
|
||||
}
|
||||
(COMPONENT_INPUT_TEXT_EDITOR, key) if key == &MSG_KEY_UP => {
|
||||
self.view.active(COMPONENT_INPUT_REMOTE_FILE_FMT);
|
||||
self.view.active(COMPONENT_INPUT_NOTIFICATIONS_THRESHOLD);
|
||||
None
|
||||
}
|
||||
// Error <ENTER> or <ESC>
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
use super::{Context, 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;
|
||||
@@ -143,8 +144,8 @@ impl SetupActivity {
|
||||
super::COMPONENT_INPUT_LOCAL_FILE_FMT,
|
||||
Box::new(Input::new(
|
||||
InputPropsBuilder::default()
|
||||
.with_foreground(Color::LightBlue)
|
||||
.with_borders(Borders::ALL, BorderType::Rounded, Color::LightBlue)
|
||||
.with_foreground(Color::LightGreen)
|
||||
.with_borders(Borders::ALL, BorderType::Rounded, Color::LightGreen)
|
||||
.with_label("File formatter syntax (local)", Alignment::Left)
|
||||
.build(),
|
||||
)),
|
||||
@@ -153,12 +154,35 @@ impl SetupActivity {
|
||||
super::COMPONENT_INPUT_REMOTE_FILE_FMT,
|
||||
Box::new(Input::new(
|
||||
InputPropsBuilder::default()
|
||||
.with_foreground(Color::LightGreen)
|
||||
.with_borders(Borders::ALL, BorderType::Rounded, Color::LightGreen)
|
||||
.with_foreground(Color::LightCyan)
|
||||
.with_borders(Borders::ALL, BorderType::Rounded, Color::LightCyan)
|
||||
.with_label("File formatter syntax (remote)", Alignment::Left)
|
||||
.build(),
|
||||
)),
|
||||
);
|
||||
self.view.mount(
|
||||
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(),
|
||||
)),
|
||||
);
|
||||
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(),
|
||||
)),
|
||||
);
|
||||
// Load values
|
||||
self.load_input_values();
|
||||
}
|
||||
@@ -173,7 +197,7 @@ impl SetupActivity {
|
||||
.constraints(
|
||||
[
|
||||
Constraint::Length(3), // Current tab
|
||||
Constraint::Length(21), // Main body
|
||||
Constraint::Length(18), // Main body
|
||||
Constraint::Length(3), // Help footer
|
||||
]
|
||||
.as_ref(),
|
||||
@@ -182,8 +206,13 @@ impl SetupActivity {
|
||||
// Render common widget
|
||||
self.view.render(super::COMPONENT_RADIO_TAB, f, chunks[0]);
|
||||
self.view.render(super::COMPONENT_TEXT_FOOTER, f, chunks[2]);
|
||||
// Make chunks
|
||||
// Make chunks (two columns)
|
||||
let ui_cfg_chunks = Layout::default()
|
||||
.direction(Direction::Horizontal)
|
||||
.constraints([Constraint::Percentage(50), Constraint::Percentage(50)].as_ref())
|
||||
.split(chunks[1]);
|
||||
// Column 1
|
||||
let ui_cfg_chunks_col1 = Layout::default()
|
||||
.direction(Direction::Vertical)
|
||||
.constraints(
|
||||
[
|
||||
@@ -193,31 +222,65 @@ impl SetupActivity {
|
||||
Constraint::Length(3), // Updates tab
|
||||
Constraint::Length(3), // Prompt file replace
|
||||
Constraint::Length(3), // Group dirs
|
||||
Constraint::Length(3), // Local Format input
|
||||
Constraint::Length(3), // Remote Format input
|
||||
]
|
||||
.as_ref(),
|
||||
)
|
||||
.split(chunks[1]);
|
||||
.split(ui_cfg_chunks[0]);
|
||||
self.view
|
||||
.render(super::COMPONENT_INPUT_TEXT_EDITOR, f, ui_cfg_chunks[0]);
|
||||
.render(super::COMPONENT_INPUT_TEXT_EDITOR, f, ui_cfg_chunks_col1[0]);
|
||||
self.view.render(
|
||||
super::COMPONENT_RADIO_DEFAULT_PROTOCOL,
|
||||
f,
|
||||
ui_cfg_chunks_col1[1],
|
||||
);
|
||||
self.view.render(
|
||||
super::COMPONENT_RADIO_HIDDEN_FILES,
|
||||
f,
|
||||
ui_cfg_chunks_col1[2],
|
||||
);
|
||||
self.view
|
||||
.render(super::COMPONENT_RADIO_DEFAULT_PROTOCOL, f, ui_cfg_chunks[1]);
|
||||
self.view
|
||||
.render(super::COMPONENT_RADIO_HIDDEN_FILES, f, ui_cfg_chunks[2]);
|
||||
self.view
|
||||
.render(super::COMPONENT_RADIO_UPDATES, f, ui_cfg_chunks[3]);
|
||||
.render(super::COMPONENT_RADIO_UPDATES, f, ui_cfg_chunks_col1[3]);
|
||||
self.view.render(
|
||||
super::COMPONENT_RADIO_PROMPT_ON_FILE_REPLACE,
|
||||
f,
|
||||
ui_cfg_chunks[4],
|
||||
ui_cfg_chunks_col1[4],
|
||||
);
|
||||
self.view
|
||||
.render(super::COMPONENT_RADIO_GROUP_DIRS, f, ui_cfg_chunks[5]);
|
||||
self.view
|
||||
.render(super::COMPONENT_INPUT_LOCAL_FILE_FMT, f, ui_cfg_chunks[6]);
|
||||
self.view
|
||||
.render(super::COMPONENT_INPUT_REMOTE_FILE_FMT, f, ui_cfg_chunks[7]);
|
||||
.render(super::COMPONENT_RADIO_GROUP_DIRS, f, ui_cfg_chunks_col1[5]);
|
||||
// Column 2
|
||||
let ui_cfg_chunks_col2 = Layout::default()
|
||||
.direction(Direction::Vertical)
|
||||
.constraints(
|
||||
[
|
||||
Constraint::Length(3), // Local Format input
|
||||
Constraint::Length(3), // Remote Format input
|
||||
Constraint::Length(3), // Notifications enabled
|
||||
Constraint::Length(3), // Notifications threshold
|
||||
Constraint::Length(1), // Filler
|
||||
]
|
||||
.as_ref(),
|
||||
)
|
||||
.split(ui_cfg_chunks[1]);
|
||||
self.view.render(
|
||||
super::COMPONENT_INPUT_LOCAL_FILE_FMT,
|
||||
f,
|
||||
ui_cfg_chunks_col2[0],
|
||||
);
|
||||
self.view.render(
|
||||
super::COMPONENT_INPUT_REMOTE_FILE_FMT,
|
||||
f,
|
||||
ui_cfg_chunks_col2[1],
|
||||
);
|
||||
self.view.render(
|
||||
super::COMPONENT_RADIO_NOTIFICATIONS_ENABLED,
|
||||
f,
|
||||
ui_cfg_chunks_col2[2],
|
||||
);
|
||||
self.view.render(
|
||||
super::COMPONENT_INPUT_NOTIFICATIONS_THRESHOLD,
|
||||
f,
|
||||
ui_cfg_chunks_col2[3],
|
||||
);
|
||||
// Popups
|
||||
if let Some(props) = self.view.get_props(super::COMPONENT_TEXT_ERROR) {
|
||||
if props.visible {
|
||||
@@ -341,6 +404,31 @@ impl SetupActivity {
|
||||
.view
|
||||
.update(super::COMPONENT_INPUT_REMOTE_FILE_FMT, props);
|
||||
}
|
||||
// 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);
|
||||
}
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
|
||||
/// ### collect_input_values
|
||||
@@ -404,5 +492,17 @@ 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)
|
||||
{
|
||||
self.config_mut().set_notifications(opt == 0);
|
||||
}
|
||||
if let Some(Payload::One(Value::U64(bytes))) = self
|
||||
.view
|
||||
.get_state(super::COMPONENT_INPUT_NOTIFICATIONS_THRESHOLD)
|
||||
{
|
||||
self.config_mut().set_notification_threshold(bytes);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user