feat: identical msg in flutter and sciter

This commit is contained in:
Kingtous 2023-03-15 17:18:59 +08:00
parent 33ca87718b
commit 7a05910807
41 changed files with 71 additions and 18 deletions

View File

@ -104,9 +104,10 @@ class FileModel {
// If `skip == true`, it means to skip this file without showing dialog. // If `skip == true`, it means to skip this file without showing dialog.
// Because `resp` may be null after the user operation or the last remembered operation, // Because `resp` may be null after the user operation or the last remembered operation,
// and we should distinguish them. // and we should distinguish them.
final resp = overrideConfirm ?? (!skip final resp = overrideConfirm ??
? await showFileConfirmDialog( (!skip
translate("Overwrite"), "${evt['read_path']}", true) ? await showFileConfirmDialog(translate("Overwrite"),
"${evt['read_path']}", true, evt['is_identical'] == "true")
: null); : null);
final id = int.tryParse(evt['id']) ?? 0; final id = int.tryParse(evt['id']) ?? 0;
if (false == resp) { if (false == resp) {
@ -147,7 +148,7 @@ class FileModel {
bool fileConfirmCheckboxRemember = false; bool fileConfirmCheckboxRemember = false;
Future<bool?> showFileConfirmDialog( Future<bool?> showFileConfirmDialog(
String title, String content, bool showCheckbox) async { String title, String content, bool showCheckbox, bool isIdentical) async {
fileConfirmCheckboxRemember = false; fileConfirmCheckboxRemember = false;
return await parent.target?.dialogManager.show<bool?>( return await parent.target?.dialogManager.show<bool?>(
(setState, Function(bool? v) close) { (setState, Function(bool? v) close) {
@ -172,6 +173,17 @@ class FileModel {
style: const TextStyle(fontWeight: FontWeight.bold)), style: const TextStyle(fontWeight: FontWeight.bold)),
const SizedBox(height: 5), const SizedBox(height: 5),
Text(content), Text(content),
Offstage(
offstage: !isIdentical,
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
const SizedBox(height: 12),
Text(translate("This file is identical with the peer's one"),
style: const TextStyle(fontWeight: FontWeight.w500))
],
),
),
showCheckbox showCheckbox
? CheckboxListTile( ? CheckboxListTile(
contentPadding: const EdgeInsets.all(0), contentPadding: const EdgeInsets.all(0),
@ -1242,7 +1254,8 @@ class FileDialogEventLoop
var event = evt as _FileDialogEvent; var event = evt as _FileDialogEvent;
event.setOverrideConfirm(_overrideConfirm); event.setOverrideConfirm(_overrideConfirm);
event.setSkip(_skip); event.setSkip(_skip);
debugPrint("FileDialogEventLoop: consuming<jobId:${evt.data['id']} overrideConfirm: $_overrideConfirm, skip:$_skip>"); debugPrint(
"FileDialogEventLoop: consuming<jobId:${evt.data['id']} overrideConfirm: $_overrideConfirm, skip:$_skip>");
} }
@override @override

View File

@ -301,6 +301,7 @@ message FileTransferDigest {
uint64 last_modified = 3; uint64 last_modified = 3;
uint64 file_size = 4; uint64 file_size = 4;
bool is_upload = 5; bool is_upload = 5;
bool is_identical = 6;
} }
message FileTransferBlock { message FileTransferBlock {

View File

@ -821,20 +821,21 @@ pub fn is_write_need_confirmation(
if path.exists() && path.is_file() { if path.exists() && path.is_file() {
let metadata = std::fs::metadata(path)?; let metadata = std::fs::metadata(path)?;
let modified_time = metadata.modified()?; let modified_time = metadata.modified()?;
// let remote_mt = Duration::from_secs(digest.last_modified); let remote_mt = Duration::from_secs(digest.last_modified);
let local_mt = modified_time.duration_since(UNIX_EPOCH)?; let local_mt = modified_time.duration_since(UNIX_EPOCH)?;
// [Note] // [Note]
// We decide not to compare the file with peers, // We decide to give the decision whether to override the existing file to users,
// which obey the behavior of the file manager in our system. // which obey the behavior of the file manager in our system.
// let mut is_identical = false;
// if remote_mt == local_mt && digest.file_size == metadata.len() { if remote_mt == local_mt && digest.file_size == metadata.len() {
// return Ok(DigestCheckResult::IsSame); is_identical = true;
// } }
Ok(DigestCheckResult::NeedConfirm(FileTransferDigest { Ok(DigestCheckResult::NeedConfirm(FileTransferDigest {
id: digest.id, id: digest.id,
file_num: digest.file_num, file_num: digest.file_num,
last_modified: local_mt.as_secs(), last_modified: local_mt.as_secs(),
file_size: metadata.len(), file_size: metadata.len(),
is_identical,
..Default::default() ..Default::default()
})) }))
} else { } else {

View File

@ -954,6 +954,7 @@ impl<T: InvokeUiSession> Remote<T> {
digest.file_num, digest.file_num,
read_path, read_path,
true, true,
digest.is_identical
); );
} }
} }
@ -997,6 +998,7 @@ impl<T: InvokeUiSession> Remote<T> {
digest.file_num, digest.file_num,
write_path, write_path,
false, false,
digest.is_identical
); );
} }
} }

View File

@ -420,7 +420,7 @@ impl InvokeUiSession for FlutterHandler {
// unused in flutter // TEST flutter // unused in flutter // TEST flutter
fn confirm_delete_files(&self, _id: i32, _i: i32, _name: String) {} fn confirm_delete_files(&self, _id: i32, _i: i32, _name: String) {}
fn override_file_confirm(&self, id: i32, file_num: i32, to: String, is_upload: bool) { fn override_file_confirm(&self, id: i32, file_num: i32, to: String, is_upload: bool, is_identical: bool) {
self.push_event( self.push_event(
"override_file_confirm", "override_file_confirm",
vec![ vec![
@ -428,6 +428,7 @@ impl InvokeUiSession for FlutterHandler {
("file_num", &file_num.to_string()), ("file_num", &file_num.to_string()),
("read_path", &to), ("read_path", &to),
("is_upload", &is_upload.to_string()), ("is_upload", &is_upload.to_string()),
("is_identical", &is_identical.to_string())
], ],
); );
} }

View File

@ -477,5 +477,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Empty Username", ""), ("Empty Username", ""),
("Empty Password", ""), ("Empty Password", ""),
("Me", ""), ("Me", ""),
("This file is identical with the peer's one", "")
].iter().cloned().collect(); ].iter().cloned().collect();
} }

