diff --git a/CHANGELOG.md b/CHANGELOG.md index 9bfe2f9..7618171 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -45,6 +45,8 @@ Released on FIXME: ?? - **Installation script**: - From now on, in case cargo is used to install termscp, all the cargo dependencies will be installed - **Start termscp from configuration**: Start termscp with `-c` or `--config` to start termscp from configuration page +- Enhancements: + - Show a "wait" message when deleting, copying and moving files and when executing commands - Bugfix: - Fixed broken input cursor when typing UTF8 characters (tui-realm 0.3.2) - Fixed save bookmark dialog: you could switch out from dialog with `` diff --git a/src/ui/activities/filetransfer/update.rs b/src/ui/activities/filetransfer/update.rs index 0ce5ac6..6067a32 100644 --- a/src/ui/activities/filetransfer/update.rs +++ b/src/ui/activities/filetransfer/update.rs @@ -366,12 +366,14 @@ impl Update for FileTransferActivity { } (COMPONENT_INPUT_COPY, Msg::OnSubmit(Payload::One(Value::Str(input)))) => { // Copy file + self.umount_copy(); + self.mount_blocking_wait("Copying file(s)…"); match self.browser.tab() { FileExplorerTab::Local => self.action_local_copy(input.to_string()), FileExplorerTab::Remote => self.action_remote_copy(input.to_string()), _ => panic!("Found tab doesn't support COPY"), } - self.umount_copy(); + self.umount_wait(); // Reload files match self.browser.tab() { FileExplorerTab::Local => self.update_local_filelist(), @@ -387,12 +389,14 @@ impl Update for FileTransferActivity { } (COMPONENT_INPUT_EXEC, Msg::OnSubmit(Payload::One(Value::Str(input)))) => { // Exex command + self.umount_exec(); + self.mount_blocking_wait(format!("Executing '{}'…", input).as_str()); match self.browser.tab() { FileExplorerTab::Local => self.action_local_exec(input.to_string()), FileExplorerTab::Remote => self.action_remote_exec(input.to_string()), _ => panic!("Found tab doesn't support EXEC"), } - self.umount_exec(); + self.umount_wait(); // Reload files match self.browser.tab() { FileExplorerTab::Local => self.update_local_filelist(), @@ -532,12 +536,14 @@ impl Update for FileTransferActivity { None } (COMPONENT_INPUT_RENAME, Msg::OnSubmit(Payload::One(Value::Str(input)))) => { + self.umount_rename(); + self.mount_blocking_wait("Moving file(s)…"); match self.browser.tab() { FileExplorerTab::Local => self.action_local_rename(input.to_string()), FileExplorerTab::Remote => self.action_remote_rename(input.to_string()), _ => panic!("Found tab doesn't support RENAME"), } - self.umount_rename(); + self.umount_wait(); // Reload files match self.browser.tab() { FileExplorerTab::Local => self.update_local_filelist(), @@ -586,6 +592,8 @@ impl Update for FileTransferActivity { } (COMPONENT_RADIO_DELETE, Msg::OnSubmit(Payload::One(Value::Usize(0)))) => { // Choice is 'YES' + self.umount_radio_delete(); + self.mount_blocking_wait("Removing file(s)…"); match self.browser.tab() { FileExplorerTab::Local => self.action_local_delete(), FileExplorerTab::Remote => self.action_remote_delete(), @@ -612,7 +620,7 @@ impl Update for FileTransferActivity { self.update_find_list(); } } - self.umount_radio_delete(); + self.umount_wait(); // Reload files match self.browser.tab() { FileExplorerTab::Local => self.update_local_filelist(), @@ -906,7 +914,7 @@ impl FileTransferActivity { /// ### elide_wrkdir_path /// /// Elide working directory path if longer than width + host.len - /// In this case, the path is formatted to {ANCESTOR[0]}/.../{PARENT[0]}/{BASENAME} + /// In this case, the path is formatted to {ANCESTOR[0]}/…/{PARENT[0]}/{BASENAME} fn elide_wrkdir_path(wrkdir: &Path, host: &str, width: usize) -> PathBuf { let fmt_path: String = format!("{}", wrkdir.display()); // NOTE: +5 is const @@ -921,9 +929,9 @@ impl FileTransferActivity { if ancestors_len > 2 { elided_path.push(ancestors.nth(ancestors_len - 2).unwrap()); } - // If ancestors_len is bigger than 3, push '...' and parent too + // If ancestors_len is bigger than 3, push '…' and parent too if ancestors_len > 3 { - elided_path.push("..."); + elided_path.push("…"); if let Some(parent) = wrkdir.ancestors().nth(1) { elided_path.push(parent.file_name().unwrap()); } diff --git a/src/ui/activities/filetransfer/view.rs b/src/ui/activities/filetransfer/view.rs index 0f44c47..41b7b49 100644 --- a/src/ui/activities/filetransfer/view.rs +++ b/src/ui/activities/filetransfer/view.rs @@ -422,17 +422,28 @@ impl FileTransferActivity { } pub(super) fn mount_wait(&mut self, text: &str) { + self.mount_wait_ex(text, false, Color::Reset); + } + + pub(super) fn mount_blocking_wait(&mut self, text: &str) { + self.mount_wait_ex(text, true, Color::Reset); + self.view(); + } + + fn mount_wait_ex(&mut self, text: &str, blink: bool, color: Color) { // Mount + let mut builder: MsgBoxPropsBuilder = MsgBoxPropsBuilder::default(); + builder + .with_foreground(color) + .with_borders(Borders::ALL, BorderType::Rounded, Color::White) + .bold() + .with_texts(None, vec![TextSpan::from(text)]); + if blink { + builder.blink(); + } self.view.mount( super::COMPONENT_TEXT_WAIT, - Box::new(MsgBox::new( - MsgBoxPropsBuilder::default() - .with_foreground(Color::White) - .with_borders(Borders::ALL, BorderType::Rounded, Color::White) - .bold() - .with_texts(None, vec![TextSpan::from(text)]) - .build(), - )), + Box::new(MsgBox::new(builder.build())), ); // Give focus to info self.view.active(super::COMPONENT_TEXT_WAIT); diff --git a/src/ui/components/msgbox.rs b/src/ui/components/msgbox.rs index aae1120..226864a 100644 --- a/src/ui/components/msgbox.rs +++ b/src/ui/components/msgbox.rs @@ -94,6 +94,13 @@ impl MsgBoxPropsBuilder { self } + pub fn blink(&mut self) -> &mut Self { + if let Some(props) = self.props.as_mut() { + props.modifiers |= Modifier::SLOW_BLINK; + } + self + } + pub fn with_borders( &mut self, borders: Borders, @@ -221,6 +228,7 @@ mod tests { .visible() .with_foreground(Color::Red) .bold() + .blink() .with_borders(Borders::ALL, BorderType::Double, Color::Red) .with_texts( None,