Merge pull request #1336 from Kingtous/flutter_desktop
feat: find id and grid/tile view for peers
This commit is contained in:
		
						commit
						75b04b9af1
					
				@ -5,6 +5,7 @@ import 'package:contextmenu/contextmenu.dart';
 | 
				
			|||||||
import 'package:flutter/material.dart';
 | 
					import 'package:flutter/material.dart';
 | 
				
			||||||
import 'package:flutter_hbb/desktop/pages/desktop_home_page.dart';
 | 
					import 'package:flutter_hbb/desktop/pages/desktop_home_page.dart';
 | 
				
			||||||
import 'package:flutter_hbb/desktop/widgets/peer_widget.dart';
 | 
					import 'package:flutter_hbb/desktop/widgets/peer_widget.dart';
 | 
				
			||||||
 | 
					import 'package:flutter_hbb/desktop/widgets/peercard_widget.dart';
 | 
				
			||||||
import 'package:flutter_hbb/utils/multi_window_manager.dart';
 | 
					import 'package:flutter_hbb/utils/multi_window_manager.dart';
 | 
				
			||||||
import 'package:get/get.dart';
 | 
					import 'package:get/get.dart';
 | 
				
			||||||
import 'package:provider/provider.dart';
 | 
					import 'package:provider/provider.dart';
 | 
				
			||||||