View File

@ -477,5 +477,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Empty Username", ""), ("Empty Username", ""),
("Empty Password", ""), ("Empty Password", ""),
("Me", ""), ("Me", ""),
("This file is identical with the peer's one", "此文件与对方的一致")
].iter().cloned().collect(); ].iter().cloned().collect();
} }

View File

@ -477,5 +477,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Empty Username", ""), ("Empty Username", ""),
("Empty Password", ""), ("Empty Password", ""),
("Me", ""), ("Me", ""),
("This file is identical with the peer's one", "")
].iter().cloned().collect(); ].iter().cloned().collect();
} }

View File

@ -477,5 +477,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Empty Username", "Tom brugernavn"), ("Empty Username", "Tom brugernavn"),
("Empty Password", "Tom adgangskode"), ("Empty Password", "Tom adgangskode"),
("Me", "Mig"), ("Me", "Mig"),
("This file is identical with the peer's one", "")
].iter().cloned().collect(); ].iter().cloned().collect();
} }

View File

@ -477,5 +477,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Empty Username", "Leerer Benutzername"), ("Empty Username", "Leerer Benutzername"),
("Empty Password", "Leeres Passwort"), ("Empty Password", "Leeres Passwort"),
("Me", "Ich"), ("Me", "Ich"),
("This file is identical with the peer's one", "")
].iter().cloned().collect(); ].iter().cloned().collect();
} }

