diff --git a/libs/hbb_common/src/fs.rs b/libs/hbb_common/src/fs.rs index 13915ac0b..4ba132f57 100644 --- a/libs/hbb_common/src/fs.rs +++ b/libs/hbb_common/src/fs.rs @@ -200,13 +200,15 @@ pub fn can_enable_overwrite_detection(version: i64) -> bool { #[derive(Default)] pub struct TransferJob { - id: i32, - remote: String, - path: PathBuf, - show_hidden: bool, - is_remote: bool, - files: Vec, - file_num: i32, + pub id: i32, + pub remote: String, + pub path: PathBuf, + pub show_hidden: bool, + pub is_remote: bool, + pub is_last_job: bool, + pub file_num: i32, + pub files: Vec, + file: Option, total_size: u64, finished_size: u64, @@ -707,6 +709,9 @@ pub async fn handle_read_jobs( ) -> ResultType<()> { let mut finished = Vec::new(); for job in jobs.iter_mut() { + if job.is_last_job { + continue; + } match job.read(stream).await { Err(err) => { stream diff --git a/src/client.rs b/src/client.rs index d31c43266..e191df80f 100644 --- a/src/client.rs +++ b/src/client.rs @@ -1326,7 +1326,8 @@ pub enum Data { ToggleClipboardFile, NewRDP, SetConfirmOverrideFile((i32, i32, bool, bool, bool)), - ResumeTransfer, + AddJob((i32, String, String, i32, bool, bool)), + ResumeJob((i32, bool)), } #[derive(Clone)] diff --git a/src/client/file_trait.rs b/src/client/file_trait.rs index fd0b2a694..be790b035 100644 --- a/src/client/file_trait.rs +++ b/src/client/file_trait.rs @@ -86,4 +86,20 @@ pub trait FileManager: Interface { ) { self.send(Data::SendFiles((id, path, to, file_num, include_hidden, is_remote))); } + + fn add_job( + &mut self, + id: i32, + path: String, + to: String, + file_num: i32, + include_hidden: bool, + is_remote: bool, + ) { + self.send(Data::AddJob((id, path, to, file_num, include_hidden, is_remote))); + } + + fn resume_job(&mut self, id: i32, is_remote: bool){ + self.send(Data::ResumeJob((id,is_remote))); + } } diff --git a/src/ui/file_transfer.css b/src/ui/file_transfer.css index d1e1a4072..9b45ea2b7 100644 --- a/src/ui/file_transfer.css +++ b/src/ui/file_transfer.css @@ -220,6 +220,10 @@ table.job-table tr.is_remote svg { transform: scale(-1, 1); } +table.job-table tr.is_remote div.svg_continue svg { + transform: scale(1, 1); +} + table.job-table tr td div.text { width: *; overflow-x: hidden; diff --git a/src/ui/file_transfer.tis b/src/ui/file_transfer.tis index bcf59b388..7d50bdf7a 100644 --- a/src/ui/file_transfer.tis +++ b/src/ui/file_transfer.tis @@ -19,6 +19,7 @@ var svg_refresh = ; var svg_cancel = ; +var svg_continue = ; var svg_computer = @@ -100,6 +101,13 @@ class JobTable: Reactor.Component { refreshDir(is_remote); } + event click $(svg.continue) (_, me) { + var job = this.jobs[me.parent.parent.parent.index]; + var id = job.id; + this.continueJob(id); + this.update(); + } + function clearAllJobs() { this.jobs = []; this.job_map = {}; @@ -123,7 +131,9 @@ class JobTable: Reactor.Component { this.jobs.push({ type: "transfer", id: id, path: path, to: to, include_hidden: show_hidden, - is_remote: is_remote }); + is_remote: is_remote, + is_last: false + }); this.job_map[id] = this.jobs[this.jobs.length - 1]; handler.send_files(id, path, to, 0, show_hidden, is_remote); var self = this; @@ -134,14 +144,23 @@ class JobTable: Reactor.Component { var job = { type: "transfer", id: id, path: path, to: to, include_hidden: show_hidden, - is_remote: is_remote }; + is_remote: is_remote, is_last: true, file_num: file_num }; this.jobs.push(job); this.job_map[id] = this.jobs[this.jobs.length - 1]; jobIdCounter = id + 1; - handler.send_files(id, path, to, file_num, show_hidden, is_remote); + handler.add_job(id, path, to, file_num, show_hidden, is_remote); stdout.println(JSON.stringify(job)); } + function continueJob(id) { + var job = this.job_map[id]; + if (job == null || !job.is_last){ + return; + } + job.is_last = false; + handler.resume_job(job.id, job.is_remote); + } + function addDelDir(path, is_remote) { var id = jobIdCounter; jobIdCounter += 1; @@ -276,6 +295,9 @@ class JobTable: Reactor.Component {
{job.path}
{this.getStatus(job)}
+
+ {svg_continue} +
{svg_cancel} ; } @@ -673,7 +695,7 @@ handler.clearAllJobs = function() { } handler.addJob = function (id, path, to, file_num, show_hidden, is_remote) { - stdout.println("restore job: " + is_remote); + // stdout.println("restore job: " + is_remote); file_transfer.job_table.addJob(id,path,to,file_num,show_hidden,is_remote); } diff --git a/src/ui/remote.rs b/src/ui/remote.rs index 89ad6b9e3..34db3d507 100644 --- a/src/ui/remote.rs +++ b/src/ui/remote.rs @@ -22,7 +22,7 @@ use clipboard::{ use enigo::{self, Enigo, KeyboardControllable}; use hbb_common::fs::{ can_enable_overwrite_detection, get_string, is_file_exists, new_send_confirm, - DigestCheckResult, RemoveJobMeta, + DigestCheckResult, RemoveJobMeta, get_job, }; use hbb_common::log::log; use hbb_common::{ @@ -205,6 +205,8 @@ impl sciter::EventHandler for Handler { fn set_no_confirm(i32); fn cancel_job(i32); fn send_files(i32, String, String, i32, bool, bool); + fn add_job(i32, String, String, i32, bool, bool); + fn resume_job(i32, bool); fn get_platform(bool); fn get_path_sep(bool); fn get_icon_path(i32, String); @@ -1652,6 +1654,69 @@ impl Remote { } } } + Data::AddJob((id, path, to, file_num, include_hidden, is_remote)) => { + let od = can_enable_overwrite_detection(self.handler.lc.read().unwrap().version); + if is_remote { + log::debug!("new write waiting job {}, write to {} from remote {}", id, to, path); + let mut job = fs::TransferJob::new_write( + id, + path.clone(), + to, + file_num, + include_hidden, + is_remote, + Vec::new(), + od, + ); + job.is_last_job = true; + self.write_jobs.push(job); + } else { + match fs::TransferJob::new_read( + id, + to.clone(), + path.clone(), + file_num, + include_hidden, + is_remote, + od, + ) { + Err(err) => { + self.handle_job_status(id, -1, Some(err.to_string())); + } + Ok(mut job) => { + log::debug!( + "new read waiting job {}, read {} to remote {}, {} files", + id, + path, + to, + job.files().len() + ); + let m = make_fd(job.id(), job.files(), true); + self.handler.call("updateFolderFiles", &make_args!(m)); + job.is_last_job = true; + self.read_jobs.push(job); + self.timer = time::interval(MILLI1); + } + } + } + } + Data::ResumeJob((id, is_remote)) => { + if is_remote { + if let Some(job) = get_job(id, &mut self.write_jobs) { + job.is_last_job = false; + allow_err!( + peer.send(&fs::new_send(id, job.remote.clone(), job.file_num, job.show_hidden)) + .await + ); + } + } else { + if let Some(job) = get_job(id, &mut self.read_jobs) { + job.is_last_job = false; + allow_err!(peer.send(&fs::new_receive(id, job.path.to_string_lossy().to_string(), + job.file_num, job.files.clone())).await); + } + } + } Data::SetNoConfirm(id) => { if let Some(job) = self.remove_jobs.get_mut(&id) { job.no_confirm = true;