Merge pull request #2455 from Kingtous/master
feat: add skipping info in file transfer page
This commit is contained in:
commit
1145ea50c9
@ -458,7 +458,7 @@ class _FileManagerPageState extends State<FileManagerPage>
|
|||||||
Wrap(
|
Wrap(
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
'${item.state.display()} ${max(0, item.fileNum)}/${item.fileCount} '),
|
'${item.display()} ${max(0, item.fileNum)}/${item.fileCount} '),
|
||||||
Text(
|
Text(
|
||||||
'${translate("files")} ${readableFileSize(item.totalSize.toDouble())} '),
|
'${translate("files")} ${readableFileSize(item.totalSize.toDouble())} '),
|
||||||
Offstage(
|
Offstage(
|
||||||
|
@ -268,6 +268,7 @@ class FileModel extends ChangeNotifier {
|
|||||||
}
|
}
|
||||||
|
|
||||||
jobError(Map<String, dynamic> evt) {
|
jobError(Map<String, dynamic> evt) {
|
||||||
|
final err = evt['err'].toString();
|
||||||
if (!isDesktop) {
|
if (!isDesktop) {
|
||||||
if (_jobResultListener.isListening) {
|
if (_jobResultListener.isListening) {
|
||||||
_jobResultListener.complete(evt);
|
_jobResultListener.complete(evt);
|
||||||
@ -275,12 +276,24 @@ class FileModel extends ChangeNotifier {
|
|||||||
}
|
}
|
||||||
_selectMode = false;
|
_selectMode = false;
|
||||||
_jobProgress.clear();
|
_jobProgress.clear();
|
||||||
|
_jobProgress.err = err;
|
||||||
_jobProgress.state = JobState.error;
|
_jobProgress.state = JobState.error;
|
||||||
|
_jobProgress.fileNum = int.parse(evt['file_num']);
|
||||||
|
if (err == "skipped") {
|
||||||
|
_jobProgress.state = JobState.done;
|
||||||
|
_jobProgress.finishedSize = _jobProgress.totalSize;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
int jobIndex = getJob(int.parse(evt['id']));
|
int jobIndex = getJob(int.parse(evt['id']));
|
||||||
if (jobIndex != -1) {
|
if (jobIndex != -1) {
|
||||||
final job = jobTable[jobIndex];
|
final job = jobTable[jobIndex];
|
||||||
job.state = JobState.error;
|
job.state = JobState.error;
|
||||||
|
job.err = err;
|
||||||
|
job.fileNum = int.parse(evt['file_num']);
|
||||||
|
if (err == "skipped") {
|
||||||
|
job.state = JobState.done;
|
||||||
|
job.finishedSize = job.totalSize;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
debugPrint("jobError $evt");
|
debugPrint("jobError $evt");
|
||||||
@ -1089,6 +1102,7 @@ class JobProgress {
|
|||||||
var remote = "";
|
var remote = "";
|
||||||
var to = "";
|
var to = "";
|
||||||
var showHidden = false;
|
var showHidden = false;
|
||||||
|
var err = "";
|
||||||
|
|
||||||
clear() {
|
clear() {
|
||||||
state = JobState.none;
|
state = JobState.none;
|
||||||
@ -1100,6 +1114,14 @@ class JobProgress {
|
|||||||
fileCount = 0;
|
fileCount = 0;
|
||||||
remote = "";
|
remote = "";
|
||||||
to = "";
|
to = "";
|
||||||
|
err = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
String display() {
|
||||||
|
if (state == JobState.done && err == "skipped") {
|
||||||
|
return translate("Skipped");
|
||||||
|
}
|
||||||
|
return state.display();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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.
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -923,11 +927,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 +987,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)) => {
|
||||||
|
@ -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();
|
||||||
}
|
}
|
||||||
|
@ -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) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user