From 7a115e5dc37ab71a982341546cf607942e380747 Mon Sep 17 00:00:00 2001 From: ChristianVisintin Date: Thu, 17 Dec 2020 08:45:50 +0100 Subject: [PATCH] wrkdir as member of FileExplorer --- .../filetransfer_activity/callbacks.rs | 65 +++++++------------ .../activities/filetransfer_activity/input.rs | 42 +++--------- .../filetransfer_activity/layout.rs | 18 ++--- .../activities/filetransfer_activity/mod.rs | 18 +++-- .../filetransfer_activity/session.rs | 55 +++++++--------- 5 files changed, 76 insertions(+), 122 deletions(-) diff --git a/src/ui/activities/filetransfer_activity/callbacks.rs b/src/ui/activities/filetransfer_activity/callbacks.rs index cecfaf2..4718b21 100644 --- a/src/ui/activities/filetransfer_activity/callbacks.rs +++ b/src/ui/activities/filetransfer_activity/callbacks.rs @@ -40,7 +40,7 @@ impl FileTransferActivity { // If path is relative, concat pwd let abs_dir_path: PathBuf = match dir_path.is_relative() { true => { - let mut d: PathBuf = self.context.as_ref().unwrap().local.pwd(); + let mut d: PathBuf = self.local.wrkdir.clone(); d.push(dir_path); d } @@ -51,19 +51,11 @@ impl FileTransferActivity { FileExplorerTab::Remote => { // If path is relative, concat pwd let abs_dir_path: PathBuf = match dir_path.is_relative() { - true => match self.client.pwd() { - Ok(mut wkrdir) => { - wkrdir.push(dir_path); - wkrdir - } - Err(err) => { - self.input_mode = InputMode::Popup(PopupType::Alert( - Color::Red, - format!("Could not retrieve current directory: {}", err), - )); - return; - } - }, + true => { + let mut wrkdir: PathBuf = self.remote.wrkdir.clone(); + wrkdir.push(dir_path); + wrkdir + } false => dir_path, }; self.remote_changedir(abs_dir_path.as_path(), true); @@ -90,7 +82,7 @@ impl FileTransferActivity { LogLevel::Info, format!("Created directory \"{}\"", input).as_ref(), ); - let wrkdir: PathBuf = self.context.as_ref().unwrap().local.pwd(); + let wrkdir: PathBuf = self.local.wrkdir.clone(); self.local_scan(wrkdir.as_path()); } Err(err) => { @@ -107,7 +99,11 @@ impl FileTransferActivity { } } FileExplorerTab::Remote => { - match self.client.mkdir(PathBuf::from(input.as_str()).as_path()) { + match self + .client + .as_mut() + .mkdir(PathBuf::from(input.as_str()).as_path()) + { Ok(_) => { // Reload files self.log( @@ -141,7 +137,7 @@ impl FileTransferActivity { let mut dst_path: PathBuf = PathBuf::from(input); // Check if path is relative if dst_path.as_path().is_relative() { - let mut wrkdir: PathBuf = self.context.as_ref().unwrap().local.pwd(); + let mut wrkdir: PathBuf = self.local.wrkdir.clone(); wrkdir.push(dst_path); dst_path = wrkdir; } @@ -158,7 +154,8 @@ impl FileTransferActivity { { Ok(_) => { // Reload files - self.local_scan(self.context.as_ref().unwrap().local.pwd().as_path()); + let path: PathBuf = self.local.wrkdir.clone(); + self.local_scan(path.as_path()); // Log self.log( LogLevel::Info, @@ -194,12 +191,11 @@ impl FileTransferActivity { let full_path: PathBuf = entry.get_abs_path(); // Rename file or directory and report status as popup let dst_path: PathBuf = PathBuf::from(input); - match self.client.rename(entry, dst_path.as_path()) { + match self.client.as_mut().rename(entry, dst_path.as_path()) { Ok(_) => { // Reload files - if let Ok(path) = self.client.pwd() { - self.remote_scan(path.as_path()); - } + let path: PathBuf = self.remote.wrkdir.clone(); + self.remote_scan(path.as_path()); // Log self.log( LogLevel::Info, @@ -246,7 +242,8 @@ impl FileTransferActivity { match self.context.as_mut().unwrap().local.remove(entry) { Ok(_) => { // Reload files - self.local_scan(self.context.as_ref().unwrap().local.pwd().as_path()); + let p: PathBuf = self.local.wrkdir.clone(); + self.local_scan(p.as_path()); // Log self.log( LogLevel::Info, @@ -313,20 +310,7 @@ impl FileTransferActivity { match self.tab { FileExplorerTab::Local => { // Get pwd - let wrkdir: PathBuf = match self.client.pwd() { - Ok(p) => p, - Err(err) => { - self.log( - LogLevel::Error, - format!("Could not get current remote path: {}", err).as_ref(), - ); - self.input_mode = InputMode::Popup(PopupType::Alert( - Color::Red, - format!("Could not get current remote path: {}", err), - )); - return; - } - }; + let wrkdir: PathBuf = self.remote.wrkdir.clone(); // Get file and clone (due to mutable / immutable stuff...) if self.local.files.get(self.local.index).is_some() { let file: FsEntry = self.local.files.get(self.local.index).unwrap().clone(); @@ -339,11 +323,8 @@ impl FileTransferActivity { if self.remote.files.get(self.remote.index).is_some() { let file: FsEntry = self.remote.files.get(self.remote.index).unwrap().clone(); // Call upload; pass realfile, keep link name - self.filetransfer_recv( - &file.get_realfile(), - self.context.as_ref().unwrap().local.pwd().as_path(), - Some(input), - ); + let wrkdir: PathBuf = self.local.wrkdir.clone(); + self.filetransfer_recv(&file.get_realfile(), wrkdir.as_path(), Some(input)); } } } diff --git a/src/ui/activities/filetransfer_activity/input.rs b/src/ui/activities/filetransfer_activity/input.rs index 1d594d5..5f2c605 100644 --- a/src/ui/activities/filetransfer_activity/input.rs +++ b/src/ui/activities/filetransfer_activity/input.rs @@ -21,12 +21,11 @@ use super::{ DialogCallback, DialogYesNoOption, FileExplorerTab, FileTransferActivity, FsEntry, InputEvent, - InputField, InputMode, LogLevel, OnInputSubmitCallback, PopupType, + InputField, InputMode, OnInputSubmitCallback, PopupType, }; use crossterm::event::{KeyCode, KeyModifiers}; use std::path::PathBuf; -use tui::style::Color; impl FileTransferActivity { /// ### read_input_event @@ -221,7 +220,7 @@ impl FileTransferActivity { } 'l' | 'L' => { // Reload file entries - let pwd: PathBuf = self.context.as_ref().unwrap().local.pwd(); + let pwd: PathBuf = self.local.wrkdir.clone(); self.local_scan(pwd.as_path()); } 'r' | 'R' => { @@ -242,27 +241,14 @@ impl FileTransferActivity { 'u' | 'U' => { // Go to parent directory // Get pwd - let path: PathBuf = self.context.as_ref().unwrap().local.pwd(); + let path: PathBuf = self.local.wrkdir.clone(); if let Some(parent) = path.as_path().parent() { self.local_changedir(parent, true); } } ' ' => { // Get pwd - let wrkdir: PathBuf = match self.client.pwd() { - Ok(p) => p, - Err(err) => { - self.log( - LogLevel::Error, - format!("Could not get current remote path: {}", err).as_ref(), - ); - self.input_mode = InputMode::Popup(PopupType::Alert( - Color::Red, - format!("Could not get current remote path: {}", err), - )); - return; - } - }; + let wrkdir: PathBuf = self.remote.wrkdir.clone(); // Get file and clone (due to mutable / immutable stuff...) if self.local.files.get(self.local.index).is_some() { let file: FsEntry = @@ -436,20 +422,11 @@ impl FileTransferActivity { )); } 'u' | 'U' => { - // Go to parent directory // Get pwd - match self.client.pwd() { - Ok(path) => { - if let Some(parent) = path.as_path().parent() { - self.remote_changedir(parent, true); - } - } - Err(err) => { - self.input_mode = InputMode::Popup(PopupType::Alert( - Color::Red, - format!("Could not change working directory: {}", err), - )) - } + let path: PathBuf = self.remote.wrkdir.clone(); + // Go to parent directory + if let Some(parent) = path.as_path().parent() { + self.remote_changedir(parent, true); } } ' ' => { @@ -459,9 +436,10 @@ impl FileTransferActivity { self.remote.files.get(self.remote.index).unwrap().clone(); let name: String = file.get_name(); // Call upload; pass realfile, keep link name + let wrkdir: PathBuf = self.local.wrkdir.clone(); self.filetransfer_recv( &file.get_realfile(), - self.context.as_ref().unwrap().local.pwd().as_path(), + wrkdir.as_path(), Some(name), ); } diff --git a/src/ui/activities/filetransfer_activity/layout.rs b/src/ui/activities/filetransfer_activity/layout.rs index 57912b9..ebb4bf4 100644 --- a/src/ui/activities/filetransfer_activity/layout.rs +++ b/src/ui/activities/filetransfer_activity/layout.rs @@ -50,7 +50,6 @@ impl FileTransferActivity { /// Draw UI pub(super) fn draw(&mut self) { let mut ctx: Context = self.context.take().unwrap(); - let local_wrkdir: PathBuf = ctx.local.pwd(); let _ = ctx.terminal.draw(|f| { // Prepare chunks let chunks = Layout::default() @@ -77,17 +76,12 @@ impl FileTransferActivity { remote_state.select(Some(self.remote.index)); // Draw tabs f.render_stateful_widget( - self.draw_local_explorer(local_wrkdir, tabs_chunks[0].width), + self.draw_local_explorer(tabs_chunks[0].width), tabs_chunks[0], &mut localhost_state, ); - // Get pwd - let remote_wrkdir: PathBuf = match self.client.pwd() { - Ok(p) => p, - Err(_) => PathBuf::from("/"), - }; f.render_stateful_widget( - self.draw_remote_explorer(remote_wrkdir, tabs_chunks[1].width), + self.draw_remote_explorer(tabs_chunks[1].width), tabs_chunks[1], &mut remote_state, ); @@ -153,7 +147,7 @@ impl FileTransferActivity { /// ### draw_local_explorer /// /// Draw local explorer list - pub(super) fn draw_local_explorer(&self, local_wrkdir: PathBuf, width: u16) -> List { + pub(super) fn draw_local_explorer(&self, width: u16) -> List { let hostname: String = match hostname::get() { Ok(h) => { let hostname: String = h.as_os_str().to_string_lossy().to_string(); @@ -188,7 +182,7 @@ impl FileTransferActivity { "{}:{} ", hostname, FileTransferActivity::elide_wrkdir_path( - local_wrkdir.as_path(), + self.local.wrkdir.as_path(), hostname.as_str(), width ) @@ -202,7 +196,7 @@ impl FileTransferActivity { /// ### draw_remote_explorer /// /// Draw remote explorer list - pub(super) fn draw_remote_explorer(&self, remote_wrkdir: PathBuf, width: u16) -> List { + pub(super) fn draw_remote_explorer(&self, width: u16) -> List { let files: Vec = self .remote .files @@ -229,7 +223,7 @@ impl FileTransferActivity { "{}:{} ", self.params.address, FileTransferActivity::elide_wrkdir_path( - remote_wrkdir.as_path(), + self.remote.wrkdir.as_path(), self.params.address.as_str(), width ) diff --git a/src/ui/activities/filetransfer_activity/mod.rs b/src/ui/activities/filetransfer_activity/mod.rs index b8c3ad6..344daa4 100644 --- a/src/ui/activities/filetransfer_activity/mod.rs +++ b/src/ui/activities/filetransfer_activity/mod.rs @@ -119,9 +119,10 @@ enum InputMode { /// /// File explorer states struct FileExplorer { - pub index: usize, - pub files: Vec, - dirstack: VecDeque, + pub wrkdir: PathBuf, // Current directory + pub index: usize, // Selected file + pub files: Vec, // Files in directory + dirstack: VecDeque, // Stack of visited directory (max 16) } impl FileExplorer { @@ -130,6 +131,7 @@ impl FileExplorer { /// Instantiates a new FileExplorer pub fn new() -> FileExplorer { FileExplorer { + wrkdir: PathBuf::from("/"), index: 0, files: Vec::new(), dirstack: VecDeque::with_capacity(16), @@ -347,8 +349,11 @@ impl Activity for FileTransferActivity { let _ = self.context.as_mut().unwrap().terminal.clear(); // Put raw mode on enabled let _ = enable_raw_mode(); + // Set working directory + let pwd: PathBuf = self.context.as_ref().unwrap().local.pwd(); // Get files at current wd - self.local_scan(self.context.as_ref().unwrap().local.pwd().as_path()); + self.local_scan(pwd.as_path()); + self.local.wrkdir = pwd; } /// ### on_draw @@ -356,8 +361,9 @@ impl Activity for FileTransferActivity { /// `on_draw` is the function which draws the graphical interface. /// This function must be called at each tick to refresh the interface fn on_draw(&mut self) { - let mut redraw: bool = false; // Should ui actually be redrawned? - // Context must be something + // Should ui actually be redrawned? + let mut redraw: bool = false; + // Context must be something if self.context.is_none() { return; } diff --git a/src/ui/activities/filetransfer_activity/session.rs b/src/ui/activities/filetransfer_activity/session.rs index 068a0d0..e22ce39 100644 --- a/src/ui/activities/filetransfer_activity/session.rs +++ b/src/ui/activities/filetransfer_activity/session.rs @@ -31,7 +31,7 @@ use crate::utils::fmt_millis; // Ext use bytesize::ByteSize; use crossterm::terminal::{disable_raw_mode, enable_raw_mode}; -use std::fs::{File, OpenOptions}; +use std::fs::OpenOptions; use std::io::{Read, Seek, Write}; use std::path::{Path, PathBuf}; use std::time::Instant; @@ -102,6 +102,8 @@ impl FileTransferActivity { // Get current entries if let Ok(pwd) = self.client.pwd() { self.remote_scan(pwd.as_path()); + // Set wrkdir + self.remote.wrkdir = pwd; } } @@ -319,9 +321,8 @@ impl FileTransferActivity { } } // Scan dir on remote - if let Ok(path) = self.client.pwd() { - self.remote_scan(path.as_path()); - } + let path: PathBuf = self.remote.wrkdir.clone(); + self.remote_scan(path.as_path()); // If aborted; show popup if self.transfer.aborted { // Log abort @@ -684,7 +685,7 @@ impl FileTransferActivity { /// Change directory for local pub(super) fn local_changedir(&mut self, path: &Path, push: bool) { // Get current directory - let prev_dir: PathBuf = self.context.as_ref().unwrap().local.pwd(); + let prev_dir: PathBuf = self.local.wrkdir.clone(); // Change directory match self .context @@ -702,6 +703,8 @@ impl FileTransferActivity { self.local_scan(path); // Reset index self.local.index = 0; + // Set wrkdir + self.local.wrkdir = PathBuf::from(path); // Push prev_dir to stack if push { self.local.pushd(prev_dir.as_path()) @@ -719,31 +722,23 @@ impl FileTransferActivity { pub(super) fn remote_changedir(&mut self, path: &Path, push: bool) { // Get current directory - match self.client.pwd() { - Ok(prev_dir) => { - // Change directory - match self.client.change_dir(path) { - Ok(_) => { - self.log( - LogLevel::Info, - format!("Changed directory on remote: {}", path.display()).as_str(), - ); - // Update files - self.remote_scan(path); - // Reset index - self.remote.index = 0; - // Push prev_dir to stack - if push { - self.remote.pushd(prev_dir.as_path()) - } - } - Err(err) => { - // Report err - self.log_and_alert( - LogLevel::Error, - format!("Could not change working directory: {}", err), - ); - } + let prev_dir: PathBuf = self.remote.wrkdir.clone(); + // Change directory + match self.client.as_mut().change_dir(path) { + Ok(_) => { + self.log( + LogLevel::Info, + format!("Changed directory on remote: {}", path.display()).as_str(), + ); + // Update files + self.remote_scan(path); + // Reset index + self.remote.index = 0; + // Set wrkdir + self.remote.wrkdir = PathBuf::from(path); + // Push prev_dir to stack + if push { + self.remote.pushd(prev_dir.as_path()) } } Err(err) => {