Autocomplete container UI changes (#6690)
* add left & right padding to autocomplete peer and format Signed-off-by: Sahil Yeole <sahilyeole93@gmail.com> * handle max height for autocomplete equal padding, add box shadow and format Signed-off-by: Sahil Yeole <sahilyeole93@gmail.com> --------- Signed-off-by: Sahil Yeole <sahilyeole93@gmail.com>
This commit is contained in:
		
							parent
							
								
									79411430a5
								
							
						
					
					
						commit
						c168b7e979
					
				@ -6,55 +6,55 @@ import 'package:flutter_hbb/models/peer_model.dart';
 | 
				
			|||||||
import 'package:flutter_hbb/common.dart';
 | 
					import 'package:flutter_hbb/common.dart';
 | 
				
			||||||
import 'package:flutter_hbb/common/widgets/peer_card.dart';
 | 
					import 'package:flutter_hbb/common/widgets/peer_card.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Future<List<Peer>> getAllPeers() async {
 | 
				
			||||||
 | 
					  Map<String, dynamic> recentPeers =
 | 
				
			||||||
 | 
					      jsonDecode(await bind.mainLoadRecentPeersSync());
 | 
				
			||||||
 | 
					  Map<String, dynamic> lanPeers = jsonDecode(await bind.mainLoadLanPeersSync());
 | 
				
			||||||
 | 
					  Map<String, dynamic> abPeers = jsonDecode(await bind.mainLoadAbSync());
 | 
				
			||||||
 | 
					  Map<String, dynamic> groupPeers = jsonDecode(await bind.mainLoadGroupSync());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 Future<List<Peer>> getAllPeers() async {
 | 
					  Map<String, dynamic> combinedPeers = {};
 | 
				
			||||||
    Map<String, dynamic> recentPeers = jsonDecode(await bind.mainLoadRecentPeersSync());
 | 
					 | 
				
			||||||
    Map<String, dynamic> lanPeers = jsonDecode(await bind.mainLoadLanPeersSync());
 | 
					 | 
				
			||||||
    Map<String, dynamic> abPeers = jsonDecode(await bind.mainLoadAbSync());
 | 
					 | 
				
			||||||
    Map<String, dynamic> groupPeers = jsonDecode(await bind.mainLoadGroupSync());
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Map<String, dynamic> combinedPeers = {};
 | 
					  void _mergePeers(Map<String, dynamic> peers) {
 | 
				
			||||||
 | 
					    if (peers.containsKey("peers")) {
 | 
				
			||||||
 | 
					      dynamic peerData = peers["peers"];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void _mergePeers(Map<String, dynamic> peers) {
 | 
					      if (peerData is String) {
 | 
				
			||||||
      if (peers.containsKey("peers")) {
 | 
					        try {
 | 
				
			||||||
        dynamic peerData = peers["peers"];
 | 
					          peerData = jsonDecode(peerData);
 | 
				
			||||||
 | 
					        } catch (e) {
 | 
				
			||||||
        if (peerData is String) {
 | 
					          print("Error decoding peers: $e");
 | 
				
			||||||
          try {
 | 
					          return;
 | 
				
			||||||
            peerData = jsonDecode(peerData);
 | 
					 | 
				
			||||||
          } catch (e) {
 | 
					 | 
				
			||||||
            print("Error decoding peers: $e");
 | 
					 | 
				
			||||||
            return;
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (peerData is List) {
 | 
					      if (peerData is List) {
 | 
				
			||||||
          for (var peer in peerData) {
 | 
					        for (var peer in peerData) {
 | 
				
			||||||
            if (peer is Map && peer.containsKey("id")) {
 | 
					          if (peer is Map && peer.containsKey("id")) {
 | 
				
			||||||
              String id = peer["id"];
 | 
					            String id = peer["id"];
 | 
				
			||||||
              if (!combinedPeers.containsKey(id)) {
 | 
					            if (!combinedPeers.containsKey(id)) {
 | 
				
			||||||
                combinedPeers[id] = peer;
 | 
					              combinedPeers[id] = peer;
 | 
				
			||||||
              }
 | 
					 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
          }
 | 
					          }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					 | 
				
			||||||
    _mergePeers(recentPeers);
 | 
					 | 
				
			||||||
    _mergePeers(lanPeers);
 | 
					 | 
				
			||||||
    _mergePeers(abPeers);
 | 
					 | 
				
			||||||
    _mergePeers(groupPeers);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      List<Peer> parsedPeers = [];
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    for (var peer in combinedPeers.values) {
 | 
					 | 
				
			||||||
      parsedPeers.add(Peer.fromJson(peer));
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    return  parsedPeers;
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 class AutocompletePeerTile extends StatefulWidget {
 | 
					  _mergePeers(recentPeers);
 | 
				
			||||||
 | 
					  _mergePeers(lanPeers);
 | 
				
			||||||
 | 
					  _mergePeers(abPeers);
 | 
				
			||||||
 | 
					  _mergePeers(groupPeers);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  List<Peer> parsedPeers = [];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  for (var peer in combinedPeers.values) {
 | 
				
			||||||
 | 
					    parsedPeers.add(Peer.fromJson(peer));
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  return parsedPeers;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class AutocompletePeerTile extends StatefulWidget {
 | 
				
			||||||
  final VoidCallback onSelect;
 | 
					  final VoidCallback onSelect;
 | 
				
			||||||
  final Peer peer;
 | 
					  final Peer peer;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -68,7 +68,7 @@ import 'package:flutter_hbb/common/widgets/peer_card.dart';
 | 
				
			|||||||
  _AutocompletePeerTileState createState() => _AutocompletePeerTileState();
 | 
					  _AutocompletePeerTileState createState() => _AutocompletePeerTileState();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class _AutocompletePeerTileState extends State<AutocompletePeerTile>{
 | 
					class _AutocompletePeerTileState extends State<AutocompletePeerTile> {
 | 
				
			||||||
  List _frontN<T>(List list, int n) {
 | 
					  List _frontN<T>(List list, int n) {
 | 
				
			||||||
    if (list.length <= n) {
 | 
					    if (list.length <= n) {
 | 
				
			||||||
      return list;
 | 
					      return list;
 | 
				
			||||||
@ -76,99 +76,114 @@ class _AutocompletePeerTileState extends State<AutocompletePeerTile>{
 | 
				
			|||||||
      return list.sublist(0, n);
 | 
					      return list.sublist(0, n);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  @override
 | 
					  @override
 | 
				
			||||||
  Widget build(BuildContext context){
 | 
					  Widget build(BuildContext context) {
 | 
				
			||||||
    final double _tileRadius = 5;
 | 
					    final double _tileRadius = 5;
 | 
				
			||||||
        final name =
 | 
					    final name =
 | 
				
			||||||
          '${widget.peer.username}${widget.peer.username.isNotEmpty && widget.peer.hostname.isNotEmpty ? '@' : ''}${widget.peer.hostname}';
 | 
					        '${widget.peer.username}${widget.peer.username.isNotEmpty && widget.peer.hostname.isNotEmpty ? '@' : ''}${widget.peer.hostname}';
 | 
				
			||||||
        final greyStyle = TextStyle(
 | 
					    final greyStyle = TextStyle(
 | 
				
			||||||
          fontSize: 11,
 | 
					        fontSize: 11,
 | 
				
			||||||
          color: Theme.of(context).textTheme.titleLarge?.color?.withOpacity(0.6));
 | 
					        color: Theme.of(context).textTheme.titleLarge?.color?.withOpacity(0.6));
 | 
				
			||||||
        final child = GestureDetector(
 | 
					    final child = GestureDetector(
 | 
				
			||||||
          onTap: () => widget.onSelect(),
 | 
					        onTap: () => widget.onSelect(),
 | 
				
			||||||
          child:
 | 
					        child: Padding(
 | 
				
			||||||
        Container(
 | 
					            padding: EdgeInsets.only(left: 5, right: 5),
 | 
				
			||||||
          height: 42,
 | 
					            child: Container(
 | 
				
			||||||
          margin: EdgeInsets.only(bottom: 5),
 | 
					                height: 42,
 | 
				
			||||||
          child: Row(
 | 
					                margin: EdgeInsets.only(bottom: 5),
 | 
				
			||||||
          mainAxisSize: MainAxisSize.max,
 | 
					                child: Row(
 | 
				
			||||||
          children: [
 | 
					                  mainAxisSize: MainAxisSize.max,
 | 
				
			||||||
            Container(
 | 
					                  children: [
 | 
				
			||||||
              decoration: BoxDecoration(
 | 
					                    Container(
 | 
				
			||||||
                color: str2color('${widget.peer.id}${widget.peer.platform}', 0x7f),
 | 
					                        decoration: BoxDecoration(
 | 
				
			||||||
                borderRadius: BorderRadius.only(
 | 
					                          color: str2color(
 | 
				
			||||||
                        topLeft: Radius.circular(_tileRadius),
 | 
					                              '${widget.peer.id}${widget.peer.platform}', 0x7f),
 | 
				
			||||||
                        bottomLeft: Radius.circular(_tileRadius),
 | 
					                          borderRadius: BorderRadius.only(
 | 
				
			||||||
                      ),
 | 
					                            topLeft: Radius.circular(_tileRadius),
 | 
				
			||||||
              ),
 | 
					                            bottomLeft: Radius.circular(_tileRadius),
 | 
				
			||||||
              alignment: Alignment.center,
 | 
					                          ),
 | 
				
			||||||
              width: 42,
 | 
					 | 
				
			||||||
              height: null,
 | 
					 | 
				
			||||||
              child: Padding(
 | 
					 | 
				
			||||||
                padding: EdgeInsets.all(6),
 | 
					 | 
				
			||||||
                child: getPlatformImage(widget.peer.platform, size: 30)
 | 
					 | 
				
			||||||
              )
 | 
					 | 
				
			||||||
            ),
 | 
					 | 
				
			||||||
            Expanded(
 | 
					 | 
				
			||||||
              child: Container(
 | 
					 | 
				
			||||||
                padding: EdgeInsets.only(left: 10),
 | 
					 | 
				
			||||||
                decoration: BoxDecoration(
 | 
					 | 
				
			||||||
                  color: Theme.of(context).colorScheme.background,
 | 
					 | 
				
			||||||
                  borderRadius: BorderRadius.only(
 | 
					 | 
				
			||||||
                    topRight: Radius.circular(_tileRadius),
 | 
					 | 
				
			||||||
                    bottomRight: Radius.circular(_tileRadius),
 | 
					 | 
				
			||||||
                  ),
 | 
					 | 
				
			||||||
                ),
 | 
					 | 
				
			||||||
            child: Row(
 | 
					 | 
				
			||||||
              children: [
 | 
					 | 
				
			||||||
                Expanded(
 | 
					 | 
				
			||||||
                  child: Container(
 | 
					 | 
				
			||||||
                    margin: EdgeInsets.only(top: 2),
 | 
					 | 
				
			||||||
                    child: Container(
 | 
					 | 
				
			||||||
                      margin: EdgeInsets.only(top: 2),
 | 
					 | 
				
			||||||
                      child: Column(
 | 
					 | 
				
			||||||
                    children: [
 | 
					 | 
				
			||||||
                      Container(
 | 
					 | 
				
			||||||
                        margin: EdgeInsets.only(top: 2),
 | 
					 | 
				
			||||||
                        child: Row(children: [
 | 
					 | 
				
			||||||
                          getOnline(8, widget.peer.online),
 | 
					 | 
				
			||||||
                          Expanded(
 | 
					 | 
				
			||||||
                              child: Text(
 | 
					 | 
				
			||||||
                            widget.peer.alias.isEmpty ? formatID(widget.peer.id) : widget.peer.alias,
 | 
					 | 
				
			||||||
                            overflow: TextOverflow.ellipsis,
 | 
					 | 
				
			||||||
                            style: Theme.of(context).textTheme.titleSmall,
 | 
					 | 
				
			||||||
                          )),
 | 
					 | 
				
			||||||
                          !widget.peer.alias.isEmpty?
 | 
					 | 
				
			||||||
                          Padding(
 | 
					 | 
				
			||||||
                            padding: const EdgeInsets.only(left: 5, right: 5),
 | 
					 | 
				
			||||||
                            child: Text(
 | 
					 | 
				
			||||||
                              "(${widget.peer.id})",
 | 
					 | 
				
			||||||
                              style: greyStyle,
 | 
					 | 
				
			||||||
                              overflow: TextOverflow.ellipsis,
 | 
					 | 
				
			||||||
                            )
 | 
					 | 
				
			||||||
                          )
 | 
					 | 
				
			||||||
                          : Container(),
 | 
					 | 
				
			||||||
                      ])),
 | 
					 | 
				
			||||||
                      Align(
 | 
					 | 
				
			||||||
                        alignment: Alignment.centerLeft,
 | 
					 | 
				
			||||||
                        child: Text(
 | 
					 | 
				
			||||||
                          name,
 | 
					 | 
				
			||||||
                          style: greyStyle,
 | 
					 | 
				
			||||||
                          textAlign: TextAlign.start,
 | 
					 | 
				
			||||||
                          overflow: TextOverflow.ellipsis,
 | 
					 | 
				
			||||||
                        ),
 | 
					                        ),
 | 
				
			||||||
                      ),
 | 
					                        alignment: Alignment.center,
 | 
				
			||||||
                    ],
 | 
					                        width: 42,
 | 
				
			||||||
                  )
 | 
					                        height: null,
 | 
				
			||||||
                ))),
 | 
					                        child: Padding(
 | 
				
			||||||
              ],
 | 
					                            padding: EdgeInsets.all(6),
 | 
				
			||||||
            )
 | 
					                            child: getPlatformImage(widget.peer.platform,
 | 
				
			||||||
            ),
 | 
					                                size: 30))),
 | 
				
			||||||
        )
 | 
					                    Expanded(
 | 
				
			||||||
      ],
 | 
					                      child: Container(
 | 
				
			||||||
    )));
 | 
					                          padding: EdgeInsets.only(left: 10),
 | 
				
			||||||
    final colors =
 | 
					                          decoration: BoxDecoration(
 | 
				
			||||||
        _frontN(widget.peer.tags, 25).map((e) => gFFI.abModel.getTagColor(e)).toList();
 | 
					                            color: Theme.of(context).colorScheme.background,
 | 
				
			||||||
 | 
					                            borderRadius: BorderRadius.only(
 | 
				
			||||||
 | 
					                              topRight: Radius.circular(_tileRadius),
 | 
				
			||||||
 | 
					                              bottomRight: Radius.circular(_tileRadius),
 | 
				
			||||||
 | 
					                            ),
 | 
				
			||||||
 | 
					                          ),
 | 
				
			||||||
 | 
					                          child: Row(
 | 
				
			||||||
 | 
					                            children: [
 | 
				
			||||||
 | 
					                              Expanded(
 | 
				
			||||||
 | 
					                                  child: Container(
 | 
				
			||||||
 | 
					                                      margin: EdgeInsets.only(top: 2),
 | 
				
			||||||
 | 
					                                      child: Container(
 | 
				
			||||||
 | 
					                                          margin: EdgeInsets.only(top: 2),
 | 
				
			||||||
 | 
					                                          child: Column(
 | 
				
			||||||
 | 
					                                            children: [
 | 
				
			||||||
 | 
					                                              Container(
 | 
				
			||||||
 | 
					                                                  margin:
 | 
				
			||||||
 | 
					                                                      EdgeInsets.only(top: 2),
 | 
				
			||||||
 | 
					                                                  child: Row(children: [
 | 
				
			||||||
 | 
					                                                    getOnline(
 | 
				
			||||||
 | 
					                                                        8, widget.peer.online),
 | 
				
			||||||
 | 
					                                                    Expanded(
 | 
				
			||||||
 | 
					                                                        child: Text(
 | 
				
			||||||
 | 
					                                                      widget.peer.alias.isEmpty
 | 
				
			||||||
 | 
					                                                          ? formatID(
 | 
				
			||||||
 | 
					                                                              widget.peer.id)
 | 
				
			||||||
 | 
					                                                          : widget.peer.alias,
 | 
				
			||||||
 | 
					                                                      overflow:
 | 
				
			||||||
 | 
					                                                          TextOverflow.ellipsis,
 | 
				
			||||||
 | 
					                                                      style: Theme.of(context)
 | 
				
			||||||
 | 
					                                                          .textTheme
 | 
				
			||||||
 | 
					                                                          .titleSmall,
 | 
				
			||||||
 | 
					                                                    )),
 | 
				
			||||||
 | 
					                                                    !widget.peer.alias.isEmpty
 | 
				
			||||||
 | 
					                                                        ? Padding(
 | 
				
			||||||
 | 
					                                                            padding:
 | 
				
			||||||
 | 
					                                                                const EdgeInsets
 | 
				
			||||||
 | 
					                                                                    .only(
 | 
				
			||||||
 | 
					                                                                    left: 5,
 | 
				
			||||||
 | 
					                                                                    right: 5),
 | 
				
			||||||
 | 
					                                                            child: Text(
 | 
				
			||||||
 | 
					                                                              "(${widget.peer.id})",
 | 
				
			||||||
 | 
					                                                              style: greyStyle,
 | 
				
			||||||
 | 
					                                                              overflow:
 | 
				
			||||||
 | 
					                                                                  TextOverflow
 | 
				
			||||||
 | 
					                                                                      .ellipsis,
 | 
				
			||||||
 | 
					                                                            ))
 | 
				
			||||||
 | 
					                                                        : Container(),
 | 
				
			||||||
 | 
					                                                  ])),
 | 
				
			||||||
 | 
					                                              Align(
 | 
				
			||||||
 | 
					                                                alignment: Alignment.centerLeft,
 | 
				
			||||||
 | 
					                                                child: Text(
 | 
				
			||||||
 | 
					                                                  name,
 | 
				
			||||||
 | 
					                                                  style: greyStyle,
 | 
				
			||||||
 | 
					                                                  textAlign: TextAlign.start,
 | 
				
			||||||
 | 
					                                                  overflow:
 | 
				
			||||||
 | 
					                                                      TextOverflow.ellipsis,
 | 
				
			||||||
 | 
					                                                ),
 | 
				
			||||||
 | 
					                                              ),
 | 
				
			||||||
 | 
					                                            ],
 | 
				
			||||||
 | 
					                                          )))),
 | 
				
			||||||
 | 
					                            ],
 | 
				
			||||||
 | 
					                          )),
 | 
				
			||||||
 | 
					                    )
 | 
				
			||||||
 | 
					                  ],
 | 
				
			||||||
 | 
					                ))));
 | 
				
			||||||
 | 
					    final colors = _frontN(widget.peer.tags, 25)
 | 
				
			||||||
 | 
					        .map((e) => gFFI.abModel.getTagColor(e))
 | 
				
			||||||
 | 
					        .toList();
 | 
				
			||||||
    return Tooltip(
 | 
					    return Tooltip(
 | 
				
			||||||
      message: isMobile
 | 
					      message: isMobile
 | 
				
			||||||
          ? ''
 | 
					          ? ''
 | 
				
			||||||
@ -188,4 +203,4 @@ class _AutocompletePeerTileState extends State<AutocompletePeerTile>{
 | 
				
			|||||||
      ]),
 | 
					      ]),
 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  }
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -308,40 +308,59 @@ class _ConnectionPageState extends State<ConnectionPage>
 | 
				
			|||||||
                      AutocompleteOnSelected<Peer> onSelected,
 | 
					                      AutocompleteOnSelected<Peer> onSelected,
 | 
				
			||||||
                      Iterable<Peer> options) {
 | 
					                      Iterable<Peer> options) {
 | 
				
			||||||
                    double maxHeight = options.length * 50;
 | 
					                    double maxHeight = options.length * 50;
 | 
				
			||||||
                    maxHeight = maxHeight > 200 ? 200 : maxHeight;
 | 
					                    if (options.length == 1) {
 | 
				
			||||||
 | 
					                      maxHeight = 52;
 | 
				
			||||||
 | 
					                    } else if (options.length == 3) {
 | 
				
			||||||
 | 
					                      maxHeight = 146;
 | 
				
			||||||
 | 
					                    } else if (options.length == 4) {
 | 
				
			||||||
 | 
					                      maxHeight = 193;
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                    maxHeight = maxHeight.clamp(0, 200);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    return Align(
 | 
					                    return Align(
 | 
				
			||||||
                      alignment: Alignment.topLeft,
 | 
					                      alignment: Alignment.topLeft,
 | 
				
			||||||
                      child: ClipRRect(
 | 
					                      child: Container(
 | 
				
			||||||
                          borderRadius: BorderRadius.circular(5),
 | 
					                          decoration: BoxDecoration(
 | 
				
			||||||
                          child: Material(
 | 
					                            boxShadow: [
 | 
				
			||||||
                            elevation: 4,
 | 
					                              BoxShadow(
 | 
				
			||||||
                            child: ConstrainedBox(
 | 
					                                color: Colors.black.withOpacity(0.3),
 | 
				
			||||||
                              constraints: BoxConstraints(
 | 
					                                blurRadius: 5,
 | 
				
			||||||
                                maxHeight: maxHeight,
 | 
					                                spreadRadius: 1,
 | 
				
			||||||
                                maxWidth: 319,
 | 
					 | 
				
			||||||
                              ),
 | 
					                              ),
 | 
				
			||||||
                              child: peers.isEmpty && isPeersLoading
 | 
					                            ],
 | 
				
			||||||
                                  ? Container(
 | 
					                          ),
 | 
				
			||||||
                                      height: 80,
 | 
					                          child: ClipRRect(
 | 
				
			||||||
                                      child: Center(
 | 
					                              borderRadius: BorderRadius.circular(5),
 | 
				
			||||||
                                        child: CircularProgressIndicator(
 | 
					                              child: Material(
 | 
				
			||||||
                                          strokeWidth: 2,
 | 
					                                elevation: 4,
 | 
				
			||||||
 | 
					                                child: ConstrainedBox(
 | 
				
			||||||
 | 
					                                  constraints: BoxConstraints(
 | 
				
			||||||
 | 
					                                    maxHeight: maxHeight,
 | 
				
			||||||
 | 
					                                    maxWidth: 319,
 | 
				
			||||||
 | 
					                                  ),
 | 
				
			||||||
 | 
					                                  child: peers.isEmpty && isPeersLoading
 | 
				
			||||||
 | 
					                                      ? Container(
 | 
				
			||||||
 | 
					                                          height: 80,
 | 
				
			||||||
 | 
					                                          child: Center(
 | 
				
			||||||
 | 
					                                            child: CircularProgressIndicator(
 | 
				
			||||||
 | 
					                                              strokeWidth: 2,
 | 
				
			||||||
 | 
					                                            ),
 | 
				
			||||||
 | 
					                                          ))
 | 
				
			||||||
 | 
					                                      : Padding(
 | 
				
			||||||
 | 
					                                          padding:
 | 
				
			||||||
 | 
					                                              const EdgeInsets.only(top: 5),
 | 
				
			||||||
 | 
					                                          child: ListView(
 | 
				
			||||||
 | 
					                                            children: options
 | 
				
			||||||
 | 
					                                                .map((peer) =>
 | 
				
			||||||
 | 
					                                                    AutocompletePeerTile(
 | 
				
			||||||
 | 
					                                                        onSelect: () =>
 | 
				
			||||||
 | 
					                                                            onSelected(peer),
 | 
				
			||||||
 | 
					                                                        peer: peer))
 | 
				
			||||||
 | 
					                                                .toList(),
 | 
				
			||||||
 | 
					                                          ),
 | 
				
			||||||
                                        ),
 | 
					                                        ),
 | 
				
			||||||
                                      ))
 | 
					                                ),
 | 
				
			||||||
                                  : Padding(
 | 
					                              ))),
 | 
				
			||||||
                                      padding: const EdgeInsets.only(top: 5),
 | 
					 | 
				
			||||||
                                      child: ListView(
 | 
					 | 
				
			||||||
                                        children: options
 | 
					 | 
				
			||||||
                                            .map((peer) => AutocompletePeerTile(
 | 
					 | 
				
			||||||
                                                onSelect: () =>
 | 
					 | 
				
			||||||
                                                    onSelected(peer),
 | 
					 | 
				
			||||||
                                                peer: peer))
 | 
					 | 
				
			||||||
                                            .toList(),
 | 
					 | 
				
			||||||
                                      ),
 | 
					 | 
				
			||||||
                                    ),
 | 
					 | 
				
			||||||
                            ),
 | 
					 | 
				
			||||||
                          )),
 | 
					 | 
				
			||||||
                    );
 | 
					                    );
 | 
				
			||||||
                  },
 | 
					                  },
 | 
				
			||||||
                )),
 | 
					                )),
 | 
				
			||||||
 | 
				
			|||||||
@ -52,6 +52,7 @@ class _ConnectionPageState extends State<ConnectionPage> {
 | 
				
			|||||||
      return list.sublist(0, n);
 | 
					      return list.sublist(0, n);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  bool isPeersLoading = false;
 | 
					  bool isPeersLoading = false;
 | 
				
			||||||
  bool isPeersLoaded = false;
 | 
					  bool isPeersLoaded = false;
 | 
				
			||||||
  StreamSubscription? _uniLinksSubscription;
 | 
					  StreamSubscription? _uniLinksSubscription;
 | 
				
			||||||
@ -137,9 +138,9 @@ class _ConnectionPageState extends State<ConnectionPage> {
 | 
				
			|||||||
    await Future.delayed(Duration(milliseconds: 100));
 | 
					    await Future.delayed(Duration(milliseconds: 100));
 | 
				
			||||||
    peers = await getAllPeers();
 | 
					    peers = await getAllPeers();
 | 
				
			||||||
    setState(() {
 | 
					    setState(() {
 | 
				
			||||||
        isPeersLoading = false;
 | 
					      isPeersLoading = false;
 | 
				
			||||||
        isPeersLoaded = true;
 | 
					      isPeersLoaded = true;
 | 
				
			||||||
      });
 | 
					    });
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /// UI for the remote ID TextField.
 | 
					  /// UI for the remote ID TextField.
 | 
				
			||||||
@ -163,9 +164,8 @@ class _ConnectionPageState extends State<ConnectionPage> {
 | 
				
			|||||||
                    optionsBuilder: (TextEditingValue textEditingValue) {
 | 
					                    optionsBuilder: (TextEditingValue textEditingValue) {
 | 
				
			||||||
                      if (textEditingValue.text == '') {
 | 
					                      if (textEditingValue.text == '') {
 | 
				
			||||||
                        return const Iterable<Peer>.empty();
 | 
					                        return const Iterable<Peer>.empty();
 | 
				
			||||||
                      }
 | 
					                      } else if (peers.isEmpty && !isPeersLoaded) {
 | 
				
			||||||
                      else if (peers.isEmpty && !isPeersLoaded) {
 | 
					                        Peer emptyPeer = Peer(
 | 
				
			||||||
                         Peer emptyPeer = Peer(
 | 
					 | 
				
			||||||
                          id: '',
 | 
					                          id: '',
 | 
				
			||||||
                          username: '',
 | 
					                          username: '',
 | 
				
			||||||
                          hostname: '',
 | 
					                          hostname: '',
 | 
				
			||||||
@ -179,9 +179,9 @@ class _ConnectionPageState extends State<ConnectionPage> {
 | 
				
			|||||||
                          loginName: '',
 | 
					                          loginName: '',
 | 
				
			||||||
                        );
 | 
					                        );
 | 
				
			||||||
                        return [emptyPeer];
 | 
					                        return [emptyPeer];
 | 
				
			||||||
                      }
 | 
					                      } else {
 | 
				
			||||||
                      else {
 | 
					                        String textWithoutSpaces =
 | 
				
			||||||
                        String textWithoutSpaces = textEditingValue.text.replaceAll(" ", "");
 | 
					                            textEditingValue.text.replaceAll(" ", "");
 | 
				
			||||||
                        if (int.tryParse(textWithoutSpaces) != null) {
 | 
					                        if (int.tryParse(textWithoutSpaces) != null) {
 | 
				
			||||||
                          textEditingValue = TextEditingValue(
 | 
					                          textEditingValue = TextEditingValue(
 | 
				
			||||||
                            text: textWithoutSpaces,
 | 
					                            text: textWithoutSpaces,
 | 
				
			||||||
@ -190,62 +190,71 @@ class _ConnectionPageState extends State<ConnectionPage> {
 | 
				
			|||||||
                        }
 | 
					                        }
 | 
				
			||||||
                        String textToFind = textEditingValue.text.toLowerCase();
 | 
					                        String textToFind = textEditingValue.text.toLowerCase();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                        return peers.where((peer) =>
 | 
					                        return peers
 | 
				
			||||||
                        peer.id.toLowerCase().contains(textToFind) ||
 | 
					                            .where((peer) =>
 | 
				
			||||||
                        peer.username.toLowerCase().contains(textToFind) ||
 | 
					                                peer.id.toLowerCase().contains(textToFind) ||
 | 
				
			||||||
                        peer.hostname.toLowerCase().contains(textToFind) ||
 | 
					                                peer.username
 | 
				
			||||||
                        peer.alias.toLowerCase().contains(textToFind))
 | 
					                                    .toLowerCase()
 | 
				
			||||||
                        .toList();
 | 
					                                    .contains(textToFind) ||
 | 
				
			||||||
 | 
					                                peer.hostname
 | 
				
			||||||
 | 
					                                    .toLowerCase()
 | 
				
			||||||
 | 
					                                    .contains(textToFind) ||
 | 
				
			||||||
 | 
					                                peer.alias.toLowerCase().contains(textToFind))
 | 
				
			||||||
 | 
					                            .toList();
 | 
				
			||||||
                      }
 | 
					                      }
 | 
				
			||||||
                    },
 | 
					                    },
 | 
				
			||||||
                    fieldViewBuilder: (BuildContext context,
 | 
					                    fieldViewBuilder: (BuildContext context,
 | 
				
			||||||
                      TextEditingController fieldTextEditingController,
 | 
					                        TextEditingController fieldTextEditingController,
 | 
				
			||||||
                      FocusNode fieldFocusNode, VoidCallback onFieldSubmitted) {
 | 
					                        FocusNode fieldFocusNode,
 | 
				
			||||||
 | 
					                        VoidCallback onFieldSubmitted) {
 | 
				
			||||||
                      fieldTextEditingController.text = _idController.text;
 | 
					                      fieldTextEditingController.text = _idController.text;
 | 
				
			||||||
                      fieldFocusNode.addListener(() async{
 | 
					                      fieldFocusNode.addListener(() async {
 | 
				
			||||||
                      _idEmpty.value = fieldTextEditingController.text.isEmpty;
 | 
					                        _idEmpty.value =
 | 
				
			||||||
                        if (fieldFocusNode.hasFocus && !isPeersLoading){
 | 
					                            fieldTextEditingController.text.isEmpty;
 | 
				
			||||||
 | 
					                        if (fieldFocusNode.hasFocus && !isPeersLoading) {
 | 
				
			||||||
                          _fetchPeers();
 | 
					                          _fetchPeers();
 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
                      });
 | 
					                      });
 | 
				
			||||||
                      final textLength = fieldTextEditingController.value.text.length;
 | 
					                      final textLength =
 | 
				
			||||||
 | 
					                          fieldTextEditingController.value.text.length;
 | 
				
			||||||
                      // select all to facilitate removing text, just following the behavior of address input of chrome
 | 
					                      // select all to facilitate removing text, just following the behavior of address input of chrome
 | 
				
			||||||
                      fieldTextEditingController.selection = TextSelection(baseOffset: 0, extentOffset: textLength);
 | 
					                      fieldTextEditingController.selection = TextSelection(
 | 
				
			||||||
                    return AutoSizeTextField(
 | 
					                          baseOffset: 0, extentOffset: textLength);
 | 
				
			||||||
                    controller: fieldTextEditingController,
 | 
					                      return AutoSizeTextField(
 | 
				
			||||||
                    focusNode: fieldFocusNode,
 | 
					                        controller: fieldTextEditingController,
 | 
				
			||||||
                    minFontSize: 18,
 | 
					                        focusNode: fieldFocusNode,
 | 
				
			||||||
                    autocorrect: false,
 | 
					                        minFontSize: 18,
 | 
				
			||||||
                    enableSuggestions: false,
 | 
					                        autocorrect: false,
 | 
				
			||||||
                    keyboardType: TextInputType.visiblePassword,
 | 
					                        enableSuggestions: false,
 | 
				
			||||||
                    // keyboardType: TextInputType.number,
 | 
					                        keyboardType: TextInputType.visiblePassword,
 | 
				
			||||||
                    onChanged: (String text) {
 | 
					                        // keyboardType: TextInputType.number,
 | 
				
			||||||
                      _idController.id = text;
 | 
					                        onChanged: (String text) {
 | 
				
			||||||
                    },
 | 
					                          _idController.id = text;
 | 
				
			||||||
                    style: const TextStyle(
 | 
					                        },
 | 
				
			||||||
                      fontFamily: 'WorkSans',
 | 
					                        style: const TextStyle(
 | 
				
			||||||
                      fontWeight: FontWeight.bold,
 | 
					                          fontFamily: 'WorkSans',
 | 
				
			||||||
                      fontSize: 30,
 | 
					                          fontWeight: FontWeight.bold,
 | 
				
			||||||
                      color: MyTheme.idColor,
 | 
					                          fontSize: 30,
 | 
				
			||||||
                    ),
 | 
					                          color: MyTheme.idColor,
 | 
				
			||||||
                    decoration: InputDecoration(
 | 
					                        ),
 | 
				
			||||||
                      labelText: translate('Remote ID'),
 | 
					                        decoration: InputDecoration(
 | 
				
			||||||
                      // hintText: 'Enter your remote ID',
 | 
					                          labelText: translate('Remote ID'),
 | 
				
			||||||
                      border: InputBorder.none,
 | 
					                          // hintText: 'Enter your remote ID',
 | 
				
			||||||
                      helperStyle: const TextStyle(
 | 
					                          border: InputBorder.none,
 | 
				
			||||||
                        fontWeight: FontWeight.bold,
 | 
					                          helperStyle: const TextStyle(
 | 
				
			||||||
                        fontSize: 16,
 | 
					                            fontWeight: FontWeight.bold,
 | 
				
			||||||
                        color: MyTheme.darkGray,
 | 
					                            fontSize: 16,
 | 
				
			||||||
                      ),
 | 
					                            color: MyTheme.darkGray,
 | 
				
			||||||
                      labelStyle: const TextStyle(
 | 
					                          ),
 | 
				
			||||||
                        fontWeight: FontWeight.w600,
 | 
					                          labelStyle: const TextStyle(
 | 
				
			||||||
                        fontSize: 16,
 | 
					                            fontWeight: FontWeight.w600,
 | 
				
			||||||
                        letterSpacing: 0.2,
 | 
					                            fontSize: 16,
 | 
				
			||||||
                        color: MyTheme.darkGray,
 | 
					                            letterSpacing: 0.2,
 | 
				
			||||||
                      ),
 | 
					                            color: MyTheme.darkGray,
 | 
				
			||||||
                    ),
 | 
					                          ),
 | 
				
			||||||
                    inputFormatters: [IDTextInputFormatter()],
 | 
					                        ),
 | 
				
			||||||
                     );
 | 
					                        inputFormatters: [IDTextInputFormatter()],
 | 
				
			||||||
 | 
					                      );
 | 
				
			||||||
                    },
 | 
					                    },
 | 
				
			||||||
                    onSelected: (option) {
 | 
					                    onSelected: (option) {
 | 
				
			||||||
                      setState(() {
 | 
					                      setState(() {
 | 
				
			||||||
@ -253,32 +262,59 @@ class _ConnectionPageState extends State<ConnectionPage> {
 | 
				
			|||||||
                        FocusScope.of(context).unfocus();
 | 
					                        FocusScope.of(context).unfocus();
 | 
				
			||||||
                      });
 | 
					                      });
 | 
				
			||||||
                    },
 | 
					                    },
 | 
				
			||||||
                    optionsViewBuilder: (BuildContext context, AutocompleteOnSelected<Peer> onSelected, Iterable<Peer> options) {
 | 
					                    optionsViewBuilder: (BuildContext context,
 | 
				
			||||||
 | 
					                        AutocompleteOnSelected<Peer> onSelected,
 | 
				
			||||||
 | 
					                        Iterable<Peer> options) {
 | 
				
			||||||
                      double maxHeight = options.length * 50;
 | 
					                      double maxHeight = options.length * 50;
 | 
				
			||||||
                      maxHeight = maxHeight > 200 ? 200 : maxHeight;
 | 
					                      if (options.length == 1) {
 | 
				
			||||||
 | 
					                        maxHeight = 52;
 | 
				
			||||||
 | 
					                      } else if (options.length == 3) {
 | 
				
			||||||
 | 
					                        maxHeight = 146;
 | 
				
			||||||
 | 
					                      } else if (options.length == 4) {
 | 
				
			||||||
 | 
					                        maxHeight = 193;
 | 
				
			||||||
 | 
					                      }
 | 
				
			||||||
 | 
					                      maxHeight = maxHeight.clamp(0, 200);
 | 
				
			||||||
                      return Align(
 | 
					                      return Align(
 | 
				
			||||||
                        alignment: Alignment.topLeft,
 | 
					                          alignment: Alignment.topLeft,
 | 
				
			||||||
                        child: ClipRRect(
 | 
					                          child: Container(
 | 
				
			||||||
                          borderRadius: BorderRadius.circular(5),
 | 
					                              decoration: BoxDecoration(
 | 
				
			||||||
                          child: Material(
 | 
					                                boxShadow: [
 | 
				
			||||||
                          elevation: 4,
 | 
					                                  BoxShadow(
 | 
				
			||||||
                          child: ConstrainedBox(
 | 
					                                    color: Colors.black.withOpacity(0.3),
 | 
				
			||||||
                            constraints: BoxConstraints(
 | 
					                                    blurRadius: 5,
 | 
				
			||||||
                              maxHeight: maxHeight,
 | 
					                                    spreadRadius: 1,
 | 
				
			||||||
                              maxWidth: 320,
 | 
					                                  ),
 | 
				
			||||||
                            ),
 | 
					                                ],
 | 
				
			||||||
                              child: peers.isEmpty && isPeersLoading
 | 
					                              ),
 | 
				
			||||||
                              ? Container(
 | 
					                              child: ClipRRect(
 | 
				
			||||||
                                    height: 80,
 | 
					                                  borderRadius: BorderRadius.circular(5),
 | 
				
			||||||
                                     child: Center( 
 | 
					                                  child: Material(
 | 
				
			||||||
                                      child: CircularProgressIndicator(
 | 
					                                      elevation: 4,
 | 
				
			||||||
                                        strokeWidth: 2,
 | 
					                                      child: ConstrainedBox(
 | 
				
			||||||
                                      )))
 | 
					                                          constraints: BoxConstraints(
 | 
				
			||||||
                              : ListView(
 | 
					                                            maxHeight: maxHeight,
 | 
				
			||||||
                              padding: EdgeInsets.only(top: 5),
 | 
					                                            maxWidth: 320,
 | 
				
			||||||
                              children: options.map((peer) => AutocompletePeerTile(onSelect: () => onSelected(peer), peer: peer)).toList(),
 | 
					                                          ),
 | 
				
			||||||
                            ))))
 | 
					                                          child: peers.isEmpty && isPeersLoading
 | 
				
			||||||
                      );
 | 
					                                              ? Container(
 | 
				
			||||||
 | 
					                                                  height: 80,
 | 
				
			||||||
 | 
					                                                  child: Center(
 | 
				
			||||||
 | 
					                                                      child:
 | 
				
			||||||
 | 
					                                                          CircularProgressIndicator(
 | 
				
			||||||
 | 
					                                                    strokeWidth: 2,
 | 
				
			||||||
 | 
					                                                  )))
 | 
				
			||||||
 | 
					                                              : ListView(
 | 
				
			||||||
 | 
					                                                  padding:
 | 
				
			||||||
 | 
					                                                      EdgeInsets.only(top: 5),
 | 
				
			||||||
 | 
					                                                  children: options
 | 
				
			||||||
 | 
					                                                      .map((peer) =>
 | 
				
			||||||
 | 
					                                                          AutocompletePeerTile(
 | 
				
			||||||
 | 
					                                                              onSelect: () =>
 | 
				
			||||||
 | 
					                                                                  onSelected(
 | 
				
			||||||
 | 
					                                                                      peer),
 | 
				
			||||||
 | 
					                                                              peer: peer))
 | 
				
			||||||
 | 
					                                                      .toList(),
 | 
				
			||||||
 | 
					                                                ))))));
 | 
				
			||||||
                    },
 | 
					                    },
 | 
				
			||||||
                  ),
 | 
					                  ),
 | 
				
			||||||
                ),
 | 
					                ),
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user