feat: add skip feature

This commit is contained in:
Kingtous 2022-12-05 19:40:49 +08:00
parent c3ea787aa8
commit cbc372991b
5 changed files with 80 additions and 29 deletions

View File

@ -215,6 +215,8 @@ pub struct TransferJob {
transferred: u64, transferred: u64,
enable_overwrite_detection: bool, enable_overwrite_detection: bool,
file_confirmed: bool, file_confirmed: bool,
// indicating the last file is skipped
file_skipped: bool,
file_is_waiting: bool, file_is_waiting: bool,
default_overwrite_strategy: Option<bool>, default_overwrite_strategy: Option<bool>,
} }
@ -541,25 +543,50 @@ impl TransferJob {
pub fn set_file_confirmed(&mut self, file_confirmed: bool) { pub fn set_file_confirmed(&mut self, file_confirmed: bool) {
log::info!("id: {}, file_confirmed: {}", self.id, file_confirmed); log::info!("id: {}, file_confirmed: {}", self.id, file_confirmed);
self.file_confirmed = file_confirmed; self.file_confirmed = file_confirmed;
self.file_skipped = false;
} }
pub fn set_file_is_waiting(&mut self, file_is_waiting: bool) { pub fn set_file_is_waiting(&mut self, file_is_waiting: bool) {
self.file_is_waiting = file_is_waiting; self.file_is_waiting = file_is_waiting;
} }
#[inline]
pub fn file_is_waiting(&self) -> bool { pub fn file_is_waiting(&self) -> bool {
self.file_is_waiting self.file_is_waiting
} }
#[inline]
pub fn file_confirmed(&self) -> bool { pub fn file_confirmed(&self) -> bool {
self.file_confirmed self.file_confirmed
} }
pub fn skip_current_file(&mut self) -> bool { /// Indicating whether the last file is skipped
#[inline]
pub fn file_skipped(&self) -> bool {
self.file_skipped
}
/// Indicating whether the whole task is skipped
#[inline]
pub fn job_skipped(&self) -> bool {
self.file_skipped() && self.files.len() == 1
}
/// Get job error message, useful for getting status when job had finished
pub fn job_error(&self) -> Option<String> {
if self.job_skipped() {
return Some("skipped".to_string());
}
None
}
pub fn set_file_skipped(&mut self) -> bool {
log::debug!("skip file {} in job {}", self.file_num, self.id);
self.file.take(); self.file.take();
self.set_file_confirmed(false); self.set_file_confirmed(false);
self.set_file_is_waiting(false); self.set_file_is_waiting(false);
self.file_num += 1; self.file_num += 1;
self.file_skipped = true;
true true
} }
@ -571,7 +598,7 @@ impl TransferJob {
Some(file_transfer_send_confirm_request::Union::Skip(s)) => { Some(file_transfer_send_confirm_request::Union::Skip(s)) => {
if s { if s {
log::debug!("skip file id:{}, file_num:{}", r.id, r.file_num); log::debug!("skip file id:{}, file_num:{}", r.id, r.file_num);
self.skip_current_file(); self.set_file_skipped();
} else { } else {
self.set_file_confirmed(true); self.set_file_confirmed(true);
} }
@ -719,7 +746,10 @@ pub async fn handle_read_jobs(
Ok(None) => { Ok(None) => {
if !job.enable_overwrite_detection || (!job.file_confirmed && !job.file_is_waiting) if !job.enable_overwrite_detection || (!job.file_confirmed && !job.file_is_waiting)
{ {
finished.push(job.id()); // for getting error detail, we do not remove this job, we will handle it in io loop
if job.job_error().is_none() {
finished.push(job.id());
}
stream.send(&new_done(job.id(), job.file_num())).await?; stream.send(&new_done(job.id(), job.file_num())).await?;
} else { } else {
// waiting confirmation. // waiting confirmation.

View File

@ -499,7 +499,7 @@ impl<T: InvokeUiSession> Remote<T> {
} }
let mut msg = Message::new(); let mut msg = Message::new();
let mut file_action = FileAction::new(); let mut file_action = FileAction::new();
file_action.set_send_confirm(FileTransferSendConfirmRequest { let req = FileTransferSendConfirmRequest {
id, id,
file_num, file_num,
union: if need_override { union: if need_override {
@ -508,7 +508,9 @@ impl<T: InvokeUiSession> Remote<T> {
Some(file_transfer_send_confirm_request::Union::Skip(true)) Some(file_transfer_send_confirm_request::Union::Skip(true))
}, },
..Default::default() ..Default::default()
}); };
job.confirm(&req);
file_action.set_send_confirm(req);
msg.set_file_action(file_action); msg.set_file_action(file_action);
allow_err!(peer.send(&msg).await); allow_err!(peer.send(&msg).await);
} }
@ -862,28 +864,30 @@ impl<T: InvokeUiSession> Remote<T> {
match fs::is_write_need_confirmation(&write_path, &digest) { match fs::is_write_need_confirmation(&write_path, &digest) {
Ok(res) => match res { Ok(res) => match res {
DigestCheckResult::IsSame => { DigestCheckResult::IsSame => {
let msg= new_send_confirm(FileTransferSendConfirmRequest { let req = FileTransferSendConfirmRequest {
id: digest.id, id: digest.id,
file_num: digest.file_num, file_num: digest.file_num,
union: Some(file_transfer_send_confirm_request::Union::Skip(true)), union: Some(file_transfer_send_confirm_request::Union::Skip(true)),
..Default::default() ..Default::default()
}); };
job.confirm(&req);
let msg = new_send_confirm(req);
allow_err!(peer.send(&msg).await); allow_err!(peer.send(&msg).await);
} }
DigestCheckResult::NeedConfirm(digest) => { DigestCheckResult::NeedConfirm(digest) => {
if let Some(overwrite) = overwrite_strategy { if let Some(overwrite) = overwrite_strategy {
let msg = new_send_confirm( let req = FileTransferSendConfirmRequest {
FileTransferSendConfirmRequest { id: digest.id,
id: digest.id, file_num: digest.file_num,
file_num: digest.file_num, union: Some(if overwrite {
union: Some(if overwrite { file_transfer_send_confirm_request::Union::OffsetBlk(0)
file_transfer_send_confirm_request::Union::OffsetBlk(0) } else {
} else { file_transfer_send_confirm_request::Union::Skip(true)
file_transfer_send_confirm_request::Union::Skip(true) }),
}), ..Default::default()
..Default::default() };
}, job.confirm(&req);
); let msg = new_send_confirm(req);
allow_err!(peer.send(&msg).await); allow_err!(peer.send(&msg).await);
} else { } else {
self.handler.override_file_confirm( self.handler.override_file_confirm(
@ -895,14 +899,14 @@ impl<T: InvokeUiSession> Remote<T> {
} }
} }
DigestCheckResult::NoSuchFile => { DigestCheckResult::NoSuchFile => {
let msg = new_send_confirm( let req = FileTransferSendConfirmRequest {
FileTransferSendConfirmRequest {
id: digest.id, id: digest.id,
file_num: digest.file_num, file_num: digest.file_num,
union: Some(file_transfer_send_confirm_request::Union::OffsetBlk(0)), union: Some(file_transfer_send_confirm_request::Union::OffsetBlk(0)),
..Default::default() ..Default::default()
}, };
); job.confirm(&req);
let msg = new_send_confirm(req);
allow_err!(peer.send(&msg).await); allow_err!(peer.send(&msg).await);
} }
}, },
@ -915,6 +919,7 @@ impl<T: InvokeUiSession> Remote<T> {
} }
} }
Some(file_response::Union::Block(block)) => { Some(file_response::Union::Block(block)) => {
log::debug!("recv block: {}", block.blk_id);
if let Some(job) = fs::get_job(block.id, &mut self.write_jobs) { if let Some(job) = fs::get_job(block.id, &mut self.write_jobs) {
if let Err(_err) = job.write(block).await { if let Err(_err) = job.write(block).await {
// to-do: add "skip" for writing job // to-do: add "skip" for writing job
@ -923,11 +928,18 @@ impl<T: InvokeUiSession> Remote<T> {
} }
} }
Some(file_response::Union::Done(d)) => { Some(file_response::Union::Done(d)) => {
let mut err: Option<String> = None;
if let Some(job) = fs::get_job(d.id, &mut self.write_jobs) { if let Some(job) = fs::get_job(d.id, &mut self.write_jobs) {
job.modify_time(); job.modify_time();
err = job.job_error();
fs::remove_job(d.id, &mut self.write_jobs); fs::remove_job(d.id, &mut self.write_jobs);
} }
self.handle_job_status(d.id, d.file_num, None); if let Some(job) = fs::get_job(d.id, &mut self.read_jobs) {
job.modify_time();
err = job.job_error();
fs::remove_job(d.id, &mut self.read_jobs);
}
self.handle_job_status(d.id, d.file_num, err);
} }
Some(file_response::Union::Error(e)) => { Some(file_response::Union::Error(e)) => {
self.handle_job_status(e.id, e.file_num, Some(e.error)); self.handle_job_status(e.id, e.file_num, Some(e.error));
@ -976,7 +988,8 @@ impl<T: InvokeUiSession> Remote<T> {
self.handler.ui_handler.switch_display(&s); self.handler.ui_handler.switch_display(&s);
self.video_sender.send(MediaData::Reset).ok(); self.video_sender.send(MediaData::Reset).ok();
if s.width > 0 && s.height > 0 { if s.width > 0 && s.height > 0 {
self.handler.set_display(s.x, s.y, s.width, s.height, s.cursor_embeded); self.handler
.set_display(s.x, s.y, s.width, s.height, s.cursor_embeded);
} }
} }
Some(misc::Union::CloseReason(c)) => { Some(misc::Union::CloseReason(c)) => {

View File

@ -210,10 +210,10 @@ impl InvokeUiSession for FlutterHandler {
); );
} }
fn job_done(&self, id: i32, file_num: i32) { fn job_done(&self, id: i32, file_num: i32, skipped: bool) {
self.push_event( self.push_event(
"job_done", "job_done",
vec![("id", &id.to_string()), ("file_num", &file_num.to_string())], vec![("id", &id.to_string()), ("file_num", &file_num.to_string()), ("skipped", skipped)],
); );
} }

View File

@ -399,5 +399,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("hide_cm_tip", "在只允许密码连接并且只用固定密码的情况下才允许隐藏"), ("hide_cm_tip", "在只允许密码连接并且只用固定密码的情况下才允许隐藏"),
("wayland_experiment_tip", ""), ("wayland_experiment_tip", ""),
("Right click to select tabs", "右键选择选项卡"), ("Right click to select tabs", "右键选择选项卡"),
("Skipped", "已跳过"),
].iter().cloned().collect(); ].iter().cloned().collect();
} }

View File

@ -245,7 +245,13 @@ class JobTable: Reactor.Component {
var percent = job.total_size == 0 ? 100 : (100. * job.finished_size / job.total_size).toInteger(); // (100. * i / (n || 1)).toInteger(); var percent = job.total_size == 0 ? 100 : (100. * job.finished_size / job.total_size).toInteger(); // (100. * i / (n || 1)).toInteger();
if (job.finished) percent = '100'; if (job.finished) percent = '100';
if (percent) res += ", " + percent + "%"; if (percent) res += ", " + percent + "%";
if (job.finished) res = translate("Finished") + " " + res; if (job.finished) {
if (job.err == "skipped") {
res = translate("Skipped") + " " + res;
} else {
res = translate("Finished") + " " + res;
}
}
if (job.speed) res += ", " + getSize(0, job.speed) + "/s"; if (job.speed) res += ", " + getSize(0, job.speed) + "/s";
return res; return res;
} }
@ -268,9 +274,10 @@ class JobTable: Reactor.Component {
if (file_num < job.file_num) return; if (file_num < job.file_num) return;
job.file_num = file_num; job.file_num = file_num;
var n = job.num_entries || job.entries.length; var n = job.num_entries || job.entries.length;
job.finished = job.file_num >= n - 1 || err == "cancel"; job.finished = job.file_num >= n - 1 || err == "cancel" || err == "skipped";
job.finished_size = finished_size; job.finished_size = finished_size;
job.speed = speed || 0; job.speed = speed || 0;
job.err = err;
this.updateJob(job); this.updateJob(job);
if (job.type == "del-dir") { if (job.type == "del-dir") {
if (job.finished) { if (job.finished) {