diff --git a/flutter/lib/common.dart b/flutter/lib/common.dart index 05e53164e..d4982c9dd 100644 --- a/flutter/lib/common.dart +++ b/flutter/lib/common.dart @@ -13,6 +13,7 @@ import 'package:flutter_hbb/desktop/widgets/refresh_wrapper.dart'; import 'package:flutter_hbb/desktop/widgets/tabbar_widget.dart'; import 'package:flutter_hbb/main.dart'; import 'package:flutter_hbb/models/peer_model.dart'; +import 'package:flutter_hbb/models/peer_tab_model.dart'; import 'package:flutter_hbb/models/state_model.dart'; import 'package:flutter_hbb/utils/multi_window_manager.dart'; import 'package:flutter_hbb/utils/platform_channel.dart'; @@ -1630,7 +1631,8 @@ bool mainGetPeerBoolOptionSync(String id, String key) { // Use `sessionGetToggleOption()` and `sessionToggleOption()` instead. // Because all session options use `Y` and `` as values. -Future matchPeer(String searchText, Peer peer) async { +Future matchPeer( + String searchText, Peer peer, PeerTabIndex peerTabIndex) async { if (searchText.isEmpty) { return true; } @@ -1641,11 +1643,14 @@ Future matchPeer(String searchText, Peer peer) async { peer.username.toLowerCase().contains(searchText)) { return true; } - final alias = peer.alias; - if (alias.isEmpty) { - return false; + if (peer.alias.toLowerCase().contains(searchText)) { + return true; } - return alias.toLowerCase().contains(searchText); + if (peerTabShowNote(peerTabIndex) && + peer.note.toLowerCase().contains(searchText)) { + return true; + } + return false; } /// Get the image for the current [platform]. @@ -4008,3 +4013,7 @@ String decode_http_response(http.Response resp) { return resp.body; } } + +bool peerTabShowNote(PeerTabIndex peerTabIndex) { + return peerTabIndex == PeerTabIndex.ab || peerTabIndex == PeerTabIndex.group; +} diff --git a/flutter/lib/common/hbbs/hbbs.dart b/flutter/lib/common/hbbs/hbbs.dart index 4fa985427..aab8ba597 100644 --- a/flutter/lib/common/hbbs/hbbs.dart +++ b/flutter/lib/common/hbbs/hbbs.dart @@ -89,6 +89,7 @@ class PeerPayload { "platform": _platform(p.info['os']), "hostname": p.info['device_name'], "device_group_name": p.device_group_name, + "note": p.note, }); } diff --git a/flutter/lib/common/widgets/address_book.dart b/flutter/lib/common/widgets/address_book.dart index 6a3cec8ad..1a09d6f53 100644 --- a/flutter/lib/common/widgets/address_book.dart +++ b/flutter/lib/common/widgets/address_book.dart @@ -466,6 +466,7 @@ class _AddressBookState extends State { IDTextEditingController idController = IDTextEditingController(text: ''); TextEditingController aliasController = TextEditingController(text: ''); TextEditingController passwordController = TextEditingController(text: ''); + TextEditingController noteController = TextEditingController(text: ''); final tags = List.of(gFFI.abModel.currentAbTags); var selectedTag = List.empty(growable: true).obs; final style = TextStyle(fontSize: 14.0); @@ -494,7 +495,11 @@ class _AddressBookState extends State { password = passwordController.text; } String? errMsg2 = await gFFI.abModel.addIdToCurrent( - id, aliasController.text.trim(), password, selectedTag); + id, + aliasController.text.trim(), + password, + selectedTag, + noteController.text); if (errMsg2 != null) { setState(() { isInProgress = false; @@ -600,6 +605,24 @@ class _AddressBookState extends State { ), ).workaroundFreezeLinuxMint(), )), + row( + label: Text( + translate('Note'), + style: style, + ), + input: Obx( + () => TextField( + controller: noteController, + maxLines: 3, + minLines: 1, + maxLength: 300, + decoration: InputDecoration( + labelText: stateGlobal.isPortrait.isFalse + ? null + : translate('Note'), + ), + ).workaroundFreezeLinuxMint(), + )), if (gFFI.abModel.currentAbTags.isNotEmpty) Align( alignment: Alignment.centerLeft, diff --git a/flutter/lib/common/widgets/dialog.dart b/flutter/lib/common/widgets/dialog.dart index fe0b799ac..b8aed9791 100644 --- a/flutter/lib/common/widgets/dialog.dart +++ b/flutter/lib/common/widgets/dialog.dart @@ -1783,6 +1783,49 @@ void editAbTagDialog( }); } +void editAbPeerNoteDialog(String id) { + var isInProgress = false; + final currentNote = gFFI.abModel.getPeerNote(id); + var controller = TextEditingController(text: currentNote); + + gFFI.dialogManager.show((setState, close, context) { + submit() async { + setState(() { + isInProgress = true; + }); + await gFFI.abModel.changeNote(id: id, note: controller.text); + close(); + } + + return CustomAlertDialog( + title: Text(translate("Edit note")), + content: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + TextField( + controller: controller, + autofocus: true, + maxLines: 3, + minLines: 1, + maxLength: 300, + decoration: InputDecoration( + labelText: translate('Note'), + ), + ).workaroundFreezeLinuxMint(), + // NOT use Offstage to wrap LinearProgressIndicator + if (isInProgress) const LinearProgressIndicator(), + ], + ), + actions: [ + dialogButton("Cancel", onPressed: close, isOutline: true), + dialogButton("OK", onPressed: submit), + ], + onSubmit: submit, + onCancel: close, + ); + }); +} + void renameDialog( {required String oldName, FormFieldValidator? validator, diff --git a/flutter/lib/common/widgets/peer_card.dart b/flutter/lib/common/widgets/peer_card.dart index 5cc8dc862..1f9f3ed7f 100644 --- a/flutter/lib/common/widgets/peer_card.dart +++ b/flutter/lib/common/widgets/peer_card.dart @@ -127,6 +127,10 @@ class _PeerCardState extends State<_PeerCard> ); } + bool _showNote(Peer peer) { + return peerTabShowNote(widget.tab) && peer.note.isNotEmpty; + } + makeChild(bool isPortrait, Peer peer) { final name = hideUsernameOnCard == true ? peer.hostname @@ -134,6 +138,8 @@ class _PeerCardState extends State<_PeerCard> final greyStyle = TextStyle( fontSize: 11, color: Theme.of(context).textTheme.titleLarge?.color?.withOpacity(0.6)); + final showNote = _showNote(peer); + return Row( mainAxisSize: MainAxisSize.max, children: [ @@ -185,14 +191,44 @@ class _PeerCardState extends State<_PeerCard> style: Theme.of(context).textTheme.titleSmall, )), ]).marginOnly(top: isPortrait ? 0 : 2), - Align( - alignment: Alignment.centerLeft, - child: Text( - name, - style: isPortrait ? null : greyStyle, - textAlign: TextAlign.start, - overflow: TextOverflow.ellipsis, - ), + Row( + children: [ + Flexible( + child: Tooltip( + message: name, + waitDuration: const Duration(seconds: 1), + child: Align( + alignment: Alignment.centerLeft, + child: Text( + name, + style: isPortrait ? null : greyStyle, + textAlign: TextAlign.start, + overflow: TextOverflow.ellipsis, + ), + ), + ), + ), + if (showNote) + Expanded( + child: Tooltip( + message: peer.note, + waitDuration: const Duration(seconds: 1), + child: Align( + alignment: Alignment.centerLeft, + child: Text( + peer.note, + style: isPortrait ? null : greyStyle, + textAlign: TextAlign.start, + overflow: TextOverflow.ellipsis, + ).marginOnly( + left: peerCardUiType.value == + PeerUiType.list + ? 32 + : 4), + ), + ), + ) + ], ), ], ).marginOnly(top: 2), @@ -278,7 +314,7 @@ class _PeerCardState extends State<_PeerCard> padding: const EdgeInsets.all(6), child: getPlatformImage(peer.platform, size: 60), - ).marginOnly(top: 4), + ), Row( children: [ Expanded( @@ -297,8 +333,26 @@ class _PeerCardState extends State<_PeerCard> ), ], ), + if (_showNote(peer)) + Row( + children: [ + Expanded( + child: Tooltip( + message: peer.note, + waitDuration: const Duration(seconds: 1), + child: Text( + peer.note, + style: const TextStyle( + color: Colors.white38, + fontSize: 10), + textAlign: TextAlign.center, + overflow: TextOverflow.ellipsis, + ), + )) + ], + ), ], - ).paddingAll(4.0), + ).paddingOnly(top: 4.0, left: 4.0, right: 4.0), ), ], ), @@ -1134,6 +1188,7 @@ class AddressBookPeerCard extends BasePeerCard { if (gFFI.abModel.currentAbTags.isNotEmpty) { menuItems.add(_editTagAction(peer.id)); } + menuItems.add(_editNoteAction(peer.id)); } final addressbooks = gFFI.abModel.addressBooksCanWrite(); if (gFFI.peerTabModel.currentTab == PeerTabIndex.ab.index) { @@ -1173,6 +1228,21 @@ class AddressBookPeerCard extends BasePeerCard { ); } + @protected + MenuEntryBase _editNoteAction(String id) { + return MenuEntryButton( + childBuilder: (TextStyle? style) => Text( + translate('Edit note'), + style: style, + ), + proc: () { + editAbPeerNoteDialog(id); + }, + padding: super.menuPadding, + dismissOnClicked: true, + ); + } + @protected @override Future _getAlias(String id) async => diff --git a/flutter/lib/common/widgets/peers_view.dart b/flutter/lib/common/widgets/peers_view.dart index 94f4af035..d81a095ca 100644 --- a/flutter/lib/common/widgets/peers_view.dart +++ b/flutter/lib/common/widgets/peers_view.dart @@ -71,10 +71,12 @@ class _PeersView extends StatefulWidget { final Peers peers; final PeerFilter? peerFilter; final PeerCardBuilder peerCardBuilder; + final PeerTabIndex peerTabIndex; const _PeersView( {required this.peers, required this.peerCardBuilder, + required this.peerTabIndex, this.peerFilter, Key? key}) : super(key: key); @@ -395,8 +397,8 @@ class _PeersViewState extends State<_PeersView> return peers; } searchText = searchText.toLowerCase(); - final matches = - await Future.wait(peers.map((peer) => matchPeer(searchText, peer))); + final matches = await Future.wait( + peers.map((peer) => matchPeer(searchText, peer, widget.peerTabIndex))); final filteredList = List.empty(growable: true); for (var i = 0; i < peers.length; i++) { if (matches[i]) { @@ -441,7 +443,10 @@ abstract class BasePeersView extends StatelessWidget { break; } return _PeersView( - peers: peers, peerFilter: peerFilter, peerCardBuilder: peerCardBuilder); + peers: peers, + peerFilter: peerFilter, + peerCardBuilder: peerCardBuilder, + peerTabIndex: peerTabIndex); } } diff --git a/flutter/lib/desktop/pages/connection_page.dart b/flutter/lib/desktop/pages/connection_page.dart index 6f672a759..bdf3829e1 100644 --- a/flutter/lib/desktop/pages/connection_page.dart +++ b/flutter/lib/desktop/pages/connection_page.dart @@ -374,6 +374,7 @@ class _ConnectionPageState extends State rdpUsername: '', loginName: '', device_group_name: '', + note: '', ); _autocompleteOpts = [emptyPeer]; } else { @@ -536,64 +537,68 @@ class _ConnectionPageState extends State builder: (context, setState) { var offset = Offset(0, 0); return Obx(() => InkWell( - child: _menuOpen.value - ? Transform.rotate( - angle: pi, - child: Icon(IconFont.more, size: 14), + child: _menuOpen.value + ? Transform.rotate( + angle: pi, + child: Icon(IconFont.more, size: 14), + ) + : Icon(IconFont.more, size: 14), + onTapDown: (e) { + offset = e.globalPosition; + }, + onTap: () async { + _menuOpen.value = true; + final x = offset.dx; + final y = offset.dy; + await mod_menu + .showMenu( + context: context, + position: RelativeRect.fromLTRB(x, y, x, y), + items: [ + ( + 'Transfer file', + () => onConnect(isFileTransfer: true) + ), + ( + 'View camera', + () => onConnect(isViewCamera: true) + ), + ( + '${translate('Terminal')} (beta)', + () => onConnect(isTerminal: true) + ), + ] + .map((e) => MenuEntryButton( + childBuilder: (TextStyle? style) => + Text( + translate(e.$1), + style: style, + ), + proc: () => e.$2(), + padding: EdgeInsets.symmetric( + horizontal: + kDesktopMenuPadding.left), + dismissOnClicked: true, + )) + .map((e) => e.build( + context, + const MenuConfig( + commonColor: CustomPopupMenuTheme + .commonColor, + height: + CustomPopupMenuTheme.height, + dividerHeight: + CustomPopupMenuTheme + .dividerHeight))) + .expand((i) => i) + .toList(), + elevation: 8, ) - : Icon(IconFont.more, size: 14), - onTapDown: (e) { - offset = e.globalPosition; - }, - onTap: () async { - _menuOpen.value = true; - final x = offset.dx; - final y = offset.dy; - await mod_menu - .showMenu( - context: context, - position: RelativeRect.fromLTRB(x, y, x, y), - items: [ - ( - 'Transfer file', - () => onConnect(isFileTransfer: true) - ), - ( - 'View camera', - () => onConnect(isViewCamera: true) - ), - ( - '${translate('Terminal')} (beta)', - () => onConnect(isTerminal: true) - ), - ] - .map((e) => MenuEntryButton( - childBuilder: (TextStyle? style) => Text( - translate(e.$1), - style: style, - ), - proc: () => e.$2(), - padding: EdgeInsets.symmetric( - horizontal: kDesktopMenuPadding.left), - dismissOnClicked: true, - )) - .map((e) => e.build( - context, - const MenuConfig( - commonColor: - CustomPopupMenuTheme.commonColor, - height: CustomPopupMenuTheme.height, - dividerHeight: CustomPopupMenuTheme - .dividerHeight))) - .expand((i) => i) - .toList(), - elevation: 8, - ) - .then((_) { - _menuOpen.value = false; - }); - }, - )); + .then((_) { + _menuOpen.value = false; + }); + }, + )); }, ), ), diff --git a/flutter/lib/mobile/pages/connection_page.dart b/flutter/lib/mobile/pages/connection_page.dart index 07aaaef8c..0e7e0a480 100644 --- a/flutter/lib/mobile/pages/connection_page.dart +++ b/flutter/lib/mobile/pages/connection_page.dart @@ -182,6 +182,7 @@ class _ConnectionPageState extends State { rdpUsername: '', loginName: '', device_group_name: '', + note: '', ); _autocompleteOpts = [emptyPeer]; } else { diff --git a/flutter/lib/models/ab_model.dart b/flutter/lib/models/ab_model.dart index 4eb200004..1a165ce11 100644 --- a/flutter/lib/models/ab_model.dart +++ b/flutter/lib/models/ab_model.dart @@ -319,8 +319,8 @@ class AbModel { // #endregion // #region peer - Future addIdToCurrent( - String id, String alias, String password, List tags) async { + Future addIdToCurrent(String id, String alias, String password, + List tags, String note) async { if (currentAbPeers.where((element) => element.id == id).isNotEmpty) { return "$id already exists in address book $_currentName"; } @@ -333,6 +333,9 @@ class AbModel { if (password.isNotEmpty) { peer['password'] = password; } + if (note.isNotEmpty) { + peer['note'] = note; + } final ret = await addPeersTo([peer], _currentName.value); _syncAllFromRecent = true; return ret; @@ -376,6 +379,14 @@ class AbModel { return res; } + Future changeNote({required String id, required String note}) async { + bool res = await current.changeNote(id: id, note: note); + await pullNonLegacyAfterChange(); + currentAbPeers.refresh(); + // no need to save cache + return res; + } + Future changePersonalHashPassword(String id, String hash) async { var ret = false; final personalAb = addressbooks[_personalAddressBookName]; @@ -658,6 +669,15 @@ class AbModel { } } + String getPeerNote(String id) { + final it = currentAbPeers.where((p0) => p0.id == id); + if (it.isEmpty) { + return ''; + } else { + return it.first.note; + } + } + Color getCurrentAbTagColor(String tag) { if (tag == kUntagged) { return MyTheme.accent; @@ -863,6 +883,8 @@ abstract class BaseAb { Future changeAlias({required String id, required String alias}); + Future changeNote({required String id, required String note}); + Future changePersonalHashPassword(String id, String hash); Future changeSharedPassword(String id, String password); @@ -1090,6 +1112,12 @@ class LegacyAb extends BaseAb { return await pushAb(); } + @override + Future changeNote({required String id, required String note}) async { + // no need to implement + return false; + } + @override Future changeSharedPassword(String id, String password) async { // no need to implement @@ -1549,6 +1577,27 @@ class Ab extends BaseAb { } } + @override + Future changeNote({required String id, required String note}) async { + try { + final api = + "${await bind.mainGetApiServer()}/api/ab/peer/update/${profile.guid}"; + var headers = getHttpHeaders(); + headers['Content-Type'] = "application/json"; + final body = jsonEncode({"id": id, "note": note}); + final resp = await http.put(Uri.parse(api), headers: headers, body: body); + final errMsg = _jsonDecodeActionResp(resp); + if (errMsg.isNotEmpty) { + BotToast.showText(contentColor: Colors.red, text: errMsg); + return false; + } + return true; + } catch (err) { + debugPrint('changeNote err: ${err.toString()}'); + return false; + } + } + Future _setPassword(Object bodyContent) async { try { final api = @@ -1815,6 +1864,11 @@ class DummyAb extends BaseAb { return false; } + @override + Future changeNote({required String id, required String note}) async { + return false; + } + @override Future changePersonalHashPassword(String id, String hash) async { return false; diff --git a/flutter/lib/models/peer_model.dart b/flutter/lib/models/peer_model.dart index 35236dd4c..59acdd591 100644 --- a/flutter/lib/models/peer_model.dart +++ b/flutter/lib/models/peer_model.dart @@ -20,6 +20,7 @@ class Peer { bool online = false; String loginName; //login username String device_group_name; + String note; bool? sameServer; String getId() { @@ -43,6 +44,7 @@ class Peer { rdpUsername = json['rdpUsername'] ?? '', loginName = json['loginName'] ?? '', device_group_name = json['device_group_name'] ?? '', + note = json['note'] is String ? json['note'] : '', sameServer = json['same_server']; Map toJson() { @@ -60,6 +62,7 @@ class Peer { "rdpUsername": rdpUsername, 'loginName': loginName, 'device_group_name': device_group_name, + 'note': note, 'same_server': sameServer, }; } @@ -104,6 +107,7 @@ class Peer { required this.rdpUsername, required this.loginName, required this.device_group_name, + required this.note, this.sameServer, }); @@ -122,6 +126,7 @@ class Peer { rdpUsername: '', loginName: '', device_group_name: '', + note: '', ); bool equal(Peer other) { return id == other.id && @@ -136,7 +141,8 @@ class Peer { rdpPort == other.rdpPort && rdpUsername == other.rdpUsername && device_group_name == other.device_group_name && - loginName == other.loginName; + loginName == other.loginName && + note == other.note; } Peer.copy(Peer other) @@ -154,6 +160,7 @@ class Peer { rdpUsername: other.rdpUsername, loginName: other.loginName, device_group_name: other.device_group_name, + note: other.note, sameServer: other.sameServer); } diff --git a/src/lang/ar.rs b/src/lang/ar.rs index cd241dce3..0d62bd10a 100644 --- a/src/lang/ar.rs +++ b/src/lang/ar.rs @@ -719,5 +719,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Small", "صغير"), ("Large", "كبير"), ("Show virtual joystick", "إظهار عصا التحكم الافتراضية"), + ("Edit note", ""), + ("Alias", ""), ].iter().cloned().collect(); } diff --git a/src/lang/be.rs b/src/lang/be.rs index e6a023388..39d1bb1a3 100644 --- a/src/lang/be.rs +++ b/src/lang/be.rs @@ -719,5 +719,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Small", ""), ("Large", ""), ("Show virtual joystick", ""), + ("Edit note", ""), + ("Alias", ""), ].iter().cloned().collect(); } diff --git a/src/lang/bg.rs b/src/lang/bg.rs index 9b35b8fb0..82b368f59 100644 --- a/src/lang/bg.rs +++ b/src/lang/bg.rs @@ -719,5 +719,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Small", ""), ("Large", ""), ("Show virtual joystick", ""), + ("Edit note", ""), + ("Alias", ""), ].iter().cloned().collect(); } diff --git a/src/lang/ca.rs b/src/lang/ca.rs index 78e070f07..df6e8518c 100644 --- a/src/lang/ca.rs +++ b/src/lang/ca.rs @@ -719,5 +719,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Small", ""), ("Large", ""), ("Show virtual joystick", ""), + ("Edit note", ""), + ("Alias", ""), ].iter().cloned().collect(); } diff --git a/src/lang/cn.rs b/src/lang/cn.rs index bcd8b9c71..471b72cca 100644 --- a/src/lang/cn.rs +++ b/src/lang/cn.rs @@ -719,5 +719,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Small", "小"), ("Large", "大"), ("Show virtual joystick", "显示虚拟摇杆"), + ("Edit note", "编辑备注"), + ("Alias", "别名"), ].iter().cloned().collect(); } diff --git a/src/lang/cs.rs b/src/lang/cs.rs index 7307c4a92..a80f74168 100644 --- a/src/lang/cs.rs +++ b/src/lang/cs.rs @@ -719,5 +719,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Small", ""), ("Large", ""), ("Show virtual joystick", ""), + ("Edit note", ""), + ("Alias", ""), ].iter().cloned().collect(); } diff --git a/src/lang/da.rs b/src/lang/da.rs index 0270ed4d9..6dbc0049d 100644 --- a/src/lang/da.rs +++ b/src/lang/da.rs @@ -719,5 +719,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Small", ""), ("Large", ""), ("Show virtual joystick", ""), + ("Edit note", ""), + ("Alias", ""), ].iter().cloned().collect(); } diff --git a/src/lang/de.rs b/src/lang/de.rs index 6bdb7f98e..e202356a2 100644 --- a/src/lang/de.rs +++ b/src/lang/de.rs @@ -719,5 +719,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Small", "Klein"), ("Large", "Groß"), ("Show virtual joystick", "Virtuellen Joystick anzeigen"), + ("Edit note", ""), + ("Alias", ""), ].iter().cloned().collect(); } diff --git a/src/lang/el.rs b/src/lang/el.rs index 6d60ff374..d0fcdd8e3 100644 --- a/src/lang/el.rs +++ b/src/lang/el.rs @@ -719,5 +719,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Small", ""), ("Large", ""), ("Show virtual joystick", ""), + ("Edit note", ""), + ("Alias", ""), ].iter().cloned().collect(); } diff --git a/src/lang/eo.rs b/src/lang/eo.rs index dbabe31a4..0670929aa 100644 --- a/src/lang/eo.rs +++ b/src/lang/eo.rs @@ -719,5 +719,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Small", ""), ("Large", ""), ("Show virtual joystick", ""), + ("Edit note", ""), + ("Alias", ""), ].iter().cloned().collect(); } diff --git a/src/lang/es.rs b/src/lang/es.rs index d1d90000c..639132194 100644 --- a/src/lang/es.rs +++ b/src/lang/es.rs @@ -708,18 +708,18 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Failed to check if the user is an administrator.", "No se ha podido comprobar si el usuario es un administrador."), ("Supported only in the installed version.", "Soportado solo en la versión instalada."), ("elevation_username_tip", "Introduzca el nombre de usuario o dominio\\NombreDeUsuario"), - ("Preparing for installation ...", "Preparando la instalación ..."), - ("Show my cursor", "Mostrar mi cursor"), + ("Preparing for installation ...", ""), + ("Show my cursor", ""), ("Scale custom", "Escala personalizada"), ("Custom scale slider", "Control deslizante de escala personalizada"), ("Decrease", "Disminuir"), ("Increase", "Aumentar"), - ("Preparing for installation ...", ""), - ("Show my cursor", ""), ("Show virtual mouse", ""), ("Virtual mouse size", ""), ("Small", ""), ("Large", ""), ("Show virtual joystick", ""), + ("Edit note", ""), + ("Alias", ""), ].iter().cloned().collect(); } diff --git a/src/lang/et.rs b/src/lang/et.rs index 034040142..bfc5530e6 100644 --- a/src/lang/et.rs +++ b/src/lang/et.rs @@ -719,5 +719,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Small", ""), ("Large", ""), ("Show virtual joystick", ""), + ("Edit note", ""), + ("Alias", ""), ].iter().cloned().collect(); } diff --git a/src/lang/eu.rs b/src/lang/eu.rs index 4071371da..36f658419 100644 --- a/src/lang/eu.rs +++ b/src/lang/eu.rs @@ -719,5 +719,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Small", ""), ("Large", ""), ("Show virtual joystick", ""), + ("Edit note", ""), + ("Alias", ""), ].iter().cloned().collect(); } diff --git a/src/lang/fa.rs b/src/lang/fa.rs index 5ec37dcca..e39901ae6 100644 --- a/src/lang/fa.rs +++ b/src/lang/fa.rs @@ -719,5 +719,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Small", "کوچک"), ("Large", "بزرگ"), ("Show virtual joystick", "نمایش جوی‌استیک مجازی"), + ("Edit note", ""), + ("Alias", ""), ].iter().cloned().collect(); } diff --git a/src/lang/fr.rs b/src/lang/fr.rs index d4f770852..01f0386e3 100644 --- a/src/lang/fr.rs +++ b/src/lang/fr.rs @@ -719,5 +719,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Small", "Petite"), ("Large", "Grande"), ("Show virtual joystick", "Afficher le joystick virtuel"), + ("Edit note", ""), + ("Alias", ""), ].iter().cloned().collect(); } diff --git a/src/lang/ge.rs b/src/lang/ge.rs index a76735c10..a6d6a7eea 100644 --- a/src/lang/ge.rs +++ b/src/lang/ge.rs @@ -719,5 +719,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Small", ""), ("Large", ""), ("Show virtual joystick", ""), + ("Edit note", ""), + ("Alias", ""), ].iter().cloned().collect(); } diff --git a/src/lang/he.rs b/src/lang/he.rs index 37ab0859a..643f78eb7 100644 --- a/src/lang/he.rs +++ b/src/lang/he.rs @@ -719,5 +719,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Small", ""), ("Large", ""), ("Show virtual joystick", ""), + ("Edit note", ""), + ("Alias", ""), ].iter().cloned().collect(); } diff --git a/src/lang/hr.rs b/src/lang/hr.rs index b75bc39ec..a80b579a4 100644 --- a/src/lang/hr.rs +++ b/src/lang/hr.rs @@ -719,5 +719,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Small", ""), ("Large", ""), ("Show virtual joystick", ""), + ("Edit note", ""), + ("Alias", ""), ].iter().cloned().collect(); } diff --git a/src/lang/hu.rs b/src/lang/hu.rs index 4291367ae..d4b7844d5 100644 --- a/src/lang/hu.rs +++ b/src/lang/hu.rs @@ -550,8 +550,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Open in new window", "Megnyitás új ablakban"), ("Show displays as individual windows", "Kijelzők megjelenítése egyedi ablakokként"), ("Use all my displays for the remote session", "Az összes kijelzőm használata a távoli munkamenethez"), - ("selinux_tip", "A SELinux engedélyezve van az eszközén, ami azt okozhatja, hogy a RustDesk nem fut megfelelően, mint ellenőrzött -."), + ("selinux_tip", "A SELinux engedélyezve van az eszközén, ami azt okozhatja, hogy a RustDesk nem fut megfelelően, mint ellenőrzött."), ("Change view", "Nézet módosítása"), ("Big tiles", "Nagy csempék"), ("Small tiles", "Kis csempék"), @@ -710,16 +709,17 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Supported only in the installed version.", "Csak a telepített változatban támogatott."), ("elevation_username_tip", "Felhasználónév vagy tartománynév megadása\\felhasználónév"), ("Preparing for installation ...", "Felkészülés a telepítésre ..."), - ("Show my cursor", "Kurzor megjelenítése"), + ("Show my cursor", ""), ("Scale custom", "Egyéni méretarány"), ("Custom scale slider", "Egyéni méretarány-csúszka"), ("Decrease", "Csökkentés"), ("Increase", "Növelés"), - ("Show my cursor", ""), ("Show virtual mouse", ""), ("Virtual mouse size", ""), ("Small", ""), ("Large", ""), ("Show virtual joystick", ""), + ("Edit note", ""), + ("Alias", ""), ].iter().cloned().collect(); } diff --git a/src/lang/id.rs b/src/lang/id.rs index 357d3229f..7dc279e2d 100644 --- a/src/lang/id.rs +++ b/src/lang/id.rs @@ -719,5 +719,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Small", ""), ("Large", ""), ("Show virtual joystick", ""), + ("Edit note", ""), + ("Alias", ""), ].iter().cloned().collect(); } diff --git a/src/lang/it.rs b/src/lang/it.rs index 26dc41a2a..cdaee2602 100644 --- a/src/lang/it.rs +++ b/src/lang/it.rs @@ -719,5 +719,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Small", "Piccola"), ("Large", "Grande"), ("Show virtual joystick", "Visualizza joystick virtuale"), + ("Edit note", ""), + ("Alias", ""), ].iter().cloned().collect(); } diff --git a/src/lang/ja.rs b/src/lang/ja.rs index b9fab6ca8..88e4b7847 100644 --- a/src/lang/ja.rs +++ b/src/lang/ja.rs @@ -57,7 +57,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("ID Server", "認証サーバー"), ("Relay Server", "中継サーバー"), ("API Server", "API サーバー"), - ("Key", "キー"), ("invalid_http", "http:// または https:// から始まる必要があります。"), ("Invalid IP", "無効な IP"), ("Invalid format", "無効な形式"), @@ -710,16 +709,17 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Supported only in the installed version.", "インストールされたバージョンでのみサポートされます。"), ("elevation_username_tip", "ユーザー名またはドメインのユーザー名を入力してください。"), ("Preparing for installation ...", "インストールの準備中です..."), - ("Show my cursor", "自分のカーソルを表示"), + ("Show my cursor", "自分のカーソルを表示する"), ("Scale custom", "カスタムスケーリング"), ("Custom scale slider", "カスタムスケールのスライダー"), ("Decrease", "縮小"), ("Increase", "拡大"), - ("Show my cursor", "自分のカーソルを表示する"), ("Show virtual mouse", "仮想マウスを表示する"), ("Virtual mouse size", "仮想マウスのサイズ"), ("Small", "小"), ("Large", "中"), ("Show virtual joystick", "仮想ジョイスティックを表示する"), + ("Edit note", ""), + ("Alias", ""), ].iter().cloned().collect(); } diff --git a/src/lang/ko.rs b/src/lang/ko.rs index 21e33a303..a4d7f626f 100644 --- a/src/lang/ko.rs +++ b/src/lang/ko.rs @@ -719,5 +719,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Small", "작게"), ("Large", "크게"), ("Show virtual joystick", "가상 조이스틱 표시"), + ("Edit note", ""), + ("Alias", ""), ].iter().cloned().collect(); } diff --git a/src/lang/kz.rs b/src/lang/kz.rs index 69eb280a6..209c8eef7 100644 --- a/src/lang/kz.rs +++ b/src/lang/kz.rs @@ -719,5 +719,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Small", ""), ("Large", ""), ("Show virtual joystick", ""), + ("Edit note", ""), + ("Alias", ""), ].iter().cloned().collect(); } diff --git a/src/lang/lt.rs b/src/lang/lt.rs index 8a2992365..42c5b0082 100644 --- a/src/lang/lt.rs +++ b/src/lang/lt.rs @@ -719,5 +719,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Small", ""), ("Large", ""), ("Show virtual joystick", ""), + ("Edit note", ""), + ("Alias", ""), ].iter().cloned().collect(); } diff --git a/src/lang/lv.rs b/src/lang/lv.rs index af88fc91b..09dfb83b0 100644 --- a/src/lang/lv.rs +++ b/src/lang/lv.rs @@ -719,5 +719,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Small", ""), ("Large", ""), ("Show virtual joystick", ""), + ("Edit note", ""), + ("Alias", ""), ].iter().cloned().collect(); } diff --git a/src/lang/nb.rs b/src/lang/nb.rs index 4d503e2a5..3e00d3f26 100644 --- a/src/lang/nb.rs +++ b/src/lang/nb.rs @@ -719,5 +719,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Small", ""), ("Large", ""), ("Show virtual joystick", ""), + ("Edit note", ""), + ("Alias", ""), ].iter().cloned().collect(); } diff --git a/src/lang/nl.rs b/src/lang/nl.rs index 43e219d74..2bb4203e6 100644 --- a/src/lang/nl.rs +++ b/src/lang/nl.rs @@ -719,5 +719,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Small", ""), ("Large", ""), ("Show virtual joystick", ""), + ("Edit note", ""), + ("Alias", ""), ].iter().cloned().collect(); } diff --git a/src/lang/pl.rs b/src/lang/pl.rs index 6cc97569d..c41cb7fd4 100644 --- a/src/lang/pl.rs +++ b/src/lang/pl.rs @@ -719,5 +719,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Small", ""), ("Large", ""), ("Show virtual joystick", ""), + ("Edit note", ""), + ("Alias", ""), ].iter().cloned().collect(); } diff --git a/src/lang/pt_PT.rs b/src/lang/pt_PT.rs index c2991a20d..b2f7b2e07 100644 --- a/src/lang/pt_PT.rs +++ b/src/lang/pt_PT.rs @@ -719,5 +719,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Small", ""), ("Large", ""), ("Show virtual joystick", ""), + ("Edit note", ""), + ("Alias", ""), ].iter().cloned().collect(); } diff --git a/src/lang/ptbr.rs b/src/lang/ptbr.rs index 8baad379b..42ec471b1 100644 --- a/src/lang/ptbr.rs +++ b/src/lang/ptbr.rs @@ -719,5 +719,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Small", ""), ("Large", ""), ("Show virtual joystick", ""), + ("Edit note", ""), + ("Alias", ""), ].iter().cloned().collect(); } diff --git a/src/lang/ro.rs b/src/lang/ro.rs index db2c37f1b..0f1516a90 100644 --- a/src/lang/ro.rs +++ b/src/lang/ro.rs @@ -719,5 +719,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Small", ""), ("Large", ""), ("Show virtual joystick", ""), + ("Edit note", ""), + ("Alias", ""), ].iter().cloned().collect(); } diff --git a/src/lang/ru.rs b/src/lang/ru.rs index 892dc94c3..062c734c4 100644 --- a/src/lang/ru.rs +++ b/src/lang/ru.rs @@ -719,5 +719,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Small", ""), ("Large", ""), ("Show virtual joystick", ""), + ("Edit note", ""), + ("Alias", ""), ].iter().cloned().collect(); } diff --git a/src/lang/sc.rs b/src/lang/sc.rs index 66bf55d92..0af391d01 100644 --- a/src/lang/sc.rs +++ b/src/lang/sc.rs @@ -719,5 +719,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Small", ""), ("Large", ""), ("Show virtual joystick", ""), + ("Edit note", ""), + ("Alias", ""), ].iter().cloned().collect(); } diff --git a/src/lang/sk.rs b/src/lang/sk.rs index 958bfb71b..1769b6130 100644 --- a/src/lang/sk.rs +++ b/src/lang/sk.rs @@ -719,5 +719,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Small", ""), ("Large", ""), ("Show virtual joystick", ""), + ("Edit note", ""), + ("Alias", ""), ].iter().cloned().collect(); } diff --git a/src/lang/sl.rs b/src/lang/sl.rs index 2fb23c5d1..63610909b 100755 --- a/src/lang/sl.rs +++ b/src/lang/sl.rs @@ -719,5 +719,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Small", ""), ("Large", ""), ("Show virtual joystick", ""), + ("Edit note", ""), + ("Alias", ""), ].iter().cloned().collect(); } diff --git a/src/lang/sq.rs b/src/lang/sq.rs index 83f7e3bdf..0477a0198 100644 --- a/src/lang/sq.rs +++ b/src/lang/sq.rs @@ -719,5 +719,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Small", ""), ("Large", ""), ("Show virtual joystick", ""), + ("Edit note", ""), + ("Alias", ""), ].iter().cloned().collect(); } diff --git a/src/lang/sr.rs b/src/lang/sr.rs index 04729340b..0e1227f89 100644 --- a/src/lang/sr.rs +++ b/src/lang/sr.rs @@ -719,5 +719,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Small", ""), ("Large", ""), ("Show virtual joystick", ""), + ("Edit note", ""), + ("Alias", ""), ].iter().cloned().collect(); } diff --git a/src/lang/sv.rs b/src/lang/sv.rs index f4e1057db..d88c48cf7 100644 --- a/src/lang/sv.rs +++ b/src/lang/sv.rs @@ -719,5 +719,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Small", ""), ("Large", ""), ("Show virtual joystick", ""), + ("Edit note", ""), + ("Alias", ""), ].iter().cloned().collect(); } diff --git a/src/lang/ta.rs b/src/lang/ta.rs index 1d161e9c5..97ff0266e 100644 --- a/src/lang/ta.rs +++ b/src/lang/ta.rs @@ -719,5 +719,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Small", ""), ("Large", ""), ("Show virtual joystick", ""), + ("Edit note", ""), + ("Alias", ""), ].iter().cloned().collect(); } diff --git a/src/lang/template.rs b/src/lang/template.rs index acc82d947..4a0d6b14f 100644 --- a/src/lang/template.rs +++ b/src/lang/template.rs @@ -719,5 +719,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Small", ""), ("Large", ""), ("Show virtual joystick", ""), + ("Edit note", ""), + ("Alias", ""), ].iter().cloned().collect(); } diff --git a/src/lang/th.rs b/src/lang/th.rs index b9d1aa2b4..d3894efd0 100644 --- a/src/lang/th.rs +++ b/src/lang/th.rs @@ -719,5 +719,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Small", ""), ("Large", ""), ("Show virtual joystick", ""), + ("Edit note", ""), + ("Alias", ""), ].iter().cloned().collect(); } diff --git a/src/lang/tr.rs b/src/lang/tr.rs index d255070d5..51f221752 100644 --- a/src/lang/tr.rs +++ b/src/lang/tr.rs @@ -719,5 +719,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Small", ""), ("Large", ""), ("Show virtual joystick", ""), + ("Edit note", ""), + ("Alias", ""), ].iter().cloned().collect(); } diff --git a/src/lang/tw.rs b/src/lang/tw.rs index a20d7613c..a006cd223 100644 --- a/src/lang/tw.rs +++ b/src/lang/tw.rs @@ -719,5 +719,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Small", ""), ("Large", ""), ("Show virtual joystick", ""), + ("Edit note", ""), + ("Alias", ""), ].iter().cloned().collect(); } diff --git a/src/lang/uk.rs b/src/lang/uk.rs index a40c098f4..336021b3a 100644 --- a/src/lang/uk.rs +++ b/src/lang/uk.rs @@ -719,5 +719,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Small", ""), ("Large", ""), ("Show virtual joystick", ""), + ("Edit note", ""), + ("Alias", ""), ].iter().cloned().collect(); } diff --git a/src/lang/vi.rs b/src/lang/vi.rs index eea8f4400..308c84502 100644 --- a/src/lang/vi.rs +++ b/src/lang/vi.rs @@ -719,5 +719,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Small", ""), ("Large", ""), ("Show virtual joystick", ""), + ("Edit note", ""), + ("Alias", ""), ].iter().cloned().collect(); }