View File

@ -477,5 +477,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Empty Username", "Κενό όνομα χρήστη"), ("Empty Username", "Κενό όνομα χρήστη"),
("Empty Password", "Κενός κωδικός πρόσβασης"), ("Empty Password", "Κενός κωδικός πρόσβασης"),
("Me", ""), ("Me", ""),
("This file is identical with the peer's one", "")
].iter().cloned().collect(); ].iter().cloned().collect();
} }

View File

@ -477,5 +477,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Empty Username", ""), ("Empty Username", ""),
("Empty Password", ""), ("Empty Password", ""),
("Me", ""), ("Me", ""),
("This file is identical with the peer's one", "")
].iter().cloned().collect(); ].iter().cloned().collect();
} }

View File

@ -477,5 +477,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Empty Username", "Nombre de usuario vacío"), ("Empty Username", "Nombre de usuario vacío"),
("Empty Password", "Contraseña vacía"), ("Empty Password", "Contraseña vacía"),
("Me", "Yo"), ("Me", "Yo"),
("This file is identical with the peer's one", "")
].iter().cloned().collect(); ].iter().cloned().collect();
} }

View File

@ -477,5 +477,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Empty Username", ""), ("Empty Username", ""),
("Empty Password", ""), ("Empty Password", ""),
("Me", ""), ("Me", ""),
("This file is identical with the peer's one", "")
].iter().cloned().collect(); ].iter().cloned().collect();
} }

View File

@ -477,5 +477,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Empty Username", ""), ("Empty Username", ""),
("Empty Password", ""), ("Empty Password", ""),
("Me", ""), ("Me", ""),
("This file is identical with the peer's one", "")
].iter().cloned().collect(); ].iter().cloned().collect();
} }

View File

@ -477,5 +477,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Empty Username", ""), ("Empty Username", ""),
("Empty Password", ""), ("Empty Password", ""),
("Me", ""), ("Me", ""),
("This file is identical with the peer's one", "")
].iter().cloned().collect(); ].iter().cloned().collect();
} }

View File

@ -477,5 +477,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Empty Username", ""), ("Empty Username", ""),
("Empty Password", ""), ("Empty Password", ""),
("Me", ""), ("Me", ""),
("This file is identical with the peer's one", "")
].iter().cloned().collect(); ].iter().cloned().collect();
} }

View File

@ -477,5 +477,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Empty Username", "Nome Utente Vuoto"), ("Empty Username", "Nome Utente Vuoto"),
("Empty Password", "Password Vuota"), ("Empty Password", "Password Vuota"),
("Me", "Io"), ("Me", "Io"),
("This file is identical with the peer's one", "")
].iter().cloned().collect(); ].iter().cloned().collect();
} }

View File

@ -477,5 +477,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Empty Username", ""), ("Empty Username", ""),
("Empty Password", ""), ("Empty Password", ""),
("Me", ""), ("Me", ""),
("This file is identical with the peer's one", "")
].iter().cloned().collect(); ].iter().cloned().collect();
} }

View File

@ -477,5 +477,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Empty Username", ""), ("Empty Username", ""),
("Empty Password", ""), ("Empty Password", ""),
("Me", ""), ("Me", ""),
("This file is identical with the peer's one", "")
].iter().cloned().collect(); ].iter().cloned().collect();
} }

View File

@ -477,5 +477,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Empty Username", ""), ("Empty Username", ""),
("Empty Password", ""), ("Empty Password", ""),
("Me", ""), ("Me", ""),
("This file is identical with the peer's one", "")
].iter().cloned().collect(); ].iter().cloned().collect();
} }

View File

