diff --git a/src/ui/activities/filetransfer_activity/input.rs b/src/ui/activities/filetransfer_activity/input.rs index 27b9c09..9df1256 100644 --- a/src/ui/activities/filetransfer_activity/input.rs +++ b/src/ui/activities/filetransfer_activity/input.rs @@ -28,7 +28,7 @@ extern crate tempfile; // Local use super::{ DialogCallback, DialogYesNoOption, FileExplorerTab, FileTransferActivity, FsEntry, InputEvent, - InputField, InputMode, LogLevel, OnInputSubmitCallback, PopupType, + InputField, LogLevel, OnInputSubmitCallback, Popup, }; use crate::fs::explorer::{FileExplorer, FileSorting}; // Ext @@ -64,13 +64,13 @@ impl FileTransferActivity { fn handle_input_event(&mut self, ev: &InputEvent) { // NOTE: this is necessary due to this // NOTE: Do you want my opinion about that issue? It's a bs and doesn't make any sense. - let popup: Option = match &self.input_mode { - InputMode::Popup(ptype) => Some(ptype.clone()), + let popup: Option = match &self.popup { + Some(ptype) => Some(ptype.clone()), _ => None, }; - match &self.input_mode { - InputMode::Explorer => self.handle_input_event_mode_explorer(ev), - InputMode::Popup(_) => { + match &self.popup { + None => self.handle_input_event_mode_explorer(ev), + Some(_) => { if let Some(popup) = popup { self.handle_input_event_mode_popup(ev, popup); } @@ -103,7 +103,7 @@ impl FileTransferActivity { KeyCode::Esc => { // Handle quit event // Create quit prompt dialog - self.input_mode = self.create_disconnect_popup(); + self.popup = self.create_disconnect_popup(); } KeyCode::Tab => self.switch_input_field(), // switch tab KeyCode::Right => self.tab = FileExplorerTab::Remote, // switch to right tab @@ -162,7 +162,7 @@ impl FileTransferActivity { FsEntry::File(file) => file.name.clone(), }; // Show delete prompt - self.input_mode = InputMode::Popup(PopupType::YesNo( + self.popup = Some(Popup::YesNo( format!("Delete file \"{}\"", file_name), FileTransferActivity::callback_delete_fsentry, FileTransferActivity::callback_nothing_to_do, @@ -176,18 +176,18 @@ impl FileTransferActivity { } 'b' | 'B' => { // Choose file sorting type - self.input_mode = InputMode::Popup(PopupType::FileSortingDialog); + self.popup = Some(Popup::FileSortingDialog); } 'c' | 'C' => { // Copy - self.input_mode = InputMode::Popup(PopupType::Input( + self.popup = Some(Popup::Input( String::from("Insert destination name"), FileTransferActivity::callback_copy, )); } 'd' | 'D' => { // Make directory - self.input_mode = InputMode::Popup(PopupType::Input( + self.popup = Some(Popup::Input( String::from("Insert directory name"), FileTransferActivity::callback_mkdir, )); @@ -201,7 +201,7 @@ impl FileTransferActivity { FsEntry::File(file) => file.name.clone(), }; // Show delete prompt - self.input_mode = InputMode::Popup(PopupType::YesNo( + self.popup = Some(Popup::YesNo( format!("Delete file \"{}\"", file_name), FileTransferActivity::callback_delete_fsentry, FileTransferActivity::callback_nothing_to_do, @@ -211,18 +211,18 @@ impl FileTransferActivity { 'g' | 'G' => { // Goto // Show input popup - self.input_mode = InputMode::Popup(PopupType::Input( + self.popup = Some(Popup::Input( String::from("Change working directory"), FileTransferActivity::callback_change_directory, )); } 'h' | 'H' => { // Show help - self.input_mode = InputMode::Popup(PopupType::Help); + self.popup = Some(Popup::Help); } 'i' | 'I' => { // Show file info - self.input_mode = InputMode::Popup(PopupType::FileInfo); + self.popup = Some(Popup::FileInfo); } 'l' | 'L' => { // Reload file entries @@ -231,7 +231,7 @@ impl FileTransferActivity { } 'n' | 'N' => { // New file - self.input_mode = InputMode::Popup(PopupType::Input( + self.popup = Some(Popup::Input( String::from("New file"), Self::callback_new_file, )); @@ -265,11 +265,11 @@ impl FileTransferActivity { } 'q' | 'Q' => { // Create quit prompt dialog - self.input_mode = self.create_quit_popup(); + self.popup = self.create_quit_popup(); } 'r' | 'R' => { // Rename - self.input_mode = InputMode::Popup(PopupType::Input( + self.popup = Some(Popup::Input( String::from("Insert new name"), FileTransferActivity::callback_rename, )); @@ -277,7 +277,7 @@ impl FileTransferActivity { 's' | 'S' => { // Save as... // Ask for input - self.input_mode = InputMode::Popup(PopupType::Input( + self.popup = Some(Popup::Input( String::from("Save as..."), FileTransferActivity::callback_save_as, )); @@ -322,7 +322,7 @@ impl FileTransferActivity { KeyCode::Esc => { // Handle quit event // Create quit prompt dialog - self.input_mode = self.create_disconnect_popup(); + self.popup = self.create_disconnect_popup(); } KeyCode::Tab => self.switch_input_field(), // switch tab KeyCode::Left => self.tab = FileExplorerTab::Local, // switch to local tab @@ -381,7 +381,7 @@ impl FileTransferActivity { FsEntry::File(file) => file.name.clone(), }; // Show delete prompt - self.input_mode = InputMode::Popup(PopupType::YesNo( + self.popup = Some(Popup::YesNo( format!("Delete file \"{}\"", file_name), FileTransferActivity::callback_delete_fsentry, FileTransferActivity::callback_nothing_to_do, @@ -395,18 +395,18 @@ impl FileTransferActivity { } 'b' | 'B' => { // Choose file sorting type - self.input_mode = InputMode::Popup(PopupType::FileSortingDialog); + self.popup = Some(Popup::FileSortingDialog); } 'c' | 'C' => { // Copy - self.input_mode = InputMode::Popup(PopupType::Input( + self.popup = Some(Popup::Input( String::from("Insert destination name"), FileTransferActivity::callback_copy, )); } 'd' | 'D' => { // Make directory - self.input_mode = InputMode::Popup(PopupType::Input( + self.popup = Some(Popup::Input( String::from("Insert directory name"), FileTransferActivity::callback_mkdir, )); @@ -420,7 +420,7 @@ impl FileTransferActivity { FsEntry::File(file) => file.name.clone(), }; // Show delete prompt - self.input_mode = InputMode::Popup(PopupType::YesNo( + self.popup = Some(Popup::YesNo( format!("Delete file \"{}\"", file_name), FileTransferActivity::callback_delete_fsentry, FileTransferActivity::callback_nothing_to_do, @@ -430,18 +430,18 @@ impl FileTransferActivity { 'g' | 'G' => { // Goto // Show input popup - self.input_mode = InputMode::Popup(PopupType::Input( + self.popup = Some(Popup::Input( String::from("Change working directory"), FileTransferActivity::callback_change_directory, )); } 'h' | 'H' => { // Show help - self.input_mode = InputMode::Popup(PopupType::Help); + self.popup = Some(Popup::Help); } 'i' | 'I' => { // Show file info - self.input_mode = InputMode::Popup(PopupType::FileInfo); + self.popup = Some(Popup::FileInfo); } 'l' | 'L' => { // Reload file entries @@ -449,7 +449,7 @@ impl FileTransferActivity { } 'n' | 'N' => { // New file - self.input_mode = InputMode::Popup(PopupType::Input( + self.popup = Some(Popup::Input( String::from("New file"), Self::callback_new_file, )); @@ -476,17 +476,17 @@ impl FileTransferActivity { Err(err) => self.log_and_alert(LogLevel::Error, err), } // Put input mode back to normal - self.input_mode = InputMode::Explorer; + self.popup = None; } } } 'q' | 'Q' => { // Create quit prompt dialog - self.input_mode = self.create_quit_popup(); + self.popup = self.create_quit_popup(); } 'r' | 'R' => { // Rename - self.input_mode = InputMode::Popup(PopupType::Input( + self.popup = Some(Popup::Input( String::from("Insert new name"), FileTransferActivity::callback_rename, )); @@ -494,7 +494,7 @@ impl FileTransferActivity { 's' | 'S' => { // Save as... // Ask for input - self.input_mode = InputMode::Popup(PopupType::Input( + self.popup = Some(Popup::Input( String::from("Save as..."), FileTransferActivity::callback_save_as, )); @@ -539,7 +539,7 @@ impl FileTransferActivity { KeyCode::Esc => { // Handle quit event // Create quit prompt dialog - self.input_mode = self.create_disconnect_popup(); + self.popup = self.create_disconnect_popup(); } KeyCode::Tab => self.switch_input_field(), // switch tab KeyCode::Down => { @@ -578,7 +578,7 @@ impl FileTransferActivity { KeyCode::Char(ch) => match ch { 'q' | 'Q' => { // Create quit prompt dialog - self.input_mode = self.create_quit_popup(); + self.popup = self.create_quit_popup(); } _ => { /* Nothing to do */ } }, @@ -590,17 +590,17 @@ impl FileTransferActivity { /// ### handle_input_event_mode_explorer /// /// Input event handler for popup mode. Handler is then based on Popup type - fn handle_input_event_mode_popup(&mut self, ev: &InputEvent, popup: PopupType) { + fn handle_input_event_mode_popup(&mut self, ev: &InputEvent, popup: Popup) { match popup { - PopupType::Alert(_, _) => self.handle_input_event_mode_popup_alert(ev), - PopupType::FileInfo => self.handle_input_event_mode_popup_fileinfo(ev), - PopupType::Fatal(_) => self.handle_input_event_mode_popup_fatal(ev), - PopupType::FileSortingDialog => self.handle_input_event_mode_popup_file_sorting(ev), - PopupType::Help => self.handle_input_event_mode_popup_help(ev), - PopupType::Input(_, cb) => self.handle_input_event_mode_popup_input(ev, cb), - PopupType::Progress(_) => self.handle_input_event_mode_popup_progress(ev), - PopupType::Wait(_) => self.handle_input_event_mode_popup_wait(ev), - PopupType::YesNo(_, yes_cb, no_cb) => { + Popup::Alert(_, _) => self.handle_input_event_mode_popup_alert(ev), + Popup::FileInfo => self.handle_input_event_mode_popup_fileinfo(ev), + Popup::Fatal(_) => self.handle_input_event_mode_popup_fatal(ev), + Popup::FileSortingDialog => self.handle_input_event_mode_popup_file_sorting(ev), + Popup::Help => self.handle_input_event_mode_popup_help(ev), + Popup::Input(_, cb) => self.handle_input_event_mode_popup_input(ev, cb), + Popup::Progress(_) => self.handle_input_event_mode_popup_progress(ev), + Popup::Wait(_) => self.handle_input_event_mode_popup_wait(ev), + Popup::YesNo(_, yes_cb, no_cb) => { self.handle_input_event_mode_popup_yesno(ev, yes_cb, no_cb) } } @@ -614,7 +614,7 @@ impl FileTransferActivity { if let InputEvent::Key(key) = ev { if matches!(key.code, KeyCode::Esc | KeyCode::Enter) { // Set input mode back to explorer - self.input_mode = InputMode::Explorer; + self.popup = None; } } } @@ -627,7 +627,7 @@ impl FileTransferActivity { if let InputEvent::Key(key) = ev { if matches!(key.code, KeyCode::Esc | KeyCode::Enter) { // Set input mode back to explorer - self.input_mode = InputMode::Explorer; + self.popup = None; } } } @@ -654,7 +654,7 @@ impl FileTransferActivity { match key.code { KeyCode::Esc | KeyCode::Enter => { // Exit - self.input_mode = InputMode::Explorer; + self.popup = None; } KeyCode::Right => { // Update sorting mode @@ -691,7 +691,7 @@ impl FileTransferActivity { if let InputEvent::Key(key) = ev { if matches!(key.code, KeyCode::Esc | KeyCode::Enter) { // Set input mode back to explorer - self.input_mode = InputMode::Explorer; + self.popup = None; } } } @@ -708,7 +708,7 @@ impl FileTransferActivity { // Clear current input text self.input_txt.clear(); // Set mode back to explorer - self.input_mode = InputMode::Explorer; + self.popup = None; } KeyCode::Enter => { // Submit @@ -716,7 +716,7 @@ impl FileTransferActivity { // Clear current input text self.input_txt.clear(); // Set mode back to explorer BEFORE CALLBACKS!!! Callback can then overwrite this, clever uh? - self.input_mode = InputMode::Explorer; + self.popup = None; // Call cb cb(self, input_text); } @@ -765,7 +765,7 @@ impl FileTransferActivity { match key.code { KeyCode::Enter => { // @! Set input mode to Explorer BEFORE CALLBACKS!!! Callback can then overwrite this, clever uh? - self.input_mode = InputMode::Explorer; + self.popup = None; // Check if user selected yes or not match self.choice_opt { DialogYesNoOption::No => no_cb(self), diff --git a/src/ui/activities/filetransfer_activity/layout.rs b/src/ui/activities/filetransfer_activity/layout.rs index fe6c33b..49a7c19 100644 --- a/src/ui/activities/filetransfer_activity/layout.rs +++ b/src/ui/activities/filetransfer_activity/layout.rs @@ -31,7 +31,7 @@ extern crate users; // Local use super::{ Context, DialogYesNoOption, FileExplorerTab, FileTransferActivity, FsEntry, InputField, - InputMode, LogLevel, LogRecord, PopupType, + LogLevel, LogRecord, Popup, }; use crate::fs::explorer::{FileExplorer, FileSorting}; use crate::utils::fmt::{align_text_center, fmt_time}; @@ -101,36 +101,36 @@ impl FileTransferActivity { &mut log_state, ); // Draw popup - if let InputMode::Popup(popup) = &self.input_mode { + if let Some(popup) = &self.popup { // Calculate popup size let (width, height): (u16, u16) = match popup { - PopupType::Alert(_, _) => (50, 10), - PopupType::Fatal(_) => (50, 10), - PopupType::FileInfo => (50, 50), - PopupType::FileSortingDialog => (50, 10), - PopupType::Help => (50, 80), - PopupType::Input(_, _) => (40, 10), - PopupType::Progress(_) => (40, 10), - PopupType::Wait(_) => (50, 10), - PopupType::YesNo(_, _, _) => (30, 10), + Popup::Alert(_, _) => (50, 10), + Popup::Fatal(_) => (50, 10), + Popup::FileInfo => (50, 50), + Popup::FileSortingDialog => (50, 10), + Popup::Help => (50, 80), + Popup::Input(_, _) => (40, 10), + Popup::Progress(_) => (40, 10), + Popup::Wait(_) => (50, 10), + Popup::YesNo(_, _, _) => (30, 10), }; let popup_area: Rect = self.draw_popup_area(f.size(), width, height); f.render_widget(Clear, popup_area); //this clears out the background match popup { - PopupType::Alert(color, txt) => f.render_widget( + Popup::Alert(color, txt) => f.render_widget( self.draw_popup_alert(*color, txt.clone(), popup_area.width), popup_area, ), - PopupType::Fatal(txt) => f.render_widget( + Popup::Fatal(txt) => f.render_widget( self.draw_popup_fatal(txt.clone(), popup_area.width), popup_area, ), - PopupType::FileInfo => f.render_widget(self.draw_popup_fileinfo(), popup_area), - PopupType::FileSortingDialog => { + Popup::FileInfo => f.render_widget(self.draw_popup_fileinfo(), popup_area), + Popup::FileSortingDialog => { f.render_widget(self.draw_popup_file_sorting_dialog(), popup_area) } - PopupType::Help => f.render_widget(self.draw_popup_help(), popup_area), - PopupType::Input(txt, _) => { + Popup::Help => f.render_widget(self.draw_popup_help(), popup_area), + Popup::Input(txt, _) => { f.render_widget(self.draw_popup_input(txt.clone()), popup_area); // Set cursor f.set_cursor( @@ -138,14 +138,14 @@ impl FileTransferActivity { popup_area.y + 1, ) } - PopupType::Progress(txt) => { + Popup::Progress(txt) => { f.render_widget(self.draw_popup_progress(txt.clone()), popup_area) } - PopupType::Wait(txt) => f.render_widget( + Popup::Wait(txt) => f.render_widget( self.draw_popup_wait(txt.clone(), popup_area.width), popup_area, ), - PopupType::YesNo(txt, _, _) => { + Popup::YesNo(txt, _, _) => { f.render_widget(self.draw_popup_yesno(txt.clone()), popup_area) } } diff --git a/src/ui/activities/filetransfer_activity/misc.rs b/src/ui/activities/filetransfer_activity/misc.rs index 5dee089..642083c 100644 --- a/src/ui/activities/filetransfer_activity/misc.rs +++ b/src/ui/activities/filetransfer_activity/misc.rs @@ -20,10 +20,7 @@ */ // Locals -use super::{ - Color, ConfigClient, FileTransferActivity, InputField, InputMode, LogLevel, LogRecord, - PopupType, -}; +use super::{Color, ConfigClient, FileTransferActivity, InputField, LogLevel, LogRecord, Popup}; use crate::fs::explorer::{builder::FileExplorerBuilder, FileExplorer, FileSorting, GroupDirs}; use crate::system::environment; use crate::system::sshkey_storage::SshKeyStorage; @@ -59,14 +56,14 @@ impl FileTransferActivity { LogLevel::Warn => Color::Yellow, }; self.log(level, msg.as_str()); - self.input_mode = InputMode::Popup(PopupType::Alert(color, msg)); + self.popup = Some(Popup::Alert(color, msg)); } /// ### create_quit_popup /// /// Create quit popup input mode (since must be shared between different input handlers) - pub(super) fn create_disconnect_popup(&mut self) -> InputMode { - InputMode::Popup(PopupType::YesNo( + pub(super) fn create_disconnect_popup(&mut self) -> Option { + Some(Popup::YesNo( String::from("Are you sure you want to disconnect?"), FileTransferActivity::disconnect, FileTransferActivity::callback_nothing_to_do, @@ -76,8 +73,8 @@ impl FileTransferActivity { /// ### create_quit_popup /// /// Create quit popup input mode (since must be shared between different input handlers) - pub(super) fn create_quit_popup(&mut self) -> InputMode { - InputMode::Popup(PopupType::YesNo( + pub(super) fn create_quit_popup(&mut self) -> Option { + Some(Popup::YesNo( String::from("Are you sure you want to quit?"), FileTransferActivity::disconnect_and_quit, FileTransferActivity::callback_nothing_to_do, diff --git a/src/ui/activities/filetransfer_activity/mod.rs b/src/ui/activities/filetransfer_activity/mod.rs index c2029da..646d0d6 100644 --- a/src/ui/activities/filetransfer_activity/mod.rs +++ b/src/ui/activities/filetransfer_activity/mod.rs @@ -89,11 +89,11 @@ enum DialogYesNoOption { No, } -/// ## PopupType +/// ## Popup /// -/// PopupType describes the type of popup +/// Popup describes the type of popup #[derive(Clone)] -enum PopupType { +enum Popup { Alert(Color, String), // Block color; Block text Fatal(String), // Must quit after being hidden FileInfo, // Show info about current file @@ -105,16 +105,6 @@ enum PopupType { YesNo(String, DialogCallback, DialogCallback), // Yes, no callback } -/// ## InputMode -/// -/// InputMode describes the current input mode -/// Each input mode handle the input events in a different way -#[derive(Clone)] -enum InputMode { - Explorer, - Popup(PopupType), -} - /// ## FileExplorerTab /// /// File explorer tab @@ -241,7 +231,7 @@ pub struct FileTransferActivity { log_index: usize, // Current log index entry selected log_records: VecDeque, // Log records log_size: usize, // Log records size (max) - input_mode: InputMode, // Current input mode + popup: Option, // Current input mode input_field: InputField, // Current selected input mode input_txt: String, // Input text choice_opt: DialogYesNoOption, // Dialog popup selected option @@ -277,7 +267,7 @@ impl FileTransferActivity { log_index: 0, log_records: VecDeque::with_capacity(256), // 256 events is enough I guess log_size: 256, // Must match with capacity - input_mode: InputMode::Explorer, + popup: None, input_field: InputField::Explorer, input_txt: String::new(), choice_opt: DialogYesNoOption::Yes, @@ -324,11 +314,10 @@ impl Activity for FileTransferActivity { if self.context.is_none() { return; } - let is_explorer_mode: bool = matches!(self.input_mode, InputMode::Explorer); - // Check if connected - if !self.client.is_connected() && is_explorer_mode { + // Check if connected (popup must be None, otherwise would try reconnecting in loop in case of error) + if !self.client.is_connected() && self.popup.is_none() { // Set init state to connecting popup - self.input_mode = InputMode::Popup(PopupType::Wait(format!( + self.popup = Some(Popup::Wait(format!( "Connecting to {}:{}...", self.params.address, self.params.port ))); diff --git a/src/ui/activities/filetransfer_activity/session.rs b/src/ui/activities/filetransfer_activity/session.rs index 381538e..633a07f 100644 --- a/src/ui/activities/filetransfer_activity/session.rs +++ b/src/ui/activities/filetransfer_activity/session.rs @@ -30,7 +30,7 @@ extern crate crossterm; extern crate tempfile; // Locals -use super::{FileTransferActivity, InputMode, LogLevel, PopupType}; +use super::{FileTransferActivity, LogLevel, Popup}; use crate::fs::{FsEntry, FsFile}; use crate::utils::fmt::fmt_millis; @@ -68,12 +68,12 @@ impl FileTransferActivity { ); } // Set state to explorer - self.input_mode = InputMode::Explorer; + self.popup = None; self.reload_remote_dir(); } Err(err) => { // Set popup fatal error - self.input_mode = InputMode::Popup(PopupType::Fatal(format!("{}", err))); + self.popup = Some(Popup::Fatal(format!("{}", err))); } } } @@ -83,7 +83,7 @@ impl FileTransferActivity { /// disconnect from remote pub(super) fn disconnect(&mut self) { // Show popup disconnecting - self.input_mode = InputMode::Popup(PopupType::Alert( + self.popup = Some(Popup::Alert( Color::Red, String::from("Disconnecting from remote..."), )); @@ -129,7 +129,7 @@ impl FileTransferActivity { FsEntry::Directory(dir) => dir.name.clone(), FsEntry::File(file) => file.name.clone(), }; - self.input_mode = InputMode::Popup(PopupType::Wait(format!("Uploading \"{}\"", file_name))); + self.popup = Some(Popup::Wait(format!("Uploading \"{}\"", file_name))); // Draw self.draw(); // Get remote path @@ -211,9 +211,9 @@ impl FileTransferActivity { } else { // @! Successful // Eventually, Reset input mode to explorer (if input mode is wait or progress) - if let InputMode::Popup(ptype) = &self.input_mode { - if matches!(ptype, PopupType::Wait(_) | PopupType::Progress(_)) { - self.input_mode = InputMode::Explorer + if let Some(ptype) = &self.popup { + if matches!(ptype, Popup::Wait(_) | Popup::Progress(_)) { + self.popup = None } } } @@ -235,8 +235,7 @@ impl FileTransferActivity { FsEntry::Directory(dir) => dir.name.clone(), FsEntry::File(file) => file.name.clone(), }; - self.input_mode = - InputMode::Popup(PopupType::Wait(format!("Downloading \"{}\"...", file_name))); + self.popup = Some(Popup::Wait(format!("Downloading \"{}\"...", file_name))); // Draw self.draw(); // Match entry @@ -352,7 +351,7 @@ impl FileTransferActivity { self.transfer.aborted = false; } else { // Eventually, Reset input mode to explorer - self.input_mode = InputMode::Explorer; + self.popup = None; } } @@ -381,10 +380,7 @@ impl FileTransferActivity { // Write remote file let mut total_bytes_written: usize = 0; // Set input state to popup progress - self.input_mode = InputMode::Popup(PopupType::Progress(format!( - "Uploading \"{}\"", - local.name - ))); + self.popup = Some(Popup::Progress(format!("Uploading \"{}\"", local.name))); // Reset transfer states self.transfer.reset(); let mut last_progress_val: f64 = 0.0; @@ -484,7 +480,7 @@ impl FileTransferActivity { match self.client.recv_file(remote) { Ok(mut rhnd) => { // Set popup progress - self.input_mode = InputMode::Popup(PopupType::Progress(format!( + self.popup = Some(Popup::Progress(format!( "Downloading \"{}\"...", remote.name, )));