| 
									
										
										
										
											2022-07-27 22:56:28 +08:00
										 |  |  | import 'dart:async'; | 
					
						
							| 
									
										
										
										
											2023-03-10 19:37:49 +01:00
										 |  |  | import 'dart:collection'; | 
					
						
							| 
									
										
										
										
											2022-07-27 22:56:28 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | import 'package:flutter/foundation.dart'; | 
					
						
							| 
									
										
										
										
											2022-08-23 17:21:50 +08:00
										 |  |  | import 'package:flutter/material.dart'; | 
					
						
							|  |  |  | import 'package:get/get.dart'; | 
					
						
							| 
									
										
										
										
											2022-07-27 22:56:28 +08:00
										 |  |  | import 'package:provider/provider.dart'; | 
					
						
							|  |  |  | import 'package:visibility_detector/visibility_detector.dart'; | 
					
						
							|  |  |  | import 'package:window_manager/window_manager.dart'; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-23 17:21:50 +08:00
										 |  |  | import '../../common.dart'; | 
					
						
							| 
									
										
										
										
											2022-07-27 22:56:28 +08:00
										 |  |  | import '../../models/peer_model.dart'; | 
					
						
							| 
									
										
										
										
											2022-08-03 22:03:31 +08:00
										 |  |  | import '../../models/platform_model.dart'; | 
					
						
							| 
									
										
										
										
											2022-09-22 15:35:46 +08:00
										 |  |  | import 'peer_card.dart'; | 
					
						
							| 
									
										
										
										
											2022-07-27 22:56:28 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-10 21:10:31 +09:00
										 |  |  | typedef PeerFilter = bool Function(Peer peer); | 
					
						
							| 
									
										
										
										
											2022-10-08 10:55:54 +09:00
										 |  |  | typedef PeerCardBuilder = Widget Function(Peer peer); | 
					
						
							| 
									
										
										
										
											2022-07-27 22:56:28 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-08 20:10:08 +01:00
										 |  |  | class PeerSortType { | 
					
						
							|  |  |  |   static const String remoteId = 'Remote ID'; | 
					
						
							|  |  |  |   static const String remoteHost = 'Remote Host'; | 
					
						
							|  |  |  |   static const String username = 'Username'; | 
					
						
							| 
									
										
										
										
											2023-03-10 15:25:19 +08:00
										 |  |  |   // static const String status = 'Status';
 | 
					
						
							| 
									
										
										
										
											2023-03-08 20:10:08 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |   static List<String> values = [ | 
					
						
							|  |  |  |     PeerSortType.remoteId, | 
					
						
							|  |  |  |     PeerSortType.remoteHost, | 
					
						
							|  |  |  |     PeerSortType.username, | 
					
						
							| 
									
										
										
										
											2023-03-10 15:25:19 +08:00
										 |  |  |     // PeerSortType.status
 | 
					
						
							| 
									
										
										
										
											2023-03-08 20:10:08 +01:00
										 |  |  |   ]; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-10 19:37:49 +01:00
										 |  |  | class LoadEvent { | 
					
						
							|  |  |  |   static const String recent = 'load_recent_peers'; | 
					
						
							|  |  |  |   static const String favorite = 'load_fav_peers'; | 
					
						
							|  |  |  |   static const String lan = 'load_lan_peers'; | 
					
						
							|  |  |  |   static const String addressBook = 'load_address_book_peers'; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-23 17:52:53 +08:00
										 |  |  | /// for peer search text, global obs value
 | 
					
						
							|  |  |  | final peerSearchText = "".obs; | 
					
						
							| 
									
										
										
										
											2023-03-03 20:53:42 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | /// for peer sort, global obs value
 | 
					
						
							| 
									
										
										
										
											2023-08-10 22:27:35 +08:00
										 |  |  | final peerSort = bind.getLocalFlutterOption(k: 'peer-sorting').obs; | 
					
						
							| 
									
										
										
										
											2023-03-03 20:53:42 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | // list for listener
 | 
					
						
							|  |  |  | final obslist = [peerSearchText, peerSort].obs; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-23 17:52:53 +08:00
										 |  |  | final peerSearchTextController = | 
					
						
							|  |  |  |     TextEditingController(text: peerSearchText.value); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-22 15:35:46 +08:00
										 |  |  | class _PeersView extends StatefulWidget { | 
					
						
							| 
									
										
										
										
											2022-09-01 06:18:29 -07:00
										 |  |  |   final Peers peers; | 
					
						
							| 
									
										
										
										
											2022-10-10 21:10:31 +09:00
										 |  |  |   final PeerFilter? peerFilter; | 
					
						
							| 
									
										
										
										
											2022-09-22 15:35:46 +08:00
										 |  |  |   final PeerCardBuilder peerCardBuilder; | 
					
						
							| 
									
										
										
										
											2022-08-23 17:52:53 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-22 15:35:46 +08:00
										 |  |  |   const _PeersView( | 
					
						
							| 
									
										
										
										
											2022-10-10 21:10:31 +09:00
										 |  |  |       {required this.peers, | 
					
						
							|  |  |  |       required this.peerCardBuilder, | 
					
						
							|  |  |  |       this.peerFilter, | 
					
						
							|  |  |  |       Key? key}) | 
					
						
							| 
									
										
										
										
											2022-09-01 06:18:29 -07:00
										 |  |  |       : super(key: key); | 
					
						
							| 
									
										
										
										
											2022-07-27 22:56:28 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   @override | 
					
						
							| 
									
										
										
										
											2022-09-22 15:35:46 +08:00
										 |  |  |   _PeersViewState createState() => _PeersViewState(); | 
					
						
							| 
									
										
										
										
											2022-07-27 22:56:28 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /// State for the peer widget.
 | 
					
						
							| 
									
										
										
										
											2022-09-22 15:35:46 +08:00
										 |  |  | class _PeersViewState extends State<_PeersView> with WindowListener { | 
					
						
							| 
									
										
										
										
											2022-07-27 22:56:28 +08:00
										 |  |  |   static const int _maxQueryCount = 3; | 
					
						
							| 
									
										
										
										
											2023-03-10 19:37:49 +01:00
										 |  |  |   final HashMap<String, String> _emptyMessages = HashMap.from({ | 
					
						
							|  |  |  |     LoadEvent.recent: 'empty_recent_tip', | 
					
						
							|  |  |  |     LoadEvent.favorite: 'empty_favorite_tip', | 
					
						
							|  |  |  |     LoadEvent.lan: 'empty_lan_tip', | 
					
						
							|  |  |  |     LoadEvent.addressBook: 'empty_address_book_tip', | 
					
						
							|  |  |  |   }); | 
					
						
							| 
									
										
										
										
											2022-09-19 20:26:39 +08:00
										 |  |  |   final space = isDesktop ? 12.0 : 8.0; | 
					
						
							| 
									
										
										
										
											2022-09-01 06:18:29 -07:00
										 |  |  |   final _curPeers = <String>{}; | 
					
						
							| 
									
										
										
										
											2022-07-27 22:56:28 +08:00
										 |  |  |   var _lastChangeTime = DateTime.now(); | 
					
						
							| 
									
										
										
										
											2022-09-01 06:18:29 -07:00
										 |  |  |   var _lastQueryPeers = <String>{}; | 
					
						
							| 
									
										
										
										
											2022-09-14 22:22:23 -07:00
										 |  |  |   var _lastQueryTime = DateTime.now().subtract(const Duration(hours: 1)); | 
					
						
							| 
									
										
										
										
											2023-03-09 11:54:17 +08:00
										 |  |  |   var _queryCount = 0; | 
					
						
							| 
									
										
										
										
											2022-07-27 22:56:28 +08:00
										 |  |  |   var _exit = false; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-19 20:26:39 +08:00
										 |  |  |   late final mobileWidth = () { | 
					
						
							|  |  |  |     const minWidth = 320.0; | 
					
						
							|  |  |  |     final windowWidth = MediaQuery.of(context).size.width; | 
					
						
							|  |  |  |     var width = windowWidth - 2 * space; | 
					
						
							|  |  |  |     if (windowWidth > minWidth + 2 * space) { | 
					
						
							|  |  |  |       final n = (windowWidth / (minWidth + 2 * space)).floor(); | 
					
						
							|  |  |  |       width = windowWidth / n - 2 * space; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return width; | 
					
						
							|  |  |  |   }(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-22 15:35:46 +08:00
										 |  |  |   _PeersViewState() { | 
					
						
							| 
									
										
										
										
											2022-07-27 22:56:28 +08:00
										 |  |  |     _startCheckOnlines(); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   @override | 
					
						
							|  |  |  |   void initState() { | 
					
						
							|  |  |  |     windowManager.addListener(this); | 
					
						
							|  |  |  |     super.initState(); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   @override | 
					
						
							|  |  |  |   void dispose() { | 
					
						
							|  |  |  |     windowManager.removeListener(this); | 
					
						
							|  |  |  |     _exit = true; | 
					
						
							|  |  |  |     super.dispose(); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   @override | 
					
						
							|  |  |  |   void onWindowFocus() { | 
					
						
							| 
									
										
										
										
											2023-03-09 11:54:17 +08:00
										 |  |  |     _queryCount = 0; | 
					
						
							| 
									
										
										
										
											2022-07-27 22:56:28 +08:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-03 15:31:19 +08:00
										 |  |  |   @override | 
					
						
							|  |  |  |   void onWindowMinimize() { | 
					
						
							| 
									
										
										
										
											2023-03-09 11:54:17 +08:00
										 |  |  |     _queryCount = _maxQueryCount; | 
					
						
							| 
									
										
										
										
											2022-08-03 15:31:19 +08:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-27 22:56:28 +08:00
										 |  |  |   @override | 
					
						
							|  |  |  |   Widget build(BuildContext context) { | 
					
						
							|  |  |  |     return ChangeNotifierProvider<Peers>( | 
					
						
							| 
									
										
										
										
											2022-09-01 06:18:29 -07:00
										 |  |  |       create: (context) => widget.peers, | 
					
						
							| 
									
										
										
										
											2023-08-10 21:32:26 +08:00
										 |  |  |       child: Consumer<Peers>(builder: (context, peers, child) { | 
					
						
							|  |  |  |         if (peers.peers.isEmpty) { | 
					
						
							|  |  |  |           gFFI.peerTabModel.setCurrentTabCachedPeers([]); | 
					
						
							|  |  |  |           return Center( | 
					
						
							|  |  |  |             child: Column( | 
					
						
							|  |  |  |               mainAxisAlignment: MainAxisAlignment.center, | 
					
						
							|  |  |  |               children: [ | 
					
						
							|  |  |  |                 Icon( | 
					
						
							|  |  |  |                   Icons.sentiment_very_dissatisfied_rounded, | 
					
						
							|  |  |  |                   color: Theme.of(context).tabBarTheme.labelColor, | 
					
						
							|  |  |  |                   size: 40, | 
					
						
							|  |  |  |                 ).paddingOnly(bottom: 10), | 
					
						
							|  |  |  |                 Text( | 
					
						
							|  |  |  |                   translate( | 
					
						
							|  |  |  |                     _emptyMessages[widget.peers.loadEvent] ?? 'Empty', | 
					
						
							|  |  |  |                   ), | 
					
						
							|  |  |  |                   textAlign: TextAlign.center, | 
					
						
							|  |  |  |                   style: TextStyle( | 
					
						
							|  |  |  |                     color: Theme.of(context).tabBarTheme.labelColor, | 
					
						
							|  |  |  |                   ), | 
					
						
							| 
									
										
										
										
											2023-03-10 19:37:49 +01:00
										 |  |  |                 ), | 
					
						
							| 
									
										
										
										
											2023-08-10 21:32:26 +08:00
										 |  |  |               ], | 
					
						
							|  |  |  |             ), | 
					
						
							|  |  |  |           ); | 
					
						
							|  |  |  |         } else { | 
					
						
							|  |  |  |           return _buildPeersView(peers); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       }), | 
					
						
							| 
									
										
										
										
											2022-07-27 22:56:28 +08:00
										 |  |  |     ); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-09 13:07:56 +08:00
										 |  |  |   onVisibilityChanged(VisibilityInfo info) { | 
					
						
							|  |  |  |     final peerId = _peerId((info.key as ValueKey).value); | 
					
						
							|  |  |  |     if (info.visibleFraction > 0.00001) { | 
					
						
							|  |  |  |       _curPeers.add(peerId); | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |       _curPeers.remove(peerId); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     _lastChangeTime = DateTime.now(); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   String _cardId(String id) => widget.peers.name + id; | 
					
						
							|  |  |  |   String _peerId(String cardId) => cardId.replaceAll(widget.peers.name, ''); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-21 14:56:01 +08:00
										 |  |  |   Widget _buildPeersView(Peers peers) { | 
					
						
							| 
									
										
										
										
											2023-06-20 23:34:05 +08:00
										 |  |  |     final updateEvent = peers.event; | 
					
						
							| 
									
										
										
										
											2023-03-03 20:53:42 +01:00
										 |  |  |     final body = ObxValue<RxList>((filters) { | 
					
						
							| 
									
										
										
										
											2022-09-21 14:56:01 +08:00
										 |  |  |       return FutureBuilder<List<Peer>>( | 
					
						
							|  |  |  |         builder: (context, snapshot) { | 
					
						
							|  |  |  |           if (snapshot.hasData) { | 
					
						
							|  |  |  |             final peers = snapshot.data!; | 
					
						
							| 
									
										
										
										
											2023-08-03 16:48:14 +08:00
										 |  |  |             gFFI.peerTabModel.setCurrentTabCachedPeers(peers); | 
					
						
							| 
									
										
										
										
											2022-09-21 14:56:01 +08:00
										 |  |  |             final cards = <Widget>[]; | 
					
						
							|  |  |  |             for (final peer in peers) { | 
					
						
							|  |  |  |               final visibilityChild = VisibilityDetector( | 
					
						
							| 
									
										
										
										
											2023-03-09 13:07:56 +08:00
										 |  |  |                 key: ValueKey(_cardId(peer.id)), | 
					
						
							|  |  |  |                 onVisibilityChanged: onVisibilityChanged, | 
					
						
							| 
									
										
										
										
											2022-09-22 15:35:46 +08:00
										 |  |  |                 child: widget.peerCardBuilder(peer), | 
					
						
							| 
									
										
										
										
											2022-09-21 14:56:01 +08:00
										 |  |  |               ); | 
					
						
							| 
									
										
										
										
											2022-10-08 10:55:54 +09:00
										 |  |  |               cards.add(isDesktop | 
					
						
							|  |  |  |                   ? Obx( | 
					
						
							|  |  |  |                       () => SizedBox( | 
					
						
							|  |  |  |                         width: 220, | 
					
						
							|  |  |  |                         height: | 
					
						
							|  |  |  |                             peerCardUiType.value == PeerUiType.grid ? 140 : 42, | 
					
						
							|  |  |  |                         child: visibilityChild, | 
					
						
							|  |  |  |                       ), | 
					
						
							|  |  |  |                     ) | 
					
						
							|  |  |  |                   : SizedBox(width: mobileWidth, child: visibilityChild)); | 
					
						
							| 
									
										
										
										
											2022-09-21 14:56:01 +08:00
										 |  |  |             } | 
					
						
							| 
									
										
										
										
											2023-06-20 23:34:05 +08:00
										 |  |  |             final child = | 
					
						
							|  |  |  |                 Wrap(spacing: space, runSpacing: space, children: cards); | 
					
						
							|  |  |  |             if (updateEvent == UpdateEvent.load) { | 
					
						
							|  |  |  |               _curPeers.clear(); | 
					
						
							|  |  |  |               _curPeers.addAll(peers.map((e) => e.id)); | 
					
						
							|  |  |  |               _queryOnlines(true); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             return child; | 
					
						
							| 
									
										
										
										
											2022-09-21 14:56:01 +08:00
										 |  |  |           } else { | 
					
						
							|  |  |  |             return const Center( | 
					
						
							|  |  |  |               child: CircularProgressIndicator(), | 
					
						
							|  |  |  |             ); | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |         }, | 
					
						
							| 
									
										
										
										
											2023-03-03 20:53:42 +01:00
										 |  |  |         future: matchPeers(filters[0].value, filters[1].value, peers.peers), | 
					
						
							| 
									
										
										
										
											2022-09-21 14:56:01 +08:00
										 |  |  |       ); | 
					
						
							| 
									
										
										
										
											2023-03-03 20:53:42 +01:00
										 |  |  |     }, obslist); | 
					
						
							| 
									
										
										
										
											2022-09-21 14:56:01 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-28 11:20:57 +08:00
										 |  |  |     return body; | 
					
						
							| 
									
										
										
										
											2022-09-21 14:56:01 +08:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-20 23:34:05 +08:00
										 |  |  |   final _queryInterval = const Duration(seconds: 20); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-27 22:56:28 +08:00
										 |  |  |   void _startCheckOnlines() { | 
					
						
							|  |  |  |     () async { | 
					
						
							|  |  |  |       while (!_exit) { | 
					
						
							|  |  |  |         final now = DateTime.now(); | 
					
						
							|  |  |  |         if (!setEquals(_curPeers, _lastQueryPeers)) { | 
					
						
							| 
									
										
										
										
											2022-09-14 22:22:23 -07:00
										 |  |  |           if (now.difference(_lastChangeTime) > const Duration(seconds: 1)) { | 
					
						
							| 
									
										
										
										
											2023-06-20 23:34:05 +08:00
										 |  |  |             _queryOnlines(false); | 
					
						
							| 
									
										
										
										
											2022-07-27 22:56:28 +08:00
										 |  |  |           } | 
					
						
							|  |  |  |         } else { | 
					
						
							| 
									
										
										
										
											2023-03-09 11:54:17 +08:00
										 |  |  |           if (_queryCount < _maxQueryCount) { | 
					
						
							| 
									
										
										
										
											2023-06-20 23:34:05 +08:00
										 |  |  |             if (now.difference(_lastQueryTime) >= _queryInterval) { | 
					
						
							| 
									
										
										
										
											2022-09-14 22:22:23 -07:00
										 |  |  |               if (_curPeers.isNotEmpty) { | 
					
						
							| 
									
										
										
										
											2022-08-03 22:03:31 +08:00
										 |  |  |                 platformFFI.ffiBind | 
					
						
							| 
									
										
										
										
											2022-08-03 15:31:19 +08:00
										 |  |  |                     .queryOnlines(ids: _curPeers.toList(growable: false)); | 
					
						
							|  |  |  |                 _lastQueryTime = DateTime.now(); | 
					
						
							| 
									
										
										
										
											2023-03-09 11:54:17 +08:00
										 |  |  |                 _queryCount += 1; | 
					
						
							| 
									
										
										
										
											2022-08-03 15:31:19 +08:00
										 |  |  |               } | 
					
						
							| 
									
										
										
										
											2022-07-27 22:56:28 +08:00
										 |  |  |             } | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2022-09-14 22:22:23 -07:00
										 |  |  |         await Future.delayed(const Duration(milliseconds: 300)); | 
					
						
							| 
									
										
										
										
											2022-07-27 22:56:28 +08:00
										 |  |  |       } | 
					
						
							|  |  |  |     }(); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2022-10-10 21:10:31 +09:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-20 23:34:05 +08:00
										 |  |  |   _queryOnlines(bool isLoadEvent) { | 
					
						
							|  |  |  |     if (_curPeers.isNotEmpty) { | 
					
						
							|  |  |  |       platformFFI.ffiBind.queryOnlines(ids: _curPeers.toList(growable: false)); | 
					
						
							|  |  |  |       _lastQueryPeers = {..._curPeers}; | 
					
						
							|  |  |  |       if (isLoadEvent) { | 
					
						
							|  |  |  |         _lastChangeTime = DateTime.now(); | 
					
						
							|  |  |  |       } else { | 
					
						
							|  |  |  |         _lastQueryTime = DateTime.now().subtract(_queryInterval); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       _queryCount = 0; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-03 20:53:42 +01:00
										 |  |  |   Future<List<Peer>>? matchPeers( | 
					
						
							|  |  |  |       String searchText, String sortedBy, List<Peer> peers) async { | 
					
						
							| 
									
										
										
										
											2022-10-10 21:10:31 +09:00
										 |  |  |     if (widget.peerFilter != null) { | 
					
						
							|  |  |  |       peers = peers.where((peer) => widget.peerFilter!(peer)).toList(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-03 20:53:42 +01:00
										 |  |  |     // fallback to id sorting
 | 
					
						
							| 
									
										
										
										
											2023-03-08 20:10:08 +01:00
										 |  |  |     if (!PeerSortType.values.contains(sortedBy)) { | 
					
						
							|  |  |  |       sortedBy = PeerSortType.remoteId; | 
					
						
							| 
									
										
										
										
											2023-08-10 22:27:35 +08:00
										 |  |  |       bind.setLocalFlutterOption( | 
					
						
							| 
									
										
										
										
											2023-03-03 20:53:42 +01:00
										 |  |  |         k: "peer-sorting", | 
					
						
							|  |  |  |         v: sortedBy, | 
					
						
							|  |  |  |       ); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-10 19:37:49 +01:00
										 |  |  |     if (widget.peers.loadEvent != LoadEvent.recent) { | 
					
						
							| 
									
										
										
										
											2023-03-03 20:53:42 +01:00
										 |  |  |       switch (sortedBy) { | 
					
						
							| 
									
										
										
										
											2023-03-08 20:10:08 +01:00
										 |  |  |         case PeerSortType.remoteId: | 
					
						
							| 
									
										
										
										
											2023-03-10 15:25:19 +08:00
										 |  |  |           peers.sort((p1, p2) => p1.getId().compareTo(p2.getId())); | 
					
						
							| 
									
										
										
										
											2023-03-03 20:53:42 +01:00
										 |  |  |           break; | 
					
						
							| 
									
										
										
										
											2023-03-08 20:10:08 +01:00
										 |  |  |         case PeerSortType.remoteHost: | 
					
						
							|  |  |  |           peers.sort((p1, p2) => | 
					
						
							|  |  |  |               p1.hostname.toLowerCase().compareTo(p2.hostname.toLowerCase())); | 
					
						
							|  |  |  |           break; | 
					
						
							|  |  |  |         case PeerSortType.username: | 
					
						
							| 
									
										
										
										
											2023-03-03 20:53:42 +01:00
										 |  |  |           peers.sort((p1, p2) => | 
					
						
							|  |  |  |               p1.username.toLowerCase().compareTo(p2.username.toLowerCase())); | 
					
						
							|  |  |  |           break; | 
					
						
							| 
									
										
										
										
											2023-03-10 15:25:19 +08:00
										 |  |  |         // case PeerSortType.status:
 | 
					
						
							|  |  |  |         // peers.sort((p1, p2) => p1.online ? -1 : 1);
 | 
					
						
							|  |  |  |         // break;
 | 
					
						
							| 
									
										
										
										
											2023-03-03 20:53:42 +01:00
										 |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-10 21:10:31 +09:00
										 |  |  |     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<Peer>.empty(growable: true); | 
					
						
							|  |  |  |     for (var i = 0; i < peers.length; i++) { | 
					
						
							|  |  |  |       if (matches[i]) { | 
					
						
							|  |  |  |         filteredList.add(peers[i]); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2023-03-03 20:53:42 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-10 21:10:31 +09:00
										 |  |  |     return filteredList; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2022-07-27 22:56:28 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-22 15:35:46 +08:00
										 |  |  | abstract class BasePeersView extends StatelessWidget { | 
					
						
							| 
									
										
										
										
											2022-09-01 06:18:29 -07:00
										 |  |  |   final String name; | 
					
						
							|  |  |  |   final String loadEvent; | 
					
						
							| 
									
										
										
										
											2022-10-10 21:10:31 +09:00
										 |  |  |   final PeerFilter? peerFilter; | 
					
						
							| 
									
										
										
										
											2022-09-22 15:35:46 +08:00
										 |  |  |   final PeerCardBuilder peerCardBuilder; | 
					
						
							| 
									
										
										
										
											2022-09-01 06:18:29 -07:00
										 |  |  |   final List<Peer> initPeers; | 
					
						
							| 
									
										
										
										
											2022-07-27 22:56:28 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-22 15:35:46 +08:00
										 |  |  |   const BasePeersView({ | 
					
						
							| 
									
										
										
										
											2022-09-01 06:18:29 -07:00
										 |  |  |     Key? key, | 
					
						
							|  |  |  |     required this.name, | 
					
						
							|  |  |  |     required this.loadEvent, | 
					
						
							| 
									
										
										
										
											2022-10-10 21:10:31 +09:00
										 |  |  |     this.peerFilter, | 
					
						
							| 
									
										
										
										
											2022-09-22 15:35:46 +08:00
										 |  |  |     required this.peerCardBuilder, | 
					
						
							| 
									
										
										
										
											2022-09-01 06:18:29 -07:00
										 |  |  |     required this.initPeers, | 
					
						
							|  |  |  |   }) : super(key: key); | 
					
						
							| 
									
										
										
										
											2022-07-27 22:56:28 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   @override | 
					
						
							|  |  |  |   Widget build(BuildContext context) { | 
					
						
							| 
									
										
										
										
											2022-09-22 15:35:46 +08:00
										 |  |  |     return _PeersView( | 
					
						
							| 
									
										
										
										
											2022-09-01 06:18:29 -07:00
										 |  |  |         peers: Peers(name: name, loadEvent: loadEvent, peers: initPeers), | 
					
						
							| 
									
										
										
										
											2022-10-10 21:10:31 +09:00
										 |  |  |         peerFilter: peerFilter, | 
					
						
							| 
									
										
										
										
											2022-09-22 15:35:46 +08:00
										 |  |  |         peerCardBuilder: peerCardBuilder); | 
					
						
							| 
									
										
										
										
											2022-07-27 22:56:28 +08:00
										 |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-22 15:35:46 +08:00
										 |  |  | class RecentPeersView extends BasePeersView { | 
					
						
							| 
									
										
										
										
											2022-09-28 11:20:57 +08:00
										 |  |  |   RecentPeersView( | 
					
						
							|  |  |  |       {Key? key, EdgeInsets? menuPadding, ScrollController? scrollController}) | 
					
						
							| 
									
										
										
										
											2022-09-01 06:18:29 -07:00
										 |  |  |       : super( | 
					
						
							|  |  |  |           key: key, | 
					
						
							|  |  |  |           name: 'recent peer', | 
					
						
							| 
									
										
										
										
											2023-03-10 19:37:49 +01:00
										 |  |  |           loadEvent: LoadEvent.recent, | 
					
						
							| 
									
										
										
										
											2022-09-22 15:35:46 +08:00
										 |  |  |           peerCardBuilder: (Peer peer) => RecentPeerCard( | 
					
						
							| 
									
										
										
										
											2022-09-01 06:18:29 -07:00
										 |  |  |             peer: peer, | 
					
						
							| 
									
										
										
										
											2022-09-23 12:20:40 +08:00
										 |  |  |             menuPadding: menuPadding, | 
					
						
							| 
									
										
										
										
											2022-09-01 06:18:29 -07:00
										 |  |  |           ), | 
					
						
							|  |  |  |           initPeers: [], | 
					
						
							| 
									
										
										
										
											2022-08-23 17:21:50 +08:00
										 |  |  |         ); | 
					
						
							| 
									
										
										
										
											2022-07-27 22:56:28 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-02 13:10:09 +08:00
										 |  |  |   @override | 
					
						
							|  |  |  |   Widget build(BuildContext context) { | 
					
						
							|  |  |  |     final widget = super.build(context); | 
					
						
							| 
									
										
										
										
											2022-08-03 22:03:31 +08:00
										 |  |  |     bind.mainLoadRecentPeers(); | 
					
						
							| 
									
										
										
										
											2022-08-02 13:10:09 +08:00
										 |  |  |     return widget; | 
					
						
							| 
									
										
										
										
											2022-07-27 22:56:28 +08:00
										 |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-22 15:35:46 +08:00
										 |  |  | class FavoritePeersView extends BasePeersView { | 
					
						
							| 
									
										
										
										
											2022-09-28 11:20:57 +08:00
										 |  |  |   FavoritePeersView( | 
					
						
							|  |  |  |       {Key? key, EdgeInsets? menuPadding, ScrollController? scrollController}) | 
					
						
							| 
									
										
										
										
											2022-09-01 06:18:29 -07:00
										 |  |  |       : super( | 
					
						
							|  |  |  |           key: key, | 
					
						
							|  |  |  |           name: 'favorite peer', | 
					
						
							| 
									
										
										
										
											2023-03-10 19:37:49 +01:00
										 |  |  |           loadEvent: LoadEvent.favorite, | 
					
						
							| 
									
										
										
										
											2022-09-22 15:35:46 +08:00
										 |  |  |           peerCardBuilder: (Peer peer) => FavoritePeerCard( | 
					
						
							| 
									
										
										
										
											2022-09-01 06:18:29 -07:00
										 |  |  |             peer: peer, | 
					
						
							| 
									
										
										
										
											2022-09-23 12:20:40 +08:00
										 |  |  |             menuPadding: menuPadding, | 
					
						
							| 
									
										
										
										
											2022-09-01 06:18:29 -07:00
										 |  |  |           ), | 
					
						
							|  |  |  |           initPeers: [], | 
					
						
							|  |  |  |         ); | 
					
						
							| 
									
										
										
										
											2022-07-27 22:56:28 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   @override | 
					
						
							| 
									
										
										
										
											2022-08-02 13:10:09 +08:00
										 |  |  |   Widget build(BuildContext context) { | 
					
						
							|  |  |  |     final widget = super.build(context); | 
					
						
							| 
									
										
										
										
											2022-08-03 22:03:31 +08:00
										 |  |  |     bind.mainLoadFavPeers(); | 
					
						
							| 
									
										
										
										
											2022-08-02 13:10:09 +08:00
										 |  |  |     return widget; | 
					
						
							| 
									
										
										
										
											2022-07-27 22:56:28 +08:00
										 |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-22 15:35:46 +08:00
										 |  |  | class DiscoveredPeersView extends BasePeersView { | 
					
						
							| 
									
										
										
										
											2022-09-28 11:20:57 +08:00
										 |  |  |   DiscoveredPeersView( | 
					
						
							|  |  |  |       {Key? key, EdgeInsets? menuPadding, ScrollController? scrollController}) | 
					
						
							| 
									
										
										
										
											2022-09-01 06:18:29 -07:00
										 |  |  |       : super( | 
					
						
							|  |  |  |           key: key, | 
					
						
							|  |  |  |           name: 'discovered peer', | 
					
						
							| 
									
										
										
										
											2023-03-10 19:37:49 +01:00
										 |  |  |           loadEvent: LoadEvent.lan, | 
					
						
							| 
									
										
										
										
											2022-09-22 15:35:46 +08:00
										 |  |  |           peerCardBuilder: (Peer peer) => DiscoveredPeerCard( | 
					
						
							| 
									
										
										
										
											2022-09-01 06:18:29 -07:00
										 |  |  |             peer: peer, | 
					
						
							| 
									
										
										
										
											2022-09-23 12:20:40 +08:00
										 |  |  |             menuPadding: menuPadding, | 
					
						
							| 
									
										
										
										
											2022-09-01 06:18:29 -07:00
										 |  |  |           ), | 
					
						
							|  |  |  |           initPeers: [], | 
					
						
							|  |  |  |         ); | 
					
						
							| 
									
										
										
										
											2022-07-27 22:56:28 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-02 13:10:09 +08:00
										 |  |  |   @override | 
					
						
							|  |  |  |   Widget build(BuildContext context) { | 
					
						
							|  |  |  |     final widget = super.build(context); | 
					
						
							| 
									
										
										
										
											2022-08-03 22:03:31 +08:00
										 |  |  |     bind.mainLoadLanPeers(); | 
					
						
							| 
									
										
										
										
											2022-08-02 13:10:09 +08:00
										 |  |  |     return widget; | 
					
						
							| 
									
										
										
										
											2022-07-27 22:56:28 +08:00
										 |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-22 15:35:46 +08:00
										 |  |  | class AddressBookPeersView extends BasePeersView { | 
					
						
							| 
									
										
										
										
											2022-09-28 11:20:57 +08:00
										 |  |  |   AddressBookPeersView( | 
					
						
							| 
									
										
										
										
											2022-10-08 16:53:03 +09:00
										 |  |  |       {Key? key, | 
					
						
							|  |  |  |       EdgeInsets? menuPadding, | 
					
						
							|  |  |  |       ScrollController? scrollController, | 
					
						
							|  |  |  |       required List<Peer> initPeers}) | 
					
						
							| 
									
										
										
										
											2022-09-01 06:18:29 -07:00
										 |  |  |       : super( | 
					
						
							|  |  |  |           key: key, | 
					
						
							|  |  |  |           name: 'address book peer', | 
					
						
							| 
									
										
										
										
											2023-03-10 19:37:49 +01:00
										 |  |  |           loadEvent: LoadEvent.addressBook, | 
					
						
							| 
									
										
										
										
											2022-10-10 21:10:31 +09:00
										 |  |  |           peerFilter: (Peer peer) => | 
					
						
							|  |  |  |               _hitTag(gFFI.abModel.selectedTags, peer.tags), | 
					
						
							|  |  |  |           peerCardBuilder: (Peer peer) => AddressBookPeerCard( | 
					
						
							|  |  |  |             peer: peer, | 
					
						
							|  |  |  |             menuPadding: menuPadding, | 
					
						
							|  |  |  |           ), | 
					
						
							| 
									
										
										
										
											2022-10-08 16:53:03 +09:00
										 |  |  |           initPeers: initPeers, | 
					
						
							| 
									
										
										
										
											2022-09-01 06:18:29 -07:00
										 |  |  |         ); | 
					
						
							| 
									
										
										
										
											2022-07-27 22:56:28 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-01 06:18:29 -07:00
										 |  |  |   static bool _hitTag(List<dynamic> selectedTags, List<dynamic> idents) { | 
					
						
							| 
									
										
										
										
											2022-07-27 22:56:28 +08:00
										 |  |  |     if (selectedTags.isEmpty) { | 
					
						
							|  |  |  |       return true; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     for (final tag in selectedTags) { | 
					
						
							| 
									
										
										
										
											2023-08-22 08:54:01 +08:00
										 |  |  |       if (idents.contains(tag)) { | 
					
						
							|  |  |  |         return true; | 
					
						
							| 
									
										
										
										
											2022-07-27 22:56:28 +08:00
										 |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2023-08-22 08:54:01 +08:00
										 |  |  |     return false; | 
					
						
							| 
									
										
										
										
											2022-07-27 22:56:28 +08:00
										 |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2022-12-11 21:40:35 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | class MyGroupPeerView extends BasePeersView { | 
					
						
							|  |  |  |   MyGroupPeerView( | 
					
						
							|  |  |  |       {Key? key, | 
					
						
							|  |  |  |       EdgeInsets? menuPadding, | 
					
						
							|  |  |  |       ScrollController? scrollController, | 
					
						
							|  |  |  |       required List<Peer> initPeers}) | 
					
						
							|  |  |  |       : super( | 
					
						
							|  |  |  |           key: key, | 
					
						
							|  |  |  |           name: 'my group peer', | 
					
						
							|  |  |  |           loadEvent: 'load_my_group_peers', | 
					
						
							| 
									
										
										
										
											2023-06-21 09:30:32 +08:00
										 |  |  |           peerFilter: filter, | 
					
						
							| 
									
										
										
										
											2022-12-11 21:40:35 +08:00
										 |  |  |           peerCardBuilder: (Peer peer) => MyGroupPeerCard( | 
					
						
							|  |  |  |             peer: peer, | 
					
						
							|  |  |  |             menuPadding: menuPadding, | 
					
						
							|  |  |  |           ), | 
					
						
							|  |  |  |           initPeers: initPeers, | 
					
						
							|  |  |  |         ); | 
					
						
							| 
									
										
										
										
											2023-06-21 09:30:32 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   static bool filter(Peer peer) { | 
					
						
							|  |  |  |     if (gFFI.groupModel.searchUserText.isNotEmpty) { | 
					
						
							|  |  |  |       if (!peer.username.contains(gFFI.groupModel.searchUserText)) { | 
					
						
							|  |  |  |         return false; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if (gFFI.groupModel.selectedUser.isNotEmpty) { | 
					
						
							|  |  |  |       if (gFFI.groupModel.selectedUser.value != peer.username) { | 
					
						
							|  |  |  |         return false; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return true; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2022-12-11 21:40:35 +08:00
										 |  |  | } |