From c4d41c21f3ab0a186859347c932e355692373e52 Mon Sep 17 00:00:00 2001 From: Kingtous Date: Tue, 17 May 2022 09:10:21 +0800 Subject: [PATCH 1/6] fix: compile --- src/mobile.rs | 39 ++++++++++++++++++++++++++++++++------- src/mobile_ffi.rs | 3 +++ 2 files changed, 35 insertions(+), 7 deletions(-) diff --git a/src/mobile.rs b/src/mobile.rs index 35114d524..cd0942e32 100644 --- a/src/mobile.rs +++ b/src/mobile.rs @@ -5,6 +5,7 @@ use hbb_common::{ compress::decompress, config::{Config, LocalConfig}, fs, log, + fs::can_enable_overwrite_detection, message_proto::*, protobuf::Message as _, rendezvous_proto::ConnType, @@ -14,6 +15,7 @@ use hbb_common::{ time::{self, Duration, Instant, Interval}, }, Stream, + get_version_number }; use std::{ collections::{HashMap, VecDeque}, @@ -192,9 +194,9 @@ impl Session { Self::send_msg_static(msg_out); } - pub fn send_files(id: i32, path: String, to: String, include_hidden: bool, is_remote: bool) { + pub fn send_files(id: i32, path: String, to: String, file_num: i32, include_hidden: bool, is_remote: bool) { if let Some(session) = SESSION.write().unwrap().as_mut() { - session.send_files(id, path, to, include_hidden, is_remote); + session.send_files(id, path, to, file_num, include_hidden, is_remote); } } @@ -732,14 +734,29 @@ impl Connection { Data::Message(msg) => { allow_err!(peer.send(&msg).await); } - Data::SendFiles((id, path, to, include_hidden, is_remote)) => { + Data::SendFiles((id, path, to, file_num, include_hidden, is_remote)) => { + // in mobile, can_enable_override_detection is always true + let od = true; if is_remote { log::debug!("New job {}, write to {} from remote {}", id, to, path); self.write_jobs - .push(fs::TransferJob::new_write(id, to, Vec::new())); - allow_err!(peer.send(&fs::new_send(id, path, include_hidden)).await); + .push(fs::TransferJob::new_write(id, + path.clone(), + to, + file_num, + include_hidden, + is_remote, + Vec::new(), + true)); + allow_err!(peer.send(&fs::new_send(id, path, file_num, include_hidden)).await); } else { - match fs::TransferJob::new_read(id, path.clone(), include_hidden) { + match fs::TransferJob::new_read(id, + to.clone(), + path.clone(), + file_num, + include_hidden, + is_remote, + true) { Err(err) => { self.handle_job_status(id, -1, Some(err.to_string())); } @@ -754,7 +771,7 @@ impl Connection { let files = job.files().clone(); self.read_jobs.push(job); self.timer = time::interval(MILLI1); - allow_err!(peer.send(&fs::new_receive(id, to, files)).await); + allow_err!(peer.send(&fs::new_receive(id, to, file_num, files)).await); } } } @@ -1180,11 +1197,18 @@ pub mod connection_manager { ipc::FS::NewWrite { path, id, + file_num, mut files, } => { + // in mobile, can_enable_override_detection is always true + let od = true; WRITE_JOBS.lock().unwrap().push(fs::TransferJob::new_write( id, + "".to_string(), path, + file_num, + false, + false, files .drain(..) .map(|f| FileEntry { @@ -1193,6 +1217,7 @@ pub mod connection_manager { ..Default::default() }) .collect(), + true )); } ipc::FS::CancelWrite { id } => { diff --git a/src/mobile_ffi.rs b/src/mobile_ffi.rs index b2101b747..e26d8c7ae 100644 --- a/src/mobile_ffi.rs +++ b/src/mobile_ffi.rs @@ -324,12 +324,14 @@ unsafe extern "C" fn set_by_name(name: *const c_char, value: *const c_char) { Some(id), Some(path), Some(to), + Some(file_num), Some(show_hidden), Some(is_remote), ) = ( m.get("id"), m.get("path"), m.get("to"), + m.get("file_num"), m.get("show_hidden"), m.get("is_remote"), ) { @@ -337,6 +339,7 @@ unsafe extern "C" fn set_by_name(name: *const c_char, value: *const c_char) { id.parse().unwrap_or(0), path.to_owned(), to.to_owned(), + file_num.parse().unwrap_or(0), show_hidden.eq("true"), is_remote.eq("true"), ); From c244e4927954234b157bd746546270a41bbec282 Mon Sep 17 00:00:00 2001 From: Kingtous Date: Tue, 17 May 2022 17:37:09 +0800 Subject: [PATCH 2/6] add: file_num to send_files --- flutter/lib/models/file_model.dart | 1 + 1 file changed, 1 insertion(+) diff --git a/flutter/lib/models/file_model.dart b/flutter/lib/models/file_model.dart index 10325f2b0..0b3140c0d 100644 --- a/flutter/lib/models/file_model.dart +++ b/flutter/lib/models/file_model.dart @@ -253,6 +253,7 @@ class FileModel extends ChangeNotifier { "id": _jobId.toString(), "path": from.path, "to": PathUtil.join(toPath, from.name, isWindows), + "file_num": "0", "show_hidden": showHidden.toString(), "is_remote": (!(items.isLocal!)).toString() }; From fc39c0ffc0cd8f854c8b7f0c3a6ce3d44fad99ec Mon Sep 17 00:00:00 2001 From: Kingtous Date: Tue, 17 May 2022 20:56:36 +0800 Subject: [PATCH 3/6] add: android file transfer logic --- flutter/lib/models/file_model.dart | 76 +++++++++++ flutter/lib/models/model.dart | 2 + libs/hbb_common/src/fs.rs | 2 +- src/mobile.rs | 202 ++++++++++++++++++++++++++++- src/mobile_ffi.rs | 25 ++++ 5 files changed, 304 insertions(+), 3 deletions(-) diff --git a/flutter/lib/models/file_model.dart b/flutter/lib/models/file_model.dart index 0b3140c0d..fc31db549 100644 --- a/flutter/lib/models/file_model.dart +++ b/flutter/lib/models/file_model.dart @@ -144,6 +144,28 @@ class FileModel extends ChangeNotifier { notifyListeners(); } + overrideFileConfirm(Map evt) async { + final resp = await showFileConfirmDialog( + translate("Overwrite"), "${evt['read_path']}", true); + if (false == resp) { + cancelJob(int.tryParse(evt['id']) ?? 0); + } else { + var msg = Map() + ..['id'] = evt['id'] + ..['file_num'] = evt['file_num'] + ..['is_upload'] = evt['is_upload'] + ..['remember'] = fileConfirmCheckboxRemember.toString(); + if (resp == null) { + // skip + msg['need_override'] = 'false'; + } else { + // overwrite + msg['need_override'] = 'true'; + } + FFI.setByName("set_confirm_override_file", jsonEncode(msg)); + } + } + jobReset() { _jobProgress.clear(); notifyListeners(); @@ -392,6 +414,60 @@ class FileModel extends ChangeNotifier { useAnimation: false); } + bool fileConfirmCheckboxRemember = false; + + Future showFileConfirmDialog( + String title, String content, bool showCheckbox) async { + return await DialogManager.show( + (setState, Function(bool? v) close) => CustomAlertDialog( + title: Row( + children: [ + Icon(Icons.warning, color: Colors.red), + SizedBox(width: 20), + Text(title) + ], + ), + content: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + Text(translate("This file exists, skip or overwrite this file?"), + style: TextStyle(fontWeight: FontWeight.bold)), + SizedBox(height: 5), + Text(content), + showCheckbox + ? CheckboxListTile( + contentPadding: const EdgeInsets.all(0), + dense: true, + controlAffinity: ListTileControlAffinity.leading, + title: Text( + translate("Do this for all conflicts"), + ), + value: fileConfirmCheckboxRemember, + onChanged: (v) { + if (v == null) return; + setState(() => fileConfirmCheckboxRemember = v); + }, + ) + : SizedBox.shrink() + ]), + actions: [ + TextButton( + style: flatButtonStyle, + onPressed: () => close(false), + child: Text(translate("Cancel"))), + TextButton( + style: flatButtonStyle, + onPressed: () => close(null), + child: Text(translate("Skip"))), + TextButton( + style: flatButtonStyle, + onPressed: () => close(true), + child: Text(translate("OK"))), + ]), + useAnimation: false); + } + sendRemoveFile(String path, int fileNum, bool isLocal) { final msg = { "id": _jobId.toString(), diff --git a/flutter/lib/models/model.dart b/flutter/lib/models/model.dart index c0e21fc45..6d51f57e2 100644 --- a/flutter/lib/models/model.dart +++ b/flutter/lib/models/model.dart @@ -156,6 +156,8 @@ class FfiModel with ChangeNotifier { FFI.fileModel.jobDone(evt); } else if (name == 'job_error') { FFI.fileModel.jobError(evt); + } else if (name == 'override_file_confirm') { + FFI.fileModel.overrideFileConfirm(evt); } else if (name == 'try_start_without_auth') { FFI.serverModel.loginRequest(evt); } else if (name == 'on_client_authorized') { diff --git a/libs/hbb_common/src/fs.rs b/libs/hbb_common/src/fs.rs index 4ba132f57..780cdbbb7 100644 --- a/libs/hbb_common/src/fs.rs +++ b/libs/hbb_common/src/fs.rs @@ -544,6 +544,7 @@ impl TransferJob { } pub fn set_file_confirmed(&mut self, file_confirmed: bool) { + log::info!("id: {}, file_confirmed: {}", self.id, file_confirmed); self.file_confirmed = file_confirmed; } @@ -581,7 +582,6 @@ impl TransferJob { } } Some(file_transfer_send_confirm_request::Union::offset_blk(offset)) => { - log::debug!("file confirmed"); self.set_file_confirmed(true); } _ => {} diff --git a/src/mobile.rs b/src/mobile.rs index cd0942e32..06a93aa1a 100644 --- a/src/mobile.rs +++ b/src/mobile.rs @@ -5,7 +5,7 @@ use hbb_common::{ compress::decompress, config::{Config, LocalConfig}, fs, log, - fs::can_enable_overwrite_detection, + fs::{can_enable_overwrite_detection, new_send_confirm, DigestCheckResult, get_string}, message_proto::*, protobuf::Message as _, rendezvous_proto::ConnType, @@ -200,6 +200,15 @@ impl Session { } } + pub fn set_confirm_override_file(id: i32, file_num: i32, need_override: bool, remember: bool, is_upload: bool) { + if let Some(session) = SESSION.read().unwrap().as_ref() { + if let Some(sender) = session.sender.read().unwrap().as_ref() { + log::info!("confirm file transfer, job: {}, need_override: {}", id, need_override); + sender.send(Data::SetConfirmOverrideFile((id, file_num, need_override, remember, is_upload))).ok(); + } + } + } + #[inline] pub fn send_msg_static(msg: Message) { if let Some(session) = SESSION.read().unwrap().as_ref() { @@ -662,6 +671,88 @@ impl Connection { Some(file_response::Union::error(e)) => { self.handle_job_status(e.id, e.file_num, Some(e.error)); } + Some(file_response::Union::digest(digest)) => { + if digest.is_upload { + if let Some(job) = fs::get_job(digest.id, &mut self.read_jobs) { + if let Some(file) = job.files().get(digest.file_num as usize) { + let read_path = get_string(&job.join(&file.name)); + let overwrite_strategy = job.default_overwrite_strategy(); + if let Some(overwrite) = overwrite_strategy { + let req = FileTransferSendConfirmRequest { + id: digest.id, + file_num: digest.file_num, + union: Some(if overwrite { + file_transfer_send_confirm_request::Union::offset_blk(0) + } else { + file_transfer_send_confirm_request::Union::skip( + true, + ) + }), + ..Default::default() + }; + job.confirm(&req); + let msg = new_send_confirm(req); + allow_err!(peer.send(&msg).await); + } else { + self.handle_override_file_confirm(digest.id, digest.file_num, read_path, true); + } + } + } + } else { + if let Some(job) = fs::get_job(digest.id, &mut self.write_jobs) { + if let Some(file) = job.files().get(digest.file_num as usize) { + let write_path = get_string(&job.join(&file.name)); + let overwrite_strategy = job.default_overwrite_strategy(); + match fs::is_write_need_confirmation(&write_path, &digest) { + Ok(res) => match res { + DigestCheckResult::IsSame => { + let msg= new_send_confirm(FileTransferSendConfirmRequest { + id: digest.id, + file_num: digest.file_num, + union: Some(file_transfer_send_confirm_request::Union::skip(true)), + ..Default::default() + }); + self.session.send_msg(msg); + } + DigestCheckResult::NeedConfirm(digest) => { + if let Some(overwrite) = overwrite_strategy { + let msg = new_send_confirm( + FileTransferSendConfirmRequest { + id: digest.id, + file_num: digest.file_num, + union: Some(if overwrite { + file_transfer_send_confirm_request::Union::offset_blk(0) + } else { + file_transfer_send_confirm_request::Union::skip(true) + }), + ..Default::default() + }, + ); + self.session.send_msg(msg); + } else { + self.handle_override_file_confirm(digest.id, digest.file_num, write_path.to_string(), false); + } + } + DigestCheckResult::NoSuchFile => { + let msg = new_send_confirm( + FileTransferSendConfirmRequest { + id: digest.id, + file_num: digest.file_num, + union: Some(file_transfer_send_confirm_request::Union::offset_blk(0)), + ..Default::default() + }, + ); + self.session.send_msg(msg); + } + }, + Err(err) => { + println!("error recving digest: {}", err); + } + } + } + } + } + } _ => {} }, Some(message::Union::misc(misc)) => match misc.union { @@ -715,6 +806,14 @@ impl Connection { self.audio_handler.handle_frame(frame); } } + Some(message::Union::file_action(action)) => match action.union { + Some(file_action::Union::send_confirm(c)) => { + if let Some(job) = fs::get_job(c.id, &mut self.read_jobs) { + job.confirm(&c); + } + } + _ => {} + }, _ => {} } } @@ -878,6 +977,45 @@ impl Connection { } } } + Data::SetConfirmOverrideFile((id, file_num, need_override, remember, is_upload)) => { + if is_upload { + if let Some(job) = fs::get_job(id, &mut self.read_jobs) { + if remember { + job.set_overwrite_strategy(Some(need_override)); + } + job.confirm(&FileTransferSendConfirmRequest { + id, + file_num, + union: if need_override { + Some(file_transfer_send_confirm_request::Union::offset_blk(0)) + } else { + Some(file_transfer_send_confirm_request::Union::skip(true)) + }, + ..Default::default() + }); + } + } else { + if let Some(job) = fs::get_job(id, &mut self.write_jobs) { + if remember { + job.set_overwrite_strategy(Some(need_override)); + } + let mut msg = Message::new(); + let mut file_action = FileAction::new(); + file_action.set_send_confirm(FileTransferSendConfirmRequest { + id, + file_num, + union: if need_override { + Some(file_transfer_send_confirm_request::Union::offset_blk(0)) + } else { + Some(file_transfer_send_confirm_request::Union::skip(true)) + }, + ..Default::default() + }); + msg.set_file_action(file_action); + self.session.send_msg(msg); + } + } + } _ => {} } true @@ -949,6 +1087,13 @@ impl Connection { ); } } + + fn handle_override_file_confirm(&mut self, id: i32, file_num: i32, read_path: String, is_upload: bool) { + self.session.push_event( + "override_file_confirm", + vec![("id", &id.to_string()), ("file_num", &file_num.to_string()), ("read_path", &read_path), ("is_upload", &is_upload.to_string())] + ); + } } pub fn make_fd_to_json(fd: FileDirectory) -> String { @@ -994,7 +1139,7 @@ pub mod connection_manager { self, sync::mpsc::{UnboundedReceiver, UnboundedSender}, task::spawn_blocking, - }, + }, fs::is_write_need_confirmation, }; use scrap::android::call_main_service_set_by_name; use serde_derive::Serialize; @@ -1259,6 +1404,59 @@ pub mod connection_manager { } } } + ipc::FS::CheckDigest { + id, + file_num, + file_size, + last_modified, + is_upload, + } => { + if let Some(job) = fs::get_job(id, &mut *WRITE_JOBS.lock().unwrap()) { + let mut req = FileTransferSendConfirmRequest { + id, + file_num, + union: Some(file_transfer_send_confirm_request::Union::offset_blk(0)), + ..Default::default() + }; + let digest = FileTransferDigest { + id, + file_num, + last_modified, + file_size, + ..Default::default() + }; + if let Some(file) = job.files().get(file_num as usize) { + let path = get_string(&job.join(&file.name)); + match is_write_need_confirmation(&path, &digest) { + Ok(digest_result) => { + match digest_result { + DigestCheckResult::IsSame => { + req.set_skip(true); + let msg_out = new_send_confirm(req); + send_raw(msg_out, &tx); + } + DigestCheckResult::NeedConfirm(mut digest) => { + // upload to server, but server has the same file, request + digest.is_upload = is_upload; + let mut msg_out = Message::new(); + let mut fr = FileResponse::new(); + fr.set_digest(digest); + msg_out.set_file_response(fr); + send_raw(msg_out, &tx); + } + DigestCheckResult::NoSuchFile => { + let msg_out = new_send_confirm(req); + send_raw(msg_out, &tx); + } + } + } + Err(err) => { + send_raw(fs::new_error(id, err, file_num), &tx); + } + } + } + } + } _ => {} } } diff --git a/src/mobile_ffi.rs b/src/mobile_ffi.rs index e26d8c7ae..8fadf1cce 100644 --- a/src/mobile_ffi.rs +++ b/src/mobile_ffi.rs @@ -346,6 +346,31 @@ unsafe extern "C" fn set_by_name(name: *const c_char, value: *const c_char) { } } } + "set_confirm_override_file" => { + if let Ok(m) = serde_json::from_str::>(value) { + if let ( + Some(id), + Some(file_num), + Some(need_override), + Some(remember), + Some(is_upload), + ) = ( + m.get("id"), + m.get("file_num"), + m.get("need_override"), + m.get("remember"), + m.get("is_upload") + ) { + Session::set_confirm_override_file( + id.parse().unwrap_or(0), + file_num.parse().unwrap_or(0), + need_override.eq("true"), + remember.eq("true"), + is_upload.eq("true"), + ); + } + } + } "remove_file" => { if let Ok(m) = serde_json::from_str::>(value) { if let ( From 3bf3b7950fb4839ebdb44506cbade969bb4af5c6 Mon Sep 17 00:00:00 2001 From: Kingtous Date: Tue, 17 May 2022 23:26:05 +0800 Subject: [PATCH 4/6] fix: compile with master --- src/mobile.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mobile.rs b/src/mobile.rs index 06a93aa1a..33018ca3d 100644 --- a/src/mobile.rs +++ b/src/mobile.rs @@ -1132,7 +1132,7 @@ pub mod connection_manager { use hbb_common::{ allow_err, config::Config, - fs, log, + fs::{self, new_send_confirm, DigestCheckResult, get_string}, log, message_proto::*, protobuf::Message as _, tokio::{ From 42f2ebc8e64b6a758c48e36541c15c491d680de6 Mon Sep 17 00:00:00 2001 From: Kingtous Date: Wed, 18 May 2022 15:45:45 +0800 Subject: [PATCH 5/6] opt: clean code --- libs/hbb_common/src/fs.rs | 2 +- src/server/connection.rs | 3 --- src/ui/cm.rs | 10 ++++------ src/ui/remote.rs | 12 +++++------- 4 files changed, 10 insertions(+), 17 deletions(-) diff --git a/libs/hbb_common/src/fs.rs b/libs/hbb_common/src/fs.rs index 780cdbbb7..8aa36dee4 100644 --- a/libs/hbb_common/src/fs.rs +++ b/libs/hbb_common/src/fs.rs @@ -581,7 +581,7 @@ impl TransferJob { self.set_file_confirmed(true); } } - Some(file_transfer_send_confirm_request::Union::offset_blk(offset)) => { + Some(file_transfer_send_confirm_request::Union::offset_blk(_offset)) => { self.set_file_confirmed(true); } _ => {} diff --git a/src/server/connection.rs b/src/server/connection.rs index f4780ea4d..3a026d924 100644 --- a/src/server/connection.rs +++ b/src/server/connection.rs @@ -7,8 +7,6 @@ use crate::common::update_clipboard; use crate::{common::MOBILE_INFO2, mobile::connection_manager::start_channel}; use crate::{ipc, VERSION}; use hbb_common::fs::can_enable_overwrite_detection; -use hbb_common::log::debug; -use hbb_common::message_proto::file_transfer_send_confirm_request::Union; use hbb_common::{ config::Config, fs, @@ -23,7 +21,6 @@ use hbb_common::{ }, tokio_util::codec::{BytesCodec, Framed}, }; -use libc::{printf, send}; #[cfg(any(target_os = "android", target_os = "ios"))] use scrap::android::call_input_service_mouse_input; use serde_json::{json, value::Value}; diff --git a/src/ui/cm.rs b/src/ui/cm.rs index 421750200..91ea8e513 100644 --- a/src/ui/cm.rs +++ b/src/ui/cm.rs @@ -8,15 +8,13 @@ use hbb_common::fs::{ can_enable_overwrite_detection, get_string, is_write_need_confirmation, new_send_confirm, DigestCheckResult, }; -use hbb_common::log::log; use hbb_common::{ allow_err, config::Config, fs, get_version_number, log, message_proto::*, protobuf::Message as _, - tokio::{self, sync::mpsc, task::spawn_blocking}, - ResultType, + tokio::{self, sync::mpsc, task::spawn_blocking} }; use sciter::{make_args, Element, Value, HELEMENT}; use std::{ @@ -278,9 +276,9 @@ impl ConnectionManager { } } ipc::FS::WriteOffset { - id, - file_num, - offset_blk, + id: _, + file_num: _, + offset_blk: _, } => {} }, #[cfg(windows)] diff --git a/src/ui/remote.rs b/src/ui/remote.rs index 34db3d507..d168e190a 100644 --- a/src/ui/remote.rs +++ b/src/ui/remote.rs @@ -21,14 +21,13 @@ use clipboard::{ }; use enigo::{self, Enigo, KeyboardControllable}; use hbb_common::fs::{ - can_enable_overwrite_detection, get_string, is_file_exists, new_send_confirm, + can_enable_overwrite_detection, get_string, new_send_confirm, DigestCheckResult, RemoveJobMeta, get_job, }; -use hbb_common::log::log; use hbb_common::{ allow_err, - config::{self, Config, LocalConfig, PeerConfig}, - fs, get_version_number, log, + config::{Config, LocalConfig, PeerConfig}, + fs, log, message_proto::{permission_info::Permission, *}, protobuf::Message as _, rendezvous_proto::ConnType, @@ -46,8 +45,7 @@ use hbb_common::{config::TransferSerde, fs::TransferJobMeta}; use crate::clipboard_file::*; use crate::{ client::*, - common::{self, check_clipboard, update_clipboard, ClipboardContext, CLIPBOARD_INTERVAL}, - VERSION, + common::{self, check_clipboard, update_clipboard, ClipboardContext, CLIPBOARD_INTERVAL} }; type Video = AssetPtr; @@ -1345,7 +1343,7 @@ impl RemoveJob { } } - pub fn gen_meta(&self) -> RemoveJobMeta { + pub fn _gen_meta(&self) -> RemoveJobMeta { RemoveJobMeta { path: self.path.clone(), is_remote: self.is_remote, From 925ca66c42c93431308cce1e1614daa0c517e020 Mon Sep 17 00:00:00 2001 From: Kingtous Date: Wed, 18 May 2022 15:47:07 +0800 Subject: [PATCH 6/6] opt: reset file confirm & clean code --- flutter/lib/common.dart | 4 +- flutter/lib/models/file_model.dart | 95 +++++++++++++++--------------- 2 files changed, 51 insertions(+), 48 deletions(-) diff --git a/flutter/lib/common.dart b/flutter/lib/common.dart index 42487379c..3070833e4 100644 --- a/flutter/lib/common.dart +++ b/flutter/lib/common.dart @@ -37,8 +37,8 @@ class MyTheme { } final ButtonStyle flatButtonStyle = TextButton.styleFrom( - minimumSize: Size(88, 36), - padding: EdgeInsets.symmetric(horizontal: 16.0), + minimumSize: Size(0, 36), + padding: EdgeInsets.symmetric(horizontal: 16.0, vertical: 10.0), shape: const RoundedRectangleBorder( borderRadius: BorderRadius.all(Radius.circular(2.0)), ), diff --git a/flutter/lib/models/file_model.dart b/flutter/lib/models/file_model.dart index fc31db549..49184cf5b 100644 --- a/flutter/lib/models/file_model.dart +++ b/flutter/lib/models/file_model.dart @@ -144,7 +144,7 @@ class FileModel extends ChangeNotifier { notifyListeners(); } - overrideFileConfirm(Map evt) async { + overrideFileConfirm(Map evt) async { final resp = await showFileConfirmDialog( translate("Overwrite"), "${evt['read_path']}", true); if (false == resp) { @@ -418,53 +418,56 @@ class FileModel extends ChangeNotifier { Future showFileConfirmDialog( String title, String content, bool showCheckbox) async { + fileConfirmCheckboxRemember = false; return await DialogManager.show( - (setState, Function(bool? v) close) => CustomAlertDialog( - title: Row( - children: [ - Icon(Icons.warning, color: Colors.red), - SizedBox(width: 20), - Text(title) - ], - ), - content: Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisSize: MainAxisSize.min, - children: [ - Text(translate("This file exists, skip or overwrite this file?"), - style: TextStyle(fontWeight: FontWeight.bold)), - SizedBox(height: 5), - Text(content), - showCheckbox - ? CheckboxListTile( - contentPadding: const EdgeInsets.all(0), - dense: true, - controlAffinity: ListTileControlAffinity.leading, - title: Text( - translate("Do this for all conflicts"), - ), - value: fileConfirmCheckboxRemember, - onChanged: (v) { - if (v == null) return; - setState(() => fileConfirmCheckboxRemember = v); - }, - ) - : SizedBox.shrink() + (setState, Function(bool? v) close) => CustomAlertDialog( + title: Row( + children: [ + Icon(Icons.warning, color: Colors.red), + SizedBox(width: 20), + Text(title) + ], + ), + content: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + Text( + translate( + "This file exists, skip or overwrite this file?"), + style: TextStyle(fontWeight: FontWeight.bold)), + SizedBox(height: 5), + Text(content), + showCheckbox + ? CheckboxListTile( + contentPadding: const EdgeInsets.all(0), + dense: true, + controlAffinity: ListTileControlAffinity.leading, + title: Text( + translate("Do this for all conflicts"), + ), + value: fileConfirmCheckboxRemember, + onChanged: (v) { + if (v == null) return; + setState(() => fileConfirmCheckboxRemember = v); + }, + ) + : SizedBox.shrink() + ]), + actions: [ + TextButton( + style: flatButtonStyle, + onPressed: () => close(false), + child: Text(translate("Cancel"))), + TextButton( + style: flatButtonStyle, + onPressed: () => close(null), + child: Text(translate("Skip"))), + TextButton( + style: flatButtonStyle, + onPressed: () => close(true), + child: Text(translate("OK"))), ]), - actions: [ - TextButton( - style: flatButtonStyle, - onPressed: () => close(false), - child: Text(translate("Cancel"))), - TextButton( - style: flatButtonStyle, - onPressed: () => close(null), - child: Text(translate("Skip"))), - TextButton( - style: flatButtonStyle, - onPressed: () => close(true), - child: Text(translate("OK"))), - ]), useAnimation: false); }