From ff20acc3678f610c2260f1f73429b30098a8705c Mon Sep 17 00:00:00 2001 From: Sahil Yeole Date: Fri, 13 Oct 2023 23:01:19 +0530 Subject: [PATCH 01/24] add rust bindings to get peers data Signed-off-by: Sahil Yeole --- src/flutter_ffi.rs | 66 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/src/flutter_ffi.rs b/src/flutter_ffi.rs index c931d8926..2a714d949 100644 --- a/src/flutter_ffi.rs +++ b/src/flutter_ffi.rs @@ -886,6 +886,72 @@ pub fn main_load_recent_peers_sync() -> SyncReturn { SyncReturn("".to_string()) } +pub fn main_load_fav_peers_sync() -> SyncReturn { + if !config::APP_DIR.read().unwrap().is_empty() { + let favs = get_fav(); + let mut recent = PeerConfig::peers(None); + let mut lan = config::LanPeers::load() + .peers + .iter() + .filter(|d| recent.iter().all(|r| r.0 != d.id)) + .map(|d| { + ( + d.id.clone(), + SystemTime::UNIX_EPOCH, + PeerConfig { + info: PeerInfoSerde { + username: d.username.clone(), + hostname: d.hostname.clone(), + platform: d.platform.clone(), + }, + ..Default::default() + }, + ) + }) + .collect(); + recent.append(&mut lan); + let peers: Vec> = recent + .into_iter() + .filter_map(|(id, _, p)| { + if favs.contains(&id) { + Some(peer_to_map(id, p)) + } else { + None + } + }) + .collect(); + + let data = HashMap::from([ + ("name", "load_fav_peers".to_owned()), + ( + "peers", + serde_json::ser::to_string(&peers).unwrap_or("".to_owned()), + ), + ]); + return SyncReturn(serde_json::ser::to_string(&data).unwrap_or("".to_owned())); + } + SyncReturn("".to_string()) +} + +pub fn main_load_lan_peers_sync() -> SyncReturn { + let data = HashMap::from([ + ("name", "load_lan_peers".to_owned()), + ( + "peers", + serde_json::to_string(&get_lan_peers()).unwrap_or_default(), + ), + ]); + return SyncReturn(serde_json::ser::to_string(&data).unwrap_or("".to_owned())); +} + +pub fn main_load_ab_sync() -> SyncReturn { + return SyncReturn(serde_json::to_string(&config::Ab::load()).unwrap_or_default()); +} + +pub fn main_load_group_sync() -> SyncReturn { + return SyncReturn(serde_json::to_string(&config::Group::load()).unwrap_or_default()); +} + pub fn main_load_recent_peers_for_ab(filter: String) -> String { let id_filters = serde_json::from_str::>(&filter).unwrap_or_default(); let id_filters = if id_filters.is_empty() { From f6b5c752f4125f8290c5ac205bd5d7ba8ca4b053 Mon Sep 17 00:00:00 2001 From: Sahil Yeole Date: Fri, 13 Oct 2023 23:10:31 +0530 Subject: [PATCH 02/24] add autocomplete feat Signed-off-by: Sahil Yeole --- .../lib/desktop/pages/connection_page.dart | 166 ++++++++++++++---- 1 file changed, 136 insertions(+), 30 deletions(-) diff --git a/flutter/lib/desktop/pages/connection_page.dart b/flutter/lib/desktop/pages/connection_page.dart index 359746f4c..029899150 100644 --- a/flutter/lib/desktop/pages/connection_page.dart +++ b/flutter/lib/desktop/pages/connection_page.dart @@ -11,6 +11,7 @@ import 'package:flutter_hbb/models/state_model.dart'; import 'package:get/get.dart'; import 'package:url_launcher/url_launcher_string.dart'; import 'package:window_manager/window_manager.dart'; +import 'package:flutter_hbb/models/peer_model.dart'; import '../../common.dart'; import '../../common/formatter/id_formatter.dart'; @@ -41,6 +42,7 @@ class _ConnectionPageState extends State var svcIsUsingPublicServer = true.obs; bool isWindowMinimized = false; + List peers = []; @override void initState() { @@ -145,6 +147,7 @@ class _ConnectionPageState extends State /// UI for the remote ID TextField. /// Search for a peer and connect to it if the id exists. Widget _buildRemoteIDTextField(BuildContext context) { + final TextEditingController fieldTextEditingController = TextEditingController.fromValue(_idController.value); var w = Container( width: 320 + 20 * 2, padding: const EdgeInsets.fromLTRB(20, 24, 20, 22), @@ -171,36 +174,139 @@ class _ConnectionPageState extends State Row( children: [ Expanded( - child: Obx( - () => TextField( - maxLength: 90, - autocorrect: false, - enableSuggestions: false, - keyboardType: TextInputType.visiblePassword, - focusNode: _idFocusNode, - style: const TextStyle( - fontFamily: 'WorkSans', - fontSize: 22, - height: 1.4, - ), - maxLines: 1, - cursorColor: - Theme.of(context).textTheme.titleLarge?.color, - decoration: InputDecoration( - filled: false, - counterText: '', - hintText: _idInputFocused.value - ? null - : translate('Enter Remote ID'), - contentPadding: const EdgeInsets.symmetric( - horizontal: 15, vertical: 13)), - controller: _idController, - inputFormatters: [IDTextInputFormatter()], - onSubmitted: (s) { - onConnect(); - }, - ), - ), + child: + Autocomplete( + optionsBuilder: (TextEditingValue textEditingValue) { + if (textEditingValue.text == '') { + return const Iterable.empty(); + } + else { + peers.clear(); + Map recentPeers = jsonDecode(bind.mainLoadRecentPeersSync()); + Map favPeers = jsonDecode(bind.mainLoadFavPeersSync()); + Map lanPeers = jsonDecode(bind.mainLoadLanPeersSync()); + Map abPeers = jsonDecode(bind.mainLoadAbSync()); + Map groupPeers = jsonDecode(bind.mainLoadGroupSync()); + + Map combinedPeers = {}; + + void mergePeers(Map peers) { + if (peers.containsKey("peers")) { + dynamic peerData = peers["peers"]; + + if (peerData is String) { + try { + peerData = jsonDecode(peerData); + } catch (e) { + print("Error decoding peers: $e"); + return; + } + } + + if (peerData is List) { + for (var peer in peerData) { + if (peer is Map && peer.containsKey("id")) { + String id = peer["id"]; + if (id != null && !combinedPeers.containsKey(id)) { + combinedPeers[id] = peer; + } + } + } + } + } + } + + mergePeers(recentPeers); + mergePeers(favPeers); + mergePeers(lanPeers); + mergePeers(abPeers); + mergePeers(groupPeers); + + for (var peer in combinedPeers.values) { + peers.add(Peer.fromJson(peer)); + } + + return peers.where((peer) => + peer.id.toLowerCase().contains(textEditingValue.text.toLowerCase()) || + peer.username.toLowerCase().contains(textEditingValue.text.toLowerCase()) || + peer.hostname.toLowerCase().contains(textEditingValue.text.toLowerCase()) || + peer.platform.toLowerCase().contains(textEditingValue.text.toLowerCase())) + .toList(); + } + }, + + fieldViewBuilder: (BuildContext context, + TextEditingController fieldTextEditingController, + FocusNode fieldFocusNode , + VoidCallback onFieldSubmitted, + + ) { + return Obx(() => + TextField( + maxLength: 90, + autocorrect: false, + enableSuggestions: false, + keyboardType: TextInputType.visiblePassword, + // focusNode: _idFocusNode, + focusNode: fieldFocusNode, + style: const TextStyle( + fontFamily: 'WorkSans', + fontSize: 22, + height: 1.4, + ), + maxLines: 1, + cursorColor: Theme.of(context).textTheme.titleLarge?.color, + decoration: InputDecoration( + filled: false, + counterText: '', + hintText: _idInputFocused.value + ? null + : translate('Enter Remote ID'), + contentPadding: const EdgeInsets.symmetric( + horizontal: 15, vertical: 13)), + // controller: _idController, + controller: fieldTextEditingController, + inputFormatters: [IDTextInputFormatter()], + onSubmitted: (s) { + onConnect(); + }, + )); + }, + optionsViewBuilder: (BuildContext context, AutocompleteOnSelected onSelected, Iterable options) { + return Align( + alignment: Alignment.topLeft, + child: Material( + elevation: 4.0, + child: ConstrainedBox( + constraints: BoxConstraints( + maxHeight: 200.0, + ), + child: SingleChildScrollView( + child: Column( + mainAxisSize: MainAxisSize.min, + children: options.map((peer) { + return ListTile( + // title: Text(peer.id), + title: Text(peer.id.length <= 6 ? peer.id : peer.id.substring(0, 6)), + subtitle: Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text(peer.username), + Text(peer.hostname), + Text(peer.platform), + for (var tag in peer.tags) + Text(tag), + ], + ), + onTap: () { + onSelected(peer); + }, + ); + }).toList(), + )))) + ); + }, + ) ), ], ), From bbd7cf306a1937ed5cefa486826b46743e0339f7 Mon Sep 17 00:00:00 2001 From: Sahil Yeole Date: Fri, 13 Oct 2023 23:28:54 +0530 Subject: [PATCH 03/24] handle id whitespaces for autocomplete Signed-off-by: Sahil Yeole --- flutter/lib/desktop/pages/connection_page.dart | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/flutter/lib/desktop/pages/connection_page.dart b/flutter/lib/desktop/pages/connection_page.dart index 029899150..0e1c65896 100644 --- a/flutter/lib/desktop/pages/connection_page.dart +++ b/flutter/lib/desktop/pages/connection_page.dart @@ -226,6 +226,13 @@ class _ConnectionPageState extends State peers.add(Peer.fromJson(peer)); } + if (textEditingValue.text.contains(" ")) { + textEditingValue = TextEditingValue( + text: textEditingValue.text.replaceAll(" ", ""), + selection: textEditingValue.selection, + ); + } + return peers.where((peer) => peer.id.toLowerCase().contains(textEditingValue.text.toLowerCase()) || peer.username.toLowerCase().contains(textEditingValue.text.toLowerCase()) || From 83d47aed2d94b6817e8a25e58abcbb677d32c33d Mon Sep 17 00:00:00 2001 From: Sahil Yeole Date: Sat, 14 Oct 2023 01:55:04 +0530 Subject: [PATCH 04/24] update UI for autocomplete Signed-off-by: Sahil Yeole --- .../lib/desktop/pages/connection_page.dart | 156 ++++++++++++++---- 1 file changed, 126 insertions(+), 30 deletions(-) diff --git a/flutter/lib/desktop/pages/connection_page.dart b/flutter/lib/desktop/pages/connection_page.dart index 0e1c65896..959a94a40 100644 --- a/flutter/lib/desktop/pages/connection_page.dart +++ b/flutter/lib/desktop/pages/connection_page.dart @@ -16,6 +16,7 @@ import 'package:flutter_hbb/models/peer_model.dart'; import '../../common.dart'; import '../../common/formatter/id_formatter.dart'; import '../../common/widgets/peer_tab_page.dart'; +import '../../common/widgets/peer_card.dart'; import '../../models/platform_model.dart'; import '../widgets/button.dart'; @@ -43,6 +44,13 @@ class _ConnectionPageState extends State bool isWindowMinimized = false; List peers = []; + List _frontN(List list, int n) { + if (list.length <= n) { + return list; + } else { + return list.sublist(0, n); + } + } @override void initState() { @@ -280,37 +288,27 @@ class _ConnectionPageState extends State )); }, optionsViewBuilder: (BuildContext context, AutocompleteOnSelected onSelected, Iterable options) { - return Align( - alignment: Alignment.topLeft, - child: Material( - elevation: 4.0, - child: ConstrainedBox( - constraints: BoxConstraints( - maxHeight: 200.0, + double maxHeight = 0; + for (var peer in options) { + if (maxHeight < 200) + maxHeight += 47; + } + return Align( + alignment: Alignment.topLeft, + child: Material( + elevation: 4, + child: ConstrainedBox( + constraints: BoxConstraints( + maxHeight: maxHeight, + maxWidth: 320, + ), + child: ListView( + children: options + .map((peer) => _buildPeerTile(context, peer, null)) + .toList() + ), ), - child: SingleChildScrollView( - child: Column( - mainAxisSize: MainAxisSize.min, - children: options.map((peer) { - return ListTile( - // title: Text(peer.id), - title: Text(peer.id.length <= 6 ? peer.id : peer.id.substring(0, 6)), - subtitle: Row( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text(peer.username), - Text(peer.hostname), - Text(peer.platform), - for (var tag in peer.tags) - Text(tag), - ], - ), - onTap: () { - onSelected(peer); - }, - ); - }).toList(), - )))) + ), ); }, ) @@ -342,6 +340,104 @@ class _ConnectionPageState extends State constraints: const BoxConstraints(maxWidth: 600), child: w); } + Widget _buildPeerTile( + BuildContext context, Peer peer, Rx? deco) { + final double _tileRadius = 5; + final name = + '${peer.username}${peer.username.isNotEmpty && peer.hostname.isNotEmpty ? '@' : ''}${peer.hostname}'; + final greyStyle = TextStyle( + fontSize: 11, + color: Theme.of(context).textTheme.titleLarge?.color?.withOpacity(0.6)); + final child = Container( + height: 42, + margin: EdgeInsets.only(bottom: 5), + child: Row( + mainAxisSize: MainAxisSize.max, + children: [ + 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, + height: null, + child: getPlatformImage(peer.platform, size: 30) + .paddingAll(6), + ), + Expanded( + child: Container( + decoration: BoxDecoration( + color: Theme.of(context).colorScheme.background, + borderRadius: BorderRadius.only( + topRight: Radius.circular(_tileRadius), + bottomRight: Radius.circular(_tileRadius), + ), + ), + child: Row( + children: [ + Expanded( + child: Column( + children: [ + Row(children: [ + getOnline(8, peer.online), + Expanded( + child: Text( + peer.alias.isEmpty ? formatID(peer.id) : peer.alias, + overflow: TextOverflow.ellipsis, + style: Theme.of(context).textTheme.titleSmall, + )), + ]).marginOnly(top: 2), + Align( + alignment: Alignment.centerLeft, + child: Text( + name, + style: greyStyle, + textAlign: TextAlign.start, + overflow: TextOverflow.ellipsis, + ), + ), + ], + ).marginOnly(top: 2), + ), + ], + ).paddingOnly(left: 10.0, top: 3.0), + ), + ) + ], + )); + final colors = + _frontN(peer.tags, 25).map((e) => gFFI.abModel.getTagColor(e)).toList(); + return Tooltip( + message: isMobile + ? '' + : peer.tags.isNotEmpty + ? '${translate('Tags')}: ${peer.tags.join(', ')}' + : '', + child: Stack(children: [ + deco == null + ? child + : Obx( + () => Container( + foregroundDecoration: deco.value, + child: child, + ), + ), + if (colors.isNotEmpty) + Positioned( + top: 5, + right: 10, + child: CustomPaint( + painter: TagPainter(radius: 3, colors: colors), + ), + ) + ]), + ); + } + Widget buildStatus() { final em = 14.0; return Container( From 95e3fb24f3a4673ec1b9b5fe4628ceaf624ee9d9 Mon Sep 17 00:00:00 2001 From: Sahil Yeole Date: Sat, 14 Oct 2023 03:09:59 +0530 Subject: [PATCH 05/24] add ontap for autocomplete Signed-off-by: Sahil Yeole --- flutter/lib/desktop/pages/connection_page.dart | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/flutter/lib/desktop/pages/connection_page.dart b/flutter/lib/desktop/pages/connection_page.dart index 959a94a40..a3b6d646d 100644 --- a/flutter/lib/desktop/pages/connection_page.dart +++ b/flutter/lib/desktop/pages/connection_page.dart @@ -155,7 +155,6 @@ class _ConnectionPageState extends State /// UI for the remote ID TextField. /// Search for a peer and connect to it if the id exists. Widget _buildRemoteIDTextField(BuildContext context) { - final TextEditingController fieldTextEditingController = TextEditingController.fromValue(_idController.value); var w = Container( width: 320 + 20 * 2, padding: const EdgeInsets.fromLTRB(20, 24, 20, 22), @@ -348,7 +347,13 @@ class _ConnectionPageState extends State final greyStyle = TextStyle( fontSize: 11, color: Theme.of(context).textTheme.titleLarge?.color?.withOpacity(0.6)); - final child = Container( + final child = GestureDetector( + onTap: () { + _idController.id = peer.id; + onConnect(); + }, + child: + Container( height: 42, margin: EdgeInsets.only(bottom: 5), child: Row( @@ -408,7 +413,7 @@ class _ConnectionPageState extends State ), ) ], - )); + ))); final colors = _frontN(peer.tags, 25).map((e) => gFFI.abModel.getTagColor(e)).toList(); return Tooltip( From 7b5801920b8a54e43653c1c774721a18a24df289 Mon Sep 17 00:00:00 2001 From: Sahil Yeole Date: Sun, 15 Oct 2023 03:34:53 +0530 Subject: [PATCH 06/24] update focusnode and texteditingcontroller for autocomplete Signed-off-by: Sahil Yeole --- .../lib/desktop/pages/connection_page.dart | 30 +++++++++++++++---- 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/flutter/lib/desktop/pages/connection_page.dart b/flutter/lib/desktop/pages/connection_page.dart index a3b6d646d..db233fdbb 100644 --- a/flutter/lib/desktop/pages/connection_page.dart +++ b/flutter/lib/desktop/pages/connection_page.dart @@ -253,15 +253,20 @@ class _ConnectionPageState extends State TextEditingController fieldTextEditingController, FocusNode fieldFocusNode , VoidCallback onFieldSubmitted, - ) { + fieldTextEditingController.text = _idController.text; + fieldFocusNode.addListener(() { + _idInputFocused.value = fieldFocusNode.hasFocus; + // select all to faciliate removing text, just following the behavior of address input of chrome + _idController.selection = TextSelection( + baseOffset: 0, extentOffset: _idController.value.text.length); + }); return Obx(() => TextField( maxLength: 90, autocorrect: false, enableSuggestions: false, keyboardType: TextInputType.visiblePassword, - // focusNode: _idFocusNode, focusNode: fieldFocusNode, style: const TextStyle( fontFamily: 'WorkSans', @@ -278,11 +283,22 @@ class _ConnectionPageState extends State : translate('Enter Remote ID'), contentPadding: const EdgeInsets.symmetric( horizontal: 15, vertical: 13)), - // controller: _idController, controller: fieldTextEditingController, inputFormatters: [IDTextInputFormatter()], + onChanged: (v) { + _idController.id = v; + }, onSubmitted: (s) { - onConnect(); + if (s == '') { + return; + } + try { + final id = int.parse(s); + _idController.id = s; + onConnect(); + } catch (_) { + return; + } }, )); }, @@ -349,8 +365,10 @@ class _ConnectionPageState extends State color: Theme.of(context).textTheme.titleLarge?.color?.withOpacity(0.6)); final child = GestureDetector( onTap: () { - _idController.id = peer.id; - onConnect(); + setState(() { + _idController.id = peer.id; + FocusScope.of(context).unfocus(); + }); }, child: Container( From 8127ce18a3b7f42e666a2a3079f9d89974768518 Mon Sep 17 00:00:00 2001 From: Sahil Yeole Date: Sun, 15 Oct 2023 04:53:57 +0530 Subject: [PATCH 07/24] optimise autocomplete Signed-off-by: Sahil Yeole --- .../lib/desktop/pages/connection_page.dart | 95 ++++++++++--------- 1 file changed, 49 insertions(+), 46 deletions(-) diff --git a/flutter/lib/desktop/pages/connection_page.dart b/flutter/lib/desktop/pages/connection_page.dart index db233fdbb..8ca3c549a 100644 --- a/flutter/lib/desktop/pages/connection_page.dart +++ b/flutter/lib/desktop/pages/connection_page.dart @@ -152,9 +152,57 @@ class _ConnectionPageState extends State connect(context, id, isFileTransfer: isFileTransfer); } + void getAllPeers(){ + peers.clear(); + Map recentPeers = jsonDecode(bind.mainLoadRecentPeersSync()); + Map favPeers = jsonDecode(bind.mainLoadFavPeersSync()); + Map lanPeers = jsonDecode(bind.mainLoadLanPeersSync()); + Map abPeers = jsonDecode(bind.mainLoadAbSync()); + Map groupPeers = jsonDecode(bind.mainLoadGroupSync()); + + Map combinedPeers = {}; + + void mergePeers(Map peers) { + if (peers.containsKey("peers")) { + dynamic peerData = peers["peers"]; + + if (peerData is String) { + try { + peerData = jsonDecode(peerData); + } catch (e) { + print("Error decoding peers: $e"); + return; + } + } + + if (peerData is List) { + for (var peer in peerData) { + if (peer is Map && peer.containsKey("id")) { + String id = peer["id"]; + if (id != null && !combinedPeers.containsKey(id)) { + combinedPeers[id] = peer; + } + } + } + } + } + } + + mergePeers(recentPeers); + mergePeers(favPeers); + mergePeers(lanPeers); + mergePeers(abPeers); + mergePeers(groupPeers); + + for (var peer in combinedPeers.values) { + peers.add(Peer.fromJson(peer)); + } + } + /// UI for the remote ID TextField. - /// Search for a peer and connect to it if the id exists. + /// Search for a peer. Widget _buildRemoteIDTextField(BuildContext context) { + getAllPeers(); var w = Container( width: 320 + 20 * 2, padding: const EdgeInsets.fromLTRB(20, 24, 20, 22), @@ -188,51 +236,6 @@ class _ConnectionPageState extends State return const Iterable.empty(); } else { - peers.clear(); - Map recentPeers = jsonDecode(bind.mainLoadRecentPeersSync()); - Map favPeers = jsonDecode(bind.mainLoadFavPeersSync()); - Map lanPeers = jsonDecode(bind.mainLoadLanPeersSync()); - Map abPeers = jsonDecode(bind.mainLoadAbSync()); - Map groupPeers = jsonDecode(bind.mainLoadGroupSync()); - - Map combinedPeers = {}; - - void mergePeers(Map peers) { - if (peers.containsKey("peers")) { - dynamic peerData = peers["peers"]; - - if (peerData is String) { - try { - peerData = jsonDecode(peerData); - } catch (e) { - print("Error decoding peers: $e"); - return; - } - } - - if (peerData is List) { - for (var peer in peerData) { - if (peer is Map && peer.containsKey("id")) { - String id = peer["id"]; - if (id != null && !combinedPeers.containsKey(id)) { - combinedPeers[id] = peer; - } - } - } - } - } - } - - mergePeers(recentPeers); - mergePeers(favPeers); - mergePeers(lanPeers); - mergePeers(abPeers); - mergePeers(groupPeers); - - for (var peer in combinedPeers.values) { - peers.add(Peer.fromJson(peer)); - } - if (textEditingValue.text.contains(" ")) { textEditingValue = TextEditingValue( text: textEditingValue.text.replaceAll(" ", ""), From 2d6322f7993e7fac262ad81e87625a35dc35dfe0 Mon Sep 17 00:00:00 2001 From: Sahil Yeole Date: Sun, 15 Oct 2023 04:59:03 +0530 Subject: [PATCH 08/24] remove extra parameter from peer tile Signed-off-by: Sahil Yeole --- flutter/lib/desktop/pages/connection_page.dart | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/flutter/lib/desktop/pages/connection_page.dart b/flutter/lib/desktop/pages/connection_page.dart index 8ca3c549a..f4f92b88f 100644 --- a/flutter/lib/desktop/pages/connection_page.dart +++ b/flutter/lib/desktop/pages/connection_page.dart @@ -322,7 +322,7 @@ class _ConnectionPageState extends State ), child: ListView( children: options - .map((peer) => _buildPeerTile(context, peer, null)) + .map((peer) => _buildPeerTile(context, peer)) .toList() ), ), @@ -359,7 +359,7 @@ class _ConnectionPageState extends State } Widget _buildPeerTile( - BuildContext context, Peer peer, Rx? deco) { + BuildContext context, Peer peer) { final double _tileRadius = 5; final name = '${peer.username}${peer.username.isNotEmpty && peer.hostname.isNotEmpty ? '@' : ''}${peer.hostname}'; @@ -444,14 +444,7 @@ class _ConnectionPageState extends State ? '${translate('Tags')}: ${peer.tags.join(', ')}' : '', child: Stack(children: [ - deco == null - ? child - : Obx( - () => Container( - foregroundDecoration: deco.value, - child: child, - ), - ), + child, if (colors.isNotEmpty) Positioned( top: 5, From 4a42e3ef1bbc58b809260d0f18ffdf398f5a90b3 Mon Sep 17 00:00:00 2001 From: Sahil Yeole Date: Mon, 16 Oct 2023 23:06:14 +0530 Subject: [PATCH 09/24] add padding autocomplete Signed-off-by: Sahil Yeole --- flutter/lib/desktop/pages/connection_page.dart | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/flutter/lib/desktop/pages/connection_page.dart b/flutter/lib/desktop/pages/connection_page.dart index f4f92b88f..0e43b7ba4 100644 --- a/flutter/lib/desktop/pages/connection_page.dart +++ b/flutter/lib/desktop/pages/connection_page.dart @@ -309,7 +309,7 @@ class _ConnectionPageState extends State double maxHeight = 0; for (var peer in options) { if (maxHeight < 200) - maxHeight += 47; + maxHeight += 52; } return Align( alignment: Alignment.topLeft, @@ -320,10 +320,13 @@ class _ConnectionPageState extends State maxHeight: maxHeight, maxWidth: 320, ), - child: ListView( - children: options - .map((peer) => _buildPeerTile(context, peer)) - .toList() + child: Padding( + padding: const EdgeInsets.only(top: 5), + child: ListView( + children: options + .map((peer) => _buildPeerTile(context, peer)) + .toList() + ), ), ), ), From 26982787ee643811fb0d738921527ac6d2e3a56a Mon Sep 17 00:00:00 2001 From: Sahil Yeole Date: Mon, 16 Oct 2023 23:36:43 +0530 Subject: [PATCH 10/24] make getAllPeers async Signed-off-by: Sahil Yeole --- flutter/lib/desktop/pages/connection_page.dart | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/flutter/lib/desktop/pages/connection_page.dart b/flutter/lib/desktop/pages/connection_page.dart index 0e43b7ba4..1f221aa5e 100644 --- a/flutter/lib/desktop/pages/connection_page.dart +++ b/flutter/lib/desktop/pages/connection_page.dart @@ -152,13 +152,13 @@ class _ConnectionPageState extends State connect(context, id, isFileTransfer: isFileTransfer); } - void getAllPeers(){ - peers.clear(); - Map recentPeers = jsonDecode(bind.mainLoadRecentPeersSync()); - Map favPeers = jsonDecode(bind.mainLoadFavPeersSync()); - Map lanPeers = jsonDecode(bind.mainLoadLanPeersSync()); - Map abPeers = jsonDecode(bind.mainLoadAbSync()); - Map groupPeers = jsonDecode(bind.mainLoadGroupSync()); + Future getAllPeers() async { + peers.clear(); + Map recentPeers = jsonDecode(await bind.mainLoadRecentPeersSync()); + Map favPeers = jsonDecode(await bind.mainLoadFavPeersSync()); + Map lanPeers = jsonDecode(await bind.mainLoadLanPeersSync()); + Map abPeers = jsonDecode(await bind.mainLoadAbSync()); + Map groupPeers = jsonDecode(await bind.mainLoadGroupSync()); Map combinedPeers = {}; @@ -170,7 +170,7 @@ class _ConnectionPageState extends State try { peerData = jsonDecode(peerData); } catch (e) { - print("Error decoding peers: $e"); + debugPrint("Error decoding peers: $e"); return; } } From 182f2ae26e8ad6a9b655ed54b71c0e659ed1a59f Mon Sep 17 00:00:00 2001 From: Sahil Yeole Date: Tue, 17 Oct 2023 01:34:00 +0530 Subject: [PATCH 11/24] add search for alias Signed-off-by: Sahil Yeole --- flutter/lib/desktop/pages/connection_page.dart | 1 + 1 file changed, 1 insertion(+) diff --git a/flutter/lib/desktop/pages/connection_page.dart b/flutter/lib/desktop/pages/connection_page.dart index 1f221aa5e..78f7844a9 100644 --- a/flutter/lib/desktop/pages/connection_page.dart +++ b/flutter/lib/desktop/pages/connection_page.dart @@ -247,6 +247,7 @@ class _ConnectionPageState extends State peer.id.toLowerCase().contains(textEditingValue.text.toLowerCase()) || peer.username.toLowerCase().contains(textEditingValue.text.toLowerCase()) || peer.hostname.toLowerCase().contains(textEditingValue.text.toLowerCase()) || + peer.alias.toLowerCase().contains(textEditingValue.text.toLowerCase()) || peer.platform.toLowerCase().contains(textEditingValue.text.toLowerCase())) .toList(); } From e0985ebb1c5931ef5fa390882b57a4c3b6aacb05 Mon Sep 17 00:00:00 2001 From: Sahil Yeole Date: Tue, 17 Oct 2023 18:22:27 +0530 Subject: [PATCH 12/24] add peers loading indicator Signed-off-by: Sahil Yeole --- .../lib/desktop/pages/connection_page.dart | 54 ++++++++++++++++--- 1 file changed, 47 insertions(+), 7 deletions(-) diff --git a/flutter/lib/desktop/pages/connection_page.dart b/flutter/lib/desktop/pages/connection_page.dart index 78f7844a9..7c4da7d9c 100644 --- a/flutter/lib/desktop/pages/connection_page.dart +++ b/flutter/lib/desktop/pages/connection_page.dart @@ -51,6 +51,7 @@ class _ConnectionPageState extends State return list.sublist(0, n); } } + bool isPeersLoading = false; @override void initState() { @@ -152,8 +153,18 @@ class _ConnectionPageState extends State connect(context, id, isFileTransfer: isFileTransfer); } - Future getAllPeers() async { - peers.clear(); + Future _fetchPeers() async { + setState(() { + isPeersLoading = true; + }); + await Future.delayed(Duration(milliseconds: 100)); + await _getAllPeers(); + setState(() { + isPeersLoading = false; + }); + } + + Future _getAllPeers() async { Map recentPeers = jsonDecode(await bind.mainLoadRecentPeersSync()); Map favPeers = jsonDecode(await bind.mainLoadFavPeersSync()); Map lanPeers = jsonDecode(await bind.mainLoadLanPeersSync()); @@ -194,15 +205,17 @@ class _ConnectionPageState extends State mergePeers(abPeers); mergePeers(groupPeers); + List parsedPeers = []; + for (var peer in combinedPeers.values) { - peers.add(Peer.fromJson(peer)); + parsedPeers.add(Peer.fromJson(peer)); } + peers = parsedPeers; } /// UI for the remote ID TextField. /// Search for a peer. Widget _buildRemoteIDTextField(BuildContext context) { - getAllPeers(); var w = Container( width: 320 + 20 * 2, padding: const EdgeInsets.fromLTRB(20, 24, 20, 22), @@ -235,6 +248,22 @@ class _ConnectionPageState extends State if (textEditingValue.text == '') { return const Iterable.empty(); } + else if (peers.isEmpty) { + Peer emptyPeer = Peer( + id: '', + username: '', + hostname: '', + alias: '', + platform: '', + tags: [], + hash: '', + forceAlwaysRelay: false, + rdpPort: '', + rdpUsername: '', + loginName: '', + ); + return [emptyPeer]; + } else { if (textEditingValue.text.contains(" ")) { textEditingValue = TextEditingValue( @@ -261,6 +290,9 @@ class _ConnectionPageState extends State fieldTextEditingController.text = _idController.text; fieldFocusNode.addListener(() { _idInputFocused.value = fieldFocusNode.hasFocus; + if (fieldFocusNode.hasFocus && !isPeersLoading){ + _fetchPeers(); + } // select all to faciliate removing text, just following the behavior of address input of chrome _idController.selection = TextSelection( baseOffset: 0, extentOffset: _idController.value.text.length); @@ -310,8 +342,7 @@ class _ConnectionPageState extends State double maxHeight = 0; for (var peer in options) { if (maxHeight < 200) - maxHeight += 52; - } + maxHeight += 50; }; return Align( alignment: Alignment.topLeft, child: Material( @@ -321,7 +352,16 @@ class _ConnectionPageState extends State maxHeight: maxHeight, maxWidth: 320, ), - child: Padding( + child: peers.isEmpty && isPeersLoading + ? Container( + height: 80, + child: Center( + child: CircularProgressIndicator( + strokeWidth: 2, + ), + ) + ) + : Padding( padding: const EdgeInsets.only(top: 5), child: ListView( children: options From c00d4c1a7bb1989df98acc276e697c9f05203a3c Mon Sep 17 00:00:00 2001 From: Sahil Yeole Date: Tue, 17 Oct 2023 18:23:44 +0530 Subject: [PATCH 13/24] update _fetchPeers Signed-off-by: Sahil Yeole --- flutter/lib/desktop/pages/connection_page.dart | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/flutter/lib/desktop/pages/connection_page.dart b/flutter/lib/desktop/pages/connection_page.dart index 7c4da7d9c..f9984b955 100644 --- a/flutter/lib/desktop/pages/connection_page.dart +++ b/flutter/lib/desktop/pages/connection_page.dart @@ -157,11 +157,11 @@ class _ConnectionPageState extends State setState(() { isPeersLoading = true; }); - await Future.delayed(Duration(milliseconds: 100)); - await _getAllPeers(); - setState(() { - isPeersLoading = false; - }); + await Future.delayed(Duration(milliseconds: 100)); + await _getAllPeers(); + setState(() { + isPeersLoading = false; + }); } Future _getAllPeers() async { From 1ad740800b49e5266f02c40a238ca18d2e419035 Mon Sep 17 00:00:00 2001 From: Sahil Yeole Date: Tue, 17 Oct 2023 18:35:38 +0530 Subject: [PATCH 14/24] remove spaces only if number Signed-off-by: Sahil Yeole --- .../lib/desktop/pages/connection_page.dart | 27 ++++++++++--------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/flutter/lib/desktop/pages/connection_page.dart b/flutter/lib/desktop/pages/connection_page.dart index f9984b955..944fd0370 100644 --- a/flutter/lib/desktop/pages/connection_page.dart +++ b/flutter/lib/desktop/pages/connection_page.dart @@ -265,20 +265,21 @@ class _ConnectionPageState extends State return [emptyPeer]; } else { - if (textEditingValue.text.contains(" ")) { - textEditingValue = TextEditingValue( - text: textEditingValue.text.replaceAll(" ", ""), - selection: textEditingValue.selection, - ); - } + String textWithoutSpaces = textEditingValue.text.replaceAll(" ", ""); + if (int.tryParse(textWithoutSpaces) != null) { + textEditingValue = TextEditingValue( + text: textWithoutSpaces, + selection: textEditingValue.selection, + ); + } - return peers.where((peer) => - peer.id.toLowerCase().contains(textEditingValue.text.toLowerCase()) || - peer.username.toLowerCase().contains(textEditingValue.text.toLowerCase()) || - peer.hostname.toLowerCase().contains(textEditingValue.text.toLowerCase()) || - peer.alias.toLowerCase().contains(textEditingValue.text.toLowerCase()) || - peer.platform.toLowerCase().contains(textEditingValue.text.toLowerCase())) - .toList(); + return peers.where((peer) => + peer.id.toLowerCase().contains(textEditingValue.text.toLowerCase()) || + peer.username.toLowerCase().contains(textEditingValue.text.toLowerCase()) || + peer.hostname.toLowerCase().contains(textEditingValue.text.toLowerCase()) || + peer.alias.toLowerCase().contains(textEditingValue.text.toLowerCase()) || + peer.platform.toLowerCase().contains(textEditingValue.text.toLowerCase())) + .toList(); } }, From 9e2c9cbba93f6ddb86417fa9ea8ba3637ec6de69 Mon Sep 17 00:00:00 2001 From: Sahil Yeole Date: Tue, 17 Oct 2023 18:57:53 +0530 Subject: [PATCH 15/24] add border radius Signed-off-by: Sahil Yeole --- flutter/lib/desktop/pages/connection_page.dart | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/flutter/lib/desktop/pages/connection_page.dart b/flutter/lib/desktop/pages/connection_page.dart index 944fd0370..db0aaf801 100644 --- a/flutter/lib/desktop/pages/connection_page.dart +++ b/flutter/lib/desktop/pages/connection_page.dart @@ -346,12 +346,14 @@ class _ConnectionPageState extends State maxHeight += 50; }; return Align( alignment: Alignment.topLeft, - child: Material( + child: ClipRRect( + borderRadius: BorderRadius.circular(5), + child: Material( elevation: 4, child: ConstrainedBox( constraints: BoxConstraints( maxHeight: maxHeight, - maxWidth: 320, + maxWidth: 319, ), child: peers.isEmpty && isPeersLoading ? Container( @@ -371,7 +373,7 @@ class _ConnectionPageState extends State ), ), ), - ), + )), ); }, ) From 149d57150c732d0927e87f3ee95a73c767973cf9 Mon Sep 17 00:00:00 2001 From: Sahil Yeole Date: Tue, 17 Oct 2023 21:29:05 +0530 Subject: [PATCH 16/24] attempt fix text selection Signed-off-by: Sahil Yeole --- flutter/lib/desktop/pages/connection_page.dart | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/flutter/lib/desktop/pages/connection_page.dart b/flutter/lib/desktop/pages/connection_page.dart index db0aaf801..604cd3f93 100644 --- a/flutter/lib/desktop/pages/connection_page.dart +++ b/flutter/lib/desktop/pages/connection_page.dart @@ -69,12 +69,6 @@ class _ConnectionPageState extends State _updateTimer = periodic_immediate(Duration(seconds: 1), () async { updateStatus(); }); - _idFocusNode.addListener(() { - _idInputFocused.value = _idFocusNode.hasFocus; - // select all to faciliate removing text, just following the behavior of address input of chrome - _idController.selection = TextSelection( - baseOffset: 0, extentOffset: _idController.value.text.length); - }); Get.put(_idController); windowManager.addListener(this); } @@ -289,14 +283,16 @@ class _ConnectionPageState extends State VoidCallback onFieldSubmitted, ) { fieldTextEditingController.text = _idController.text; - fieldFocusNode.addListener(() { + fieldFocusNode.addListener(() async { _idInputFocused.value = fieldFocusNode.hasFocus; if (fieldFocusNode.hasFocus && !isPeersLoading){ _fetchPeers(); } - // select all to faciliate removing text, just following the behavior of address input of chrome - _idController.selection = TextSelection( - baseOffset: 0, extentOffset: _idController.value.text.length); + // select all to facilitate removing text, just following the behavior of address input of chrome + final textLength = fieldTextEditingController.value.text.length; + await Future.delayed(Duration(milliseconds: 200)); + fieldTextEditingController.selection = TextSelection.collapsed(offset: textLength); + fieldTextEditingController.selection = TextSelection(baseOffset: 0, extentOffset: textLength); }); return Obx(() => TextField( From 5d95d61aefe8f94e6805b0980866ff5c558205be Mon Sep 17 00:00:00 2001 From: Sahil Yeole Date: Wed, 18 Oct 2023 14:40:29 +0530 Subject: [PATCH 17/24] remove fav peers from search Signed-off-by: Sahil Yeole --- flutter/lib/desktop/pages/connection_page.dart | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/flutter/lib/desktop/pages/connection_page.dart b/flutter/lib/desktop/pages/connection_page.dart index 604cd3f93..a19a70c99 100644 --- a/flutter/lib/desktop/pages/connection_page.dart +++ b/flutter/lib/desktop/pages/connection_page.dart @@ -271,8 +271,7 @@ class _ConnectionPageState extends State peer.id.toLowerCase().contains(textEditingValue.text.toLowerCase()) || peer.username.toLowerCase().contains(textEditingValue.text.toLowerCase()) || peer.hostname.toLowerCase().contains(textEditingValue.text.toLowerCase()) || - peer.alias.toLowerCase().contains(textEditingValue.text.toLowerCase()) || - peer.platform.toLowerCase().contains(textEditingValue.text.toLowerCase())) + peer.alias.toLowerCase().contains(textEditingValue.text.toLowerCase())) .toList(); } }, From 05c789ae5076484b11aad6dac26e68bff3926720 Mon Sep 17 00:00:00 2001 From: Sahil Yeole Date: Wed, 18 Oct 2023 16:00:50 +0530 Subject: [PATCH 18/24] remove fav peers from search Signed-off-by: Sahil Yeole --- .../lib/desktop/pages/connection_page.dart | 2 - src/flutter_ffi.rs | 47 ------------------- 2 files changed, 49 deletions(-) diff --git a/flutter/lib/desktop/pages/connection_page.dart b/flutter/lib/desktop/pages/connection_page.dart index a19a70c99..40cb4100f 100644 --- a/flutter/lib/desktop/pages/connection_page.dart +++ b/flutter/lib/desktop/pages/connection_page.dart @@ -160,7 +160,6 @@ class _ConnectionPageState extends State Future _getAllPeers() async { Map recentPeers = jsonDecode(await bind.mainLoadRecentPeersSync()); - Map favPeers = jsonDecode(await bind.mainLoadFavPeersSync()); Map lanPeers = jsonDecode(await bind.mainLoadLanPeersSync()); Map abPeers = jsonDecode(await bind.mainLoadAbSync()); Map groupPeers = jsonDecode(await bind.mainLoadGroupSync()); @@ -194,7 +193,6 @@ class _ConnectionPageState extends State } mergePeers(recentPeers); - mergePeers(favPeers); mergePeers(lanPeers); mergePeers(abPeers); mergePeers(groupPeers); diff --git a/src/flutter_ffi.rs b/src/flutter_ffi.rs index 2a714d949..4636bca08 100644 --- a/src/flutter_ffi.rs +++ b/src/flutter_ffi.rs @@ -886,53 +886,6 @@ pub fn main_load_recent_peers_sync() -> SyncReturn { SyncReturn("".to_string()) } -pub fn main_load_fav_peers_sync() -> SyncReturn { - if !config::APP_DIR.read().unwrap().is_empty() { - let favs = get_fav(); - let mut recent = PeerConfig::peers(None); - let mut lan = config::LanPeers::load() - .peers - .iter() - .filter(|d| recent.iter().all(|r| r.0 != d.id)) - .map(|d| { - ( - d.id.clone(), - SystemTime::UNIX_EPOCH, - PeerConfig { - info: PeerInfoSerde { - username: d.username.clone(), - hostname: d.hostname.clone(), - platform: d.platform.clone(), - }, - ..Default::default() - }, - ) - }) - .collect(); - recent.append(&mut lan); - let peers: Vec> = recent - .into_iter() - .filter_map(|(id, _, p)| { - if favs.contains(&id) { - Some(peer_to_map(id, p)) - } else { - None - } - }) - .collect(); - - let data = HashMap::from([ - ("name", "load_fav_peers".to_owned()), - ( - "peers", - serde_json::ser::to_string(&peers).unwrap_or("".to_owned()), - ), - ]); - return SyncReturn(serde_json::ser::to_string(&data).unwrap_or("".to_owned())); - } - SyncReturn("".to_string()) -} - pub fn main_load_lan_peers_sync() -> SyncReturn { let data = HashMap::from([ ("name", "load_lan_peers".to_owned()), From cfc0925e75a031849e8d309d7558dbee3f8a899d Mon Sep 17 00:00:00 2001 From: Sahil Yeole Date: Fri, 20 Oct 2023 01:35:54 +0530 Subject: [PATCH 19/24] reduce toLowerCase Signed-off-by: Sahil Yeole --- flutter/lib/desktop/pages/connection_page.dart | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/flutter/lib/desktop/pages/connection_page.dart b/flutter/lib/desktop/pages/connection_page.dart index 40cb4100f..0eca17eac 100644 --- a/flutter/lib/desktop/pages/connection_page.dart +++ b/flutter/lib/desktop/pages/connection_page.dart @@ -258,6 +258,7 @@ class _ConnectionPageState extends State } else { String textWithoutSpaces = textEditingValue.text.replaceAll(" ", ""); + String textToFind = textWithoutSpaces.toLowerCase(); if (int.tryParse(textWithoutSpaces) != null) { textEditingValue = TextEditingValue( text: textWithoutSpaces, @@ -266,10 +267,10 @@ class _ConnectionPageState extends State } return peers.where((peer) => - peer.id.toLowerCase().contains(textEditingValue.text.toLowerCase()) || - peer.username.toLowerCase().contains(textEditingValue.text.toLowerCase()) || - peer.hostname.toLowerCase().contains(textEditingValue.text.toLowerCase()) || - peer.alias.toLowerCase().contains(textEditingValue.text.toLowerCase())) + peer.id.toLowerCase().contains(textToFind) || + peer.username.toLowerCase().contains(textToFind) || + peer.hostname.toLowerCase().contains(textToFind) || + peer.alias.toLowerCase().contains(textToFind)) .toList(); } }, From f4b0b39beb77b0d07d1114ae06a290438bcfcbd4 Mon Sep 17 00:00:00 2001 From: Sahil Yeole Date: Fri, 20 Oct 2023 02:40:54 +0530 Subject: [PATCH 20/24] show id if alias exists Signed-off-by: Sahil Yeole --- flutter/lib/desktop/pages/connection_page.dart | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/flutter/lib/desktop/pages/connection_page.dart b/flutter/lib/desktop/pages/connection_page.dart index 0eca17eac..b6ac07672 100644 --- a/flutter/lib/desktop/pages/connection_page.dart +++ b/flutter/lib/desktop/pages/connection_page.dart @@ -457,6 +457,16 @@ class _ConnectionPageState extends State overflow: TextOverflow.ellipsis, style: Theme.of(context).textTheme.titleSmall, )), + !peer.alias.isEmpty? + Padding( + padding: const EdgeInsets.only(left: 5, right: 5), + child: Text( + "(${peer.id})", + style: greyStyle, + overflow: TextOverflow.ellipsis, + ) + ) + : Container(), ]).marginOnly(top: 2), Align( alignment: Alignment.centerLeft, From e8c4615ff6781f06bbdb4df8819bdcf459454f9f Mon Sep 17 00:00:00 2001 From: Sahil Yeole Date: Fri, 20 Oct 2023 04:34:50 +0530 Subject: [PATCH 21/24] improve text selection Signed-off-by: Sahil Yeole --- flutter/lib/desktop/pages/connection_page.dart | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/flutter/lib/desktop/pages/connection_page.dart b/flutter/lib/desktop/pages/connection_page.dart index b6ac07672..0b15404ca 100644 --- a/flutter/lib/desktop/pages/connection_page.dart +++ b/flutter/lib/desktop/pages/connection_page.dart @@ -12,6 +12,7 @@ import 'package:get/get.dart'; import 'package:url_launcher/url_launcher_string.dart'; import 'package:window_manager/window_manager.dart'; import 'package:flutter_hbb/models/peer_model.dart'; +import 'package:flutter/scheduler.dart'; import '../../common.dart'; import '../../common/formatter/id_formatter.dart'; @@ -287,10 +288,13 @@ class _ConnectionPageState extends State _fetchPeers(); } // select all to facilitate removing text, just following the behavior of address input of chrome - final textLength = fieldTextEditingController.value.text.length; - await Future.delayed(Duration(milliseconds: 200)); - fieldTextEditingController.selection = TextSelection.collapsed(offset: textLength); - fieldTextEditingController.selection = TextSelection(baseOffset: 0, extentOffset: textLength); + SchedulerBinding.instance.addPostFrameCallback((_) { + final textLength = fieldTextEditingController.value.text.length; + Future.delayed(Duration(milliseconds: 150) , () { + fieldTextEditingController.selection = TextSelection.collapsed(offset: textLength); + fieldTextEditingController.selection = TextSelection(baseOffset: 0, extentOffset: textLength); + }); + }); }); return Obx(() => TextField( From 00555a8e9e9a381833a2530729887d70f3b946e2 Mon Sep 17 00:00:00 2001 From: Sahil Yeole Date: Fri, 20 Oct 2023 04:44:53 +0530 Subject: [PATCH 22/24] fix text selection Signed-off-by: Sahil Yeole --- flutter/lib/desktop/pages/connection_page.dart | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/flutter/lib/desktop/pages/connection_page.dart b/flutter/lib/desktop/pages/connection_page.dart index 0b15404ca..e714d979f 100644 --- a/flutter/lib/desktop/pages/connection_page.dart +++ b/flutter/lib/desktop/pages/connection_page.dart @@ -287,15 +287,10 @@ class _ConnectionPageState extends State if (fieldFocusNode.hasFocus && !isPeersLoading){ _fetchPeers(); } - // select all to facilitate removing text, just following the behavior of address input of chrome - SchedulerBinding.instance.addPostFrameCallback((_) { - final textLength = fieldTextEditingController.value.text.length; - Future.delayed(Duration(milliseconds: 150) , () { - fieldTextEditingController.selection = TextSelection.collapsed(offset: textLength); - fieldTextEditingController.selection = TextSelection(baseOffset: 0, extentOffset: textLength); - }); - }); }); + final textLength = fieldTextEditingController.value.text.length; + // select all to facilitate removing text, just following the behavior of address input of chrome + fieldTextEditingController.selection = TextSelection(baseOffset: 0, extentOffset: textLength); return Obx(() => TextField( maxLength: 90, From 4651d9df68fef8c185bcbaf4b726c563036ec2af Mon Sep 17 00:00:00 2001 From: Sahil Yeole Date: Fri, 20 Oct 2023 04:50:07 +0530 Subject: [PATCH 23/24] fix textToFind Signed-off-by: Sahil Yeole --- flutter/lib/desktop/pages/connection_page.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/flutter/lib/desktop/pages/connection_page.dart b/flutter/lib/desktop/pages/connection_page.dart index e714d979f..beae21d8b 100644 --- a/flutter/lib/desktop/pages/connection_page.dart +++ b/flutter/lib/desktop/pages/connection_page.dart @@ -259,13 +259,13 @@ class _ConnectionPageState extends State } else { String textWithoutSpaces = textEditingValue.text.replaceAll(" ", ""); - String textToFind = textWithoutSpaces.toLowerCase(); if (int.tryParse(textWithoutSpaces) != null) { textEditingValue = TextEditingValue( text: textWithoutSpaces, selection: textEditingValue.selection, ); } + String textToFind = textEditingValue.text.toLowerCase(); return peers.where((peer) => peer.id.toLowerCase().contains(textToFind) || From 7136400a33a02f9a3d712d1de0e9789a56f07b8e Mon Sep 17 00:00:00 2001 From: Sahil Yeole Date: Fri, 20 Oct 2023 05:11:07 +0530 Subject: [PATCH 24/24] remove scheduler import Signed-off-by: Sahil Yeole --- flutter/lib/desktop/pages/connection_page.dart | 1 - 1 file changed, 1 deletion(-) diff --git a/flutter/lib/desktop/pages/connection_page.dart b/flutter/lib/desktop/pages/connection_page.dart index beae21d8b..859fd0d70 100644 --- a/flutter/lib/desktop/pages/connection_page.dart +++ b/flutter/lib/desktop/pages/connection_page.dart @@ -12,7 +12,6 @@ import 'package:get/get.dart'; import 'package:url_launcher/url_launcher_string.dart'; import 'package:window_manager/window_manager.dart'; import 'package:flutter_hbb/models/peer_model.dart'; -import 'package:flutter/scheduler.dart'; import '../../common.dart'; import '../../common/formatter/id_formatter.dart';