From 6725c9544b73d63d3508c131dd3c13e16494367f Mon Sep 17 00:00:00 2001 From: Kingtous Date: Wed, 15 Mar 2023 10:43:27 +0800 Subject: [PATCH 1/6] opt: add event loop def --- flutter/lib/models/file_model.dart | 77 ++++++++++++++++++++++++++--- flutter/lib/utils/event_loop.dart | 79 ++++++++++++++++++++++++++++++ 2 files changed, 148 insertions(+), 8 deletions(-) create mode 100644 flutter/lib/utils/event_loop.dart diff --git a/flutter/lib/models/file_model.dart b/flutter/lib/models/file_model.dart index 4170a5461..953625c96 100644 --- a/flutter/lib/models/file_model.dart +++ b/flutter/lib/models/file_model.dart @@ -4,7 +4,7 @@ import 'dart:io'; import 'package:flutter/material.dart'; import 'package:flutter_hbb/common.dart'; -import 'package:flutter_hbb/consts.dart'; +import 'package:flutter_hbb/utils/event_loop.dart'; import 'package:get/get.dart'; import 'package:path/path.dart' as path; @@ -45,6 +45,7 @@ class FileModel { late final GetSessionID getSessionID; String get sessionID => getSessionID(); + late final _FileDialogEventLoop evtLoop; FileModel(this.parent) { getSessionID = () => parent.target?.id ?? ""; @@ -64,14 +65,17 @@ class FileModel { jobController: jobController, fileFetcher: fileFetcher, getOtherSideDirectoryData: () => localController.directoryData()); + evtLoop = _FileDialogEventLoop(); } Future onReady() async { + await evtLoop.onReady(); await localController.onReady(); await remoteController.onReady(); } Future close() async { + await evtLoop.close(); parent.target?.dialogManager.dismissAll(); await localController.close(); await remoteController.close(); @@ -90,14 +94,16 @@ class FileModel { fileFetcher.tryCompleteTask(evt['value'], evt['is_local']); } - void overrideFileConfirm(Map evt) async { - final resp = await showFileConfirmDialog( - translate("Overwrite"), "${evt['read_path']}", true); + Future overrideFileConfirm(Map evt, + {bool? overrideConfirm}) async { + final resp = overrideConfirm ?? + await showFileConfirmDialog( + translate("Overwrite"), "${evt['read_path']}", true); final id = int.tryParse(evt['id']) ?? 0; if (false == resp) { final jobIndex = jobController.getJob(id); if (jobIndex != -1) { - jobController.cancelJob(id); + await jobController.cancelJob(id); final job = jobController.jobTable[jobIndex]; job.state = JobState.done; jobController.jobTable.refresh(); @@ -111,7 +117,7 @@ class FileModel { // overwrite need_override = true; } - bind.sessionSetConfirmOverrideFile( + await bind.sessionSetConfirmOverrideFile( id: sessionID, actId: id, fileNum: int.parse(evt['file_num']), @@ -677,8 +683,8 @@ class JobController { debugPrint("jobError $evt"); } - void cancelJob(int id) async { - bind.sessionCancelJob(id: sessionID, actId: id); + Future cancelJob(int id) async { + await bind.sessionCancelJob(id: sessionID, actId: id); } void loadLastJob(Map evt) { @@ -1167,3 +1173,58 @@ List _sortList(List list, SortBy sortType, bool ascending) { } return []; } + +/// Define a general queue which can accepts different dialog type. +/// +/// [Visibility] +/// The `_FileDialogType` and `_DialogEvent` are invisible for other models. +enum _FileDialogType { overwrite, unknown } + +class _FileDialogEvent + extends BaseEvent<_FileDialogType, Map> { + WeakReference fileModel; + bool? _overrideConfirm; + + _FileDialogEvent(this.fileModel, super.type, super.data); + + void setOverrideConfirm(bool? confirm) { + _overrideConfirm = confirm; + } + + @override + EventCallback>? findCallback(_FileDialogType type) { + final model = fileModel.target; + if (model == null) { + return null; + } + switch (type) { + case _FileDialogType.overwrite: + return (data) async { + return await model.overrideFileConfirm(data, overrideConfirm: _overrideConfirm); + }; + default: + return null; + } + } +} + +class _FileDialogEventLoop extends BaseEventLoop<_FileDialogType, Map> { + + bool? overrideConfirm; + + @override + Future onPreConsume(BaseEvent<_FileDialogType, Map> evt) async { + var event = evt as _FileDialogEvent; + event.setOverrideConfirm(overrideConfirm); + } + + @override + Future onEventsClear() { + overrideConfirm = null; + return super.onEventsClear(); + } + + void setOverrideConfirm(bool confirm) { + overrideConfirm = confirm; + } +} \ No newline at end of file diff --git a/flutter/lib/utils/event_loop.dart b/flutter/lib/utils/event_loop.dart new file mode 100644 index 000000000..dc3671533 --- /dev/null +++ b/flutter/lib/utils/event_loop.dart @@ -0,0 +1,79 @@ +import 'dart:async'; + +import 'package:flutter/foundation.dart'; + +typedef EventCallback = Future Function(Data data); + +abstract class BaseEvent { + EventType type; + Data data; + + /// Constructor + BaseEvent(this.type, this.data); + + /// Consume this event + @visibleForTesting + Future consume() async { + final cb = findCallback(type); + if (cb == null) { + return null; + } else { + return cb(data); + } + } + + EventCallback? findCallback(EventType type); +} + +abstract class BaseEventLoop { + final List> _evts = []; + Timer? _timer; + + List> get evts => _evts; + + Future onReady() async { + // Poll every 100ms. + _timer = Timer.periodic(Duration(milliseconds: 100), _handleTimer); + } + + /// An Event is about to be consumed. + Future onPreConsume(BaseEvent evt) async {} + /// An Event was consumed. + Future onPostConsume(BaseEvent evt) async {} + /// Events are all handled and cleared. + Future onEventsClear() async {} + /// Events start to consume. + Future onEventsStartConsuming() async {} + + Future _handleTimer(Timer timer) async { + if (_evts.isEmpty) { + return; + } + timer.cancel(); + _timer = null; + // handle logic + await onEventsStartConsuming(); + while (_evts.isNotEmpty) { + final evt = _evts.first; + _evts.remove(evt); + await onPreConsume(evt); + await evt.consume(); + await onPostConsume(evt); + } + await onEventsClear(); + // Now events are all processed + _timer = Timer.periodic(Duration(milliseconds: 100), _handleTimer); + } + + Future close() async { + _timer?.cancel(); + } + + void push_event(BaseEvent evt) { + _evts.add(evt); + } + + void clear() { + _evts.clear(); + } +} From b187d0fd594f832a36296760a67d6124c4c04663 Mon Sep 17 00:00:00 2001 From: Kingtous Date: Wed, 15 Mar 2023 15:13:23 +0800 Subject: [PATCH 2/6] feat: fit for file confirm dialog queue --- flutter/lib/models/file_model.dart | 70 ++++++++++++++++++++++-------- 1 file changed, 51 insertions(+), 19 deletions(-) diff --git a/flutter/lib/models/file_model.dart b/flutter/lib/models/file_model.dart index 953625c96..5a73d777e 100644 --- a/flutter/lib/models/file_model.dart +++ b/flutter/lib/models/file_model.dart @@ -45,7 +45,7 @@ class FileModel { late final GetSessionID getSessionID; String get sessionID => getSessionID(); - late final _FileDialogEventLoop evtLoop; + late final FileDialogEventLoop evtLoop; FileModel(this.parent) { getSessionID = () => parent.target?.id ?? ""; @@ -65,7 +65,7 @@ class FileModel { jobController: jobController, fileFetcher: fileFetcher, getOtherSideDirectoryData: () => localController.directoryData()); - evtLoop = _FileDialogEventLoop(); + evtLoop = FileDialogEventLoop(); } Future onReady() async { @@ -94,11 +94,20 @@ class FileModel { fileFetcher.tryCompleteTask(evt['value'], evt['is_local']); } + Future postOverrideFileConfirm(Map evt) async { + evtLoop.push_event( + _FileDialogEvent(WeakReference(this), FileDialogType.overwrite, evt)); + } + Future overrideFileConfirm(Map evt, - {bool? overrideConfirm}) async { - final resp = overrideConfirm ?? - await showFileConfirmDialog( - translate("Overwrite"), "${evt['read_path']}", true); + {bool? overrideConfirm, bool skip = false}) async { + // 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, + // and we should distinguish them. + final resp = overrideConfirm ?? (!skip + ? await showFileConfirmDialog( + translate("Overwrite"), "${evt['read_path']}", true) + : null); final id = int.tryParse(evt['id']) ?? 0; if (false == resp) { final jobIndex = jobController.getJob(id); @@ -117,6 +126,10 @@ class FileModel { // overwrite need_override = true; } + // Update the loop config. + if (fileConfirmCheckboxRemember) { + evtLoop.setSkip(!need_override); + } await bind.sessionSetConfirmOverrideFile( id: sessionID, actId: id, @@ -125,6 +138,10 @@ class FileModel { remember: fileConfirmCheckboxRemember, isUpload: evt['is_upload'] == "true"); } + // Update the loop config. + if (fileConfirmCheckboxRemember) { + evtLoop.setOverrideConfirm(resp); + } } bool fileConfirmCheckboxRemember = false; @@ -1178,12 +1195,12 @@ List _sortList(List list, SortBy sortType, bool ascending) { /// /// [Visibility] /// The `_FileDialogType` and `_DialogEvent` are invisible for other models. -enum _FileDialogType { overwrite, unknown } +enum FileDialogType { overwrite, unknown } -class _FileDialogEvent - extends BaseEvent<_FileDialogType, Map> { +class _FileDialogEvent extends BaseEvent> { WeakReference fileModel; bool? _overrideConfirm; + bool _skip = false; _FileDialogEvent(this.fileModel, super.type, super.data); @@ -1191,40 +1208,55 @@ class _FileDialogEvent _overrideConfirm = confirm; } + void setSkip(bool skip) { + _skip = skip; + } + @override - EventCallback>? findCallback(_FileDialogType type) { + EventCallback>? findCallback(FileDialogType type) { final model = fileModel.target; if (model == null) { return null; } switch (type) { - case _FileDialogType.overwrite: + case FileDialogType.overwrite: return (data) async { - return await model.overrideFileConfirm(data, overrideConfirm: _overrideConfirm); + return await model.overrideFileConfirm(data, + overrideConfirm: _overrideConfirm, skip: _skip); }; default: - return null; + debugPrint("Unknown event type: $type with $data"); + return null; } } } -class _FileDialogEventLoop extends BaseEventLoop<_FileDialogType, Map> { - +class FileDialogEventLoop + extends BaseEventLoop> { bool? overrideConfirm; + bool _skip = false; @override - Future onPreConsume(BaseEvent<_FileDialogType, Map> evt) async { + Future onPreConsume( + BaseEvent> evt) async { var event = evt as _FileDialogEvent; event.setOverrideConfirm(overrideConfirm); + event.setSkip(_skip); + debugPrint("FileDialogEventLoop: consuming"); } - + @override Future onEventsClear() { overrideConfirm = null; + _skip = false; return super.onEventsClear(); } - void setOverrideConfirm(bool confirm) { + void setOverrideConfirm(bool? confirm) { overrideConfirm = confirm; } -} \ No newline at end of file + + void setSkip(bool skip) { + _skip = skip; + } +} From b627a0d6c1a5159ef61700b69f746f1a5d86ff7c Mon Sep 17 00:00:00 2001 From: Kingtous Date: Wed, 15 Mar 2023 15:19:40 +0800 Subject: [PATCH 3/6] feat: post file confirm and make files with the same name confirm --- flutter/lib/models/model.dart | 2 +- libs/hbb_common/src/fs.rs | 12 ++++++++---- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/flutter/lib/models/model.dart b/flutter/lib/models/model.dart index 94e28ea21..fd88a5332 100644 --- a/flutter/lib/models/model.dart +++ b/flutter/lib/models/model.dart @@ -173,7 +173,7 @@ class FfiModel with ChangeNotifier { } else if (name == 'job_error') { parent.target?.fileModel.jobController.jobError(evt); } else if (name == 'override_file_confirm') { - parent.target?.fileModel.overrideFileConfirm(evt); + parent.target?.fileModel.postOverrideFileConfirm(evt); } else if (name == 'load_last_job') { parent.target?.fileModel.jobController.loadLastJob(evt); } else if (name == 'update_folder_files') { diff --git a/libs/hbb_common/src/fs.rs b/libs/hbb_common/src/fs.rs index ea54e113a..8ebfffc0a 100644 --- a/libs/hbb_common/src/fs.rs +++ b/libs/hbb_common/src/fs.rs @@ -821,11 +821,15 @@ pub fn is_write_need_confirmation( if path.exists() && path.is_file() { let metadata = std::fs::metadata(path)?; 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)?; - if remote_mt == local_mt && digest.file_size == metadata.len() { - return Ok(DigestCheckResult::IsSame); - } + // [Note] + // We decide not to compare the file with peers, + // which obey the behavior of the file manager in our system. + // + // if remote_mt == local_mt && digest.file_size == metadata.len() { + // return Ok(DigestCheckResult::IsSame); + // } Ok(DigestCheckResult::NeedConfirm(FileTransferDigest { id: digest.id, file_num: digest.file_num, From 33ca87718b2aa26933f716592edc98f3206dd400 Mon Sep 17 00:00:00 2001 From: Kingtous Date: Wed, 15 Mar 2023 15:20:50 +0800 Subject: [PATCH 4/6] opt: better docs --- flutter/lib/models/file_model.dart | 12 ++++++------ flutter/lib/utils/event_loop.dart | 10 +++++----- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/flutter/lib/models/file_model.dart b/flutter/lib/models/file_model.dart index 5a73d777e..6be69aa85 100644 --- a/flutter/lib/models/file_model.dart +++ b/flutter/lib/models/file_model.dart @@ -95,7 +95,7 @@ class FileModel { } Future postOverrideFileConfirm(Map evt) async { - evtLoop.push_event( + evtLoop.pushEvent( _FileDialogEvent(WeakReference(this), FileDialogType.overwrite, evt)); } @@ -1233,27 +1233,27 @@ class _FileDialogEvent extends BaseEvent> { class FileDialogEventLoop extends BaseEventLoop> { - bool? overrideConfirm; + bool? _overrideConfirm; bool _skip = false; @override Future onPreConsume( BaseEvent> evt) async { var event = evt as _FileDialogEvent; - event.setOverrideConfirm(overrideConfirm); + event.setOverrideConfirm(_overrideConfirm); event.setSkip(_skip); - debugPrint("FileDialogEventLoop: consuming"); + debugPrint("FileDialogEventLoop: consuming"); } @override Future onEventsClear() { - overrideConfirm = null; + _overrideConfirm = null; _skip = false; return super.onEventsClear(); } void setOverrideConfirm(bool? confirm) { - overrideConfirm = confirm; + _overrideConfirm = confirm; } void setSkip(bool skip) { diff --git a/flutter/lib/utils/event_loop.dart b/flutter/lib/utils/event_loop.dart index dc3671533..a982cf9e2 100644 --- a/flutter/lib/utils/event_loop.dart +++ b/flutter/lib/utils/event_loop.dart @@ -8,10 +8,10 @@ abstract class BaseEvent { EventType type; Data data; - /// Constructor + /// Constructor. BaseEvent(this.type, this.data); - /// Consume this event + /// Consume this event. @visibleForTesting Future consume() async { final cb = findCallback(type); @@ -51,7 +51,7 @@ abstract class BaseEventLoop { } timer.cancel(); _timer = null; - // handle logic + // Handle the logic. await onEventsStartConsuming(); while (_evts.isNotEmpty) { final evt = _evts.first; @@ -61,7 +61,7 @@ abstract class BaseEventLoop { await onPostConsume(evt); } await onEventsClear(); - // Now events are all processed + // Now events are all processed. _timer = Timer.periodic(Duration(milliseconds: 100), _handleTimer); } @@ -69,7 +69,7 @@ abstract class BaseEventLoop { _timer?.cancel(); } - void push_event(BaseEvent evt) { + void pushEvent(BaseEvent evt) { _evts.add(evt); } From 7a0591080701e1a7207cab0f64d2af3c54956d68 Mon Sep 17 00:00:00 2001 From: Kingtous Date: Wed, 15 Mar 2023 17:18:59 +0800 Subject: [PATCH 5/6] feat: identical msg in flutter and sciter --- flutter/lib/models/file_model.dart | 25 +++++++++++++++++++------ libs/hbb_common/protos/message.proto | 1 + libs/hbb_common/src/fs.rs | 13 +++++++------ src/client/io_loop.rs | 2 ++ src/flutter.rs | 3 ++- src/lang/ca.rs | 1 + src/lang/cn.rs | 1 + src/lang/cs.rs | 1 + src/lang/da.rs | 1 + src/lang/de.rs | 1 + src/lang/el.rs | 1 + src/lang/eo.rs | 1 + src/lang/es.rs | 1 + src/lang/fa.rs | 1 + src/lang/fr.rs | 1 + src/lang/hu.rs | 1 + src/lang/id.rs | 1 + src/lang/it.rs | 1 + src/lang/ja.rs | 1 + src/lang/ko.rs | 1 + src/lang/kz.rs | 1 + src/lang/nl.rs | 1 + src/lang/pl.rs | 1 + src/lang/pt_PT.rs | 1 + src/lang/ptbr.rs | 1 + src/lang/ro.rs | 1 + src/lang/ru.rs | 1 + src/lang/sk.rs | 1 + src/lang/sl.rs | 1 + src/lang/sq.rs | 1 + src/lang/sr.rs | 1 + src/lang/sv.rs | 1 + src/lang/template.rs | 1 + src/lang/th.rs | 1 + src/lang/tr.rs | 1 + src/lang/tw.rs | 1 + src/lang/ua.rs | 1 + src/lang/vn.rs | 1 + src/ui/file_transfer.tis | 6 ++++-- src/ui/remote.rs | 4 ++-- src/ui_session_interface.rs | 2 +- 41 files changed, 71 insertions(+), 18 deletions(-) diff --git a/flutter/lib/models/file_model.dart b/flutter/lib/models/file_model.dart index 6be69aa85..c77afcbb4 100644 --- a/flutter/lib/models/file_model.dart +++ b/flutter/lib/models/file_model.dart @@ -104,10 +104,11 @@ class FileModel { // 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, // and we should distinguish them. - final resp = overrideConfirm ?? (!skip - ? await showFileConfirmDialog( - translate("Overwrite"), "${evt['read_path']}", true) - : null); + final resp = overrideConfirm ?? + (!skip + ? await showFileConfirmDialog(translate("Overwrite"), + "${evt['read_path']}", true, evt['is_identical'] == "true") + : null); final id = int.tryParse(evt['id']) ?? 0; if (false == resp) { final jobIndex = jobController.getJob(id); @@ -147,7 +148,7 @@ class FileModel { bool fileConfirmCheckboxRemember = false; Future showFileConfirmDialog( - String title, String content, bool showCheckbox) async { + String title, String content, bool showCheckbox, bool isIdentical) async { fileConfirmCheckboxRemember = false; return await parent.target?.dialogManager.show( (setState, Function(bool? v) close) { @@ -172,6 +173,17 @@ class FileModel { style: const TextStyle(fontWeight: FontWeight.bold)), const SizedBox(height: 5), 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 ? CheckboxListTile( contentPadding: const EdgeInsets.all(0), @@ -1242,7 +1254,8 @@ class FileDialogEventLoop var event = evt as _FileDialogEvent; event.setOverrideConfirm(_overrideConfirm); event.setSkip(_skip); - debugPrint("FileDialogEventLoop: consuming"); + debugPrint( + "FileDialogEventLoop: consuming"); } @override diff --git a/libs/hbb_common/protos/message.proto b/libs/hbb_common/protos/message.proto index be3a1e51e..0c29a5f19 100644 --- a/libs/hbb_common/protos/message.proto +++ b/libs/hbb_common/protos/message.proto @@ -301,6 +301,7 @@ message FileTransferDigest { uint64 last_modified = 3; uint64 file_size = 4; bool is_upload = 5; + bool is_identical = 6; } message FileTransferBlock { diff --git a/libs/hbb_common/src/fs.rs b/libs/hbb_common/src/fs.rs index 8ebfffc0a..41160f49d 100644 --- a/libs/hbb_common/src/fs.rs +++ b/libs/hbb_common/src/fs.rs @@ -821,20 +821,21 @@ pub fn is_write_need_confirmation( if path.exists() && path.is_file() { let metadata = std::fs::metadata(path)?; 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)?; // [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. - // - // if remote_mt == local_mt && digest.file_size == metadata.len() { - // return Ok(DigestCheckResult::IsSame); - // } + let mut is_identical = false; + if remote_mt == local_mt && digest.file_size == metadata.len() { + is_identical = true; + } Ok(DigestCheckResult::NeedConfirm(FileTransferDigest { id: digest.id, file_num: digest.file_num, last_modified: local_mt.as_secs(), file_size: metadata.len(), + is_identical, ..Default::default() })) } else { diff --git a/src/client/io_loop.rs b/src/client/io_loop.rs index 1c7788193..c37f235c0 100644 --- a/src/client/io_loop.rs +++ b/src/client/io_loop.rs @@ -954,6 +954,7 @@ impl Remote { digest.file_num, read_path, true, + digest.is_identical ); } } @@ -997,6 +998,7 @@ impl Remote { digest.file_num, write_path, false, + digest.is_identical ); } } diff --git a/src/flutter.rs b/src/flutter.rs index 354e418eb..2262df660 100644 --- a/src/flutter.rs +++ b/src/flutter.rs @@ -420,7 +420,7 @@ impl InvokeUiSession for FlutterHandler { // unused in flutter // TEST flutter 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( "override_file_confirm", vec![ @@ -428,6 +428,7 @@ impl InvokeUiSession for FlutterHandler { ("file_num", &file_num.to_string()), ("read_path", &to), ("is_upload", &is_upload.to_string()), + ("is_identical", &is_identical.to_string()) ], ); } diff --git a/src/lang/ca.rs b/src/lang/ca.rs index 93d9c76fe..72d52ffd2 100644 --- a/src/lang/ca.rs +++ b/src/lang/ca.rs @@ -477,5 +477,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Empty Username", ""), ("Empty Password", ""), ("Me", ""), + ("This file is identical with the peer's one", "") ].iter().cloned().collect(); } diff --git a/src/lang/cn.rs b/src/lang/cn.rs index bdc2257b3..8807d5454 100644 --- a/src/lang/cn.rs +++ b/src/lang/cn.rs @@ -477,5 +477,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Empty Username", ""), ("Empty Password", ""), ("Me", ""), + ("This file is identical with the peer's one", "此文件与对方的一致") ].iter().cloned().collect(); } diff --git a/src/lang/cs.rs b/src/lang/cs.rs index 651043850..ae7df823d 100644 --- a/src/lang/cs.rs +++ b/src/lang/cs.rs @@ -477,5 +477,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Empty Username", ""), ("Empty Password", ""), ("Me", ""), + ("This file is identical with the peer's one", "") ].iter().cloned().collect(); } diff --git a/src/lang/da.rs b/src/lang/da.rs index 31ca52c11..ebd55d44f 100644 --- a/src/lang/da.rs +++ b/src/lang/da.rs @@ -477,5 +477,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Empty Username", "Tom brugernavn"), ("Empty Password", "Tom adgangskode"), ("Me", "Mig"), + ("This file is identical with the peer's one", "") ].iter().cloned().collect(); } diff --git a/src/lang/de.rs b/src/lang/de.rs index 09fad80eb..26235b2af 100644 --- a/src/lang/de.rs +++ b/src/lang/de.rs @@ -477,5 +477,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Empty Username", "Leerer Benutzername"), ("Empty Password", "Leeres Passwort"), ("Me", "Ich"), + ("This file is identical with the peer's one", "") ].iter().cloned().collect(); } diff --git a/src/lang/el.rs b/src/lang/el.rs index 923d4b64e..bec769f22 100644 --- a/src/lang/el.rs +++ b/src/lang/el.rs @@ -477,5 +477,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Empty Username", "Κενό όνομα χρήστη"), ("Empty Password", "Κενός κωδικός πρόσβασης"), ("Me", ""), + ("This file is identical with the peer's one", "") ].iter().cloned().collect(); } diff --git a/src/lang/eo.rs b/src/lang/eo.rs index 57a519338..9dd2e50b4 100644 --- a/src/lang/eo.rs +++ b/src/lang/eo.rs @@ -477,5 +477,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Empty Username", ""), ("Empty Password", ""), ("Me", ""), + ("This file is identical with the peer's one", "") ].iter().cloned().collect(); } diff --git a/src/lang/es.rs b/src/lang/es.rs index d15061286..8cf50154e 100644 --- a/src/lang/es.rs +++ b/src/lang/es.rs @@ -477,5 +477,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Empty Username", "Nombre de usuario vacío"), ("Empty Password", "Contraseña vacía"), ("Me", "Yo"), + ("This file is identical with the peer's one", "") ].iter().cloned().collect(); } diff --git a/src/lang/fa.rs b/src/lang/fa.rs index be9821083..2c820ea21 100644 --- a/src/lang/fa.rs +++ b/src/lang/fa.rs @@ -477,5 +477,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Empty Username", ""), ("Empty Password", ""), ("Me", ""), + ("This file is identical with the peer's one", "") ].iter().cloned().collect(); } diff --git a/src/lang/fr.rs b/src/lang/fr.rs index 5798253ad..4617335de 100644 --- a/src/lang/fr.rs +++ b/src/lang/fr.rs @@ -477,5 +477,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Empty Username", ""), ("Empty Password", ""), ("Me", ""), + ("This file is identical with the peer's one", "") ].iter().cloned().collect(); } diff --git a/src/lang/hu.rs b/src/lang/hu.rs index 672c65bbb..36080f5be 100644 --- a/src/lang/hu.rs +++ b/src/lang/hu.rs @@ -477,5 +477,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Empty Username", ""), ("Empty Password", ""), ("Me", ""), + ("This file is identical with the peer's one", "") ].iter().cloned().collect(); } diff --git a/src/lang/id.rs b/src/lang/id.rs index a6272dbd3..08f54500f 100644 --- a/src/lang/id.rs +++ b/src/lang/id.rs @@ -477,5 +477,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Empty Username", ""), ("Empty Password", ""), ("Me", ""), + ("This file is identical with the peer's one", "") ].iter().cloned().collect(); } diff --git a/src/lang/it.rs b/src/lang/it.rs index 2333e23dd..3ff073c9c 100644 --- a/src/lang/it.rs +++ b/src/lang/it.rs @@ -477,5 +477,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Empty Username", "Nome Utente Vuoto"), ("Empty Password", "Password Vuota"), ("Me", "Io"), + ("This file is identical with the peer's one", "") ].iter().cloned().collect(); } diff --git a/src/lang/ja.rs b/src/lang/ja.rs index 5b1bcec4c..bf15afb47 100644 --- a/src/lang/ja.rs +++ b/src/lang/ja.rs @@ -477,5 +477,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Empty Username", ""), ("Empty Password", ""), ("Me", ""), + ("This file is identical with the peer's one", "") ].iter().cloned().collect(); } diff --git a/src/lang/ko.rs b/src/lang/ko.rs index 3b31b631b..0d4ea8e00 100644 --- a/src/lang/ko.rs +++ b/src/lang/ko.rs @@ -477,5 +477,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Empty Username", ""), ("Empty Password", ""), ("Me", ""), + ("This file is identical with the peer's one", "") ].iter().cloned().collect(); } diff --git a/src/lang/kz.rs b/src/lang/kz.rs index ccce435fc..0b0416f50 100644 --- a/src/lang/kz.rs +++ b/src/lang/kz.rs @@ -477,5 +477,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Empty Username", ""), ("Empty Password", ""), ("Me", ""), + ("This file is identical with the peer's one", "") ].iter().cloned().collect(); } diff --git a/src/lang/nl.rs b/src/lang/nl.rs index 9574581e5..4aef1587d 100644 --- a/src/lang/nl.rs +++ b/src/lang/nl.rs @@ -477,5 +477,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Empty Username", "Gebruikersnaam Leeg"), ("Empty Password", "Wachtwoord Leeg"), ("Me", ""), + ("This file is identical with the peer's one", "") ].iter().cloned().collect(); } diff --git a/src/lang/pl.rs b/src/lang/pl.rs index 5534bbe1b..cb96687cc 100644 --- a/src/lang/pl.rs +++ b/src/lang/pl.rs @@ -477,5 +477,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Empty Username", ""), ("Empty Password", ""), ("Me", ""), + ("This file is identical with the peer's one", "") ].iter().cloned().collect(); } diff --git a/src/lang/pt_PT.rs b/src/lang/pt_PT.rs index 780bc46c6..ad430635d 100644 --- a/src/lang/pt_PT.rs +++ b/src/lang/pt_PT.rs @@ -477,5 +477,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Empty Username", ""), ("Empty Password", ""), ("Me", ""), + ("This file is identical with the peer's one", "") ].iter().cloned().collect(); } diff --git a/src/lang/ptbr.rs b/src/lang/ptbr.rs index 5cfc2e5a3..83b84e6d9 100644 --- a/src/lang/ptbr.rs +++ b/src/lang/ptbr.rs @@ -477,5 +477,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Empty Username", ""), ("Empty Password", ""), ("Me", ""), + ("This file is identical with the peer's one", "") ].iter().cloned().collect(); } diff --git a/src/lang/ro.rs b/src/lang/ro.rs index c354c4685..804ee83ee 100644 --- a/src/lang/ro.rs +++ b/src/lang/ro.rs @@ -477,5 +477,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Empty Username", ""), ("Empty Password", ""), ("Me", ""), + ("This file is identical with the peer's one", "") ].iter().cloned().collect(); } diff --git a/src/lang/ru.rs b/src/lang/ru.rs index 3abea8029..8f7b66f71 100644 --- a/src/lang/ru.rs +++ b/src/lang/ru.rs @@ -477,5 +477,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Empty Username", ""), ("Empty Password", ""), ("Me", ""), + ("This file is identical with the peer's one", "") ].iter().cloned().collect(); } diff --git a/src/lang/sk.rs b/src/lang/sk.rs index 820b7a7db..8b3f29ac1 100644 --- a/src/lang/sk.rs +++ b/src/lang/sk.rs @@ -477,5 +477,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Empty Username", ""), ("Empty Password", ""), ("Me", ""), + ("This file is identical with the peer's one", "") ].iter().cloned().collect(); } diff --git a/src/lang/sl.rs b/src/lang/sl.rs index e81124d5c..5f3bdf93f 100755 --- a/src/lang/sl.rs +++ b/src/lang/sl.rs @@ -477,5 +477,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Empty Username", ""), ("Empty Password", ""), ("Me", ""), + ("This file is identical with the peer's one", "") ].iter().cloned().collect(); } diff --git a/src/lang/sq.rs b/src/lang/sq.rs index d237b8895..f5d24d604 100644 --- a/src/lang/sq.rs +++ b/src/lang/sq.rs @@ -477,5 +477,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Empty Username", ""), ("Empty Password", ""), ("Me", ""), + ("This file is identical with the peer's one", "") ].iter().cloned().collect(); } diff --git a/src/lang/sr.rs b/src/lang/sr.rs index 8e7ecf824..1d510b107 100644 --- a/src/lang/sr.rs +++ b/src/lang/sr.rs @@ -477,5 +477,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Empty Username", ""), ("Empty Password", ""), ("Me", ""), + ("This file is identical with the peer's one", "") ].iter().cloned().collect(); } diff --git a/src/lang/sv.rs b/src/lang/sv.rs index e0807d892..7345edb9c 100644 --- a/src/lang/sv.rs +++ b/src/lang/sv.rs @@ -477,5 +477,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Empty Username", ""), ("Empty Password", ""), ("Me", ""), + ("This file is identical with the peer's one", "") ].iter().cloned().collect(); } diff --git a/src/lang/template.rs b/src/lang/template.rs index 085ed025d..fb3a341d9 100644 --- a/src/lang/template.rs +++ b/src/lang/template.rs @@ -477,5 +477,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Empty Username", ""), ("Empty Password", ""), ("Me", ""), + ("This file is identical with the peer's one", "") ].iter().cloned().collect(); } diff --git a/src/lang/th.rs b/src/lang/th.rs index 6b3e34e48..3e50acf66 100644 --- a/src/lang/th.rs +++ b/src/lang/th.rs @@ -477,5 +477,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Empty Username", ""), ("Empty Password", ""), ("Me", ""), + ("This file is identical with the peer's one", "") ].iter().cloned().collect(); } diff --git a/src/lang/tr.rs b/src/lang/tr.rs index c92044e39..19006c7d1 100644 --- a/src/lang/tr.rs +++ b/src/lang/tr.rs @@ -477,5 +477,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Empty Username", ""), ("Empty Password", ""), ("Me", ""), + ("This file is identical with the peer's one", "") ].iter().cloned().collect(); } diff --git a/src/lang/tw.rs b/src/lang/tw.rs index a16bf26b8..3269963db 100644 --- a/src/lang/tw.rs +++ b/src/lang/tw.rs @@ -477,5 +477,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Empty Username", ""), ("Empty Password", ""), ("Me", ""), + ("This file is identical with the peer's one", "") ].iter().cloned().collect(); } diff --git a/src/lang/ua.rs b/src/lang/ua.rs index 302dd9166..f4eb574f0 100644 --- a/src/lang/ua.rs +++ b/src/lang/ua.rs @@ -477,5 +477,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Empty Username", ""), ("Empty Password", ""), ("Me", ""), + ("This file is identical with the peer's one", "") ].iter().cloned().collect(); } diff --git a/src/lang/vn.rs b/src/lang/vn.rs index e72be8ea5..9bdcb743e 100644 --- a/src/lang/vn.rs +++ b/src/lang/vn.rs @@ -477,5 +477,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Empty Username", ""), ("Empty Password", ""), ("Me", ""), + ("This file is identical with the peer's one", "") ].iter().cloned().collect(); } diff --git a/src/ui/file_transfer.tis b/src/ui/file_transfer.tis index f69f6d323..21c0562a1 100644 --- a/src/ui/file_transfer.tis +++ b/src/ui/file_transfer.tis @@ -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 identical_msg = is_identical ? translate("This file is identical with the peer's one"): ""; msgbox("custom-skip", "Confirm Write Strategy", "
\ -
" + translate('Overwrite') + translate('files') + ".
\ +
" + translate('Overwrite') + " " + translate('files') + ".
\
" + translate('This file exists, skip or overwrite this file?') + "
\ " + to + "
\ +
" + identical_msg + "
\
" + translate('Do this for all conflicts') + "
\ ", "", function(res=null) { if (!res) { diff --git a/src/ui/remote.rs b/src/ui/remote.rs index ed16f1e0e..68decf955 100644 --- a/src/ui/remote.rs +++ b/src/ui/remote.rs @@ -197,10 +197,10 @@ impl InvokeUiSession for SciterHandler { 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( "overrideFileConfirm", - &make_args!(id, file_num, to, is_upload), + &make_args!(id, file_num, to, is_upload, is_identical), ); } diff --git a/src/ui_session_interface.rs b/src/ui_session_interface.rs index 11bcff925..b90f5fbea 100644 --- a/src/ui_session_interface.rs +++ b/src/ui_session_interface.rs @@ -872,7 +872,7 @@ pub trait InvokeUiSession: Send + Sync + Clone + 'static + Sized + Default { only_count: bool, ); 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 job_progress(&self, id: i32, file_num: i32, speed: f64, finished_size: f64); fn adapt_size(&self); From 8044b0926b6b3e59422e1c42caa5f0e07354f718 Mon Sep 17 00:00:00 2001 From: Kingtous Date: Wed, 15 Mar 2023 17:26:33 +0800 Subject: [PATCH 6/6] opt: better short alias for the identical tip --- flutter/lib/models/file_model.dart | 2 +- src/lang/ca.rs | 2 +- src/lang/cn.rs | 2 +- src/lang/cs.rs | 2 +- src/lang/da.rs | 2 +- src/lang/de.rs | 2 +- src/lang/el.rs | 2 +- src/lang/en.rs | 1 + src/lang/eo.rs | 2 +- src/lang/es.rs | 2 +- src/lang/fa.rs | 2 +- src/lang/fr.rs | 2 +- src/lang/hu.rs | 2 +- src/lang/id.rs | 2 +- src/lang/it.rs | 2 +- src/lang/ja.rs | 2 +- src/lang/ko.rs | 2 +- src/lang/kz.rs | 2 +- src/lang/nl.rs | 2 +- src/lang/pl.rs | 2 +- src/lang/pt_PT.rs | 2 +- src/lang/ptbr.rs | 2 +- src/lang/ro.rs | 2 +- src/lang/ru.rs | 2 +- src/lang/sk.rs | 2 +- src/lang/sl.rs | 2 +- src/lang/sq.rs | 2 +- src/lang/sr.rs | 2 +- src/lang/sv.rs | 2 +- src/lang/template.rs | 2 +- src/lang/th.rs | 2 +- src/lang/tr.rs | 2 +- src/lang/tw.rs | 2 +- src/lang/ua.rs | 2 +- src/lang/vn.rs | 2 +- src/ui/file_transfer.tis | 2 +- 36 files changed, 36 insertions(+), 35 deletions(-) diff --git a/flutter/lib/models/file_model.dart b/flutter/lib/models/file_model.dart index c77afcbb4..10fab63d3 100644 --- a/flutter/lib/models/file_model.dart +++ b/flutter/lib/models/file_model.dart @@ -179,7 +179,7 @@ class FileModel { mainAxisSize: MainAxisSize.min, children: [ const SizedBox(height: 12), - Text(translate("This file is identical with the peer's one"), + Text(translate("identical_file_tip"), style: const TextStyle(fontWeight: FontWeight.w500)) ], ), diff --git a/src/lang/ca.rs b/src/lang/ca.rs index 72d52ffd2..34671474f 100644 --- a/src/lang/ca.rs +++ b/src/lang/ca.rs @@ -477,6 +477,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Empty Username", ""), ("Empty Password", ""), ("Me", ""), - ("This file is identical with the peer's one", "") + ("identical_file_tip", "") ].iter().cloned().collect(); } diff --git a/src/lang/cn.rs b/src/lang/cn.rs index 8807d5454..6778a8818 100644 --- a/src/lang/cn.rs +++ b/src/lang/cn.rs @@ -477,6 +477,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Empty Username", ""), ("Empty Password", ""), ("Me", ""), - ("This file is identical with the peer's one", "此文件与对方的一致") + ("identical_file_tip", "此文件与对方的一致") ].iter().cloned().collect(); } diff --git a/src/lang/cs.rs b/src/lang/cs.rs index ae7df823d..b60b927f0 100644 --- a/src/lang/cs.rs +++ b/src/lang/cs.rs @@ -477,6 +477,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Empty Username", ""), ("Empty Password", ""), ("Me", ""), - ("This file is identical with the peer's one", "") + ("identical_file_tip", "") ].iter().cloned().collect(); } diff --git a/src/lang/da.rs b/src/lang/da.rs index ebd55d44f..9b6ac2be5 100644 --- a/src/lang/da.rs +++ b/src/lang/da.rs @@ -477,6 +477,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Empty Username", "Tom brugernavn"), ("Empty Password", "Tom adgangskode"), ("Me", "Mig"), - ("This file is identical with the peer's one", "") + ("identical_file_tip", "") ].iter().cloned().collect(); } diff --git a/src/lang/de.rs b/src/lang/de.rs index 26235b2af..042756885 100644 --- a/src/lang/de.rs +++ b/src/lang/de.rs @@ -477,6 +477,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Empty Username", "Leerer Benutzername"), ("Empty Password", "Leeres Passwort"), ("Me", "Ich"), - ("This file is identical with the peer's one", "") + ("identical_file_tip", "") ].iter().cloned().collect(); } diff --git a/src/lang/el.rs b/src/lang/el.rs index bec769f22..771fa8797 100644 --- a/src/lang/el.rs +++ b/src/lang/el.rs @@ -477,6 +477,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Empty Username", "Κενό όνομα χρήστη"), ("Empty Password", "Κενός κωδικός πρόσβασης"), ("Me", ""), - ("This file is identical with the peer's one", "") + ("identical_file_tip", "") ].iter().cloned().collect(); } diff --git a/src/lang/en.rs b/src/lang/en.rs index b44ff2e40..c44c9c9f9 100644 --- a/src/lang/en.rs +++ b/src/lang/en.rs @@ -52,5 +52,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("empty_favorite_tip", "No favorite peers yet?\nLet's find someone to connect with and add it to your favorites!"), ("empty_lan_tip", "Oh no, it looks like we haven't discovered any peers yet."), ("empty_address_book_tip", "Oh dear, it appears that there are currently no peers listed in your address book."), + ("identical_file_tip", "This file is identical with the peer's one.") ].iter().cloned().collect(); } diff --git a/src/lang/eo.rs b/src/lang/eo.rs index 9dd2e50b4..3219e3b42 100644 --- a/src/lang/eo.rs +++ b/src/lang/eo.rs @@ -477,6 +477,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Empty Username", ""), ("Empty Password", ""), ("Me", ""), - ("This file is identical with the peer's one", "") + ("identical_file_tip", "") ].iter().cloned().collect(); } diff --git a/src/lang/es.rs b/src/lang/es.rs index 8cf50154e..58f331d01 100644 --- a/src/lang/es.rs +++ b/src/lang/es.rs @@ -477,6 +477,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Empty Username", "Nombre de usuario vacío"), ("Empty Password", "Contraseña vacía"), ("Me", "Yo"), - ("This file is identical with the peer's one", "") + ("identical_file_tip", "") ].iter().cloned().collect(); } diff --git a/src/lang/fa.rs b/src/lang/fa.rs index 2c820ea21..b57f0dbe9 100644 --- a/src/lang/fa.rs +++ b/src/lang/fa.rs @@ -477,6 +477,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Empty Username", ""), ("Empty Password", ""), ("Me", ""), - ("This file is identical with the peer's one", "") + ("identical_file_tip", "") ].iter().cloned().collect(); } diff --git a/src/lang/fr.rs b/src/lang/fr.rs index 4617335de..ed8089774 100644 --- a/src/lang/fr.rs +++ b/src/lang/fr.rs @@ -477,6 +477,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Empty Username", ""), ("Empty Password", ""), ("Me", ""), - ("This file is identical with the peer's one", "") + ("identical_file_tip", "") ].iter().cloned().collect(); } diff --git a/src/lang/hu.rs b/src/lang/hu.rs index 36080f5be..3b281a25f 100644 --- a/src/lang/hu.rs +++ b/src/lang/hu.rs @@ -477,6 +477,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Empty Username", ""), ("Empty Password", ""), ("Me", ""), - ("This file is identical with the peer's one", "") + ("identical_file_tip", "") ].iter().cloned().collect(); } diff --git a/src/lang/id.rs b/src/lang/id.rs index 08f54500f..7e6095715 100644 --- a/src/lang/id.rs +++ b/src/lang/id.rs @@ -477,6 +477,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Empty Username", ""), ("Empty Password", ""), ("Me", ""), - ("This file is identical with the peer's one", "") + ("identical_file_tip", "") ].iter().cloned().collect(); } diff --git a/src/lang/it.rs b/src/lang/it.rs index 3ff073c9c..f860dbc88 100644 --- a/src/lang/it.rs +++ b/src/lang/it.rs @@ -477,6 +477,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Empty Username", "Nome Utente Vuoto"), ("Empty Password", "Password Vuota"), ("Me", "Io"), - ("This file is identical with the peer's one", "") + ("identical_file_tip", "") ].iter().cloned().collect(); } diff --git a/src/lang/ja.rs b/src/lang/ja.rs index bf15afb47..366082cc4 100644 --- a/src/lang/ja.rs +++ b/src/lang/ja.rs @@ -477,6 +477,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Empty Username", ""), ("Empty Password", ""), ("Me", ""), - ("This file is identical with the peer's one", "") + ("identical_file_tip", "") ].iter().cloned().collect(); } diff --git a/src/lang/ko.rs b/src/lang/ko.rs index 0d4ea8e00..5244704bb 100644 --- a/src/lang/ko.rs +++ b/src/lang/ko.rs @@ -477,6 +477,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Empty Username", ""), ("Empty Password", ""), ("Me", ""), - ("This file is identical with the peer's one", "") + ("identical_file_tip", "") ].iter().cloned().collect(); } diff --git a/src/lang/kz.rs b/src/lang/kz.rs index 0b0416f50..120bcb81e 100644 --- a/src/lang/kz.rs +++ b/src/lang/kz.rs @@ -477,6 +477,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Empty Username", ""), ("Empty Password", ""), ("Me", ""), - ("This file is identical with the peer's one", "") + ("identical_file_tip", "") ].iter().cloned().collect(); } diff --git a/src/lang/nl.rs b/src/lang/nl.rs index 4aef1587d..dadc27705 100644 --- a/src/lang/nl.rs +++ b/src/lang/nl.rs @@ -477,6 +477,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Empty Username", "Gebruikersnaam Leeg"), ("Empty Password", "Wachtwoord Leeg"), ("Me", ""), - ("This file is identical with the peer's one", "") + ("identical_file_tip", "") ].iter().cloned().collect(); } diff --git a/src/lang/pl.rs b/src/lang/pl.rs index cb96687cc..c75b392da 100644 --- a/src/lang/pl.rs +++ b/src/lang/pl.rs @@ -477,6 +477,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Empty Username", ""), ("Empty Password", ""), ("Me", ""), - ("This file is identical with the peer's one", "") + ("identical_file_tip", "") ].iter().cloned().collect(); } diff --git a/src/lang/pt_PT.rs b/src/lang/pt_PT.rs index ad430635d..0ed7642f3 100644 --- a/src/lang/pt_PT.rs +++ b/src/lang/pt_PT.rs @@ -477,6 +477,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Empty Username", ""), ("Empty Password", ""), ("Me", ""), - ("This file is identical with the peer's one", "") + ("identical_file_tip", "") ].iter().cloned().collect(); } diff --git a/src/lang/ptbr.rs b/src/lang/ptbr.rs index 83b84e6d9..66dbcd6b7 100644 --- a/src/lang/ptbr.rs +++ b/src/lang/ptbr.rs @@ -477,6 +477,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Empty Username", ""), ("Empty Password", ""), ("Me", ""), - ("This file is identical with the peer's one", "") + ("identical_file_tip", "") ].iter().cloned().collect(); } diff --git a/src/lang/ro.rs b/src/lang/ro.rs index 804ee83ee..3efbcc281 100644 --- a/src/lang/ro.rs +++ b/src/lang/ro.rs @@ -477,6 +477,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Empty Username", ""), ("Empty Password", ""), ("Me", ""), - ("This file is identical with the peer's one", "") + ("identical_file_tip", "") ].iter().cloned().collect(); } diff --git a/src/lang/ru.rs b/src/lang/ru.rs index 8f7b66f71..91ef210c8 100644 --- a/src/lang/ru.rs +++ b/src/lang/ru.rs @@ -477,6 +477,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Empty Username", ""), ("Empty Password", ""), ("Me", ""), - ("This file is identical with the peer's one", "") + ("identical_file_tip", "") ].iter().cloned().collect(); } diff --git a/src/lang/sk.rs b/src/lang/sk.rs index 8b3f29ac1..0b891ff03 100644 --- a/src/lang/sk.rs +++ b/src/lang/sk.rs @@ -477,6 +477,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Empty Username", ""), ("Empty Password", ""), ("Me", ""), - ("This file is identical with the peer's one", "") + ("identical_file_tip", "") ].iter().cloned().collect(); } diff --git a/src/lang/sl.rs b/src/lang/sl.rs index 5f3bdf93f..29fb6be3c 100755 --- a/src/lang/sl.rs +++ b/src/lang/sl.rs @@ -477,6 +477,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Empty Username", ""), ("Empty Password", ""), ("Me", ""), - ("This file is identical with the peer's one", "") + ("identical_file_tip", "") ].iter().cloned().collect(); } diff --git a/src/lang/sq.rs b/src/lang/sq.rs index f5d24d604..3a923d742 100644 --- a/src/lang/sq.rs +++ b/src/lang/sq.rs @@ -477,6 +477,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Empty Username", ""), ("Empty Password", ""), ("Me", ""), - ("This file is identical with the peer's one", "") + ("identical_file_tip", "") ].iter().cloned().collect(); } diff --git a/src/lang/sr.rs b/src/lang/sr.rs index 1d510b107..cf077ac58 100644 --- a/src/lang/sr.rs +++ b/src/lang/sr.rs @@ -477,6 +477,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Empty Username", ""), ("Empty Password", ""), ("Me", ""), - ("This file is identical with the peer's one", "") + ("identical_file_tip", "") ].iter().cloned().collect(); } diff --git a/src/lang/sv.rs b/src/lang/sv.rs index 7345edb9c..66f140e99 100644 --- a/src/lang/sv.rs +++ b/src/lang/sv.rs @@ -477,6 +477,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Empty Username", ""), ("Empty Password", ""), ("Me", ""), - ("This file is identical with the peer's one", "") + ("identical_file_tip", "") ].iter().cloned().collect(); } diff --git a/src/lang/template.rs b/src/lang/template.rs index fb3a341d9..9f4ad1835 100644 --- a/src/lang/template.rs +++ b/src/lang/template.rs @@ -477,6 +477,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Empty Username", ""), ("Empty Password", ""), ("Me", ""), - ("This file is identical with the peer's one", "") + ("identical_file_tip", "") ].iter().cloned().collect(); } diff --git a/src/lang/th.rs b/src/lang/th.rs index 3e50acf66..1ada40612 100644 --- a/src/lang/th.rs +++ b/src/lang/th.rs @@ -477,6 +477,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Empty Username", ""), ("Empty Password", ""), ("Me", ""), - ("This file is identical with the peer's one", "") + ("identical_file_tip", "") ].iter().cloned().collect(); } diff --git a/src/lang/tr.rs b/src/lang/tr.rs index 19006c7d1..9215464ea 100644 --- a/src/lang/tr.rs +++ b/src/lang/tr.rs @@ -477,6 +477,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Empty Username", ""), ("Empty Password", ""), ("Me", ""), - ("This file is identical with the peer's one", "") + ("identical_file_tip", "") ].iter().cloned().collect(); } diff --git a/src/lang/tw.rs b/src/lang/tw.rs index 3269963db..b18488b26 100644 --- a/src/lang/tw.rs +++ b/src/lang/tw.rs @@ -477,6 +477,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Empty Username", ""), ("Empty Password", ""), ("Me", ""), - ("This file is identical with the peer's one", "") + ("identical_file_tip", "") ].iter().cloned().collect(); } diff --git a/src/lang/ua.rs b/src/lang/ua.rs index f4eb574f0..f5c0c22f7 100644 --- a/src/lang/ua.rs +++ b/src/lang/ua.rs @@ -477,6 +477,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Empty Username", ""), ("Empty Password", ""), ("Me", ""), - ("This file is identical with the peer's one", "") + ("identical_file_tip", "") ].iter().cloned().collect(); } diff --git a/src/lang/vn.rs b/src/lang/vn.rs index 9bdcb743e..e8bc76c8e 100644 --- a/src/lang/vn.rs +++ b/src/lang/vn.rs @@ -477,6 +477,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Empty Username", ""), ("Empty Password", ""), ("Me", ""), - ("This file is identical with the peer's one", "") + ("identical_file_tip", "") ].iter().cloned().collect(); } diff --git a/src/ui/file_transfer.tis b/src/ui/file_transfer.tis index 21c0562a1..6c741b31f 100644 --- a/src/ui/file_transfer.tis +++ b/src/ui/file_transfer.tis @@ -780,7 +780,7 @@ handler.confirmDeleteFiles = function(id, i, name) { handler.overrideFileConfirm = function(id, file_num, to, is_upload, is_identical) { var jt = file_transfer.job_table; - var identical_msg = is_identical ? translate("This file is identical with the peer's one"): ""; + var identical_msg = is_identical ? translate("identical_file_tip"): ""; msgbox("custom-skip", "Confirm Write Strategy", "
\
" + translate('Overwrite') + " " + translate('files') + ".
\
" + translate('This file exists, skip or overwrite this file?') + "
\