@ -976,6 +977,9 @@ class _PeerTabbedPageState extends State<_PeerTabbedPage>
 | 
				
			|||||||
  // hard code for now
 | 
					  // hard code for now
 | 
				
			||||||
  void _handleTabSelection() {
 | 
					  void _handleTabSelection() {
 | 
				
			||||||
    if (_tabController.indexIsChanging) {
 | 
					    if (_tabController.indexIsChanging) {
 | 
				
			||||||
 | 
					      // reset search text
 | 
				
			||||||
 | 
					      peerSearchText.value = "";
 | 
				
			||||||
 | 
					      peerSearchTextController.clear();
 | 
				
			||||||
      _tabIndex.value = _tabController.index;
 | 
					      _tabIndex.value = _tabController.index;
 | 
				
			||||||
      switch (_tabController.index) {
 | 
					      switch (_tabController.index) {
 | 
				
			||||||
        case 0:
 | 
					        case 0:
 | 
				
			||||||
@ -1014,7 +1018,13 @@ class _PeerTabbedPageState extends State<_PeerTabbedPage>
 | 
				
			|||||||
    return Column(
 | 
					    return Column(
 | 
				
			||||||
      crossAxisAlignment: CrossAxisAlignment.start,
 | 
					      crossAxisAlignment: CrossAxisAlignment.start,
 | 
				
			||||||
      children: [
 | 
					      children: [
 | 
				
			||||||
        _createTabBar(context),
 | 
					        Row(
 | 
				
			||||||
 | 
					          children: [
 | 
				
			||||||
 | 
					            Expanded(child: _createTabBar(context)),
 | 
				
			||||||
 | 
					            _createSearchBar(context),
 | 
				
			||||||
 | 
					            _createPeerViewTypeSwitch(context),
 | 
				
			||||||
 | 
					          ],
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
        _createTabBarView(),
 | 
					        _createTabBarView(),
 | 
				
			||||||
      ],
 | 
					      ],
 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
@ -1054,4 +1064,72 @@ class _PeerTabbedPageState extends State<_PeerTabbedPage>
 | 
				
			|||||||
                controller: _tabController, children: super.widget.children)
 | 
					                controller: _tabController, children: super.widget.children)
 | 
				
			||||||
            .paddingSymmetric(horizontal: 12.0, vertical: 4.0));
 | 
					            .paddingSymmetric(horizontal: 12.0, vertical: 4.0));
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  _createSearchBar(BuildContext context) {
 | 
				
			||||||
 | 
					    return Container(
 | 
				
			||||||
 | 
					      width: 175,
 | 
				
			||||||
 | 
					      height: 30,
 | 
				
			||||||
 | 
					      margin: EdgeInsets.only(right: 16),
 | 
				
			||||||
 | 
					      decoration: BoxDecoration(color: Colors.white),
 | 
				
			||||||
 | 
					      child: Obx(
 | 
				
			||||||
 | 
					        () => TextField(
 | 
				
			||||||
 | 
					          controller: peerSearchTextController,
 | 
				
			||||||
 | 
					          onChanged: (searchText) {
 | 
				
			||||||
 | 
					            peerSearchText.value = searchText;
 | 
				
			||||||
 | 
					          },
 | 
				
			||||||
 | 
					          decoration: InputDecoration(
 | 
				
			||||||
 | 
					            prefixIcon: Icon(
 | 
				
			||||||
 | 
					              Icons.search,
 | 
				
			||||||
 | 
					              size: 20,
 | 
				
			||||||
 | 
					            ),
 | 
				
			||||||
 | 
					            contentPadding: EdgeInsets.zero,
 | 
				
			||||||
 | 
					            hintText: translate("Search ID"),
 | 
				
			||||||
 | 
					            hintStyle: TextStyle(fontSize: 14),
 | 
				
			||||||
 | 
					            border: OutlineInputBorder(),
 | 
				
			||||||
 | 
					            isDense: true,
 | 
				
			||||||
 | 
					          ),
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					      ),
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  _createPeerViewTypeSwitch(BuildContext context) {
 | 
				
			||||||
 | 
					    final activeDeco = BoxDecoration(color: Colors.white);
 | 
				
			||||||
 | 
					    return Row(
 | 
				
			||||||
 | 
					      children: [
 | 
				
			||||||
 | 
					        Obx(
 | 
				
			||||||
 | 
					          () => Container(
 | 
				
			||||||
 | 
					            padding: EdgeInsets.all(4.0),
 | 
				
			||||||
 | 
					            decoration:
 | 
				
			||||||
 | 
					                peerCardUiType.value == PeerUiType.grid ? activeDeco : null,
 | 
				
			||||||
 | 
					            child: InkWell(
 | 
				
			||||||
 | 
					                onTap: () {
 | 
				
			||||||
 | 
					                  peerCardUiType.value = PeerUiType.grid;
 | 
				
			||||||
 | 
					                },
 | 
				
			||||||
 | 
					                child: Icon(
 | 
				
			||||||
 | 
					                  Icons.grid_view_rounded,
 | 
				
			||||||
 | 
					                  size: 20,
 | 
				
			||||||
 | 
					                  color: Colors.black54,
 | 
				
			||||||
 | 
					                )),
 | 
				
			||||||
 | 
					          ),
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        Obx(
 | 
				
			||||||
 | 
					          () => Container(
 | 
				
			||||||
 | 
					            padding: EdgeInsets.all(4.0),
 | 
				
			||||||
 | 
					            decoration:
 | 
				
			||||||
 | 
					                peerCardUiType.value == PeerUiType.list ? activeDeco : null,
 | 
				
			||||||
 | 
					            child: InkWell(
 | 
				
			||||||
 | 
					                onTap: () {
 | 
				
			||||||
 | 
					                  peerCardUiType.value = PeerUiType.list;
 | 
				
			||||||
 | 
					                },
 | 
				
			||||||
 | 
					                child: Icon(
 | 
				
			||||||
 | 
					                  Icons.list,
 | 
				
			||||||
 | 
					                  size: 24,
 | 
				
			||||||
 | 
					                  color: Colors.black54,
 | 
				
			||||||
 | 
					                )),
 | 
				
			||||||
 | 
					          ),
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					      ],
 | 
				
			||||||
 | 
					    ).paddingOnly(right: 16.0);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -1,23 +1,30 @@
 | 
				
			|||||||
import 'dart:async';
 | 
					import 'dart:async';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import 'package:flutter/material.dart';
 | 
					 | 
				
			||||||
import 'package:flutter/foundation.dart';
 | 
					import 'package:flutter/foundation.dart';
 | 
				
			||||||
 | 
					import 'package:flutter/material.dart';
 | 
				
			||||||
 | 
					import 'package:get/get.dart';
 | 
				
			||||||
import 'package:provider/provider.dart';
 | 
					import 'package:provider/provider.dart';
 | 
				
			||||||
import 'package:visibility_detector/visibility_detector.dart';
 | 
					import 'package:visibility_detector/visibility_detector.dart';
 | 
				
			||||||
import 'package:window_manager/window_manager.dart';
 | 
					import 'package:window_manager/window_manager.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import '../../common.dart';
 | 
				
			||||||
import '../../models/peer_model.dart';
 | 
					import '../../models/peer_model.dart';
 | 
				
			||||||
import '../../models/platform_model.dart';
 | 
					import '../../models/platform_model.dart';
 | 
				
			||||||
import '../../common.dart';
 | 
					 | 
				
			||||||
import 'peercard_widget.dart';
 | 
					import 'peercard_widget.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef OffstageFunc = bool Function(Peer peer);
 | 
					typedef OffstageFunc = bool Function(Peer peer);
 | 
				
			||||||
typedef PeerCardWidgetFunc = Widget Function(Peer peer);
 | 
					typedef PeerCardWidgetFunc = Widget Function(Peer peer);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// for peer search text, global obs value
 | 
				
			||||||
 | 
					final peerSearchText = "".obs;
 | 
				
			||||||
 | 
					final peerSearchTextController =
 | 
				
			||||||
 | 
					    TextEditingController(text: peerSearchText.value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class _PeerWidget extends StatefulWidget {
 | 
					class _PeerWidget extends StatefulWidget {
 | 
				
			||||||
  late final _peers;
 | 
					  late final _peers;
 | 
				
			||||||
  late final OffstageFunc _offstageFunc;
 | 
					  late final OffstageFunc _offstageFunc;
 | 
				
			||||||
  late final PeerCardWidgetFunc _peerCardWidgetFunc;
 | 
					  late final PeerCardWidgetFunc _peerCardWidgetFunc;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  _PeerWidget(Peers peers, OffstageFunc offstageFunc,
 | 
					  _PeerWidget(Peers peers, OffstageFunc offstageFunc,
 | 
				
			||||||
      PeerCardWidgetFunc peerCardWidgetFunc,
 | 
					      PeerCardWidgetFunc peerCardWidgetFunc,
 | 
				
			||||||
      {Key? key})
 | 
					      {Key? key})
 | 
				
			||||||
@ -71,20 +78,32 @@ class _PeerWidgetState extends State<_PeerWidget> with WindowListener {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  @override
 | 
					  @override
 | 
				
			||||||
  Widget build(BuildContext context) {
 | 
					  Widget build(BuildContext context) {
 | 
				
			||||||
    final space = 8.0;
 | 
					    final space = 12.0;
 | 
				
			||||||
    return ChangeNotifierProvider<Peers>(
 | 
					    return ChangeNotifierProvider<Peers>(
 | 
				
			||||||
      create: (context) => super.widget._peers,
 | 
					      create: (context) => super.widget._peers,
 | 
				
			||||||
      child: SingleChildScrollView(
 | 
					 | 
				
			||||||
      child: Consumer<Peers>(
 | 
					      child: Consumer<Peers>(
 | 
				
			||||||
              builder: (context, peers, child) => Wrap(
 | 
					          builder: (context, peers, child) => peers.peers.isEmpty
 | 
				
			||||||
                  children: () {
 | 
					              ? Center(
 | 
				
			||||||
 | 
					                  child: Text(translate("Empty")),
 | 
				
			||||||
 | 
					                )
 | 
				
			||||||
 | 
					              : SingleChildScrollView(
 | 
				
			||||||
 | 
					                  child: ObxValue<RxString>((searchText) {
 | 
				
			||||||
                    final cards = <Widget>[];
 | 
					                    final cards = <Widget>[];
 | 
				
			||||||
                    peers.peers.forEach((peer) {
 | 
					                    peers.peers.where((peer) {
 | 
				
			||||||
 | 
					                      if (searchText.isEmpty) {
 | 
				
			||||||
 | 
					                        return true;
 | 
				
			||||||
 | 
					                      } else {
 | 
				
			||||||
 | 
					                        return peer.id.contains(peerSearchText.value);
 | 
				
			||||||
 | 
					                      }
 | 
				
			||||||
 | 
					                    }).forEach((peer) {
 | 
				
			||||||
                      cards.add(Offstage(
 | 
					                      cards.add(Offstage(
 | 
				
			||||||
                          offstage: super.widget._offstageFunc(peer),
 | 
					                          offstage: super.widget._offstageFunc(peer),
 | 
				
			||||||
                          child: Container(
 | 
					                          child: Obx(
 | 
				
			||||||
 | 
					                            () => Container(
 | 
				
			||||||
                              width: 225,
 | 
					                              width: 225,
 | 
				
			||||||
                            height: 150,
 | 
					                              height: peerCardUiType.value == PeerUiType.grid
 | 
				
			||||||
 | 
					                                  ? 150
 | 
				
			||||||
 | 
					                                  : 50,
 | 
				
			||||||
                              child: VisibilityDetector(
 | 
					                              child: VisibilityDetector(
 | 
				
			||||||
                                key: Key('${peer.id}'),
 | 
					                                key: Key('${peer.id}'),
 | 
				
			||||||
                                onVisibilityChanged: (info) {
 | 
					                                onVisibilityChanged: (info) {
 | 
				
			||||||
@ -98,12 +117,13 @@ class _PeerWidgetState extends State<_PeerWidget> with WindowListener {
 | 
				
			|||||||
                                },
 | 
					                                },
 | 
				
			||||||
                                child: super.widget._peerCardWidgetFunc(peer),
 | 
					                                child: super.widget._peerCardWidgetFunc(peer),
 | 
				
			||||||
                              ),
 | 
					                              ),
 | 
				
			||||||
 | 
					                            ),
 | 
				
			||||||
                          )));
 | 
					                          )));
 | 
				
			||||||
                    });
 | 
					                    });
 | 
				
			||||||
                    return cards;
 | 
					                    return Wrap(
 | 
				
			||||||
                  }(),
 | 
					                        children: cards, spacing: space, runSpacing: space);
 | 
				
			||||||
                  spacing: space,
 | 
					                  }, peerSearchText),
 | 
				
			||||||
                  runSpacing: space))),
 | 
					                )),
 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -162,7 +182,9 @@ class RecentPeerWidget extends BasePeerWidget {
 | 
				
			|||||||
    super._name = "recent peer";
 | 
					    super._name = "recent peer";
 | 
				
			||||||
    super._loadEvent = "load_recent_peers";
 | 
					    super._loadEvent = "load_recent_peers";
 | 
				
			||||||
    super._offstageFunc = (Peer _peer) => false;
 | 
					    super._offstageFunc = (Peer _peer) => false;
 | 
				
			||||||
    super._peerCardWidgetFunc = (Peer peer) => RecentPeerCard(peer: peer);
 | 
					    super._peerCardWidgetFunc = (Peer peer) => RecentPeerCard(
 | 
				
			||||||
 | 
					          peer: peer,
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
    super._initPeers = [];
 | 
					    super._initPeers = [];
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -5,13 +5,17 @@ import 'package:get/get.dart';
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import '../../common.dart';
 | 
					import '../../common.dart';
 | 
				
			||||||
import '../../models/model.dart';
 | 
					import '../../models/model.dart';
 | 
				
			||||||
import '../../models/platform_model.dart';
 | 
					 | 
				
			||||||
import '../../models/peer_model.dart';
 | 
					import '../../models/peer_model.dart';
 | 
				
			||||||
 | 
					import '../../models/platform_model.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef PopupMenuItemsFunc = Future<List<PopupMenuItem<String>>> Function();
 | 
					typedef PopupMenuItemsFunc = Future<List<PopupMenuItem<String>>> Function();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
enum PeerType { recent, fav, discovered, ab }
 | 
					enum PeerType { recent, fav, discovered, ab }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum PeerUiType { grid, list }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					final peerCardUiType = PeerUiType.grid.obs;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class _PeerCard extends StatefulWidget {
 | 
					class _PeerCard extends StatefulWidget {
 | 
				
			||||||
  final Peer peer;
 | 
					  final Peer peer;
 | 
				
			||||||
  final PopupMenuItemsFunc popupMenuItemsFunc;
 | 
					  final PopupMenuItemsFunc popupMenuItemsFunc;
 | 
				
			||||||
@ -39,29 +43,134 @@ class _PeerCardState extends State<_PeerCard>
 | 
				
			|||||||
    final peer = super.widget.peer;
 | 
					    final peer = super.widget.peer;
 | 
				
			||||||
    var deco = Rx<BoxDecoration?>(BoxDecoration(
 | 
					    var deco = Rx<BoxDecoration?>(BoxDecoration(
 | 
				
			||||||
        border: Border.all(color: Colors.transparent, width: 1.0),
 | 
					        border: Border.all(color: Colors.transparent, width: 1.0),
 | 
				
			||||||
        borderRadius: BorderRadius.circular(20)));
 | 
					        borderRadius: peerCardUiType.value == PeerUiType.grid
 | 
				
			||||||
    return Card(
 | 
					            ? BorderRadius.circular(20)
 | 
				
			||||||
        shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(20)),
 | 
					            : null));
 | 
				
			||||||
        child: MouseRegion(
 | 
					    return MouseRegion(
 | 
				
			||||||
      onEnter: (evt) {
 | 
					      onEnter: (evt) {
 | 
				
			||||||
        deco.value = BoxDecoration(
 | 
					        deco.value = BoxDecoration(
 | 
				
			||||||
            border: Border.all(color: Colors.blue, width: 1.0),
 | 
					            border: Border.all(color: Colors.blue, width: 1.0),
 | 
				
			||||||
                borderRadius: BorderRadius.circular(20));
 | 
					            borderRadius: peerCardUiType.value == PeerUiType.grid
 | 
				
			||||||
 | 
					                ? BorderRadius.circular(20)
 | 
				
			||||||
 | 
					                : null);
 | 
				
			||||||
      },
 | 
					      },
 | 
				
			||||||
      onExit: (evt) {
 | 
					      onExit: (evt) {
 | 
				
			||||||
        deco.value = BoxDecoration(
 | 
					        deco.value = BoxDecoration(
 | 
				
			||||||
            border: Border.all(color: Colors.transparent, width: 1.0),
 | 
					            border: Border.all(color: Colors.transparent, width: 1.0),
 | 
				
			||||||
                borderRadius: BorderRadius.circular(20));
 | 
					            borderRadius: peerCardUiType.value == PeerUiType.grid
 | 
				
			||||||
 | 
					                ? BorderRadius.circular(20)
 | 
				
			||||||
 | 
					                : null);
 | 
				
			||||||
      },
 | 
					      },
 | 
				
			||||||
      child: GestureDetector(
 | 
					      child: GestureDetector(
 | 
				
			||||||
          onDoubleTap: () => _connect(peer.id),
 | 
					          onDoubleTap: () => _connect(peer.id),
 | 
				
			||||||
              child: _buildPeerTile(context, peer, deco)),
 | 
					          child: Obx(() => peerCardUiType.value == PeerUiType.grid
 | 
				
			||||||
        ));
 | 
					              ? _buildPeerCard(context, peer, deco)
 | 
				
			||||||
 | 
					              : _buildPeerTile(context, peer, deco))),
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  Widget _buildPeerTile(
 | 
					  Widget _buildPeerTile(
 | 
				
			||||||
      BuildContext context, Peer peer, Rx<BoxDecoration?> deco) {
 | 
					      BuildContext context, Peer peer, Rx<BoxDecoration?> deco) {
 | 
				
			||||||
 | 
					    final greyStyle = TextStyle(fontSize: 12, color: Colors.grey);
 | 
				
			||||||
    return Obx(
 | 
					    return Obx(
 | 
				
			||||||
 | 
					      () => Container(
 | 
				
			||||||
 | 
					        decoration: deco.value,
 | 
				
			||||||
 | 
					        child: Row(
 | 
				
			||||||
 | 
					          mainAxisSize: MainAxisSize.max,
 | 
				
			||||||
 | 
					          children: [
 | 
				
			||||||
 | 
					            Container(
 | 
				
			||||||
 | 
					              height: 50,
 | 
				
			||||||
 | 
					              width: 50,
 | 
				
			||||||
 | 
					              decoration: BoxDecoration(
 | 
				
			||||||
 | 
					                color: str2color('${peer.id}${peer.platform}', 0x7f),
 | 
				
			||||||
 | 
					              ),
 | 
				
			||||||
 | 
					              alignment: Alignment.center,
 | 
				
			||||||
 | 
					              child: _getPlatformImage('${peer.platform}').paddingAll(8.0),
 | 
				
			||||||
 | 
					            ),
 | 
				
			||||||
 | 
					            Expanded(
 | 
				
			||||||
 | 
					              child: Container(
 | 
				
			||||||
 | 
					                decoration: BoxDecoration(color: Colors.white),
 | 
				
			||||||
 | 
					                child: Row(
 | 
				
			||||||
 | 
					                  mainAxisAlignment: MainAxisAlignment.spaceBetween,
 | 
				
			||||||
 | 
					                  children: [
 | 
				
			||||||
 | 
					                    Expanded(
 | 
				
			||||||
 | 
					                      child: Column(
 | 
				
			||||||
 | 
					                        mainAxisAlignment: MainAxisAlignment.spaceAround,
 | 
				
			||||||
 | 
					                        children: [
 | 
				
			||||||
 | 
					                          Row(children: [
 | 
				
			||||||
 | 
					                            Text(
 | 
				
			||||||
 | 
					                              '${peer.id}',
 | 
				
			||||||
 | 
					                              style: TextStyle(fontWeight: FontWeight.w400),
 | 
				
			||||||
 | 
					                            ),
 | 
				
			||||||
 | 
					                            Padding(
 | 
				
			||||||
 | 
					                                padding: EdgeInsets.fromLTRB(4, 4, 8, 4),
 | 
				
			||||||
 | 
					                                child: CircleAvatar(
 | 
				
			||||||
 | 
					                                    radius: 5,
 | 
				
			||||||
 | 
					                                    backgroundColor: peer.online
 | 
				
			||||||
 | 
					                                        ? Colors.green
 | 
				
			||||||
 | 
					                                        : Colors.yellow)),
 | 
				
			||||||
 | 
					                          ]),
 | 
				
			||||||
 | 
					                          Align(
 | 
				
			||||||
 | 
					                            alignment: Alignment.centerLeft,
 | 
				
			||||||
 | 
					                            child: FutureBuilder<String>(
 | 
				
			||||||
 | 
					                              future: bind.mainGetPeerOption(
 | 
				
			||||||
 | 
					                                  id: peer.id, key: 'alias'),
 | 
				
			||||||
 | 
					                              builder: (_, snapshot) {
 | 
				
			||||||
 | 
					                                if (snapshot.hasData) {
 | 
				
			||||||
 | 
					                                  final name = snapshot.data!.isEmpty
 | 
				
			||||||
 | 
					                                      ? '${peer.username}@${peer.hostname}'
 | 
				
			||||||
 | 
					                                      : snapshot.data!;
 | 
				
			||||||
 | 
					                                  return Tooltip(
 | 
				
			||||||
 | 
					                                    message: name,
 | 
				
			||||||
 | 
					                                    child: Text(
 | 
				
			||||||
 | 
					                                      name,
 | 
				
			||||||
 | 
					                                      style: greyStyle,
 | 
				
			||||||
 | 
					                                      textAlign: TextAlign.start,
 | 
				
			||||||
 | 
					                                      overflow: TextOverflow.ellipsis,
 | 
				
			||||||
 | 
					                                    ),
 | 
				
			||||||
 | 
					                                  );
 | 
				
			||||||
 | 
					                                } else {
 | 
				
			||||||
 | 
					                                  // alias has not arrived
 | 
				
			||||||
 | 
					                                  return Text(
 | 
				
			||||||
 | 
					                                    '${peer.username}@${peer.hostname}',
 | 
				
			||||||
 | 
					                                    style: greyStyle,
 | 
				
			||||||
 | 
					                                    textAlign: TextAlign.start,
 | 
				
			||||||
 | 
					                                    overflow: TextOverflow.ellipsis,
 | 
				
			||||||
 | 
					                                  );
 | 
				
			||||||
 | 
					                                }
 | 
				
			||||||
 | 
					                              },
 | 
				
			||||||
 | 
					                            ),
 | 
				
			||||||
 | 
					                          ),
 | 
				
			||||||
 | 
					                        ],
 | 
				
			||||||
 | 
					                      ),
 | 
				
			||||||
 | 
					                    ),
 | 
				
			||||||
 | 
					                    InkWell(
 | 
				
			||||||
 | 
					                        child: Icon(Icons.more_vert),
 | 
				
			||||||
 | 
					                        onTapDown: (e) {
 | 
				
			||||||
 | 
					                          final x = e.globalPosition.dx;
 | 
				
			||||||
 | 
					                          final y = e.globalPosition.dy;
 | 
				
			||||||
 | 
					                          _menuPos = RelativeRect.fromLTRB(x, y, x, y);
 | 
				
			||||||
 | 
					                        },
 | 
				
			||||||
 | 
					                        onTap: () {
 | 
				
			||||||
 | 
					                          _showPeerMenu(context, peer.id);
 | 
				
			||||||
 | 
					                        }),
 | 
				
			||||||
 | 
					                  ],
 | 
				
			||||||
 | 
					                ).paddingSymmetric(horizontal: 8.0),
 | 
				
			||||||
 | 
					              ),
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
 | 
					          ],
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					      ),
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  Widget _buildPeerCard(
 | 
				
			||||||
 | 
					      BuildContext context, Peer peer, Rx<BoxDecoration?> deco) {
 | 
				
			||||||
 | 
					    return Card(
 | 
				
			||||||
 | 
					      shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(20)),
 | 
				
			||||||
 | 
					      child: GestureDetector(
 | 
				
			||||||
 | 
					          onDoubleTap: () => _connect(peer.id),
 | 
				
			||||||
 | 
					          child: Obx(
 | 
				
			||||||
            () => Container(
 | 
					            () => Container(
 | 
				
			||||||
              decoration: deco.value,
 | 
					              decoration: deco.value,
 | 
				
			||||||
              child: Column(
 | 
					              child: Column(
 | 
				
			||||||
@ -141,8 +250,9 @@ class _PeerCardState extends State<_PeerCard>
 | 
				
			|||||||
                            padding: EdgeInsets.fromLTRB(0, 4, 8, 4),
 | 
					                            padding: EdgeInsets.fromLTRB(0, 4, 8, 4),
 | 
				
			||||||
                            child: CircleAvatar(
 | 
					                            child: CircleAvatar(
 | 
				
			||||||
                                radius: 5,
 | 
					                                radius: 5,
 | 
				
			||||||
                          backgroundColor:
 | 
					                                backgroundColor: peer.online
 | 
				
			||||||
                              peer.online ? Colors.green : Colors.yellow)),
 | 
					                                    ? Colors.green
 | 
				
			||||||
 | 
					                                    : Colors.yellow)),
 | 
				
			||||||
                        Text('${peer.id}')
 | 
					                        Text('${peer.id}')
 | 
				
			||||||
                      ]),
 | 
					                      ]),
 | 
				
			||||||
                      InkWell(
 | 
					                      InkWell(
 | 
				
			||||||
@ -160,6 +270,7 @@ class _PeerCardState extends State<_PeerCard>
 | 
				
			|||||||
                ],
 | 
					                ],
 | 
				
			||||||
              ),
 | 
					              ),
 | 
				
			||||||
            ),
 | 
					            ),
 | 
				
			||||||
 | 
					          )),
 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -1230,8 +1230,8 @@ packages:
 | 
				
			|||||||
    dependency: "direct main"
 | 
					    dependency: "direct main"
 | 
				
			||||||
    description:
 | 
					    description:
 | 
				
			||||||
      path: "."
 | 
					      path: "."
 | 
				
			||||||
      ref: f1d69e5d0531af947373ec26ae22808f08b1aac6
 | 
					      ref: "799ef079e87938c3f4340591b4330c2598f38bb9"
 | 
				
			||||||
      resolved-ref: f1d69e5d0531af947373ec26ae22808f08b1aac6
 | 
					      resolved-ref: "799ef079e87938c3f4340591b4330c2598f38bb9"
 | 
				
			||||||
      url: "https://github.com/Kingtous/rustdesk_window_manager"
 | 
					      url: "https://github.com/Kingtous/rustdesk_window_manager"
 | 
				
			||||||
    source: git
 | 
					    source: git
 | 
				
			||||||
    version: "0.2.5"
 | 
					    version: "0.2.5"
 | 
				
			||||||
 | 
				
			|||||||
@ -61,7 +61,7 @@ dependencies:
 | 
				
			|||||||
    window_manager:
 | 
					    window_manager:
 | 
				
			||||||
        git:
 | 
					        git:
 | 
				
			||||||
            url: https://github.com/Kingtous/rustdesk_window_manager
 | 
					            url: https://github.com/Kingtous/rustdesk_window_manager
 | 
				
			||||||
            ref: f1d69e5d0531af947373ec26ae22808f08b1aac6
 | 
					            ref: 799ef079e87938c3f4340591b4330c2598f38bb9
 | 
				
			||||||
    desktop_multi_window:
 | 
					    desktop_multi_window:
 | 
				
			||||||
        git:
 | 
					        git:
 | 
				
			||||||
            url: https://github.com/Kingtous/rustdesk_desktop_multi_window
 | 
					            url: https://github.com/Kingtous/rustdesk_desktop_multi_window
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user