diff --git a/flutter/lib/common.dart b/flutter/lib/common.dart index 643705d69..17e45ba95 100644 --- a/flutter/lib/common.dart +++ b/flutter/lib/common.dart @@ -8,6 +8,7 @@ import 'package:desktop_multi_window/desktop_multi_window.dart'; import 'package:flutter/gestures.dart'; import 'package:flutter/material.dart'; import 'package:flutter_hbb/desktop/widgets/tabbar_widget.dart'; +import 'package:flutter_hbb/models/peer_model.dart'; import 'package:get/get.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'package:window_manager/window_manager.dart'; @@ -704,3 +705,38 @@ String bool2option(String option, bool b) { } return res; } + +Future matchPeer(String searchText, Peer peer) async { + if (searchText.isEmpty) { + return true; + } + if (peer.id.toLowerCase().contains(searchText)) { + return true; + } + if (peer.hostname.toLowerCase().contains(searchText) || + peer.username.toLowerCase().contains(searchText)) { + return true; + } + final alias = await bind.mainGetPeerOption(id: peer.id, key: 'alias'); + if (alias.isEmpty) { + return false; + } + return alias.toLowerCase().contains(searchText); +} + +Future>? matchPeers(String searchText, List peers) async { + searchText = searchText.trim(); + if (searchText.isEmpty) { + return peers; + } + searchText = searchText.toLowerCase(); + final matches = + await Future.wait(peers.map((peer) => matchPeer(searchText, peer))); + final filteredList = List.empty(growable: true); + for (var i = 0; i < peers.length; i++) { + if (matches[i]) { + filteredList.add(peers[i]); + } + } + return filteredList; +} diff --git a/flutter/lib/desktop/widgets/peer_widget.dart b/flutter/lib/desktop/widgets/peer_widget.dart index fa79db624..3bfff60bf 100644 --- a/flutter/lib/desktop/widgets/peer_widget.dart +++ b/flutter/lib/desktop/widgets/peer_widget.dart @@ -88,40 +88,53 @@ class _PeerWidgetState extends State<_PeerWidget> with WindowListener { ) : SingleChildScrollView( child: ObxValue((searchText) { - final cards = []; - peers.peers.where((peer) { - if (searchText.isEmpty) { - return true; - } else { - return peer.id.contains(peerSearchText.value); - } - }).forEach((peer) { - cards.add(Offstage( - offstage: super.widget._offstageFunc(peer), - child: Obx( - () => Container( - width: 220, - height: peerCardUiType.value == PeerUiType.grid - ? 140 - : 42, - child: VisibilityDetector( - key: Key('${peer.id}'), - onVisibilityChanged: (info) { - final peerId = (info.key as ValueKey).value; - if (info.visibleFraction > 0.00001) { - _curPeers.add(peerId); - } else { - _curPeers.remove(peerId); - } - _lastChangeTime = DateTime.now(); - }, - child: super.widget._peerCardWidgetFunc(peer), - ), - ), - ))); - }); - return Wrap( - children: cards, spacing: space, runSpacing: space); + return FutureBuilder>( + builder: (context, snapshot) { + if (snapshot.hasData) { + final peers = snapshot.data!; + final cards = []; + for (final peer in peers) { + cards.add(Offstage( + key: ValueKey("off${peer.id}"), + offstage: super.widget._offstageFunc(peer), + child: Obx( + () => SizedBox( + width: 220, + height: + peerCardUiType.value == PeerUiType.grid + ? 140 + : 42, + child: VisibilityDetector( + key: ValueKey(peer.id), + onVisibilityChanged: (info) { + final peerId = + (info.key as ValueKey).value; + if (info.visibleFraction > 0.00001) { + _curPeers.add(peerId); + } else { + _curPeers.remove(peerId); + } + _lastChangeTime = DateTime.now(); + }, + child: super + .widget + ._peerCardWidgetFunc(peer), + ), + ), + ))); + } + return Wrap( + spacing: space, + runSpacing: space, + children: cards); + } else { + return const Center( + child: CircularProgressIndicator(), + ); + } + }, + future: matchPeers(searchText.value, peers.peers), + ); }, peerSearchText), )), ); diff --git a/src/ui/ab.tis b/src/ui/ab.tis index 658783623..ac2efb7dd 100644 --- a/src/ui/ab.tis +++ b/src/ui/ab.tis @@ -245,7 +245,7 @@ class SearchBar: Reactor.Component { } event change $(input) (_, el) { - this.onChange(el.value.trim()); + this.onChange(el.value.trim().toLowerCase()); } function onChange(v) { @@ -297,8 +297,13 @@ class SessionList: Reactor.Component { if (!p) return this.sessions; var tmp = []; this.sessions.map(function(s) { - var name = s[4] || s.alias || s[0] || s.id || ""; - if (name.indexOf(p) >= 0) tmp.push(s); + var name = (s[4] || s.alias || "").toLowerCase(); + var id = (s[0] || s.id || "").toLowerCase(); + var user = (s[1] || "").toLowerCase(); + var hostname = (s[2] || "").toLowerCase(); + if (name.indexOf(p) >= 0 || id.indexOf(p) >= 0 || user.indexOf(p) >= 0 || hostname.indexOf(p) >= 0) { + tmp.push(s); + } }); return tmp; }