@ -477,5 +477,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Empty Username", "Gebruikersnaam Leeg"), ("Empty Username", "Gebruikersnaam Leeg"),
("Empty Password", "Wachtwoord Leeg"), ("Empty Password", "Wachtwoord Leeg"),
("Me", ""), ("Me", ""),
("This file is identical with the peer's one", "")
].iter().cloned().collect(); ].iter().cloned().collect();
} }

View File

@ -477,5 +477,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Empty Username", ""), ("Empty Username", ""),
("Empty Password", ""), ("Empty Password", ""),
("Me", ""), ("Me", ""),
("This file is identical with the peer's one", "")
].iter().cloned().collect(); ].iter().cloned().collect();
} }

View File

@ -477,5 +477,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Empty Username", ""), ("Empty Username", ""),
("Empty Password", ""), ("Empty Password", ""),
("Me", ""), ("Me", ""),
("This file is identical with the peer's one", "")
].iter().cloned().collect(); ].iter().cloned().collect();
} }

View File

@ -477,5 +477,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Empty Username", ""), ("Empty Username", ""),
("Empty Password", ""), ("Empty Password", ""),
("Me", ""), ("Me", ""),
("This file is identical with the peer's one", "")
].iter().cloned().collect(); ].iter().cloned().collect();
} }

View File

@ -477,5 +477,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Empty Username", ""), ("Empty Username", ""),
("Empty Password", ""), ("Empty Password", ""),
("Me", ""), ("Me", ""),
("This file is identical with the peer's one", "")
].iter().cloned().collect(); ].iter().cloned().collect();
} }

View File

@ -477,5 +477,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Empty Username", ""), ("Empty Username", ""),
("Empty Password", ""), ("Empty Password", ""),
("Me", ""), ("Me", ""),
("This file is identical with the peer's one", "")
].iter().cloned().collect(); ].iter().cloned().collect();
} }

View File

@ -477,5 +477,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Empty Username", ""), ("Empty Username", ""),
("Empty Password", ""), ("Empty Password", ""),
("Me", ""), ("Me", ""),
("This file is identical with the peer's one", "")
].iter().cloned().collect(); ].iter().cloned().collect();
} }

View File

@ -477,5 +477,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Empty Username", ""), ("Empty Username", ""),
("Empty Password", ""), ("Empty Password", ""),
("Me", ""), ("Me", ""),
("This file is identical with the peer's one", "")
].iter().cloned().collect(); ].iter().cloned().collect();
} }

View File

@ -477,5 +477,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Empty Username", ""), ("Empty Username", ""),
("Empty Password", ""), ("Empty Password", ""),
("Me", ""), ("Me", ""),
("This file is identical with the peer's one", "")
].iter().cloned().collect(); ].iter().cloned().collect();
} }

View File

@ -477,5 +477,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Empty Username", ""), ("Empty Username", ""),
("Empty Password", ""), ("Empty Password", ""),
("Me", ""), ("Me", ""),
("This file is identical with the peer's one", "")
].iter().cloned().collect(); ].iter().cloned().collect();
} }

View File

@ -477,5 +477,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Empty Username", ""), ("Empty Username", ""),
("Empty Password", ""), ("Empty Password", ""),
("Me", ""), ("Me", ""),
("This file is identical with the peer's one", "")
].iter().cloned().collect(); ].iter().cloned().collect();
} }

View File

@ -477,5 +477,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Empty Username", ""), ("Empty Username", ""),
("Empty Password", ""), ("Empty Password", ""),
("Me", ""), ("Me", ""),
("This file is identical with the peer's one", "")
].iter().cloned().collect(); ].iter().cloned().collect();
} }

View File

@ -477,5 +477,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Empty Username", ""), ("Empty Username", ""),
("Empty Password", ""), ("Empty Password", ""),
("Me", ""), ("Me", ""),
("This file is identical with the peer's one", "")
].iter().cloned().collect(); ].iter().cloned().collect();
} }

View File

@ -477,5 +477,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Empty Username", ""), ("Empty Username", ""),
("Empty Password", ""), ("Empty Password", ""),
("Me", ""), ("Me", ""),
("This file is identical with the peer's one", "")
].iter().cloned().collect(); ].iter().cloned().collect();
} }

