From cde7620eda101b463c79ce7a47ef95cf4be6f3b3 Mon Sep 17 00:00:00 2001 From: 21pages Date: Fri, 11 Oct 2024 16:35:15 +0800 Subject: [PATCH] fix web peer card tap (#9622) Signed-off-by: 21pages --- flutter/lib/common/widgets/peer_card.dart | 180 +++++++++++----------- flutter/lib/main.dart | 3 +- flutter/lib/models/peer_tab_model.dart | 2 +- 3 files changed, 94 insertions(+), 91 deletions(-) diff --git a/flutter/lib/common/widgets/peer_card.dart b/flutter/lib/common/widgets/peer_card.dart index 7827298b6..246b337a9 100644 --- a/flutter/lib/common/widgets/peer_card.dart +++ b/flutter/lib/common/widgets/peer_card.dart @@ -58,27 +58,33 @@ class _PeerCardState extends State<_PeerCard> stateGlobal.isPortrait.isTrue ? _buildPortrait() : _buildLandscape()); } + Widget gestureDetector({required Widget child}) { + final PeerTabModel peerTabModel = Provider.of(context); + final peer = super.widget.peer; + return GestureDetector( + onDoubleTap: peerTabModel.multiSelectionMode || peerTabModel.isShiftDown + ? null + : () => widget.connect(context, peer.id), + onTap: () { + if (peerTabModel.multiSelectionMode) { + peerTabModel.select(peer); + } else { + if (isMobile) { + widget.connect(context, peer.id); + } else { + peerTabModel.select(peer); + } + } + }, + onLongPress: () => peerTabModel.select(peer), + child: child); + } + Widget _buildPortrait() { final peer = super.widget.peer; - final PeerTabModel peerTabModel = Provider.of(context); return Card( margin: EdgeInsets.symmetric(horizontal: 2), - child: GestureDetector( - onTap: () { - if (peerTabModel.multiSelectionMode) { - peerTabModel.select(peer); - } else { - if (!isWebDesktop) { - connectInPeerTab(context, peer, widget.tab); - } - } - }, - onDoubleTap: isWebDesktop - ? () => connectInPeerTab(context, peer, widget.tab) - : null, - onLongPress: () { - peerTabModel.select(peer); - }, + child: gestureDetector( child: Container( padding: EdgeInsets.only(left: 12, top: 8, bottom: 8), child: _buildPeerTile(context, peer, null)), @@ -86,7 +92,6 @@ class _PeerCardState extends State<_PeerCard> } Widget _buildLandscape() { - final PeerTabModel peerTabModel = Provider.of(context); final peer = super.widget.peer; var deco = Rx( BoxDecoration( @@ -115,30 +120,21 @@ class _PeerCardState extends State<_PeerCard> ), ); }, - child: GestureDetector( - onDoubleTap: - peerTabModel.multiSelectionMode || peerTabModel.isShiftDown - ? null - : () => widget.connect(context, peer.id), - onTap: () => peerTabModel.select(peer), - onLongPress: () => peerTabModel.select(peer), + child: gestureDetector( child: Obx(() => peerCardUiType.value == PeerUiType.grid ? _buildPeerCard(context, peer, deco) : _buildPeerTile(context, peer, deco))), ); } - Widget _buildPeerTile( - BuildContext context, Peer peer, Rx? deco) { - hideUsernameOnCard ??= - bind.mainGetBuildinOption(key: kHideUsernameOnCard) == 'Y'; + makeChild(bool isPortrait, Peer peer) { final name = hideUsernameOnCard == true ? peer.hostname : '${peer.username}${peer.username.isNotEmpty && peer.hostname.isNotEmpty ? '@' : ''}${peer.hostname}'; final greyStyle = TextStyle( fontSize: 11, color: Theme.of(context).textTheme.titleLarge?.color?.withOpacity(0.6)); - makeChild(bool isPortrait) => Row( + return Row( mainAxisSize: MainAxisSize.max, children: [ Container( @@ -210,6 +206,12 @@ class _PeerCardState extends State<_PeerCard> ) ], ); + } + + Widget _buildPeerTile( + BuildContext context, Peer peer, Rx? deco) { + hideUsernameOnCard ??= + bind.mainGetBuildinOption(key: kHideUsernameOnCard) == 'Y'; final colors = _frontN(peer.tags, 25) .map((e) => gFFI.abModel.getCurrentAbTagColor(e)) .toList(); @@ -220,21 +222,22 @@ class _PeerCardState extends State<_PeerCard> ? '${translate('Tags')}: ${peer.tags.join(', ')}' : '', child: Stack(children: [ - Obx(() => deco == null - ? makeChild(stateGlobal.isPortrait.isTrue) - : Container( + Obx( + () => deco == null + ? makeChild(stateGlobal.isPortrait.isTrue, peer) + : Container( foregroundDecoration: deco.value, - child: makeChild(stateGlobal.isPortrait.isTrue), + child: makeChild(stateGlobal.isPortrait.isTrue, peer), ), - ), + ), if (colors.isNotEmpty) - Obx(()=> Positioned( - top: 2, - right: stateGlobal.isPortrait.isTrue ? 20 : 10, - child: CustomPaint( - painter: TagPainter(radius: 3, colors: colors), - ), - )) + Obx(() => Positioned( + top: 2, + right: stateGlobal.isPortrait.isTrue ? 20 : 10, + child: CustomPaint( + painter: TagPainter(radius: 3, colors: colors), + ), + )) ]), ); } @@ -1259,54 +1262,53 @@ void _rdpDialog(String id) async { ], ).marginOnly(bottom: isDesktop ? 8 : 0), Obx(() => Row( - children: [ - stateGlobal.isPortrait.isFalse - ? ConstrainedBox( - constraints: const BoxConstraints(minWidth: 140), - child: Text( - "${translate('Username')}:", - textAlign: TextAlign.right, - ).marginOnly(right: 10)) - : SizedBox.shrink(), - Expanded( - child: TextField( - decoration: InputDecoration( - labelText: isDesktop - ? null - : translate('Username')), - controller: userController, - ), - ), - ], - ).marginOnly(bottom: stateGlobal.isPortrait.isFalse ? 8 : 0)), - Obx(() => Row( - children: [ - stateGlobal.isPortrait.isFalse - ? ConstrainedBox( - constraints: const BoxConstraints(minWidth: 140), - child: Text( - "${translate('Password')}:", - textAlign: TextAlign.right, - ).marginOnly(right: 10)) - : SizedBox.shrink(), - Expanded( - child: Obx(() => TextField( - obscureText: secure.value, - maxLength: maxLength, + children: [ + stateGlobal.isPortrait.isFalse + ? ConstrainedBox( + constraints: const BoxConstraints(minWidth: 140), + child: Text( + "${translate('Username')}:", + textAlign: TextAlign.right, + ).marginOnly(right: 10)) + : SizedBox.shrink(), + Expanded( + child: TextField( decoration: InputDecoration( - labelText: isDesktop - ? null - : translate('Password'), - suffixIcon: IconButton( - onPressed: () => secure.value = !secure.value, - icon: Icon(secure.value - ? Icons.visibility_off - : Icons.visibility))), - controller: passwordController, - )), - ), - ], - )) + labelText: + isDesktop ? null : translate('Username')), + controller: userController, + ), + ), + ], + ).marginOnly(bottom: stateGlobal.isPortrait.isFalse ? 8 : 0)), + Obx(() => Row( + children: [ + stateGlobal.isPortrait.isFalse + ? ConstrainedBox( + constraints: const BoxConstraints(minWidth: 140), + child: Text( + "${translate('Password')}:", + textAlign: TextAlign.right, + ).marginOnly(right: 10)) + : SizedBox.shrink(), + Expanded( + child: Obx(() => TextField( + obscureText: secure.value, + maxLength: maxLength, + decoration: InputDecoration( + labelText: + isDesktop ? null : translate('Password'), + suffixIcon: IconButton( + onPressed: () => + secure.value = !secure.value, + icon: Icon(secure.value + ? Icons.visibility_off + : Icons.visibility))), + controller: passwordController, + )), + ), + ], + )) ], ), ), diff --git a/flutter/lib/main.dart b/flutter/lib/main.dart index dc02ac81f..9342c9e50 100644 --- a/flutter/lib/main.dart +++ b/flutter/lib/main.dart @@ -475,7 +475,8 @@ class _AppState extends State with WidgetsBindingObserver { : (context, child) { child = _keepScaleBuilder(context, child); child = botToastBuilder(context, child); - if (isDesktop && desktopType == DesktopType.main) { + if ((isDesktop && desktopType == DesktopType.main) || + isWebDesktop) { child = keyListenerBuilder(context, child); } if (isLinux) { diff --git a/flutter/lib/models/peer_tab_model.dart b/flutter/lib/models/peer_tab_model.dart index 7dab2574d..fbde560c2 100644 --- a/flutter/lib/models/peer_tab_model.dart +++ b/flutter/lib/models/peer_tab_model.dart @@ -152,7 +152,7 @@ class PeerTabModel with ChangeNotifier { // https://github.com/flutter/flutter/issues/101275#issuecomment-1604541700 // After onTap, the shift key should be pressed for a while when not in multiselection mode, // because onTap is delayed when onDoubleTap is not null - if (isDesktop && !_isShiftDown) return; + if ((isDesktop || isWebDesktop) && !_isShiftDown) return; _multiSelectionMode = true; } final cached = _currentTabCachedPeers.map((e) => e.id).toList();