diff --git a/flutter/lib/common/widgets/peer_card.dart b/flutter/lib/common/widgets/peer_card.dart index 73660cc3a..124057662 100644 --- a/flutter/lib/common/widgets/peer_card.dart +++ b/flutter/lib/common/widgets/peer_card.dart @@ -42,6 +42,7 @@ class _PeerCardState extends State<_PeerCard> with AutomaticKeepAliveClientMixin { var _menuPos = RelativeRect.fill; final double _cardRadius = 16; + final double _tileRadius = 5; final double _borderWidth = 2; @override @@ -116,27 +117,32 @@ class _PeerCardState extends State<_PeerCard> Widget _buildDesktop() { final peer = super.widget.peer; - var deco = Rx(BoxDecoration( + var deco = Rx( + BoxDecoration( border: Border.all(color: Colors.transparent, width: _borderWidth), - borderRadius: peerCardUiType.value == PeerUiType.grid - ? BorderRadius.circular(_cardRadius) - : null)); + borderRadius: BorderRadius.circular( + peerCardUiType.value == PeerUiType.grid ? _cardRadius : _tileRadius, + ), + ), + ); return MouseRegion( onEnter: (evt) { deco.value = BoxDecoration( - border: Border.all( - color: Theme.of(context).colorScheme.primary, - width: _borderWidth), - borderRadius: peerCardUiType.value == PeerUiType.grid - ? BorderRadius.circular(_cardRadius) - : null); + border: Border.all( + color: Theme.of(context).colorScheme.primary, + width: _borderWidth), + borderRadius: BorderRadius.circular( + peerCardUiType.value == PeerUiType.grid ? _cardRadius : _tileRadius, + ), + ); }, onExit: (evt) { deco.value = BoxDecoration( - border: Border.all(color: Colors.transparent, width: _borderWidth), - borderRadius: peerCardUiType.value == PeerUiType.grid - ? BorderRadius.circular(_cardRadius) - : null); + border: Border.all(color: Colors.transparent, width: _borderWidth), + borderRadius: BorderRadius.circular( + peerCardUiType.value == PeerUiType.grid ? _cardRadius : _tileRadius, + ), + ); }, child: GestureDetector( onDoubleTap: () => widget.connect(context, peer.id), @@ -163,6 +169,10 @@ class _PeerCardState extends State<_PeerCard> Container( decoration: BoxDecoration( color: str2color('${peer.id}${peer.platform}', 0x7f), + borderRadius: BorderRadius.only( + topLeft: Radius.circular(_tileRadius), + bottomLeft: Radius.circular(_tileRadius), + ), ), alignment: Alignment.center, width: 42, @@ -171,7 +181,12 @@ class _PeerCardState extends State<_PeerCard> Expanded( child: Container( decoration: BoxDecoration( - color: Theme.of(context).colorScheme.background), + color: Theme.of(context).colorScheme.background, + borderRadius: BorderRadius.only( + topRight: Radius.circular(_tileRadius), + bottomRight: Radius.circular(_tileRadius), + ), + ), child: Row( children: [ Expanded( diff --git a/flutter/lib/common/widgets/peer_tab_page.dart b/flutter/lib/common/widgets/peer_tab_page.dart index da7e37e6b..869bd5fd9 100644 --- a/flutter/lib/common/widgets/peer_tab_page.dart +++ b/flutter/lib/common/widgets/peer_tab_page.dart @@ -17,6 +17,7 @@ import 'package:get/get.dart'; import 'package:get/get_rx/src/rx_workers/utils/debouncer.dart'; import 'package:provider/provider.dart'; import 'package:visibility_detector/visibility_detector.dart'; +import 'package:dropdown_button2/dropdown_button2.dart'; import '../../common.dart'; import '../../models/platform_model.dart'; @@ -39,6 +40,8 @@ EdgeInsets? _menuPadding() { class _PeerTabPageState extends State with SingleTickerProviderStateMixin { + bool _hideSort = bind.getLocalFlutterConfig(k: 'peer-tab-index') == '0'; + final List<_TabEntry> entries = [ _TabEntry( RecentPeersView( @@ -83,6 +86,7 @@ class _PeerTabPageState extends State if (tabIndex < entries.length) { gFFI.peerTabModel.setCurrentTab(tabIndex); entries[tabIndex].load(); + _hideSort = tabIndex == 0; } } @@ -95,22 +99,27 @@ class _PeerTabPageState extends State SizedBox( height: 28, child: Container( - padding: isDesktop ? null : EdgeInsets.symmetric(horizontal: 2), - constraints: isDesktop ? null : kMobilePageConstraints, - child: Row( - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - Expanded( - child: visibleContextMenuListener( - _createSwitchBar(context))), - buildScrollJumper(), - const PeerSearchBar(), - Offstage( - offstage: !isDesktop, - child: _createPeerViewTypeSwitch(context) - .marginOnly(left: 13)), - ], - )), + padding: isDesktop ? null : EdgeInsets.symmetric(horizontal: 2), + constraints: isDesktop ? null : kMobilePageConstraints, + child: Row( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Expanded( + child: + visibleContextMenuListener(_createSwitchBar(context))), + buildScrollJumper(), + const PeerSearchBar(), + Offstage( + offstage: !isDesktop, + child: _createPeerViewTypeSwitch(context) + .marginOnly(left: 13)), + Offstage( + offstage: _hideSort, + child: PeerSortDropdown().marginOnly(left: 8), + ), + ], + ), + ), ), _createPeersView(), ], @@ -231,32 +240,32 @@ class _PeerTabPageState extends State Widget _createPeerViewTypeSwitch(BuildContext context) { final textColor = Theme.of(context).textTheme.titleLarge?.color; - final activeDeco = - BoxDecoration(color: Theme.of(context).colorScheme.background); - return Row( - children: [PeerUiType.grid, PeerUiType.list] - .map((type) => Obx( - () => Container( - padding: EdgeInsets.all(4.0), - decoration: peerCardUiType.value == type ? activeDeco : null, - child: InkWell( - onTap: () async { - await bind.setLocalFlutterConfig( - k: 'peer-card-ui-type', v: type.index.toString()); - peerCardUiType.value = type; - }, - child: Icon( - type == PeerUiType.grid - ? Icons.grid_view_rounded - : Icons.list, - size: 18, - color: - peerCardUiType.value == type ? textColor : textColor - ?..withOpacity(0.5), - )), - ), - )) - .toList(), + final deco = BoxDecoration( + color: Theme.of(context).colorScheme.background, + borderRadius: BorderRadius.circular(5), + ); + final types = [PeerUiType.grid, PeerUiType.list]; + + return Obx( + () => Container( + padding: EdgeInsets.all(4.0), + decoration: deco, + child: InkWell( + onTap: () async { + final type = types.elementAt( + peerCardUiType.value == types.elementAt(0) ? 1 : 0); + await bind.setLocalFlutterConfig( + k: 'peer-card-ui-type', v: type.index.toString()); + peerCardUiType.value = type; + }, + child: Icon( + peerCardUiType.value == PeerUiType.grid + ? Icons.list_rounded + : Icons.grid_view_rounded, + size: 18, + color: textColor, + )), + ), ); } @@ -417,3 +426,90 @@ class _PeerSearchBarState extends State { ); } } + +class PeerSortDropdown extends StatefulWidget { + const PeerSortDropdown({super.key}); + + @override + State createState() => _PeerSortDropdownState(); +} + +class _PeerSortDropdownState extends State { + @override + void initState() { + if (!PeerSortType.values.contains(peerSort.value)) { + peerSort.value = PeerSortType.remoteId; + bind.setLocalFlutterConfig( + k: "peer-sorting", + v: peerSort.value, + ); + } + super.initState(); + } + + @override + Widget build(BuildContext context) { + final deco = BoxDecoration( + color: Theme.of(context).colorScheme.background, + borderRadius: BorderRadius.circular(5), + ); + return Container( + padding: EdgeInsets.all(4.0), + decoration: deco, + child: DropdownButtonHideUnderline( + child: DropdownButton2( + onChanged: (v) async { + if (v != null) { + setState(() => peerSort.value = v); + await bind.setLocalFlutterConfig( + k: "peer-sorting", + v: peerSort.value, + ); + } + }, + customButton: Icon( + Icons.sort, + size: 18, + ), + dropdownStyleData: DropdownStyleData( + decoration: BoxDecoration( + color: Theme.of(context).cardColor, + borderRadius: BorderRadius.circular(10), + ), + width: 160, + ), + items: [ + DropdownMenuItem( + alignment: Alignment.center, + child: Text( + translate("Sort by"), + style: TextStyle(fontWeight: FontWeight.bold), + ), + enabled: false, + ), + ...PeerSortType.values + .map>( + (String value) => DropdownMenuItem( + value: value, + child: Row( + children: [ + Icon( + value == peerSort.value + ? Icons.radio_button_checked_rounded + : Icons.radio_button_off_rounded, + size: 18, + ).paddingOnly(right: 12), + Text( + translate(value), + overflow: TextOverflow.ellipsis, + ), + ], + ), + ), + ) + .toList(), + ]), + ), + ); + } +} diff --git a/flutter/lib/common/widgets/peers_view.dart b/flutter/lib/common/widgets/peers_view.dart index 720e6727c..197e55376 100644 --- a/flutter/lib/common/widgets/peers_view.dart +++ b/flutter/lib/common/widgets/peers_view.dart @@ -16,8 +16,31 @@ import 'peer_card.dart'; typedef PeerFilter = bool Function(Peer peer); typedef PeerCardBuilder = Widget Function(Peer peer); +class PeerSortType { + static const String remoteId = 'Remote ID'; + static const String remoteHost = 'Remote Host'; + static const String alias = 'Alias'; + static const String username = 'Username'; + static const String status = 'Status'; + + static List values = [ + PeerSortType.remoteId, + PeerSortType.remoteHost, + PeerSortType.alias, + PeerSortType.username, + PeerSortType.status + ]; +} + /// for peer search text, global obs value final peerSearchText = "".obs; + +/// for peer sort, global obs value +final peerSort = bind.getLocalFlutterConfig(k: 'peer-sorting').obs; + +// list for listener +final obslist = [peerSearchText, peerSort].obs; + final peerSearchTextController = TextEditingController(text: peerSearchText.value); @@ -114,7 +137,7 @@ class _PeersViewState extends State<_PeersView> with WindowListener { String _peerId(String cardId) => cardId.replaceAll(widget.peers.name, ''); Widget _buildPeersView(Peers peers) { - final body = ObxValue((searchText) { + final body = ObxValue((filters) { return FutureBuilder>( builder: (context, snapshot) { if (snapshot.hasData) { @@ -144,9 +167,9 @@ class _PeersViewState extends State<_PeersView> with WindowListener { ); } }, - future: matchPeers(searchText.value, peers.peers), + future: matchPeers(filters[0].value, filters[1].value, peers.peers), ); - }, peerSearchText); + }, obslist); return body; } @@ -185,11 +208,44 @@ class _PeersViewState extends State<_PeersView> with WindowListener { }(); } - Future>? matchPeers(String searchText, List peers) async { + Future>? matchPeers( + String searchText, String sortedBy, List peers) async { if (widget.peerFilter != null) { peers = peers.where((peer) => widget.peerFilter!(peer)).toList(); } + // fallback to id sorting + if (!PeerSortType.values.contains(sortedBy)) { + sortedBy = PeerSortType.remoteId; + bind.setLocalFlutterConfig( + k: "peer-sorting", + v: sortedBy, + ); + } + + if (widget.peers.loadEvent != 'load_recent_peers') { + switch (sortedBy) { + case PeerSortType.remoteId: + peers.sort((p1, p2) => p1.id.compareTo(p2.id)); + break; + case PeerSortType.remoteHost: + peers.sort((p1, p2) => + p1.hostname.toLowerCase().compareTo(p2.hostname.toLowerCase())); + break; + case PeerSortType.alias: + peers.sort((p1, p2) => + p1.alias.toLowerCase().compareTo(p2.alias.toLowerCase())); + break; + case PeerSortType.username: + peers.sort((p1, p2) => + p1.username.toLowerCase().compareTo(p2.username.toLowerCase())); + break; + case PeerSortType.status: + peers.sort((p1, p2) => p1.online ? -1 : 1); + break; + } + } + searchText = searchText.trim(); if (searchText.isEmpty) { return peers; @@ -203,6 +259,7 @@ class _PeersViewState extends State<_PeersView> with WindowListener { filteredList.add(peers[i]); } } + return filteredList; } } diff --git a/flutter/pubspec.lock b/flutter/pubspec.lock index 63f6c804c..f3db95378 100644 --- a/flutter/pubspec.lock +++ b/flutter/pubspec.lock @@ -386,6 +386,14 @@ packages: url: "https://pub.dev" source: hosted version: "0.0.2" + dropdown_button2: + dependency: "direct main" + description: + name: dropdown_button2 + sha256: "4458d81bfd24207f3d58f66f78097064e02f810f94cf1bc80bf20fe7685ebc80" + url: "https://pub.dev" + source: hosted + version: "2.0.0" event_bus: dependency: transitive description: diff --git a/flutter/pubspec.yaml b/flutter/pubspec.yaml index 087fba71e..46278bf0d 100644 --- a/flutter/pubspec.yaml +++ b/flutter/pubspec.yaml @@ -94,6 +94,7 @@ dependencies: flutter_keyboard_visibility: ^5.4.0 texture_rgba_renderer: ^0.0.12 percent_indicator: ^4.2.2 + dropdown_button2: ^2.0.0 dev_dependencies: icons_launcher: ^2.0.4 diff --git a/src/lang/ca.rs b/src/lang/ca.rs index 9507ffc25..a3c31c55d 100644 --- a/src/lang/ca.rs +++ b/src/lang/ca.rs @@ -464,5 +464,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("idd_driver_tip", ""), ("confirm_idd_driver_tip", ""), ("RDP Settings", ""), + ("Sort by", ""), ].iter().cloned().collect(); } diff --git a/src/lang/cn.rs b/src/lang/cn.rs index e5ba70aa6..a32f35a5b 100644 --- a/src/lang/cn.rs +++ b/src/lang/cn.rs @@ -464,5 +464,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("idd_driver_tip", "安装虚拟显示器驱动,以便在没有连接显示器的情况下启动虚拟显示器进行控制。"), ("confirm_idd_driver_tip", "安装虚拟显示器驱动的选项已勾选。请注意,测试证书将被安装以信任虚拟显示器驱动。测试证书仅会用于信任Rustdesk的驱动。"), ("RDP Settings", ""), + ("Sort by", ""), ].iter().cloned().collect(); } diff --git a/src/lang/cs.rs b/src/lang/cs.rs index 5920e002c..50ea4e61c 100644 --- a/src/lang/cs.rs +++ b/src/lang/cs.rs @@ -464,5 +464,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("idd_driver_tip", ""), ("confirm_idd_driver_tip", ""), ("RDP Settings", ""), + ("Sort by", ""), ].iter().cloned().collect(); } diff --git a/src/lang/da.rs b/src/lang/da.rs index 6e7394d79..c0d722219 100644 --- a/src/lang/da.rs +++ b/src/lang/da.rs @@ -464,5 +464,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("idd_driver_tip", ""), ("confirm_idd_driver_tip", ""), ("RDP Settings", ""), + ("Sort by", ""), ].iter().cloned().collect(); } diff --git a/src/lang/de.rs b/src/lang/de.rs index f753265f8..bdd82d471 100644 --- a/src/lang/de.rs +++ b/src/lang/de.rs @@ -464,5 +464,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("idd_driver_tip", "Installieren Sie den virtuellen Anzeigetreiber, der verwendet wird, wenn Sie keine physischen Anzeigen haben."), ("confirm_idd_driver_tip", "Die Option zur Installation des virtuellen Anzeigetreibers ist aktiviert. Beachten Sie, dass ein Testzertifikat installiert wird, um dem virtuellen Anzeigetreiber zu vertrauen. Dieses Testzertifikat wird nur verwendet, um Rustdesk-Treibern zu vertrauen."), ("RDP Settings", "RDP-Einstellungen"), + ("Sort by", ""), ].iter().cloned().collect(); } diff --git a/src/lang/el.rs b/src/lang/el.rs index b0c8be87a..6599e7a59 100644 --- a/src/lang/el.rs +++ b/src/lang/el.rs @@ -464,5 +464,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("idd_driver_tip", "Εγκαταστήστε το πρόγραμμα οδήγησης εικονικής οθόνης που χρησιμοποιείται όταν δεν έχετε φυσικές οθόνες."), ("confirm_idd_driver_tip", "Είναι ενεργοποιημένη η επιλογή εγκατάστασης του προγράμματος οδήγησης εικονικής οθόνης. Λάβετε υπόψη ότι θα εγκατασταθεί ένα δοκιμαστικό πιστοποιητικό για το πρόγραμμα οδήγησης εικονικής οθόνης. Αυτό το πιστοποιητικό θα χρησιμοποιηθεί μόνο για την πιστοποίηση των προγραμμάτων οδήγησης του Rustdesk."), ("RDP Settings", "Ρυθμίσεις RDP"), + ("Sort by", ""), ].iter().cloned().collect(); } diff --git a/src/lang/eo.rs b/src/lang/eo.rs index 457fbea02..7ccb8a8ca 100644 --- a/src/lang/eo.rs +++ b/src/lang/eo.rs @@ -464,5 +464,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("idd_driver_tip", ""), ("confirm_idd_driver_tip", ""), ("RDP Settings", ""), + ("Sort by", ""), ].iter().cloned().collect(); } diff --git a/src/lang/es.rs b/src/lang/es.rs index 3543c5155..85239cdd1 100644 --- a/src/lang/es.rs +++ b/src/lang/es.rs @@ -464,5 +464,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("idd_driver_tip", "Instalar controlador virtual de pantalla a usar cuando no hay pantalla física."), ("confirm_idd_driver_tip", "La opción de instalar el controlador de pantalla virtual está marcada. Hay que tener en cuenta que se instalará un certificado de prueba para confirar en el controlador de pantalla. Este certificado solo se usará para confiar en controladores Rustdesk."), ("RDP Settings", "Ajustes RDP"), + ("Sort by", ""), ].iter().cloned().collect(); } diff --git a/src/lang/fa.rs b/src/lang/fa.rs index f1503a83e..a64597883 100644 --- a/src/lang/fa.rs +++ b/src/lang/fa.rs @@ -464,5 +464,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("idd_driver_tip", ""), ("confirm_idd_driver_tip", ""), ("RDP Settings", ""), + ("Sort by", ""), ].iter().cloned().collect(); } diff --git a/src/lang/fr.rs b/src/lang/fr.rs index 63d1ce317..887965b9e 100644 --- a/src/lang/fr.rs +++ b/src/lang/fr.rs @@ -464,5 +464,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("idd_driver_tip", ""), ("confirm_idd_driver_tip", ""), ("RDP Settings", ""), + ("Sort by", ""), ].iter().cloned().collect(); } diff --git a/src/lang/hu.rs b/src/lang/hu.rs index 4789ba55d..e64d972b6 100644 --- a/src/lang/hu.rs +++ b/src/lang/hu.rs @@ -464,5 +464,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("idd_driver_tip", ""), ("confirm_idd_driver_tip", ""), ("RDP Settings", ""), + ("Sort by", ""), ].iter().cloned().collect(); } diff --git a/src/lang/id.rs b/src/lang/id.rs index e2a969a88..ffba760ee 100644 --- a/src/lang/id.rs +++ b/src/lang/id.rs @@ -464,5 +464,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("idd_driver_tip", ""), ("confirm_idd_driver_tip", ""), ("RDP Settings", ""), + ("Sort by", ""), ].iter().cloned().collect(); } diff --git a/src/lang/it.rs b/src/lang/it.rs index dc59ccea3..4d2da35fa 100644 --- a/src/lang/it.rs +++ b/src/lang/it.rs @@ -208,7 +208,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("x11 expected", "x11 necessario"), ("Port", "Porta"), ("Settings", "Impostazioni"), - ("Username", " Nome utente"), + ("Username", "Nome utente"), ("Invalid port", "Numero di porta non valido"), ("Closed manually by the peer", "Chiuso manualmente dal peer"), ("Enable remote configuration modification", "Abilita la modifica remota della configurazione"), @@ -461,8 +461,9 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("Resolution", "Risoluzione"), ("No transfers in progress", "Nessun trasferimento in corso"), ("Set one-time password length", "Imposta la lunghezza della password monouso"), - ("idd_driver_tip", ""), - ("confirm_idd_driver_tip", ""), + ("idd_driver_tip", "Installa il driver per lo schermo virtuale che sarà utilizzato quando non si dispone di schermi fisici."), + ("confirm_idd_driver_tip", "L'opzione per installare il driver per lo schermo virtuale è selezionata. Nota che un certificato di test sarà installato per l'attendibilità del driver dello schermo virtuale. Questo certificato di test verrà utilizzato solo per l'attendibilità dei driver di RustDesk."), ("RDP Settings", "Impostazioni RDP"), + ("Sort by", "Ordina per"), ].iter().cloned().collect(); } diff --git a/src/lang/ja.rs b/src/lang/ja.rs index a2d3446bb..9b7741d4d 100644 --- a/src/lang/ja.rs +++ b/src/lang/ja.rs @@ -464,5 +464,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("idd_driver_tip", ""), ("confirm_idd_driver_tip", ""), ("RDP Settings", ""), + ("Sort by", ""), ].iter().cloned().collect(); } diff --git a/src/lang/ko.rs b/src/lang/ko.rs index 9c2076d63..ff6fdafb4 100644 --- a/src/lang/ko.rs +++ b/src/lang/ko.rs @@ -464,5 +464,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("idd_driver_tip", ""), ("confirm_idd_driver_tip", ""), ("RDP Settings", ""), + ("Sort by", ""), ].iter().cloned().collect(); } diff --git a/src/lang/kz.rs b/src/lang/kz.rs index b8a415e48..ca7c2d508 100644 --- a/src/lang/kz.rs +++ b/src/lang/kz.rs @@ -464,5 +464,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("idd_driver_tip", ""), ("confirm_idd_driver_tip", ""), ("RDP Settings", ""), + ("Sort by", ""), ].iter().cloned().collect(); } diff --git a/src/lang/nl.rs b/src/lang/nl.rs index 595e0710e..a617ba2eb 100644 --- a/src/lang/nl.rs +++ b/src/lang/nl.rs @@ -464,5 +464,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("idd_driver_tip", ""), ("confirm_idd_driver_tip", ""), ("RDP Settings", ""), + ("Sort by", ""), ].iter().cloned().collect(); } diff --git a/src/lang/pl.rs b/src/lang/pl.rs index 08f6ca905..0e8bbd311 100644 --- a/src/lang/pl.rs +++ b/src/lang/pl.rs @@ -464,5 +464,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("idd_driver_tip", ""), ("confirm_idd_driver_tip", ""), ("RDP Settings", ""), + ("Sort by", ""), ].iter().cloned().collect(); } diff --git a/src/lang/pt_PT.rs b/src/lang/pt_PT.rs index 1eb5fc6e7..96a84de39 100644 --- a/src/lang/pt_PT.rs +++ b/src/lang/pt_PT.rs @@ -464,5 +464,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("idd_driver_tip", ""), ("confirm_idd_driver_tip", ""), ("RDP Settings", ""), + ("Sort by", ""), ].iter().cloned().collect(); } diff --git a/src/lang/ptbr.rs b/src/lang/ptbr.rs index df0f5a26e..f98e1116a 100644 --- a/src/lang/ptbr.rs +++ b/src/lang/ptbr.rs @@ -464,5 +464,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("idd_driver_tip", ""), ("confirm_idd_driver_tip", ""), ("RDP Settings", ""), + ("Sort by", ""), ].iter().cloned().collect(); } diff --git a/src/lang/ro.rs b/src/lang/ro.rs index 7515ccbf1..386f88c85 100644 --- a/src/lang/ro.rs +++ b/src/lang/ro.rs @@ -464,5 +464,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("idd_driver_tip", ""), ("confirm_idd_driver_tip", ""), ("RDP Settings", ""), + ("Sort by", ""), ].iter().cloned().collect(); } diff --git a/src/lang/ru.rs b/src/lang/ru.rs index a11828431..dc714ec72 100644 --- a/src/lang/ru.rs +++ b/src/lang/ru.rs @@ -464,5 +464,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("idd_driver_tip", "Установите драйвер виртуального дисплея, который используется при отсутствии физических дисплеев."), ("confirm_idd_driver_tip", "Включена функция установки драйвера виртуального дисплея. Обратите внимание, что для доверия к драйверу будет установлен тестовый сертификат. Этот сертификат будет использоваться только для подтверждения доверия драйверам Rustdesk."), ("RDP Settings", "Настройки RDP"), + ("Sort by", ""), ].iter().cloned().collect(); } diff --git a/src/lang/sk.rs b/src/lang/sk.rs index 1d8c6c626..38a3bd655 100644 --- a/src/lang/sk.rs +++ b/src/lang/sk.rs @@ -464,5 +464,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("idd_driver_tip", ""), ("confirm_idd_driver_tip", ""), ("RDP Settings", ""), + ("Sort by", ""), ].iter().cloned().collect(); } diff --git a/src/lang/sl.rs b/src/lang/sl.rs index 07bb2b543..41f4facbb 100755 --- a/src/lang/sl.rs +++ b/src/lang/sl.rs @@ -464,5 +464,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("idd_driver_tip", ""), ("confirm_idd_driver_tip", ""), ("RDP Settings", ""), + ("Sort by", ""), ].iter().cloned().collect(); } diff --git a/src/lang/sq.rs b/src/lang/sq.rs index a7cdfa8e7..7e559287e 100644 --- a/src/lang/sq.rs +++ b/src/lang/sq.rs @@ -464,5 +464,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("idd_driver_tip", ""), ("confirm_idd_driver_tip", ""), ("RDP Settings", ""), + ("Sort by", ""), ].iter().cloned().collect(); } diff --git a/src/lang/sr.rs b/src/lang/sr.rs index bcdedef59..b2f5b62f0 100644 --- a/src/lang/sr.rs +++ b/src/lang/sr.rs @@ -464,5 +464,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("idd_driver_tip", ""), ("confirm_idd_driver_tip", ""), ("RDP Settings", ""), + ("Sort by", ""), ].iter().cloned().collect(); } diff --git a/src/lang/sv.rs b/src/lang/sv.rs index 63167ed82..7a35df417 100644 --- a/src/lang/sv.rs +++ b/src/lang/sv.rs @@ -464,5 +464,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("idd_driver_tip", ""), ("confirm_idd_driver_tip", ""), ("RDP Settings", ""), + ("Sort by", ""), ].iter().cloned().collect(); } diff --git a/src/lang/template.rs b/src/lang/template.rs index 3fb6d17a9..80e7f04e6 100644 --- a/src/lang/template.rs +++ b/src/lang/template.rs @@ -464,5 +464,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("idd_driver_tip", ""), ("confirm_idd_driver_tip", ""), ("RDP Settings", ""), + ("Sort by", ""), ].iter().cloned().collect(); } diff --git a/src/lang/th.rs b/src/lang/th.rs index 808f69f8d..f9bcf0800 100644 --- a/src/lang/th.rs +++ b/src/lang/th.rs @@ -464,5 +464,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("idd_driver_tip", ""), ("confirm_idd_driver_tip", ""), ("RDP Settings", ""), + ("Sort by", ""), ].iter().cloned().collect(); } diff --git a/src/lang/tr.rs b/src/lang/tr.rs index 34949aa4c..58a38e075 100644 --- a/src/lang/tr.rs +++ b/src/lang/tr.rs @@ -464,5 +464,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("idd_driver_tip", ""), ("confirm_idd_driver_tip", ""), ("RDP Settings", ""), + ("Sort by", ""), ].iter().cloned().collect(); } diff --git a/src/lang/tw.rs b/src/lang/tw.rs index 17ef4b7ed..ff05d5643 100644 --- a/src/lang/tw.rs +++ b/src/lang/tw.rs @@ -464,5 +464,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("idd_driver_tip", ""), ("confirm_idd_driver_tip", ""), ("RDP Settings", ""), + ("Sort by", ""), ].iter().cloned().collect(); } diff --git a/src/lang/ua.rs b/src/lang/ua.rs index cc44d86d0..04047ce9c 100644 --- a/src/lang/ua.rs +++ b/src/lang/ua.rs @@ -464,5 +464,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("idd_driver_tip", ""), ("confirm_idd_driver_tip", ""), ("RDP Settings", ""), + ("Sort by", ""), ].iter().cloned().collect(); } diff --git a/src/lang/vn.rs b/src/lang/vn.rs index b774e094f..e38b06a57 100644 --- a/src/lang/vn.rs +++ b/src/lang/vn.rs @@ -464,5 +464,6 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> = ("idd_driver_tip", ""), ("confirm_idd_driver_tip", ""), ("RDP Settings", ""), + ("Sort by", ""), ].iter().cloned().collect(); }