mirror of
https://github.com/veeso/termscp.git
synced 2025-12-07 09:36:00 -08:00
fix: renamed local to Host bridge
This commit is contained in:
@@ -136,7 +136,7 @@ impl FileToRemove {
|
||||
#[derive(Debug, PartialEq, Eq, Clone)]
|
||||
pub struct FileUpdate {
|
||||
/// Path to file which has changed
|
||||
local: PathBuf,
|
||||
host_bridge: PathBuf,
|
||||
/// Path to remote file to update
|
||||
remote: PathBuf,
|
||||
}
|
||||
@@ -152,13 +152,13 @@ impl FileUpdate {
|
||||
fn new(changed_path: PathBuf, local_watched_path: &Path, remote_synched_path: &Path) -> Self {
|
||||
Self {
|
||||
remote: remote_relative_path(&changed_path, local_watched_path, remote_synched_path),
|
||||
local: changed_path,
|
||||
host_bridge: changed_path,
|
||||
}
|
||||
}
|
||||
|
||||
/// Get path to local file to sync
|
||||
pub fn local(&self) -> &Path {
|
||||
self.local.as_path()
|
||||
pub fn host_bridge(&self) -> &Path {
|
||||
self.host_bridge.as_path()
|
||||
}
|
||||
|
||||
/// Get path to remote file to sync
|
||||
@@ -288,7 +288,7 @@ mod test {
|
||||
Path::new("/home/foo/bar.txt"),
|
||||
);
|
||||
if let FsChange::Update(change) = change {
|
||||
assert_eq!(change.local(), Path::new("/tmp/bar.txt"),);
|
||||
assert_eq!(change.host_bridge(), Path::new("/tmp/bar.txt"),);
|
||||
assert_eq!(change.remote(), Path::new("/home/foo/bar.txt"));
|
||||
} else {
|
||||
panic!("not an update");
|
||||
@@ -303,7 +303,7 @@ mod test {
|
||||
Path::new("/home/foo/temp"),
|
||||
);
|
||||
if let FsChange::Update(change) = change {
|
||||
assert_eq!(change.local(), Path::new("/tmp/abc/foo.txt"),);
|
||||
assert_eq!(change.host_bridge(), Path::new("/tmp/abc/foo.txt"),);
|
||||
assert_eq!(change.remote(), Path::new("/home/foo/temp/abc/foo.txt"));
|
||||
} else {
|
||||
panic!("not an update");
|
||||
|
||||
@@ -19,7 +19,7 @@ enum SyncBrowsingDestination {
|
||||
impl FileTransferActivity {
|
||||
/// Enter a directory on local host from entry
|
||||
pub(crate) fn action_enter_local_dir(&mut self, dir: File) {
|
||||
self.local_changedir(dir.path(), true);
|
||||
self.host_bridge_changedir(dir.path(), true);
|
||||
if self.browser.sync_browsing && self.browser.found().is_none() {
|
||||
self.synchronize_browsing(SyncBrowsingDestination::Path(dir.name()));
|
||||
}
|
||||
@@ -35,8 +35,9 @@ impl FileTransferActivity {
|
||||
|
||||
/// Change local directory reading value from input
|
||||
pub(crate) fn action_change_local_dir(&mut self, input: String) {
|
||||
let dir_path: PathBuf = self.local_to_abs_path(PathBuf::from(input.as_str()).as_path());
|
||||
self.local_changedir(dir_path.as_path(), true);
|
||||
let dir_path: PathBuf =
|
||||
self.host_bridge_to_abs_path(PathBuf::from(input.as_str()).as_path());
|
||||
self.host_bridge_changedir(dir_path.as_path(), true);
|
||||
// Check whether to sync
|
||||
if self.browser.sync_browsing && self.browser.found().is_none() {
|
||||
self.synchronize_browsing(SyncBrowsingDestination::Path(input));
|
||||
@@ -55,8 +56,8 @@ impl FileTransferActivity {
|
||||
|
||||
/// Go to previous directory from localhost
|
||||
pub(crate) fn action_go_to_previous_local_dir(&mut self) {
|
||||
if let Some(d) = self.local_mut().popd() {
|
||||
self.local_changedir(d.as_path(), false);
|
||||
if let Some(d) = self.host_bridge_mut().popd() {
|
||||
self.host_bridge_changedir(d.as_path(), false);
|
||||
// Check whether to sync
|
||||
if self.browser.sync_browsing && self.browser.found().is_none() {
|
||||
self.synchronize_browsing(SyncBrowsingDestination::PreviousDir);
|
||||
@@ -78,10 +79,10 @@ impl FileTransferActivity {
|
||||
/// Go to upper directory on local host
|
||||
pub(crate) fn action_go_to_local_upper_dir(&mut self) {
|
||||
// Get pwd
|
||||
let path: PathBuf = self.local().wrkdir.clone();
|
||||
let path: PathBuf = self.host_bridge().wrkdir.clone();
|
||||
// Go to parent directory
|
||||
if let Some(parent) = path.as_path().parent() {
|
||||
self.local_changedir(parent, true);
|
||||
self.host_bridge_changedir(parent, true);
|
||||
// If sync is enabled update remote too
|
||||
if self.browser.sync_browsing && self.browser.found().is_none() {
|
||||
self.synchronize_browsing(SyncBrowsingDestination::ParentDir);
|
||||
@@ -118,7 +119,7 @@ impl FileTransferActivity {
|
||||
trace!("Synchronizing browsing to path {}", path.display());
|
||||
// Check whether destination exists on host
|
||||
let exists = match self.browser.tab() {
|
||||
FileExplorerTab::Local => match self.client.exists(path.as_path()) {
|
||||
FileExplorerTab::HostBridge => match self.client.exists(path.as_path()) {
|
||||
Ok(e) => e,
|
||||
Err(err) => {
|
||||
error!(
|
||||
@@ -129,7 +130,7 @@ impl FileTransferActivity {
|
||||
return;
|
||||
}
|
||||
},
|
||||
FileExplorerTab::Remote => match self.host.exists(path.as_path()) {
|
||||
FileExplorerTab::Remote => match self.host_bridge.exists(path.as_path()) {
|
||||
Ok(e) => e,
|
||||
Err(err) => {
|
||||
error!(
|
||||
@@ -160,7 +161,7 @@ impl FileTransferActivity {
|
||||
trace!("User wants to create the unexisting directory");
|
||||
// Make directory
|
||||
match self.browser.tab() {
|
||||
FileExplorerTab::Local => self.action_remote_mkdir(name.clone()),
|
||||
FileExplorerTab::HostBridge => self.action_remote_mkdir(name.clone()),
|
||||
FileExplorerTab::Remote => self.action_local_mkdir(name.clone()),
|
||||
_ => {}
|
||||
}
|
||||
@@ -183,18 +184,18 @@ impl FileTransferActivity {
|
||||
// Enter directory
|
||||
match destination {
|
||||
SyncBrowsingDestination::ParentDir => match self.browser.tab() {
|
||||
FileExplorerTab::Local => self.remote_changedir(path.as_path(), true),
|
||||
FileExplorerTab::Remote => self.local_changedir(path.as_path(), true),
|
||||
FileExplorerTab::HostBridge => self.remote_changedir(path.as_path(), true),
|
||||
FileExplorerTab::Remote => self.host_bridge_changedir(path.as_path(), true),
|
||||
_ => {}
|
||||
},
|
||||
SyncBrowsingDestination::Path(_) => match self.browser.tab() {
|
||||
FileExplorerTab::Local => self.remote_changedir(path.as_path(), true),
|
||||
FileExplorerTab::Remote => self.local_changedir(path.as_path(), true),
|
||||
FileExplorerTab::HostBridge => self.remote_changedir(path.as_path(), true),
|
||||
FileExplorerTab::Remote => self.host_bridge_changedir(path.as_path(), true),
|
||||
_ => {}
|
||||
},
|
||||
SyncBrowsingDestination::PreviousDir => match self.browser.tab() {
|
||||
FileExplorerTab::Local => self.remote_changedir(path.as_path(), false),
|
||||
FileExplorerTab::Remote => self.local_changedir(path.as_path(), false),
|
||||
FileExplorerTab::HostBridge => self.remote_changedir(path.as_path(), false),
|
||||
FileExplorerTab::Remote => self.host_bridge_changedir(path.as_path(), false),
|
||||
_ => {}
|
||||
},
|
||||
}
|
||||
@@ -207,13 +208,13 @@ impl FileTransferActivity {
|
||||
) -> Option<PathBuf> {
|
||||
match (destination, self.browser.tab()) {
|
||||
// NOTE: tab and methods are switched on purpose
|
||||
(SyncBrowsingDestination::ParentDir, FileExplorerTab::Local) => {
|
||||
(SyncBrowsingDestination::ParentDir, FileExplorerTab::HostBridge) => {
|
||||
self.remote().wrkdir.parent().map(|x| x.to_path_buf())
|
||||
}
|
||||
(SyncBrowsingDestination::ParentDir, FileExplorerTab::Remote) => {
|
||||
self.local().wrkdir.parent().map(|x| x.to_path_buf())
|
||||
self.host_bridge().wrkdir.parent().map(|x| x.to_path_buf())
|
||||
}
|
||||
(SyncBrowsingDestination::PreviousDir, FileExplorerTab::Local) => {
|
||||
(SyncBrowsingDestination::PreviousDir, FileExplorerTab::HostBridge) => {
|
||||
if let Some(p) = self.remote_mut().popd() {
|
||||
Some(p)
|
||||
} else {
|
||||
@@ -222,7 +223,7 @@ impl FileTransferActivity {
|
||||
}
|
||||
}
|
||||
(SyncBrowsingDestination::PreviousDir, FileExplorerTab::Remote) => {
|
||||
if let Some(p) = self.local_mut().popd() {
|
||||
if let Some(p) = self.host_bridge_mut().popd() {
|
||||
Some(p)
|
||||
} else {
|
||||
warn!("Cannot synchronize browsing: local has no previous directory in stack");
|
||||
|
||||
@@ -8,7 +8,7 @@ impl FileTransferActivity {
|
||||
let files = self.get_local_selected_entries().get_files();
|
||||
|
||||
for file in files {
|
||||
if let Err(err) = self.host.chmod(file.path(), mode) {
|
||||
if let Err(err) = self.host_bridge.chmod(file.path(), mode) {
|
||||
self.log_and_alert(
|
||||
LogLevel::Error,
|
||||
format!(
|
||||
@@ -56,7 +56,7 @@ impl FileTransferActivity {
|
||||
let files = self.get_found_selected_entries().get_files();
|
||||
|
||||
for file in files {
|
||||
if let Err(err) = self.host.chmod(file.path(), mode) {
|
||||
if let Err(err) = self.host_bridge.chmod(file.path(), mode) {
|
||||
self.log_and_alert(
|
||||
LogLevel::Error,
|
||||
format!(
|
||||
|
||||
@@ -53,7 +53,7 @@ impl FileTransferActivity {
|
||||
}
|
||||
|
||||
fn local_copy_file(&mut self, entry: &File, dest: &Path) {
|
||||
match self.host.copy(entry, dest) {
|
||||
match self.host_bridge.copy(entry, dest) {
|
||||
Ok(_) => {
|
||||
self.log(
|
||||
LogLevel::Info,
|
||||
@@ -136,7 +136,7 @@ impl FileTransferActivity {
|
||||
return Err(err);
|
||||
}
|
||||
// Stat dir
|
||||
let tempdir_entry = match self.host.stat(tempdir_path.as_path()) {
|
||||
let tempdir_entry = match self.host_bridge.stat(tempdir_path.as_path()) {
|
||||
Ok(e) => e,
|
||||
Err(err) => {
|
||||
self.log_and_alert(
|
||||
@@ -189,7 +189,7 @@ impl FileTransferActivity {
|
||||
return Err(err);
|
||||
}
|
||||
// Get local fs entry
|
||||
let tmpfile_entry = match self.host.stat(tmpfile.path()) {
|
||||
let tmpfile_entry = match self.host_bridge.stat(tmpfile.path()) {
|
||||
Ok(e) if e.is_file() => e,
|
||||
Ok(_) => panic!("{} is not a file", tmpfile.path().display()),
|
||||
Err(err) => {
|
||||
|
||||
@@ -43,7 +43,7 @@ impl FileTransferActivity {
|
||||
}
|
||||
|
||||
pub(crate) fn local_remove_file(&mut self, entry: &File) {
|
||||
match self.host.remove(entry) {
|
||||
match self.host_bridge.remove(entry) {
|
||||
Ok(_) => {
|
||||
// Log
|
||||
self.log(
|
||||
|
||||
@@ -138,7 +138,7 @@ impl FileTransferActivity {
|
||||
return Err(format!("Could not open file {file_name}: {err}"));
|
||||
}
|
||||
// Get current file modification time
|
||||
let prev_mtime: SystemTime = match self.host.stat(tmpfile.as_path()) {
|
||||
let prev_mtime: SystemTime = match self.host_bridge.stat(tmpfile.as_path()) {
|
||||
Ok(e) => e.metadata().modified.unwrap_or(std::time::UNIX_EPOCH),
|
||||
Err(err) => {
|
||||
return Err(format!(
|
||||
@@ -151,7 +151,7 @@ impl FileTransferActivity {
|
||||
// Edit file
|
||||
self.edit_local_file(tmpfile.as_path())?;
|
||||
// Get local fs entry
|
||||
let tmpfile_entry: File = match self.host.stat(tmpfile.as_path()) {
|
||||
let tmpfile_entry: File = match self.host_bridge.stat(tmpfile.as_path()) {
|
||||
Ok(e) => e,
|
||||
Err(err) => {
|
||||
return Err(format!(
|
||||
@@ -177,7 +177,7 @@ impl FileTransferActivity {
|
||||
),
|
||||
);
|
||||
// Get local fs entry
|
||||
let tmpfile_entry = match self.host.stat(tmpfile.as_path()) {
|
||||
let tmpfile_entry = match self.host_bridge.stat(tmpfile.as_path()) {
|
||||
Ok(e) => e,
|
||||
Err(err) => {
|
||||
return Err(format!(
|
||||
|
||||
@@ -7,7 +7,7 @@ use super::{FileTransferActivity, LogLevel};
|
||||
|
||||
impl FileTransferActivity {
|
||||
pub(crate) fn action_local_exec(&mut self, input: String) {
|
||||
match self.host.exec(input.as_str()) {
|
||||
match self.host_bridge.exec(input.as_str()) {
|
||||
Ok(output) => {
|
||||
// Reload files
|
||||
self.log(LogLevel::Info, format!("\"{input}\": {output}"));
|
||||
|
||||
@@ -40,7 +40,7 @@ impl FileTransferActivity {
|
||||
let filter = Filter::from_str(filter).unwrap();
|
||||
|
||||
match self.browser.tab() {
|
||||
FileExplorerTab::Local => self.browser.local().iter_files(),
|
||||
FileExplorerTab::HostBridge => self.browser.host_bridge().iter_files(),
|
||||
FileExplorerTab::Remote => self.browser.remote().iter_files(),
|
||||
_ => return vec![],
|
||||
}
|
||||
|
||||
@@ -24,8 +24,8 @@ impl FileTransferActivity {
|
||||
};
|
||||
// Change directory
|
||||
match self.browser.tab() {
|
||||
FileExplorerTab::FindLocal | FileExplorerTab::Local => {
|
||||
self.local_changedir(path.as_path(), true)
|
||||
FileExplorerTab::FindHostBridge | FileExplorerTab::HostBridge => {
|
||||
self.host_bridge_changedir(path.as_path(), true)
|
||||
}
|
||||
FileExplorerTab::FindRemote | FileExplorerTab::Remote => {
|
||||
self.remote_changedir(path.as_path(), true)
|
||||
@@ -36,12 +36,16 @@ impl FileTransferActivity {
|
||||
|
||||
pub(crate) fn action_find_transfer(&mut self, opts: TransferOpts) {
|
||||
let wrkdir: PathBuf = match self.browser.tab() {
|
||||
FileExplorerTab::FindLocal | FileExplorerTab::Local => self.remote().wrkdir.clone(),
|
||||
FileExplorerTab::FindRemote | FileExplorerTab::Remote => self.local().wrkdir.clone(),
|
||||
FileExplorerTab::FindHostBridge | FileExplorerTab::HostBridge => {
|
||||
self.remote().wrkdir.clone()
|
||||
}
|
||||
FileExplorerTab::FindRemote | FileExplorerTab::Remote => {
|
||||
self.host_bridge().wrkdir.clone()
|
||||
}
|
||||
};
|
||||
match self.get_found_selected_entries() {
|
||||
SelectedFile::One(entry) => match self.browser.tab() {
|
||||
FileExplorerTab::FindLocal | FileExplorerTab::Local => {
|
||||
FileExplorerTab::FindHostBridge | FileExplorerTab::HostBridge => {
|
||||
let file_to_check = Self::file_to_check(&entry, opts.save_as.as_ref());
|
||||
if self.config().get_prompt_on_file_replace()
|
||||
&& self.remote_file_exists(file_to_check.as_path())
|
||||
@@ -66,7 +70,7 @@ impl FileTransferActivity {
|
||||
FileExplorerTab::FindRemote | FileExplorerTab::Remote => {
|
||||
let file_to_check = Self::file_to_check(&entry, opts.save_as.as_ref());
|
||||
if self.config().get_prompt_on_file_replace()
|
||||
&& self.local_file_exists(file_to_check.as_path())
|
||||
&& self.host_bridge_file_exists(file_to_check.as_path())
|
||||
&& !self.should_replace_file(
|
||||
opts.save_as.clone().unwrap_or_else(|| entry.name()),
|
||||
)
|
||||
@@ -94,7 +98,7 @@ impl FileTransferActivity {
|
||||
}
|
||||
// Iter files
|
||||
match self.browser.tab() {
|
||||
FileExplorerTab::FindLocal | FileExplorerTab::Local => {
|
||||
FileExplorerTab::FindHostBridge | FileExplorerTab::HostBridge => {
|
||||
if self.config().get_prompt_on_file_replace() {
|
||||
// Check which file would be replaced
|
||||
let existing_files: Vec<&File> = entries
|
||||
@@ -131,7 +135,7 @@ impl FileTransferActivity {
|
||||
let existing_files: Vec<&File> = entries
|
||||
.iter()
|
||||
.filter(|x| {
|
||||
self.local_file_exists(
|
||||
self.host_bridge_file_exists(
|
||||
Self::file_to_check_many(x, dest_path.as_path()).as_path(),
|
||||
)
|
||||
})
|
||||
@@ -179,7 +183,7 @@ impl FileTransferActivity {
|
||||
|
||||
fn remove_found_file(&mut self, entry: &File) {
|
||||
match self.browser.tab() {
|
||||
FileExplorerTab::FindLocal | FileExplorerTab::Local => {
|
||||
FileExplorerTab::FindHostBridge | FileExplorerTab::HostBridge => {
|
||||
self.local_remove_file(entry);
|
||||
}
|
||||
FileExplorerTab::FindRemote | FileExplorerTab::Remote => {
|
||||
@@ -224,7 +228,7 @@ impl FileTransferActivity {
|
||||
|
||||
fn open_found_file(&mut self, entry: &File, with: Option<&str>) {
|
||||
match self.browser.tab() {
|
||||
FileExplorerTab::FindLocal | FileExplorerTab::Local => {
|
||||
FileExplorerTab::FindHostBridge | FileExplorerTab::HostBridge => {
|
||||
self.action_open_local_file(entry, with);
|
||||
}
|
||||
FileExplorerTab::FindRemote | FileExplorerTab::Remote => {
|
||||
|
||||
@@ -11,7 +11,10 @@ use super::{FileTransferActivity, LogLevel};
|
||||
|
||||
impl FileTransferActivity {
|
||||
pub(crate) fn action_local_mkdir(&mut self, input: String) {
|
||||
match self.host.mkdir(PathBuf::from(input.as_str()).as_path()) {
|
||||
match self
|
||||
.host_bridge
|
||||
.mkdir(PathBuf::from(input.as_str()).as_path())
|
||||
{
|
||||
Ok(_) => {
|
||||
// Reload files
|
||||
self.log(LogLevel::Info, format!("Created directory \"{input}\""));
|
||||
|
||||
@@ -86,12 +86,12 @@ impl From<Vec<&File>> for SelectedFile {
|
||||
impl FileTransferActivity {
|
||||
/// Get local file entry
|
||||
pub(crate) fn get_local_selected_entries(&self) -> SelectedFile {
|
||||
match self.get_selected_index(&Id::ExplorerLocal) {
|
||||
SelectedFileIndex::One(idx) => SelectedFile::from(self.local().get(idx)),
|
||||
match self.get_selected_index(&Id::ExplorerHostBridge) {
|
||||
SelectedFileIndex::One(idx) => SelectedFile::from(self.host_bridge().get(idx)),
|
||||
SelectedFileIndex::Many(files) => {
|
||||
let files: Vec<&File> = files
|
||||
.iter()
|
||||
.filter_map(|x| self.local().get(*x)) // Usize to Option<File>
|
||||
.filter_map(|x| self.host_bridge().get(*x)) // Usize to Option<File>
|
||||
.collect();
|
||||
SelectedFile::from(files)
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ impl FileTransferActivity {
|
||||
pub(crate) fn action_local_newfile(&mut self, input: String) {
|
||||
// Check if file exists
|
||||
let mut file_exists: bool = false;
|
||||
for file in self.local().iter_files_all() {
|
||||
for file in self.host_bridge().iter_files_all() {
|
||||
if input == file.name() {
|
||||
file_exists = true;
|
||||
}
|
||||
@@ -27,7 +27,7 @@ impl FileTransferActivity {
|
||||
// Create file
|
||||
let file_path: PathBuf = PathBuf::from(input.as_str());
|
||||
let writer = match self
|
||||
.host
|
||||
.host_bridge
|
||||
.create_file(file_path.as_path(), &Metadata::default())
|
||||
{
|
||||
Ok(f) => f,
|
||||
@@ -40,7 +40,7 @@ impl FileTransferActivity {
|
||||
}
|
||||
};
|
||||
// finalize write
|
||||
if let Err(err) = self.host.finalize_write(writer) {
|
||||
if let Err(err) = self.host_bridge.finalize_write(writer) {
|
||||
self.log_and_alert(
|
||||
LogLevel::Error,
|
||||
format!("Could not write file \"{}\": {}", file_path.display(), err),
|
||||
@@ -75,7 +75,7 @@ impl FileTransferActivity {
|
||||
}
|
||||
Ok(tfile) => {
|
||||
// Stat tempfile
|
||||
let local_file: File = match self.host.stat(tfile.path()) {
|
||||
let local_file: File = match self.host_bridge.stat(tfile.path()) {
|
||||
Err(err) => {
|
||||
self.log_and_alert(
|
||||
LogLevel::Error,
|
||||
|
||||
@@ -51,7 +51,7 @@ impl FileTransferActivity {
|
||||
}
|
||||
|
||||
fn local_rename_file(&mut self, entry: &File, dest: &Path) {
|
||||
match self.host.rename(entry, dest) {
|
||||
match self.host_bridge.rename(entry, dest) {
|
||||
Ok(_) => {
|
||||
self.log(
|
||||
LogLevel::Info,
|
||||
|
||||
@@ -93,12 +93,12 @@ impl FileTransferActivity {
|
||||
}
|
||||
|
||||
fn remote_recv_file(&mut self, opts: TransferOpts) {
|
||||
let wrkdir: PathBuf = self.local().wrkdir.clone();
|
||||
let wrkdir: PathBuf = self.host_bridge().wrkdir.clone();
|
||||
match self.get_remote_selected_entries() {
|
||||
SelectedFile::One(entry) => {
|
||||
let file_to_check = Self::file_to_check(&entry, opts.save_as.as_ref());
|
||||
if self.config().get_prompt_on_file_replace()
|
||||
&& self.local_file_exists(file_to_check.as_path())
|
||||
&& self.host_bridge_file_exists(file_to_check.as_path())
|
||||
&& !self
|
||||
.should_replace_file(opts.save_as.clone().unwrap_or_else(|| entry.name()))
|
||||
{
|
||||
@@ -129,7 +129,7 @@ impl FileTransferActivity {
|
||||
let existing_files: Vec<&File> = entries
|
||||
.iter()
|
||||
.filter(|x| {
|
||||
self.local_file_exists(
|
||||
self.host_bridge_file_exists(
|
||||
Self::file_to_check_many(x, dest_path.as_path()).as_path(),
|
||||
)
|
||||
})
|
||||
|
||||
@@ -6,8 +6,8 @@ use crate::ui::activities::filetransfer::lib::browser::FileExplorerTab;
|
||||
impl FileTransferActivity {
|
||||
pub(crate) fn action_scan(&mut self, p: &Path) -> Result<Vec<File>, String> {
|
||||
match self.browser.tab() {
|
||||
FileExplorerTab::Local | FileExplorerTab::FindLocal => self
|
||||
.host
|
||||
FileExplorerTab::HostBridge | FileExplorerTab::FindHostBridge => self
|
||||
.host_bridge
|
||||
.list_dir(p)
|
||||
.map_err(|e| format!("Failed to list directory: {}", e)),
|
||||
FileExplorerTab::Remote | FileExplorerTab::FindRemote => self
|
||||
|
||||
@@ -19,7 +19,7 @@ impl FileTransferActivity {
|
||||
} else if entry.metadata().symlink.is_some() {
|
||||
// Stat file
|
||||
let symlink = entry.metadata().symlink.as_ref().unwrap();
|
||||
let stat_file = match self.host.stat(symlink.as_path()) {
|
||||
let stat_file = match self.host_bridge.stat(symlink.as_path()) {
|
||||
Ok(e) => e,
|
||||
Err(err) => {
|
||||
warn!(
|
||||
|
||||
@@ -13,7 +13,7 @@ impl FileTransferActivity {
|
||||
pub(crate) fn action_local_symlink(&mut self, name: String) {
|
||||
if let SelectedFile::One(entry) = self.get_local_selected_entries() {
|
||||
match self
|
||||
.host
|
||||
.host_bridge
|
||||
.symlink(PathBuf::from(name.as_str()).as_path(), entry.path())
|
||||
{
|
||||
Ok(_) => {
|
||||
|
||||
@@ -19,12 +19,15 @@ impl FileTransferActivity {
|
||||
let mut acc = Vec::with_capacity(32_768);
|
||||
|
||||
let pwd = self
|
||||
.host
|
||||
.host_bridge
|
||||
.pwd()
|
||||
.map_err(|e| WalkdirError::Error(e.to_string()))?;
|
||||
|
||||
self.walkdir(&mut acc, &pwd, |activity, path| {
|
||||
activity.host.list_dir(path).map_err(|e| e.to_string())
|
||||
activity
|
||||
.host_bridge
|
||||
.list_dir(path)
|
||||
.map_err(|e| e.to_string())
|
||||
})?;
|
||||
|
||||
Ok(acc)
|
||||
|
||||
@@ -1551,8 +1551,8 @@ pub struct StatusBarLocal {
|
||||
|
||||
impl StatusBarLocal {
|
||||
pub fn new(browser: &Browser, sorting_color: Color, hidden_color: Color) -> Self {
|
||||
let file_sorting = file_sorting_label(browser.local().file_sorting);
|
||||
let hidden_files = hidden_files_label(browser.local().hidden_files_visible());
|
||||
let file_sorting = file_sorting_label(browser.host_bridge().file_sorting);
|
||||
let hidden_files = hidden_files_label(browser.host_bridge().hidden_files_visible());
|
||||
Self {
|
||||
component: Span::default().spans(&[
|
||||
TextSpan::new("File sorting: ").fg(sorting_color),
|
||||
|
||||
@@ -30,10 +30,10 @@ impl FileTransferActivity {
|
||||
Ok(Some(FsChange::Update(update))) => {
|
||||
debug!(
|
||||
"fs watcher reported an `Update` from {} to {}",
|
||||
update.local().display(),
|
||||
update.host_bridge().display(),
|
||||
update.remote().display()
|
||||
);
|
||||
self.upload_watched_file(update.local(), update.remote());
|
||||
self.upload_watched_file(update.host_bridge(), update.remote());
|
||||
}
|
||||
Err(err) => {
|
||||
self.log(
|
||||
@@ -87,9 +87,9 @@ impl FileTransferActivity {
|
||||
}
|
||||
}
|
||||
|
||||
fn upload_watched_file(&mut self, local: &Path, remote: &Path) {
|
||||
// stat local file
|
||||
let entry = match self.host.stat(local) {
|
||||
fn upload_watched_file(&mut self, host: &Path, remote: &Path) {
|
||||
// stat host file
|
||||
let entry = match self.host_bridge.stat(host) {
|
||||
Ok(e) => e,
|
||||
Err(err) => {
|
||||
self.log(
|
||||
@@ -105,8 +105,8 @@ impl FileTransferActivity {
|
||||
};
|
||||
// send
|
||||
trace!(
|
||||
"syncing local file {} with remote {}",
|
||||
local.display(),
|
||||
"syncing host file {} with remote {}",
|
||||
host.display(),
|
||||
remote.display()
|
||||
);
|
||||
let remote_path = remote.parent().unwrap_or_else(|| Path::new("/"));
|
||||
@@ -116,7 +116,7 @@ impl FileTransferActivity {
|
||||
LogLevel::Info,
|
||||
format!(
|
||||
"synched watched file {} with {}",
|
||||
local.display(),
|
||||
host.display(),
|
||||
remote.display()
|
||||
),
|
||||
);
|
||||
|
||||
@@ -16,10 +16,10 @@ const FUZZY_SEARCH_THRESHOLD: u16 = 50;
|
||||
/// File explorer tab
|
||||
#[derive(Clone, Copy, PartialEq, Eq)]
|
||||
pub enum FileExplorerTab {
|
||||
Local,
|
||||
HostBridge,
|
||||
Remote,
|
||||
FindLocal, // Find result tab
|
||||
FindRemote, // Find result tab
|
||||
FindHostBridge, // Find result tab
|
||||
FindRemote, // Find result tab
|
||||
}
|
||||
|
||||
/// Describes the explorer tab type
|
||||
@@ -31,10 +31,10 @@ pub enum FoundExplorerTab {
|
||||
|
||||
/// Browser contains the browser options
|
||||
pub struct Browser {
|
||||
local: FileExplorer, // Local File explorer state
|
||||
remote: FileExplorer, // Remote File explorer state
|
||||
found: Option<Found>, // File explorer for find result
|
||||
tab: FileExplorerTab, // Current selected tab
|
||||
host_bridge: FileExplorer, // Local File explorer state
|
||||
remote: FileExplorer, // Remote File explorer state
|
||||
found: Option<Found>, // File explorer for find result
|
||||
tab: FileExplorerTab, // Current selected tab
|
||||
pub sync_browsing: bool,
|
||||
}
|
||||
|
||||
@@ -42,30 +42,30 @@ impl Browser {
|
||||
/// Build a new `Browser` struct
|
||||
pub fn new(cli: &ConfigClient) -> Self {
|
||||
Self {
|
||||
local: Self::build_local_explorer(cli),
|
||||
host_bridge: Self::build_local_explorer(cli),
|
||||
remote: Self::build_remote_explorer(cli),
|
||||
found: None,
|
||||
tab: FileExplorerTab::Local,
|
||||
tab: FileExplorerTab::HostBridge,
|
||||
sync_browsing: false,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn explorer(&self) -> &FileExplorer {
|
||||
match self.tab {
|
||||
FileExplorerTab::Local => &self.local,
|
||||
FileExplorerTab::HostBridge => &self.host_bridge,
|
||||
FileExplorerTab::Remote => &self.remote,
|
||||
FileExplorerTab::FindLocal | FileExplorerTab::FindRemote => {
|
||||
FileExplorerTab::FindHostBridge | FileExplorerTab::FindRemote => {
|
||||
self.found.as_ref().map(|x| &x.explorer).unwrap()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn local(&self) -> &FileExplorer {
|
||||
&self.local
|
||||
pub fn host_bridge(&self) -> &FileExplorer {
|
||||
&self.host_bridge
|
||||
}
|
||||
|
||||
pub fn local_mut(&mut self) -> &mut FileExplorer {
|
||||
&mut self.local
|
||||
pub fn host_bridge_mut(&mut self) -> &mut FileExplorer {
|
||||
&mut self.host_bridge
|
||||
}
|
||||
|
||||
pub fn remote(&self) -> &FileExplorer {
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
// Locals
|
||||
use std::env;
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
// Ext
|
||||
use bytesize::ByteSize;
|
||||
use tuirealm::props::{
|
||||
Alignment, AttrValue, Attribute, Color, PropPayload, PropValue, TableBuilder, TextSpan,
|
||||
@@ -95,9 +93,9 @@ impl FileTransferActivity {
|
||||
env::set_var("EDITOR", self.config().get_text_editor());
|
||||
}
|
||||
|
||||
/// Convert a path to absolute according to local explorer
|
||||
pub(super) fn local_to_abs_path(&self, path: &Path) -> PathBuf {
|
||||
path::absolutize(self.local().wrkdir.as_path(), path)
|
||||
/// Convert a path to absolute according to host explorer
|
||||
pub(super) fn host_bridge_to_abs_path(&self, path: &Path) -> PathBuf {
|
||||
path::absolutize(self.host_bridge().wrkdir.as_path(), path)
|
||||
}
|
||||
|
||||
/// Convert a path to absolute according to remote explorer
|
||||
@@ -217,9 +215,9 @@ impl FileTransferActivity {
|
||||
}
|
||||
}
|
||||
|
||||
/// Update local file list
|
||||
pub(super) fn update_local_filelist(&mut self) {
|
||||
self.reload_local_dir();
|
||||
/// Update host bridge file list
|
||||
pub(super) fn update_host_bridge_filelist(&mut self) {
|
||||
self.reload_host_bridge_dir();
|
||||
// Get width
|
||||
let width = self
|
||||
.context_mut()
|
||||
@@ -239,18 +237,22 @@ impl FileTransferActivity {
|
||||
let hostname: String = format!(
|
||||
"{}:{} ",
|
||||
hostname,
|
||||
fmt_path_elide_ex(self.local().wrkdir.as_path(), width, hostname.len() + 3) // 3 because of '/…/'
|
||||
fmt_path_elide_ex(
|
||||
self.host_bridge().wrkdir.as_path(),
|
||||
width,
|
||||
hostname.len() + 3
|
||||
) // 3 because of '/…/'
|
||||
);
|
||||
let files: Vec<Vec<TextSpan>> = self
|
||||
.local()
|
||||
.host_bridge()
|
||||
.iter_files()
|
||||
.map(|x| vec![TextSpan::from(self.local().fmt_file(x))])
|
||||
.map(|x| vec![TextSpan::from(self.host_bridge().fmt_file(x))])
|
||||
.collect();
|
||||
// Update content and title
|
||||
assert!(self
|
||||
.app
|
||||
.attr(
|
||||
&Id::ExplorerLocal,
|
||||
&Id::ExplorerHostBridge,
|
||||
Attribute::Content,
|
||||
AttrValue::Table(files)
|
||||
)
|
||||
@@ -258,7 +260,7 @@ impl FileTransferActivity {
|
||||
assert!(self
|
||||
.app
|
||||
.attr(
|
||||
&Id::ExplorerLocal,
|
||||
&Id::ExplorerHostBridge,
|
||||
Attribute::Title,
|
||||
AttrValue::Title((hostname, Alignment::Left))
|
||||
)
|
||||
@@ -409,17 +411,19 @@ impl FileTransferActivity {
|
||||
self.browser.del_found();
|
||||
// Restore tab
|
||||
let new_tab = match self.browser.tab() {
|
||||
FileExplorerTab::FindLocal => FileExplorerTab::Local,
|
||||
FileExplorerTab::FindHostBridge => FileExplorerTab::HostBridge,
|
||||
FileExplorerTab::FindRemote => FileExplorerTab::Remote,
|
||||
_ => FileExplorerTab::Local,
|
||||
_ => FileExplorerTab::HostBridge,
|
||||
};
|
||||
// Give focus to new tab
|
||||
match new_tab {
|
||||
FileExplorerTab::Local => assert!(self.app.active(&Id::ExplorerLocal).is_ok()),
|
||||
FileExplorerTab::HostBridge => {
|
||||
assert!(self.app.active(&Id::ExplorerHostBridge).is_ok())
|
||||
}
|
||||
FileExplorerTab::Remote => {
|
||||
assert!(self.app.active(&Id::ExplorerRemote).is_ok())
|
||||
}
|
||||
FileExplorerTab::FindLocal | FileExplorerTab::FindRemote => {
|
||||
FileExplorerTab::FindHostBridge | FileExplorerTab::FindRemote => {
|
||||
assert!(self.app.active(&Id::ExplorerFind).is_ok())
|
||||
}
|
||||
}
|
||||
@@ -445,15 +449,21 @@ impl FileTransferActivity {
|
||||
|
||||
pub(super) fn update_browser_file_list(&mut self) {
|
||||
match self.browser.tab() {
|
||||
FileExplorerTab::Local | FileExplorerTab::FindLocal => self.update_local_filelist(),
|
||||
FileExplorerTab::HostBridge | FileExplorerTab::FindHostBridge => {
|
||||
self.update_host_bridge_filelist()
|
||||
}
|
||||
FileExplorerTab::Remote | FileExplorerTab::FindRemote => self.update_remote_filelist(),
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) fn update_browser_file_list_swapped(&mut self) {
|
||||
match self.browser.tab() {
|
||||
FileExplorerTab::Local | FileExplorerTab::FindLocal => self.update_remote_filelist(),
|
||||
FileExplorerTab::Remote | FileExplorerTab::FindRemote => self.update_local_filelist(),
|
||||
FileExplorerTab::HostBridge | FileExplorerTab::FindHostBridge => {
|
||||
self.update_remote_filelist()
|
||||
}
|
||||
FileExplorerTab::Remote | FileExplorerTab::FindRemote => {
|
||||
self.update_host_bridge_filelist()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,7 +47,7 @@ enum Id {
|
||||
ErrorPopup,
|
||||
ExecPopup,
|
||||
ExplorerFind,
|
||||
ExplorerLocal,
|
||||
ExplorerHostBridge,
|
||||
ExplorerRemote,
|
||||
FatalPopup,
|
||||
FileInfoPopup,
|
||||
@@ -68,7 +68,7 @@ enum Id {
|
||||
ReplacingFilesListPopup,
|
||||
SaveAsPopup,
|
||||
SortingPopup,
|
||||
StatusBarLocal,
|
||||
StatusBarHostBridge,
|
||||
StatusBarRemote,
|
||||
SymlinkPopup,
|
||||
SyncBrowsingMkdirPopup,
|
||||
@@ -213,8 +213,8 @@ pub struct FileTransferActivity {
|
||||
app: Application<Id, Msg, NoUserEvent>,
|
||||
/// Whether should redraw UI
|
||||
redraw: bool,
|
||||
/// Localhost bridge
|
||||
host: Box<dyn HostBridge>,
|
||||
/// Host bridge
|
||||
host_bridge: Box<dyn HostBridge>,
|
||||
/// Remote host client
|
||||
client: Box<dyn RemoteFs>,
|
||||
/// Browser
|
||||
@@ -247,7 +247,7 @@ impl FileTransferActivity {
|
||||
.default_input_listener(ticks),
|
||||
),
|
||||
redraw: true,
|
||||
host: Box::new(host),
|
||||
host_bridge: Box::new(host),
|
||||
client: Builder::build(params.protocol, params.params.clone(), &config_client),
|
||||
browser: Browser::new(&config_client),
|
||||
log_records: VecDeque::with_capacity(256), // 256 events is enough I guess
|
||||
@@ -268,12 +268,12 @@ impl FileTransferActivity {
|
||||
}
|
||||
}
|
||||
|
||||
fn local(&self) -> &FileExplorer {
|
||||
self.browser.local()
|
||||
fn host_bridge(&self) -> &FileExplorer {
|
||||
self.browser.host_bridge()
|
||||
}
|
||||
|
||||
fn local_mut(&mut self) -> &mut FileExplorer {
|
||||
self.browser.local_mut()
|
||||
fn host_bridge_mut(&mut self) -> &mut FileExplorer {
|
||||
self.browser.host_bridge_mut()
|
||||
}
|
||||
|
||||
fn remote(&self) -> &FileExplorer {
|
||||
@@ -361,7 +361,7 @@ impl Activity for FileTransferActivity {
|
||||
error!("Failed to enter raw mode: {}", err);
|
||||
}
|
||||
// Get files at current pwd
|
||||
self.reload_local_dir();
|
||||
self.reload_host_bridge_dir();
|
||||
debug!("Read working directory");
|
||||
// Configure text editor
|
||||
self.setup_text_editor();
|
||||
|
||||
@@ -2,12 +2,10 @@
|
||||
//!
|
||||
//! `filetransfer_activiy` is the module which implements the Filetransfer activity, which is the main activity afterall
|
||||
|
||||
// Locals
|
||||
use std::io::{Read, Write};
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::time::Instant;
|
||||
|
||||
// Ext
|
||||
use bytesize::ByteSize;
|
||||
use remotefs::fs::{File, Metadata, ReadStream, UnixPex, Welcome, WriteStream};
|
||||
use remotefs::{RemoteError, RemoteErrorType, RemoteResult};
|
||||
@@ -25,8 +23,8 @@ const BUFSIZE: usize = 65535;
|
||||
enum TransferErrorReason {
|
||||
#[error("File transfer aborted")]
|
||||
Abrupted,
|
||||
#[error("I/O error on localhost: {0}")]
|
||||
LocalIoError(std::io::Error),
|
||||
#[error("I/O error on host_bridgehost: {0}")]
|
||||
HostIoError(std::io::Error),
|
||||
#[error("Host error: {0}")]
|
||||
HostError(HostError),
|
||||
#[error("I/O error on remote: {0}")]
|
||||
@@ -91,7 +89,7 @@ impl FileTransferActivity {
|
||||
self.umount_wait();
|
||||
self.reload_remote_dir();
|
||||
// Update file lists
|
||||
self.update_local_filelist();
|
||||
self.update_host_bridge_filelist();
|
||||
self.update_remote_filelist();
|
||||
}
|
||||
Err(err) => {
|
||||
@@ -146,38 +144,38 @@ impl FileTransferActivity {
|
||||
}
|
||||
}
|
||||
|
||||
/// Reload local directory entries and update browser
|
||||
pub(super) fn reload_local_dir(&mut self) {
|
||||
self.mount_blocking_wait("Loading local directory...");
|
||||
/// Reload host_bridge directory entries and update browser
|
||||
pub(super) fn reload_host_bridge_dir(&mut self) {
|
||||
self.mount_blocking_wait("Loading host bridge directory...");
|
||||
|
||||
let Ok(wrkdir) = self.host.pwd() else {
|
||||
let Ok(wrkdir) = self.host_bridge.pwd() else {
|
||||
error!("failed to get host working directory");
|
||||
return;
|
||||
};
|
||||
|
||||
let res = self.local_scan(wrkdir.as_path());
|
||||
let res = self.host_bridge_scan(wrkdir.as_path());
|
||||
|
||||
self.umount_wait();
|
||||
|
||||
match res {
|
||||
Ok(_) => {
|
||||
self.local_mut().wrkdir = wrkdir;
|
||||
self.host_bridge_mut().wrkdir = wrkdir;
|
||||
}
|
||||
Err(err) => {
|
||||
self.log_and_alert(
|
||||
LogLevel::Error,
|
||||
format!("Could not scan current local directory: {err}"),
|
||||
format!("Could not scan current host bridge directory: {err}"),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Scan current local directory
|
||||
fn local_scan(&mut self, path: &Path) -> Result<(), HostError> {
|
||||
match self.host.list_dir(path) {
|
||||
/// Scan current host bridge directory
|
||||
fn host_bridge_scan(&mut self, path: &Path) -> Result<(), HostError> {
|
||||
match self.host_bridge.list_dir(path) {
|
||||
Ok(files) => {
|
||||
// Set files and sort (sorting is implicit)
|
||||
self.local_mut().set_files(files);
|
||||
self.host_bridge_mut().set_files(files);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@@ -270,7 +268,7 @@ impl FileTransferActivity {
|
||||
// Reset states
|
||||
self.transfer.reset();
|
||||
// Calculate total size of transfer
|
||||
let total_transfer_size: usize = self.get_total_transfer_size_local(entry);
|
||||
let total_transfer_size: usize = self.get_total_transfer_size_host(entry);
|
||||
self.transfer.full.init(total_transfer_size);
|
||||
// Mount progress bar
|
||||
self.mount_progress_bar(format!("Uploading {}…", entry.path().display()));
|
||||
@@ -292,7 +290,7 @@ impl FileTransferActivity {
|
||||
// Calculate total size of transfer
|
||||
let total_transfer_size: usize = entries
|
||||
.iter()
|
||||
.map(|x| self.get_total_transfer_size_local(x))
|
||||
.map(|x| self.get_total_transfer_size_host(x))
|
||||
.sum();
|
||||
self.transfer.full.init(total_transfer_size);
|
||||
// Mount progress bar
|
||||
@@ -358,7 +356,7 @@ impl FileTransferActivity {
|
||||
}
|
||||
}
|
||||
// Get files in dir
|
||||
match self.host.list_dir(entry.path()) {
|
||||
match self.host_bridge.list_dir(entry.path()) {
|
||||
Ok(entries) => {
|
||||
// Iterate over files
|
||||
for entry in entries.iter() {
|
||||
@@ -433,17 +431,17 @@ impl FileTransferActivity {
|
||||
result
|
||||
}
|
||||
|
||||
/// Send local file and write it to remote path
|
||||
/// Send host_bridge file and write it to remote path
|
||||
fn filetransfer_send_one(
|
||||
&mut self,
|
||||
local: &File,
|
||||
host_bridge: &File,
|
||||
remote: &Path,
|
||||
file_name: String,
|
||||
) -> Result<(), TransferErrorReason> {
|
||||
// Sync file size and attributes before transfer
|
||||
let metadata = self
|
||||
.host
|
||||
.stat(local.path.as_path())
|
||||
.host_bridge
|
||||
.stat(host_bridge.path.as_path())
|
||||
.map_err(TransferErrorReason::HostError)
|
||||
.map(|x| x.metadata().clone())?;
|
||||
|
||||
@@ -452,21 +450,30 @@ impl FileTransferActivity {
|
||||
LogLevel::Info,
|
||||
format!(
|
||||
"file {} won't be transferred since hasn't changed",
|
||||
local.path().display()
|
||||
host_bridge.path().display()
|
||||
),
|
||||
);
|
||||
self.transfer.full.update_progress(metadata.size as usize);
|
||||
return Ok(());
|
||||
}
|
||||
// Upload file
|
||||
// Try to open local file
|
||||
match self.host.open_file(local.path.as_path()) {
|
||||
Ok(local_read) => match self.client.create(remote, &metadata) {
|
||||
Ok(rhnd) => self
|
||||
.filetransfer_send_one_with_stream(local, remote, file_name, local_read, rhnd),
|
||||
Err(err) if err.kind == RemoteErrorType::UnsupportedFeature => {
|
||||
self.filetransfer_send_one_wno_stream(local, remote, file_name, local_read)
|
||||
}
|
||||
// Try to open host_bridge file
|
||||
match self.host_bridge.open_file(host_bridge.path.as_path()) {
|
||||
Ok(host_bridge_read) => match self.client.create(remote, &metadata) {
|
||||
Ok(rhnd) => self.filetransfer_send_one_with_stream(
|
||||
host_bridge,
|
||||
remote,
|
||||
file_name,
|
||||
host_bridge_read,
|
||||
rhnd,
|
||||
),
|
||||
Err(err) if err.kind == RemoteErrorType::UnsupportedFeature => self
|
||||
.filetransfer_send_one_wno_stream(
|
||||
host_bridge,
|
||||
remote,
|
||||
file_name,
|
||||
host_bridge_read,
|
||||
),
|
||||
Err(err) => Err(TransferErrorReason::FileTransferError(err)),
|
||||
},
|
||||
Err(err) => Err(TransferErrorReason::HostError(err)),
|
||||
@@ -476,7 +483,7 @@ impl FileTransferActivity {
|
||||
/// Send file to remote using stream
|
||||
fn filetransfer_send_one_with_stream(
|
||||
&mut self,
|
||||
local: &File,
|
||||
host: &File,
|
||||
remote: &Path,
|
||||
file_name: String,
|
||||
mut reader: Box<dyn Read + Send>,
|
||||
@@ -484,8 +491,8 @@ impl FileTransferActivity {
|
||||
) -> Result<(), TransferErrorReason> {
|
||||
// Write file
|
||||
let file_size = self
|
||||
.host
|
||||
.stat(local.path())
|
||||
.host_bridge
|
||||
.stat(host.path())
|
||||
.map_err(TransferErrorReason::HostError)
|
||||
.map(|x| x.metadata().size as usize)?;
|
||||
// Init transfer
|
||||
@@ -535,7 +542,7 @@ impl FileTransferActivity {
|
||||
}
|
||||
}
|
||||
Err(err) => {
|
||||
return Err(TransferErrorReason::LocalIoError(err));
|
||||
return Err(TransferErrorReason::HostIoError(err));
|
||||
}
|
||||
};
|
||||
// Increase progress
|
||||
@@ -561,14 +568,14 @@ impl FileTransferActivity {
|
||||
return Err(TransferErrorReason::Abrupted);
|
||||
}
|
||||
// set stat
|
||||
if let Err(err) = self.client.setstat(remote, local.metadata().clone()) {
|
||||
if let Err(err) = self.client.setstat(remote, host.metadata().clone()) {
|
||||
error!("failed to set stat for {}: {}", remote.display(), err);
|
||||
}
|
||||
self.log(
|
||||
LogLevel::Info,
|
||||
format!(
|
||||
"Saved file \"{}\" to \"{}\" (took {} seconds; at {}/s)",
|
||||
local.path.display(),
|
||||
host.path.display(),
|
||||
remote.display(),
|
||||
fmt_millis(self.transfer.partial.started().elapsed()),
|
||||
ByteSize(self.transfer.partial.calc_bytes_per_second()),
|
||||
@@ -580,21 +587,21 @@ impl FileTransferActivity {
|
||||
/// Send an `File` to remote without using streams.
|
||||
fn filetransfer_send_one_wno_stream(
|
||||
&mut self,
|
||||
local: &File,
|
||||
host: &File,
|
||||
remote: &Path,
|
||||
file_name: String,
|
||||
reader: Box<dyn Read + Send>,
|
||||
) -> Result<(), TransferErrorReason> {
|
||||
// Sync file size and attributes before transfer
|
||||
let metadata = self
|
||||
.host
|
||||
.stat(local.path.as_path())
|
||||
.host_bridge
|
||||
.stat(host.path.as_path())
|
||||
.map_err(TransferErrorReason::HostError)
|
||||
.map(|x| x.metadata().clone())?;
|
||||
// Write file
|
||||
let file_size = self
|
||||
.host
|
||||
.stat(local.path())
|
||||
.host_bridge
|
||||
.stat(host.path())
|
||||
.map_err(TransferErrorReason::HostError)
|
||||
.map(|x| x.metadata().size as usize)?;
|
||||
// Init transfer
|
||||
@@ -622,7 +629,7 @@ impl FileTransferActivity {
|
||||
LogLevel::Info,
|
||||
format!(
|
||||
"Saved file \"{}\" to \"{}\" (took {} seconds; at {}/s)",
|
||||
local.path.display(),
|
||||
host.path.display(),
|
||||
remote.display(),
|
||||
fmt_millis(self.transfer.partial.started().elapsed()),
|
||||
ByteSize(self.transfer.partial.calc_bytes_per_second()),
|
||||
@@ -637,15 +644,17 @@ impl FileTransferActivity {
|
||||
pub(super) fn filetransfer_recv(
|
||||
&mut self,
|
||||
payload: TransferPayload,
|
||||
local_path: &Path,
|
||||
host_bridge_path: &Path,
|
||||
dst_name: Option<String>,
|
||||
) -> Result<(), String> {
|
||||
let result = match payload {
|
||||
TransferPayload::Any(ref entry) => {
|
||||
self.filetransfer_recv_any(entry, local_path, dst_name)
|
||||
self.filetransfer_recv_any(entry, host_bridge_path, dst_name)
|
||||
}
|
||||
TransferPayload::File(ref file) => self.filetransfer_recv_file(file, host_bridge_path),
|
||||
TransferPayload::Many(ref entries) => {
|
||||
self.filetransfer_recv_many(entries, host_bridge_path)
|
||||
}
|
||||
TransferPayload::File(ref file) => self.filetransfer_recv_file(file, local_path),
|
||||
TransferPayload::Many(ref entries) => self.filetransfer_recv_many(entries, local_path),
|
||||
};
|
||||
// Notify
|
||||
match &result {
|
||||
@@ -665,7 +674,7 @@ impl FileTransferActivity {
|
||||
fn filetransfer_recv_any(
|
||||
&mut self,
|
||||
entry: &File,
|
||||
local_path: &Path,
|
||||
host_path: &Path,
|
||||
dst_name: Option<String>,
|
||||
) -> Result<(), String> {
|
||||
// Reset states
|
||||
@@ -676,14 +685,18 @@ impl FileTransferActivity {
|
||||
// Mount progress bar
|
||||
self.mount_progress_bar(format!("Downloading {}…", entry.path().display()));
|
||||
// Receive
|
||||
let result = self.filetransfer_recv_recurse(entry, local_path, dst_name);
|
||||
let result = self.filetransfer_recv_recurse(entry, host_path, dst_name);
|
||||
// Umount progress bar
|
||||
self.umount_progress_bar();
|
||||
result
|
||||
}
|
||||
|
||||
/// Receive a single file from remote.
|
||||
fn filetransfer_recv_file(&mut self, entry: &File, local_path: &Path) -> Result<(), String> {
|
||||
fn filetransfer_recv_file(
|
||||
&mut self,
|
||||
entry: &File,
|
||||
host_bridge_path: &Path,
|
||||
) -> Result<(), String> {
|
||||
// Reset states
|
||||
self.transfer.reset();
|
||||
// Calculate total transfer size
|
||||
@@ -692,7 +705,7 @@ impl FileTransferActivity {
|
||||
// Mount progress bar
|
||||
self.mount_progress_bar(format!("Downloading {}…", entry.path.display()));
|
||||
// Receive
|
||||
let result = self.filetransfer_recv_one(local_path, entry, entry.name());
|
||||
let result = self.filetransfer_recv_one(host_bridge_path, entry, entry.name());
|
||||
// Umount progress bar
|
||||
self.umount_progress_bar();
|
||||
// Return result
|
||||
@@ -729,7 +742,7 @@ impl FileTransferActivity {
|
||||
fn filetransfer_recv_recurse(
|
||||
&mut self,
|
||||
entry: &File,
|
||||
local_path: &Path,
|
||||
host_bridge_path: &Path,
|
||||
dst_name: Option<String>,
|
||||
) -> Result<(), String> {
|
||||
// Write popup
|
||||
@@ -737,32 +750,35 @@ impl FileTransferActivity {
|
||||
// Match entry
|
||||
let result: Result<(), String> = if entry.is_dir() {
|
||||
// Get dir name
|
||||
let mut local_dir_path: PathBuf = PathBuf::from(local_path);
|
||||
let mut host_bridge_dir_path: PathBuf = PathBuf::from(host_bridge_path);
|
||||
match dst_name {
|
||||
Some(name) => local_dir_path.push(name),
|
||||
None => local_dir_path.push(entry.name()),
|
||||
Some(name) => host_bridge_dir_path.push(name),
|
||||
None => host_bridge_dir_path.push(entry.name()),
|
||||
}
|
||||
// Create directory on local
|
||||
match self.host.mkdir_ex(local_dir_path.as_path(), true) {
|
||||
// Create directory on host_bridge
|
||||
match self
|
||||
.host_bridge
|
||||
.mkdir_ex(host_bridge_dir_path.as_path(), true)
|
||||
{
|
||||
Ok(_) => {
|
||||
// Apply file mode to directory
|
||||
if let Err(err) = self
|
||||
.host
|
||||
.setstat(local_dir_path.as_path(), entry.metadata())
|
||||
.host_bridge
|
||||
.setstat(host_bridge_dir_path.as_path(), entry.metadata())
|
||||
{
|
||||
self.log(
|
||||
LogLevel::Error,
|
||||
format!(
|
||||
"Could not set stat to directory {:?} to \"{}\": {}",
|
||||
entry.metadata(),
|
||||
local_dir_path.display(),
|
||||
host_bridge_dir_path.display(),
|
||||
err
|
||||
),
|
||||
);
|
||||
}
|
||||
self.log(
|
||||
LogLevel::Info,
|
||||
format!("Created directory \"{}\"", local_dir_path.display()),
|
||||
format!("Created directory \"{}\"", host_bridge_dir_path.display()),
|
||||
);
|
||||
// Get files in dir
|
||||
match self.client.list_dir(entry.path()) {
|
||||
@@ -774,10 +790,10 @@ impl FileTransferActivity {
|
||||
break;
|
||||
}
|
||||
// Receive entry; name is always None after first call
|
||||
// Local path becomes local_dir_path
|
||||
// Local path becomes host_bridge_dir_path
|
||||
self.filetransfer_recv_recurse(
|
||||
entry,
|
||||
local_dir_path.as_path(),
|
||||
host_bridge_dir_path.as_path(),
|
||||
None,
|
||||
)?
|
||||
}
|
||||
@@ -801,7 +817,7 @@ impl FileTransferActivity {
|
||||
LogLevel::Error,
|
||||
format!(
|
||||
"Failed to create directory \"{}\": {}",
|
||||
local_dir_path.display(),
|
||||
host_bridge_dir_path.display(),
|
||||
err
|
||||
),
|
||||
);
|
||||
@@ -809,39 +825,39 @@ impl FileTransferActivity {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Get local file
|
||||
let mut local_file_path: PathBuf = PathBuf::from(local_path);
|
||||
let local_file_name: String = match dst_name {
|
||||
// Get host_bridge file
|
||||
let mut host_bridge_file_path: PathBuf = PathBuf::from(host_bridge_path);
|
||||
let host_bridge_file_name: String = match dst_name {
|
||||
Some(n) => n,
|
||||
None => entry.name(),
|
||||
};
|
||||
local_file_path.push(local_file_name.as_str());
|
||||
host_bridge_file_path.push(host_bridge_file_name.as_str());
|
||||
// Download file
|
||||
if let Err(err) =
|
||||
self.filetransfer_recv_one(local_file_path.as_path(), entry, file_name)
|
||||
self.filetransfer_recv_one(host_bridge_file_path.as_path(), entry, file_name)
|
||||
{
|
||||
// If transfer was abrupted or there was an IO error on remote, remove file
|
||||
if matches!(
|
||||
err,
|
||||
TransferErrorReason::Abrupted | TransferErrorReason::LocalIoError(_)
|
||||
TransferErrorReason::Abrupted | TransferErrorReason::HostIoError(_)
|
||||
) {
|
||||
// Stat file
|
||||
match self.host.stat(local_file_path.as_path()) {
|
||||
match self.host_bridge.stat(host_bridge_file_path.as_path()) {
|
||||
Err(err) => self.log(
|
||||
LogLevel::Error,
|
||||
format!(
|
||||
"Could not remove created file {}: {}",
|
||||
local_file_path.display(),
|
||||
host_bridge_file_path.display(),
|
||||
err
|
||||
),
|
||||
),
|
||||
Ok(entry) => {
|
||||
if let Err(err) = self.host.remove(&entry) {
|
||||
if let Err(err) = self.host_bridge.remove(&entry) {
|
||||
self.log(
|
||||
LogLevel::Error,
|
||||
format!(
|
||||
"Could not remove created file {}: {}",
|
||||
local_file_path.display(),
|
||||
host_bridge_file_path.display(),
|
||||
err
|
||||
),
|
||||
);
|
||||
@@ -854,8 +870,8 @@ impl FileTransferActivity {
|
||||
Ok(())
|
||||
}
|
||||
};
|
||||
// Reload directory on local
|
||||
self.reload_local_dir();
|
||||
// Reload directory on host_bridge
|
||||
self.reload_host_bridge_dir();
|
||||
// if aborted; show alert
|
||||
if self.transfer.aborted() {
|
||||
// Log abort
|
||||
@@ -867,15 +883,15 @@ impl FileTransferActivity {
|
||||
result
|
||||
}
|
||||
|
||||
/// Receive file from remote and write it to local path
|
||||
/// Receive file from remote and write it to host_bridge path
|
||||
fn filetransfer_recv_one(
|
||||
&mut self,
|
||||
local: &Path,
|
||||
host_bridge: &Path,
|
||||
remote: &File,
|
||||
file_name: String,
|
||||
) -> Result<(), TransferErrorReason> {
|
||||
// check if files are equal (in case, don't transfer)
|
||||
if !self.has_local_file_changed(local, remote) {
|
||||
if !self.has_host_bridge_file_changed(host_bridge, remote) {
|
||||
self.log(
|
||||
LogLevel::Info,
|
||||
format!(
|
||||
@@ -889,15 +905,20 @@ impl FileTransferActivity {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
// Try to open local file
|
||||
match self.host.create_file(local, &remote.metadata) {
|
||||
// Try to open host_bridge file
|
||||
match self.host_bridge.create_file(host_bridge, &remote.metadata) {
|
||||
Ok(writer) => {
|
||||
// Download file from remote
|
||||
match self.client.open(remote.path.as_path()) {
|
||||
Ok(rhnd) => self
|
||||
.filetransfer_recv_one_with_stream(local, remote, file_name, rhnd, writer),
|
||||
Ok(rhnd) => self.filetransfer_recv_one_with_stream(
|
||||
host_bridge,
|
||||
remote,
|
||||
file_name,
|
||||
rhnd,
|
||||
writer,
|
||||
),
|
||||
Err(err) if err.kind == RemoteErrorType::UnsupportedFeature => {
|
||||
self.filetransfer_recv_one_wno_stream(local, remote, file_name)
|
||||
self.filetransfer_recv_one_wno_stream(host_bridge, remote, file_name)
|
||||
}
|
||||
Err(err) => Err(TransferErrorReason::FileTransferError(err)),
|
||||
}
|
||||
@@ -909,7 +930,7 @@ impl FileTransferActivity {
|
||||
/// Receive an `File` from remote using stream
|
||||
fn filetransfer_recv_one_with_stream(
|
||||
&mut self,
|
||||
local: &Path,
|
||||
host_bridge: &Path,
|
||||
remote: &File,
|
||||
file_name: String,
|
||||
mut reader: ReadStream,
|
||||
@@ -918,7 +939,7 @@ impl FileTransferActivity {
|
||||
let mut total_bytes_written: usize = 0;
|
||||
// Init transfer
|
||||
self.transfer.partial.init(remote.metadata.size as usize);
|
||||
// Write local file
|
||||
// Write host_bridge file
|
||||
let mut last_progress_val: f64 = 0.0;
|
||||
let mut last_input_event_fetch: Option<Instant> = None;
|
||||
// While the entire file hasn't been completely read,
|
||||
@@ -951,7 +972,7 @@ impl FileTransferActivity {
|
||||
match writer.write(&buffer[delta..bytes_read]) {
|
||||
Ok(bytes) => delta += bytes,
|
||||
Err(err) => {
|
||||
return Err(TransferErrorReason::LocalIoError(err));
|
||||
return Err(TransferErrorReason::HostIoError(err));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -986,18 +1007,18 @@ impl FileTransferActivity {
|
||||
}
|
||||
|
||||
// finalize write
|
||||
self.host
|
||||
self.host_bridge
|
||||
.finalize_write(writer)
|
||||
.map_err(TransferErrorReason::HostError)?;
|
||||
|
||||
// Apply file mode to file
|
||||
if let Err(err) = self.host.setstat(local, remote.metadata()) {
|
||||
if let Err(err) = self.host_bridge.setstat(host_bridge, remote.metadata()) {
|
||||
self.log(
|
||||
LogLevel::Error,
|
||||
format!(
|
||||
"Could not set stat to file {:?} to \"{}\": {}",
|
||||
remote.metadata(),
|
||||
local.display(),
|
||||
host_bridge.display(),
|
||||
err
|
||||
),
|
||||
);
|
||||
@@ -1008,7 +1029,7 @@ impl FileTransferActivity {
|
||||
format!(
|
||||
"Saved file \"{}\" to \"{}\" (took {} seconds; at {}/s)",
|
||||
remote.path.display(),
|
||||
local.display(),
|
||||
host_bridge.display(),
|
||||
fmt_millis(self.transfer.partial.started().elapsed()),
|
||||
ByteSize(self.transfer.partial.calc_bytes_per_second()),
|
||||
),
|
||||
@@ -1020,14 +1041,14 @@ impl FileTransferActivity {
|
||||
/// Receive an `File` from remote without using stream
|
||||
fn filetransfer_recv_one_wno_stream(
|
||||
&mut self,
|
||||
local: &Path,
|
||||
host_bridge: &Path,
|
||||
remote: &File,
|
||||
file_name: String,
|
||||
) -> Result<(), TransferErrorReason> {
|
||||
// Open local file
|
||||
// Open host_bridge file
|
||||
let reader = self
|
||||
.host
|
||||
.create_file(local, &remote.metadata)
|
||||
.host_bridge
|
||||
.create_file(host_bridge, &remote.metadata)
|
||||
.map_err(TransferErrorReason::HostError)
|
||||
.map(Box::new)?;
|
||||
// Init transfer
|
||||
@@ -1050,13 +1071,13 @@ impl FileTransferActivity {
|
||||
self.update_progress_bar(format!("Downloading \"{file_name}\""));
|
||||
self.view();
|
||||
// Apply file mode to file
|
||||
if let Err(err) = self.host.setstat(local, remote.metadata()) {
|
||||
if let Err(err) = self.host_bridge.setstat(host_bridge, remote.metadata()) {
|
||||
self.log(
|
||||
LogLevel::Error,
|
||||
format!(
|
||||
"Could not set stat to file {:?} to \"{}\": {}",
|
||||
remote.metadata(),
|
||||
local.display(),
|
||||
host_bridge.display(),
|
||||
err
|
||||
),
|
||||
);
|
||||
@@ -1067,7 +1088,7 @@ impl FileTransferActivity {
|
||||
format!(
|
||||
"Saved file \"{}\" to \"{}\" (took {} seconds; at {}/s)",
|
||||
remote.path.display(),
|
||||
local.display(),
|
||||
host_bridge.display(),
|
||||
fmt_millis(self.transfer.partial.started().elapsed()),
|
||||
ByteSize(self.transfer.partial.calc_bytes_per_second()),
|
||||
),
|
||||
@@ -1075,20 +1096,20 @@ impl FileTransferActivity {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Change directory for local
|
||||
pub(super) fn local_changedir(&mut self, path: &Path, push: bool) {
|
||||
/// Change directory for host_bridge
|
||||
pub(super) fn host_bridge_changedir(&mut self, path: &Path, push: bool) {
|
||||
// Get current directory
|
||||
let prev_dir: PathBuf = self.local().wrkdir.clone();
|
||||
let prev_dir: PathBuf = self.host_bridge().wrkdir.clone();
|
||||
// Change directory
|
||||
match self.host.change_wrkdir(path) {
|
||||
match self.host_bridge.change_wrkdir(path) {
|
||||
Ok(_) => {
|
||||
self.log(
|
||||
LogLevel::Info,
|
||||
format!("Changed directory on local: {}", path.display()),
|
||||
format!("Changed directory on host_bridge: {}", path.display()),
|
||||
);
|
||||
// Push prev_dir to stack
|
||||
if push {
|
||||
self.local_mut().pushd(prev_dir.as_path())
|
||||
self.host_bridge_mut().pushd(prev_dir.as_path())
|
||||
}
|
||||
}
|
||||
Err(err) => {
|
||||
@@ -1159,14 +1180,14 @@ impl FileTransferActivity {
|
||||
|
||||
// -- transfer sizes
|
||||
|
||||
/// Get total size of transfer for localhost
|
||||
fn get_total_transfer_size_local(&mut self, entry: &File) -> usize {
|
||||
/// Get total size of transfer for host_bridgehost
|
||||
fn get_total_transfer_size_host(&mut self, entry: &File) -> usize {
|
||||
if entry.is_dir() {
|
||||
// List dir
|
||||
match self.host.list_dir(entry.path()) {
|
||||
match self.host_bridge.list_dir(entry.path()) {
|
||||
Ok(files) => files
|
||||
.iter()
|
||||
.map(|x| self.get_total_transfer_size_local(x))
|
||||
.map(|x| self.get_total_transfer_size_host(x))
|
||||
.sum(),
|
||||
Err(err) => {
|
||||
self.log(
|
||||
@@ -1213,23 +1234,23 @@ impl FileTransferActivity {
|
||||
|
||||
// file changed
|
||||
|
||||
/// Check whether provided file has changed on local disk, compared to remote file
|
||||
fn has_local_file_changed(&mut self, local: &Path, remote: &File) -> bool {
|
||||
/// Check whether provided file has changed on host_bridge disk, compared to remote file
|
||||
fn has_host_bridge_file_changed(&mut self, host_bridge: &Path, remote: &File) -> bool {
|
||||
// check if files are equal (in case, don't transfer)
|
||||
if let Ok(local_file) = self.host.stat(local) {
|
||||
local_file.metadata().modified != remote.metadata().modified
|
||||
|| local_file.metadata().size != remote.metadata().size
|
||||
if let Ok(host_bridge_file) = self.host_bridge.stat(host_bridge) {
|
||||
host_bridge_file.metadata().modified != remote.metadata().modified
|
||||
|| host_bridge_file.metadata().size != remote.metadata().size
|
||||
} else {
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
/// Checks whether remote file has changed compared to local file
|
||||
fn has_remote_file_changed(&mut self, remote: &Path, local_metadata: &Metadata) -> bool {
|
||||
/// Checks whether remote file has changed compared to host_bridge file
|
||||
fn has_remote_file_changed(&mut self, remote: &Path, host_bridge_metadata: &Metadata) -> bool {
|
||||
// check if files are equal (in case, don't transfer)
|
||||
if let Ok(remote_file) = self.client.stat(remote) {
|
||||
local_metadata.modified != remote_file.metadata().modified
|
||||
|| local_metadata.size != remote_file.metadata().size
|
||||
host_bridge_metadata.modified != remote_file.metadata().modified
|
||||
|| host_bridge_metadata.size != remote_file.metadata().size
|
||||
} else {
|
||||
true
|
||||
}
|
||||
@@ -1237,8 +1258,8 @@ impl FileTransferActivity {
|
||||
|
||||
// -- file exist
|
||||
|
||||
pub(crate) fn local_file_exists(&mut self, p: &Path) -> bool {
|
||||
self.host.exists(p).unwrap_or_default()
|
||||
pub(crate) fn host_bridge_file_exists(&mut self, p: &Path) -> bool {
|
||||
self.host_bridge.exists(p).unwrap_or_default()
|
||||
}
|
||||
|
||||
pub(crate) fn remote_file_exists(&mut self, p: &Path) -> bool {
|
||||
|
||||
@@ -41,13 +41,13 @@ impl FileTransferActivity {
|
||||
self.mount_blocking_wait("Applying new file mode…");
|
||||
match self.browser.tab() {
|
||||
#[cfg(unix)]
|
||||
FileExplorerTab::Local => self.action_local_chmod(mode),
|
||||
FileExplorerTab::HostBridge => self.action_local_chmod(mode),
|
||||
#[cfg(unix)]
|
||||
FileExplorerTab::FindLocal => self.action_find_local_chmod(mode),
|
||||
FileExplorerTab::FindHostBridge => self.action_find_local_chmod(mode),
|
||||
FileExplorerTab::Remote => self.action_remote_chmod(mode),
|
||||
FileExplorerTab::FindRemote => self.action_find_remote_chmod(mode),
|
||||
#[cfg(windows)]
|
||||
FileExplorerTab::Local | FileExplorerTab::FindLocal => {}
|
||||
FileExplorerTab::HostBridge | FileExplorerTab::FindHostBridge => {}
|
||||
}
|
||||
self.umount_wait();
|
||||
self.update_browser_file_list();
|
||||
@@ -56,7 +56,7 @@ impl FileTransferActivity {
|
||||
self.umount_copy();
|
||||
self.mount_blocking_wait("Copying file(s)…");
|
||||
match self.browser.tab() {
|
||||
FileExplorerTab::Local => self.action_local_copy(dest),
|
||||
FileExplorerTab::HostBridge => self.action_local_copy(dest),
|
||||
FileExplorerTab::Remote => self.action_remote_copy(dest),
|
||||
_ => panic!("Found tab doesn't support COPY"),
|
||||
}
|
||||
@@ -68,7 +68,7 @@ impl FileTransferActivity {
|
||||
self.umount_symlink();
|
||||
self.mount_blocking_wait("Creating symlink…");
|
||||
match self.browser.tab() {
|
||||
FileExplorerTab::Local => self.action_local_symlink(name),
|
||||
FileExplorerTab::HostBridge => self.action_local_symlink(name),
|
||||
FileExplorerTab::Remote => self.action_remote_symlink(name),
|
||||
_ => panic!("Found tab doesn't support SYMLINK"),
|
||||
}
|
||||
@@ -80,9 +80,9 @@ impl FileTransferActivity {
|
||||
self.umount_radio_delete();
|
||||
self.mount_blocking_wait("Removing file(s)…");
|
||||
match self.browser.tab() {
|
||||
FileExplorerTab::Local => self.action_local_delete(),
|
||||
FileExplorerTab::HostBridge => self.action_local_delete(),
|
||||
FileExplorerTab::Remote => self.action_remote_delete(),
|
||||
FileExplorerTab::FindLocal | FileExplorerTab::FindRemote => {
|
||||
FileExplorerTab::FindHostBridge | FileExplorerTab::FindRemote => {
|
||||
// Get entry
|
||||
self.action_find_delete();
|
||||
// Delete entries
|
||||
@@ -108,20 +108,20 @@ impl FileTransferActivity {
|
||||
self.umount_wait();
|
||||
// Reload files
|
||||
match self.browser.tab() {
|
||||
FileExplorerTab::Local => self.update_local_filelist(),
|
||||
FileExplorerTab::HostBridge => self.update_host_bridge_filelist(),
|
||||
FileExplorerTab::Remote => self.update_remote_filelist(),
|
||||
FileExplorerTab::FindLocal => self.update_local_filelist(),
|
||||
FileExplorerTab::FindHostBridge => self.update_host_bridge_filelist(),
|
||||
FileExplorerTab::FindRemote => self.update_remote_filelist(),
|
||||
}
|
||||
}
|
||||
TransferMsg::EnterDirectory if self.browser.tab() == FileExplorerTab::Local => {
|
||||
TransferMsg::EnterDirectory if self.browser.tab() == FileExplorerTab::HostBridge => {
|
||||
if let SelectedFile::One(entry) = self.get_local_selected_entries() {
|
||||
self.action_submit_local(entry);
|
||||
// Update file list if sync
|
||||
if self.browser.sync_browsing && self.browser.found().is_none() {
|
||||
self.update_remote_filelist();
|
||||
}
|
||||
self.update_local_filelist();
|
||||
self.update_host_bridge_filelist();
|
||||
}
|
||||
}
|
||||
TransferMsg::EnterDirectory if self.browser.tab() == FileExplorerTab::Remote => {
|
||||
@@ -129,7 +129,7 @@ impl FileTransferActivity {
|
||||
self.action_submit_remote(entry);
|
||||
// Update file list if sync
|
||||
if self.browser.sync_browsing && self.browser.found().is_none() {
|
||||
self.update_local_filelist();
|
||||
self.update_host_bridge_filelist();
|
||||
}
|
||||
self.update_remote_filelist();
|
||||
}
|
||||
@@ -150,7 +150,7 @@ impl FileTransferActivity {
|
||||
self.umount_exec();
|
||||
self.mount_blocking_wait(format!("Executing '{cmd}'…").as_str());
|
||||
match self.browser.tab() {
|
||||
FileExplorerTab::Local => self.action_local_exec(cmd),
|
||||
FileExplorerTab::HostBridge => self.action_local_exec(cmd),
|
||||
FileExplorerTab::Remote => self.action_remote_exec(cmd),
|
||||
_ => panic!("Found tab doesn't support EXEC"),
|
||||
}
|
||||
@@ -160,7 +160,7 @@ impl FileTransferActivity {
|
||||
}
|
||||
TransferMsg::GoTo(dir) => {
|
||||
match self.browser.tab() {
|
||||
FileExplorerTab::Local => self.action_change_local_dir(dir),
|
||||
FileExplorerTab::HostBridge => self.action_change_local_dir(dir),
|
||||
FileExplorerTab::Remote => self.action_change_remote_dir(dir),
|
||||
_ => panic!("Found tab doesn't support GOTO"),
|
||||
}
|
||||
@@ -175,18 +175,18 @@ impl FileTransferActivity {
|
||||
}
|
||||
TransferMsg::GoToParentDirectory => {
|
||||
match self.browser.tab() {
|
||||
FileExplorerTab::Local => {
|
||||
FileExplorerTab::HostBridge => {
|
||||
self.action_go_to_local_upper_dir();
|
||||
if self.browser.sync_browsing && self.browser.found().is_none() {
|
||||
self.update_remote_filelist();
|
||||
}
|
||||
// Reload file list component
|
||||
self.update_local_filelist()
|
||||
self.update_host_bridge_filelist()
|
||||
}
|
||||
FileExplorerTab::Remote => {
|
||||
self.action_go_to_remote_upper_dir();
|
||||
if self.browser.sync_browsing && self.browser.found().is_none() {
|
||||
self.update_local_filelist();
|
||||
self.update_host_bridge_filelist();
|
||||
}
|
||||
// Reload file list component
|
||||
self.update_remote_filelist()
|
||||
@@ -196,18 +196,18 @@ impl FileTransferActivity {
|
||||
}
|
||||
TransferMsg::GoToPreviousDirectory => {
|
||||
match self.browser.tab() {
|
||||
FileExplorerTab::Local => {
|
||||
FileExplorerTab::HostBridge => {
|
||||
self.action_go_to_previous_local_dir();
|
||||
if self.browser.sync_browsing && self.browser.found().is_none() {
|
||||
self.update_remote_filelist();
|
||||
}
|
||||
// Reload file list component
|
||||
self.update_local_filelist()
|
||||
self.update_host_bridge_filelist()
|
||||
}
|
||||
FileExplorerTab::Remote => {
|
||||
self.action_go_to_previous_remote_dir();
|
||||
if self.browser.sync_browsing && self.browser.found().is_none() {
|
||||
self.update_local_filelist();
|
||||
self.update_host_bridge_filelist();
|
||||
}
|
||||
// Reload file list component
|
||||
self.update_remote_filelist()
|
||||
@@ -220,7 +220,7 @@ impl FileTransferActivity {
|
||||
self.mount_walkdir_wait();
|
||||
// Find
|
||||
let res: Result<Vec<File>, WalkdirError> = match self.browser.tab() {
|
||||
FileExplorerTab::Local => self.action_walkdir_local(),
|
||||
FileExplorerTab::HostBridge => self.action_walkdir_local(),
|
||||
FileExplorerTab::Remote => self.action_walkdir_remote(),
|
||||
_ => panic!("Trying to search for files, while already in a find result"),
|
||||
};
|
||||
@@ -242,13 +242,13 @@ impl FileTransferActivity {
|
||||
Ok(files) => {
|
||||
// Get wrkdir
|
||||
let wrkdir = match self.browser.tab() {
|
||||
FileExplorerTab::Local => self.local().wrkdir.clone(),
|
||||
FileExplorerTab::HostBridge => self.host_bridge().wrkdir.clone(),
|
||||
_ => self.remote().wrkdir.clone(),
|
||||
};
|
||||
// Create explorer and load files
|
||||
self.browser.set_found(
|
||||
match self.browser.tab() {
|
||||
FileExplorerTab::Local => FoundExplorerTab::Local,
|
||||
FileExplorerTab::HostBridge => FoundExplorerTab::Local,
|
||||
_ => FoundExplorerTab::Remote,
|
||||
},
|
||||
files,
|
||||
@@ -261,16 +261,16 @@ impl FileTransferActivity {
|
||||
self.update_find_list();
|
||||
// Initialize tab
|
||||
self.browser.change_tab(match self.browser.tab() {
|
||||
FileExplorerTab::Local => FileExplorerTab::FindLocal,
|
||||
FileExplorerTab::HostBridge => FileExplorerTab::FindHostBridge,
|
||||
FileExplorerTab::Remote => FileExplorerTab::FindRemote,
|
||||
_ => FileExplorerTab::FindLocal,
|
||||
_ => FileExplorerTab::FindHostBridge,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
TransferMsg::Mkdir(dir) => {
|
||||
match self.browser.tab() {
|
||||
FileExplorerTab::Local => self.action_local_mkdir(dir),
|
||||
FileExplorerTab::HostBridge => self.action_local_mkdir(dir),
|
||||
FileExplorerTab::Remote => self.action_remote_mkdir(dir),
|
||||
_ => {}
|
||||
}
|
||||
@@ -280,7 +280,7 @@ impl FileTransferActivity {
|
||||
}
|
||||
TransferMsg::NewFile(name) => {
|
||||
match self.browser.tab() {
|
||||
FileExplorerTab::Local => self.action_local_newfile(name),
|
||||
FileExplorerTab::HostBridge => self.action_local_newfile(name),
|
||||
FileExplorerTab::Remote => self.action_remote_newfile(name),
|
||||
_ => {}
|
||||
}
|
||||
@@ -289,15 +289,17 @@ impl FileTransferActivity {
|
||||
self.update_browser_file_list()
|
||||
}
|
||||
TransferMsg::OpenFile => match self.browser.tab() {
|
||||
FileExplorerTab::Local => self.action_open_local(),
|
||||
FileExplorerTab::HostBridge => self.action_open_local(),
|
||||
FileExplorerTab::Remote => self.action_open_remote(),
|
||||
FileExplorerTab::FindLocal | FileExplorerTab::FindRemote => self.action_find_open(),
|
||||
FileExplorerTab::FindHostBridge | FileExplorerTab::FindRemote => {
|
||||
self.action_find_open()
|
||||
}
|
||||
},
|
||||
TransferMsg::OpenFileWith(prog) => {
|
||||
match self.browser.tab() {
|
||||
FileExplorerTab::Local => self.action_local_open_with(&prog),
|
||||
FileExplorerTab::HostBridge => self.action_local_open_with(&prog),
|
||||
FileExplorerTab::Remote => self.action_remote_open_with(&prog),
|
||||
FileExplorerTab::FindLocal | FileExplorerTab::FindRemote => {
|
||||
FileExplorerTab::FindHostBridge | FileExplorerTab::FindRemote => {
|
||||
self.action_find_open_with(&prog)
|
||||
}
|
||||
}
|
||||
@@ -305,7 +307,7 @@ impl FileTransferActivity {
|
||||
}
|
||||
TransferMsg::OpenTextFile => {
|
||||
match self.browser.tab() {
|
||||
FileExplorerTab::Local => self.action_edit_local_file(),
|
||||
FileExplorerTab::HostBridge => self.action_edit_local_file(),
|
||||
FileExplorerTab::Remote => self.action_edit_remote_file(),
|
||||
_ => {}
|
||||
}
|
||||
@@ -316,7 +318,7 @@ impl FileTransferActivity {
|
||||
self.umount_rename();
|
||||
self.mount_blocking_wait("Moving file(s)…");
|
||||
match self.browser.tab() {
|
||||
FileExplorerTab::Local => self.action_local_rename(dest),
|
||||
FileExplorerTab::HostBridge => self.action_local_rename(dest),
|
||||
FileExplorerTab::Remote => self.action_remote_rename(dest),
|
||||
_ => {}
|
||||
}
|
||||
@@ -336,9 +338,9 @@ impl FileTransferActivity {
|
||||
TransferMsg::SaveFileAs(dest) => {
|
||||
self.umount_saveas();
|
||||
match self.browser.tab() {
|
||||
FileExplorerTab::Local => self.action_local_saveas(dest),
|
||||
FileExplorerTab::HostBridge => self.action_local_saveas(dest),
|
||||
FileExplorerTab::Remote => self.action_remote_saveas(dest),
|
||||
FileExplorerTab::FindLocal | FileExplorerTab::FindRemote => {
|
||||
FileExplorerTab::FindHostBridge | FileExplorerTab::FindRemote => {
|
||||
// Get entry
|
||||
self.action_find_transfer(TransferOpts::default().save_as(Some(dest)));
|
||||
}
|
||||
@@ -352,9 +354,9 @@ impl FileTransferActivity {
|
||||
TransferMsg::ToggleWatchFor(index) => self.action_toggle_watch_for(index),
|
||||
TransferMsg::TransferFile => {
|
||||
match self.browser.tab() {
|
||||
FileExplorerTab::Local => self.action_local_send(),
|
||||
FileExplorerTab::HostBridge => self.action_local_send(),
|
||||
FileExplorerTab::Remote => self.action_remote_recv(),
|
||||
FileExplorerTab::FindLocal | FileExplorerTab::FindRemote => {
|
||||
FileExplorerTab::FindHostBridge | FileExplorerTab::FindRemote => {
|
||||
self.action_find_transfer(TransferOpts::default())
|
||||
}
|
||||
}
|
||||
@@ -371,8 +373,8 @@ impl FileTransferActivity {
|
||||
UiMsg::CloseChmodPopup => self.umount_chmod(),
|
||||
UiMsg::ChangeFileSorting(sorting) => {
|
||||
match self.browser.tab() {
|
||||
FileExplorerTab::Local | FileExplorerTab::FindLocal => {
|
||||
self.local_mut().sort_by(sorting);
|
||||
FileExplorerTab::HostBridge | FileExplorerTab::FindHostBridge => {
|
||||
self.host_bridge_mut().sort_by(sorting);
|
||||
self.refresh_local_status_bar();
|
||||
}
|
||||
FileExplorerTab::Remote | FileExplorerTab::FindRemote => {
|
||||
@@ -384,22 +386,28 @@ impl FileTransferActivity {
|
||||
}
|
||||
UiMsg::ChangeTransferWindow => {
|
||||
let new_tab = match self.browser.tab() {
|
||||
FileExplorerTab::Local if self.browser.found().is_some() => {
|
||||
FileExplorerTab::HostBridge if self.browser.found().is_some() => {
|
||||
FileExplorerTab::FindRemote
|
||||
}
|
||||
FileExplorerTab::FindLocal | FileExplorerTab::Local => FileExplorerTab::Remote,
|
||||
FileExplorerTab::Remote if self.browser.found().is_some() => {
|
||||
FileExplorerTab::FindLocal
|
||||
FileExplorerTab::FindHostBridge | FileExplorerTab::HostBridge => {
|
||||
FileExplorerTab::Remote
|
||||
}
|
||||
FileExplorerTab::Remote if self.browser.found().is_some() => {
|
||||
FileExplorerTab::FindHostBridge
|
||||
}
|
||||
FileExplorerTab::FindRemote | FileExplorerTab::Remote => {
|
||||
FileExplorerTab::HostBridge
|
||||
}
|
||||
FileExplorerTab::FindRemote | FileExplorerTab::Remote => FileExplorerTab::Local,
|
||||
};
|
||||
// Set focus
|
||||
match new_tab {
|
||||
FileExplorerTab::Local => assert!(self.app.active(&Id::ExplorerLocal).is_ok()),
|
||||
FileExplorerTab::HostBridge => {
|
||||
assert!(self.app.active(&Id::ExplorerHostBridge).is_ok())
|
||||
}
|
||||
FileExplorerTab::Remote => {
|
||||
assert!(self.app.active(&Id::ExplorerRemote).is_ok())
|
||||
}
|
||||
FileExplorerTab::FindLocal | FileExplorerTab::FindRemote => {
|
||||
FileExplorerTab::FindHostBridge | FileExplorerTab::FindRemote => {
|
||||
assert!(self.app.active(&Id::ExplorerFind).is_ok())
|
||||
}
|
||||
}
|
||||
@@ -441,13 +449,13 @@ impl FileTransferActivity {
|
||||
let files = self.filter(&filter);
|
||||
// Get wrkdir
|
||||
let wrkdir = match self.browser.tab() {
|
||||
FileExplorerTab::Local => self.local().wrkdir.clone(),
|
||||
FileExplorerTab::HostBridge => self.host_bridge().wrkdir.clone(),
|
||||
_ => self.remote().wrkdir.clone(),
|
||||
};
|
||||
// Create explorer and load files
|
||||
self.browser.set_found(
|
||||
match self.browser.tab() {
|
||||
FileExplorerTab::Local => FoundExplorerTab::Local,
|
||||
FileExplorerTab::HostBridge => FoundExplorerTab::Local,
|
||||
_ => FoundExplorerTab::Remote,
|
||||
},
|
||||
files,
|
||||
@@ -458,9 +466,9 @@ impl FileTransferActivity {
|
||||
self.update_find_list();
|
||||
// Initialize tab
|
||||
self.browser.change_tab(match self.browser.tab() {
|
||||
FileExplorerTab::Local => FileExplorerTab::FindLocal,
|
||||
FileExplorerTab::HostBridge => FileExplorerTab::FindHostBridge,
|
||||
FileExplorerTab::Remote => FileExplorerTab::FindRemote,
|
||||
_ => FileExplorerTab::FindLocal,
|
||||
_ => FileExplorerTab::FindHostBridge,
|
||||
});
|
||||
}
|
||||
UiMsg::FuzzySearch(needle) => {
|
||||
@@ -471,7 +479,7 @@ impl FileTransferActivity {
|
||||
assert!(self.app.active(&Id::Log).is_ok());
|
||||
}
|
||||
UiMsg::LogBackTabbed => {
|
||||
assert!(self.app.active(&Id::ExplorerLocal).is_ok());
|
||||
assert!(self.app.active(&Id::ExplorerHostBridge).is_ok());
|
||||
}
|
||||
UiMsg::Quit => {
|
||||
self.disconnect_and_quit();
|
||||
@@ -489,13 +497,15 @@ impl FileTransferActivity {
|
||||
UiMsg::ShowChmodPopup => {
|
||||
let selected_file = match self.browser.tab() {
|
||||
#[cfg(unix)]
|
||||
FileExplorerTab::Local => self.get_local_selected_entries(),
|
||||
FileExplorerTab::HostBridge => self.get_local_selected_entries(),
|
||||
#[cfg(unix)]
|
||||
FileExplorerTab::FindLocal => self.get_found_selected_entries(),
|
||||
FileExplorerTab::FindHostBridge => self.get_found_selected_entries(),
|
||||
FileExplorerTab::Remote => self.get_remote_selected_entries(),
|
||||
FileExplorerTab::FindRemote => self.get_found_selected_entries(),
|
||||
#[cfg(windows)]
|
||||
FileExplorerTab::Local | FileExplorerTab::FindLocal => SelectedFile::None,
|
||||
FileExplorerTab::HostBridge | FileExplorerTab::FindHostBridge => {
|
||||
SelectedFile::None
|
||||
}
|
||||
};
|
||||
if let Some(mode) = selected_file.unix_pex() {
|
||||
self.mount_chmod(
|
||||
@@ -516,7 +526,7 @@ impl FileTransferActivity {
|
||||
UiMsg::ShowDeletePopup => self.mount_radio_delete(),
|
||||
UiMsg::ShowDisconnectPopup => self.mount_disconnect(),
|
||||
UiMsg::ShowExecPopup => self.mount_exec(),
|
||||
UiMsg::ShowFileInfoPopup if self.browser.tab() == FileExplorerTab::Local => {
|
||||
UiMsg::ShowFileInfoPopup if self.browser.tab() == FileExplorerTab::HostBridge => {
|
||||
if let SelectedFile::One(file) = self.get_local_selected_entries() {
|
||||
self.mount_file_info(&file);
|
||||
}
|
||||
@@ -543,9 +553,9 @@ impl FileTransferActivity {
|
||||
UiMsg::ShowSaveAsPopup => self.mount_saveas(),
|
||||
UiMsg::ShowSymlinkPopup => {
|
||||
if match self.browser.tab() {
|
||||
FileExplorerTab::Local => self.is_local_selected_one(),
|
||||
FileExplorerTab::HostBridge => self.is_local_selected_one(),
|
||||
FileExplorerTab::Remote => self.is_remote_selected_one(),
|
||||
FileExplorerTab::FindLocal | FileExplorerTab::FindRemote => false,
|
||||
FileExplorerTab::FindHostBridge | FileExplorerTab::FindRemote => false,
|
||||
} {
|
||||
// Only if only one entry is selected
|
||||
self.mount_symlink();
|
||||
@@ -558,8 +568,8 @@ impl FileTransferActivity {
|
||||
UiMsg::ShowWatchedPathsList => self.action_show_watched_paths_list(),
|
||||
UiMsg::ShowWatcherPopup => self.action_show_radio_watch(),
|
||||
UiMsg::ToggleHiddenFiles => match self.browser.tab() {
|
||||
FileExplorerTab::FindLocal | FileExplorerTab::Local => {
|
||||
self.browser.local_mut().toggle_hidden_files();
|
||||
FileExplorerTab::FindHostBridge | FileExplorerTab::HostBridge => {
|
||||
self.browser.host_bridge_mut().toggle_hidden_files();
|
||||
self.refresh_local_status_bar();
|
||||
self.update_browser_file_list();
|
||||
}
|
||||
|
||||
@@ -44,7 +44,7 @@ impl FileTransferActivity {
|
||||
assert!(self
|
||||
.app
|
||||
.mount(
|
||||
Id::ExplorerLocal,
|
||||
Id::ExplorerHostBridge,
|
||||
Box::new(components::ExplorerLocal::new(
|
||||
"",
|
||||
&[],
|
||||
@@ -81,12 +81,12 @@ impl FileTransferActivity {
|
||||
self.refresh_local_status_bar();
|
||||
self.refresh_remote_status_bar();
|
||||
// Update components
|
||||
self.update_local_filelist();
|
||||
self.update_host_bridge_filelist();
|
||||
// self.update_remote_filelist();
|
||||
// Global listener
|
||||
self.mount_global_listener();
|
||||
// Give focus to local explorer
|
||||
assert!(self.app.active(&Id::ExplorerLocal).is_ok());
|
||||
assert!(self.app.active(&Id::ExplorerHostBridge).is_ok());
|
||||
}
|
||||
|
||||
// -- view
|
||||
@@ -141,7 +141,7 @@ impl FileTransferActivity {
|
||||
if matches!(self.browser.found_tab(), Some(FoundExplorerTab::Local)) {
|
||||
self.app.view(&Id::ExplorerFind, f, tabs_chunks[0]);
|
||||
} else {
|
||||
self.app.view(&Id::ExplorerLocal, f, tabs_chunks[0]);
|
||||
self.app.view(&Id::ExplorerHostBridge, f, tabs_chunks[0]);
|
||||
}
|
||||
// @! Remote explorer (Find or default)
|
||||
if matches!(self.browser.found_tab(), Some(FoundExplorerTab::Remote)) {
|
||||
@@ -152,7 +152,8 @@ impl FileTransferActivity {
|
||||
// Draw log box
|
||||
self.app.view(&Id::Log, f, bottom_chunks[1]);
|
||||
// Draw status bar
|
||||
self.app.view(&Id::StatusBarLocal, f, status_bar_chunks[0]);
|
||||
self.app
|
||||
.view(&Id::StatusBarHostBridge, f, status_bar_chunks[0]);
|
||||
self.app.view(&Id::StatusBarRemote, f, status_bar_chunks[1]);
|
||||
// @! Draw popups
|
||||
if self.app.mounted(&Id::FatalPopup) {
|
||||
@@ -555,7 +556,7 @@ impl FileTransferActivity {
|
||||
pub(super) fn mount_find(&mut self, msg: impl ToString, fuzzy_search: bool) {
|
||||
// Get color
|
||||
let (bg, fg, hg) = match self.browser.tab() {
|
||||
FileExplorerTab::Local | FileExplorerTab::FindLocal => (
|
||||
FileExplorerTab::HostBridge | FileExplorerTab::FindHostBridge => (
|
||||
self.theme().transfer_local_explorer_background,
|
||||
self.theme().transfer_local_explorer_foreground,
|
||||
self.theme().transfer_local_explorer_highlighted,
|
||||
@@ -763,7 +764,7 @@ impl FileTransferActivity {
|
||||
pub(super) fn mount_file_sorting(&mut self) {
|
||||
let sorting_color = self.theme().transfer_status_sorting;
|
||||
let sorting: FileSorting = match self.browser.tab() {
|
||||
FileExplorerTab::Local => self.local().get_file_sorting(),
|
||||
FileExplorerTab::HostBridge => self.host_bridge().get_file_sorting(),
|
||||
FileExplorerTab::Remote => self.remote().get_file_sorting(),
|
||||
_ => return,
|
||||
};
|
||||
@@ -901,7 +902,7 @@ impl FileTransferActivity {
|
||||
assert!(self
|
||||
.app
|
||||
.remount(
|
||||
Id::StatusBarLocal,
|
||||
Id::StatusBarHostBridge,
|
||||
Box::new(components::StatusBarLocal::new(
|
||||
&self.browser,
|
||||
sorting_color,
|
||||
|
||||
Reference in New Issue
Block a user