View File

@ -477,5 +477,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Empty Username", ""), ("Empty Username", ""),
("Empty Password", ""), ("Empty Password", ""),
("Me", ""), ("Me", ""),
("This file is identical with the peer's one", "")
].iter().cloned().collect(); ].iter().cloned().collect();
} }

View File

@ -477,5 +477,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Empty Username", ""), ("Empty Username", ""),
("Empty Password", ""), ("Empty Password", ""),
("Me", ""), ("Me", ""),
("This file is identical with the peer's one", "")
].iter().cloned().collect(); ].iter().cloned().collect();
} }

View File

@ -477,5 +477,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("Empty Username", ""), ("Empty Username", ""),
("Empty Password", ""), ("Empty Password", ""),
("Me", ""), ("Me", ""),
("This file is identical with the peer's one", "")
].iter().cloned().collect(); ].iter().cloned().collect();
} }

View File

@ -778,12 +778,14 @@ handler.confirmDeleteFiles = function(id, i, name) {
}); });
} }
handler.overrideFileConfirm = function(id, file_num, to, is_upload) { handler.overrideFileConfirm = function(id, file_num, to, is_upload, is_identical) {
var jt = file_transfer.job_table; var jt = file_transfer.job_table;
var identical_msg = is_identical ? translate("This file is identical with the peer's one"): "";
msgbox("custom-skip", "Confirm Write Strategy", "<div .form> \ msgbox("custom-skip", "Confirm Write Strategy", "<div .form> \
<div>" + translate('Overwrite') + translate('files') + ".</div> \ <div>" + translate('Overwrite') + " " + translate('files') + ".</div> \
<div>" + translate('This file exists, skip or overwrite this file?') + "</div> \ <div>" + translate('This file exists, skip or overwrite this file?') + "</div> \
<div.ellipsis style=\"font-weight: bold;\" .text>" + to + "</div> \ <div.ellipsis style=\"font-weight: bold;\" .text>" + to + "</div> \
<div>" + identical_msg + "</div> \
<div><button|checkbox(remember) {ts}>" + translate('Do this for all conflicts') + "</button></div> \ <div><button|checkbox(remember) {ts}>" + translate('Do this for all conflicts') + "</button></div> \
</div>", "", function(res=null) { </div>", "", function(res=null) {
if (!res) { if (!res) {

View File

@ -197,10 +197,10 @@ impl InvokeUiSession for SciterHandler {
self.call("confirmDeleteFiles", &make_args!(id, i, name)); self.call("confirmDeleteFiles", &make_args!(id, i, name));
} }
fn override_file_confirm(&self, id: i32, file_num: i32, to: String, is_upload: bool) { fn override_file_confirm(&self, id: i32, file_num: i32, to: String, is_upload: bool, is_identical: bool) {
self.call( self.call(
"overrideFileConfirm", "overrideFileConfirm",
&make_args!(id, file_num, to, is_upload), &make_args!(id, file_num, to, is_upload, is_identical),
); );
} }

View File

@ -872,7 +872,7 @@ pub trait InvokeUiSession: Send + Sync + Clone + 'static + Sized + Default {
only_count: bool, only_count: bool,
); );
fn confirm_delete_files(&self, id: i32, i: i32, name: String); fn confirm_delete_files(&self, id: i32, i: i32, name: String);
fn override_file_confirm(&self, id: i32, file_num: i32, to: String, is_upload: bool); fn override_file_confirm(&self, id: i32, file_num: i32, to: String, is_upload: bool, is_identical: bool);
fn update_block_input_state(&self, on: bool); fn update_block_input_state(&self, on: bool);
fn job_progress(&self, id: i32, file_num: i32, speed: f64, finished_size: f64); fn job_progress(&self, id: i32, file_num: i32, speed: f64, finished_size: f64);
fn adapt_size(&self); fn adapt_size(&self);