From ae640dda564210fae2510a4fd958f43e31603ef5 Mon Sep 17 00:00:00 2001 From: 21pages Date: Sun, 13 Aug 2023 17:50:19 +0800 Subject: [PATCH 1/2] fix macos minisized after checking permission Signed-off-by: 21pages --- flutter/lib/common.dart | 14 +++++++++++--- .../lib/desktop/pages/desktop_setting_page.dart | 5 +---- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/flutter/lib/common.dart b/flutter/lib/common.dart index 6c3716f53..520156efb 100644 --- a/flutter/lib/common.dart +++ b/flutter/lib/common.dart @@ -222,7 +222,7 @@ class MyTheme { //tooltip static TooltipThemeData tooltipTheme() { return TooltipThemeData( - waitDuration: Duration(seconds: 1, milliseconds: 500), + waitDuration: Duration(seconds: 1, milliseconds: 500), ); } @@ -1554,7 +1554,7 @@ Future restoreWindowPosition(WindowType type, bool isRemotePeerPos = false; String? pos; // No need to check mainGetLocalBoolOptionSync(kOptionOpenNewConnInTabs) - // Though "open in tabs" is true and the new window restore peer position, it's ok. + // Though "open in tabs" is true and the new window restore peer position, it's ok. if (type == WindowType.RemoteDesktop && windowId != null && peerId != null) { // If the restore position is called by main window, and the peer id is not null // then we may need to get the position by reading the peer config. @@ -2281,10 +2281,18 @@ void onCopyFingerprint(String value) { } } +Future callMainCheckSuperUserPermission() async { + bool checked = await bind.mainCheckSuperUserPermission(); + if (Platform.isMacOS) { + await windowManager.show(); + } + return checked; +} + Future start_service(bool is_start) async { bool checked = !bind.mainIsInstalled() || !Platform.isMacOS || - await bind.mainCheckSuperUserPermission(); + await callMainCheckSuperUserPermission(); if (checked) { bind.mainSetOption(key: "stop-service", value: is_start ? "" : "Y"); } diff --git a/flutter/lib/desktop/pages/desktop_setting_page.dart b/flutter/lib/desktop/pages/desktop_setting_page.dart index e0e5858b7..b868042a4 100644 --- a/flutter/lib/desktop/pages/desktop_setting_page.dart +++ b/flutter/lib/desktop/pages/desktop_setting_page.dart @@ -1832,13 +1832,10 @@ Widget _lock( Text(translate(label)).marginOnly(left: 5), ]).marginSymmetric(vertical: 2)), onPressed: () async { - bool checked = await bind.mainCheckSuperUserPermission(); + bool checked = await callMainCheckSuperUserPermission(); if (checked) { onUnlock(); } - if (Platform.isMacOS) { - await windowManager.show(); - } }, ).marginSymmetric(horizontal: 2, vertical: 4), ).marginOnly(left: _kCardLeftMargin), From a5bba37cae2f7116a5d6de7db66c8e73ae55859b Mon Sep 17 00:00:00 2001 From: 21pages Date: Sun, 13 Aug 2023 18:13:06 +0800 Subject: [PATCH 2/2] add tag color Signed-off-by: 21pages --- flutter/lib/common.dart | 24 ++++++ flutter/lib/common/widgets/address_book.dart | 45 ++++++---- flutter/lib/common/widgets/peer_card.dart | 88 +++++++++++++++++++- 3 files changed, 139 insertions(+), 18 deletions(-) diff --git a/flutter/lib/common.dart b/flutter/lib/common.dart index 520156efb..0db48c096 100644 --- a/flutter/lib/common.dart +++ b/flutter/lib/common.dart @@ -1074,6 +1074,30 @@ Color str2color(String str, [alpha = 0xFF]) { return Color((hash & 0xFF7FFF) | (alpha << 24)); } +Color str2color2(String str, [alpha = 0xFF]) { + List colorList = [ + Colors.red, + Colors.green, + Colors.blue, + Colors.orange, + Colors.yellow, + Colors.purple, + Colors.grey, + Colors.cyan, + Colors.lime, + Colors.teal, + Colors.pink, + Colors.indigo, + Colors.brown, + ]; + var hash = 0; + for (var i = 0; i < str.length; i++) { + hash += str.codeUnitAt(i); + } + hash = hash % colorList.length; + return colorList[hash].withAlpha(alpha); +} + const K = 1024; const M = K * K; const G = M * K; diff --git a/flutter/lib/common/widgets/address_book.dart b/flutter/lib/common/widgets/address_book.dart index fa7d15b73..38701e246 100644 --- a/flutter/lib/common/widgets/address_book.dart +++ b/flutter/lib/common/widgets/address_book.dart @@ -449,26 +449,43 @@ class AddressBookTag extends StatelessWidget { pos = RelativeRect.fromLTRB(x, y, x, y); } + const double radius = 8; return GestureDetector( onTap: onTap, onTapDown: showActionMenu ? setPosition : null, onSecondaryTapDown: showActionMenu ? setPosition : null, onSecondaryTap: showActionMenu ? () => _showMenu(context, pos) : null, onLongPress: showActionMenu ? () => _showMenu(context, pos) : null, - child: Obx( - () => Container( - decoration: BoxDecoration( - color: tags.contains(name) - ? Colors.blue - : Theme.of(context).colorScheme.background, - borderRadius: BorderRadius.circular(6)), - margin: const EdgeInsets.symmetric(horizontal: 4.0, vertical: 8.0), - padding: const EdgeInsets.symmetric(vertical: 2.0, horizontal: 8.0), - child: Text(name, - style: - TextStyle(color: tags.contains(name) ? Colors.white : null)), - ), - ), + child: Obx(() => Container( + decoration: BoxDecoration( + color: tags.contains(name) + ? str2color2(name, 0xFF) + : Theme.of(context).colorScheme.background, + borderRadius: BorderRadius.circular(4)), + margin: const EdgeInsets.symmetric(horizontal: 4.0, vertical: 4.0), + padding: const EdgeInsets.symmetric(vertical: 2.0, horizontal: 6.0), + child: IntrinsicWidth( + child: Row( + children: [ + Container( + width: radius, + height: radius, + decoration: BoxDecoration( + shape: BoxShape.circle, + color: tags.contains(name) + ? Colors.white + : str2color2(name)), + ).marginOnly(right: radius / 2), + Expanded( + child: Text(name, + style: TextStyle( + overflow: TextOverflow.ellipsis, + color: tags.contains(name) ? Colors.white : null)), + ), + ], + ), + ), + )), ); } diff --git a/flutter/lib/common/widgets/peer_card.dart b/flutter/lib/common/widgets/peer_card.dart index 4d49bd496..1e147a736 100644 --- a/flutter/lib/common/widgets/peer_card.dart +++ b/flutter/lib/common/widgets/peer_card.dart @@ -14,6 +14,7 @@ import '../../models/peer_model.dart'; import '../../models/platform_model.dart'; import '../../desktop/widgets/material_mod_popup_menu.dart' as mod_menu; import '../../desktop/widgets/popup_menu.dart'; +import 'dart:math' as math; typedef PopupMenuEntryBuilder = Future>> Function(BuildContext); @@ -159,7 +160,7 @@ class _PeerCardState extends State<_PeerCard> fontSize: 11, color: Theme.of(context).textTheme.titleLarge?.color?.withOpacity(0.6)); final alias = bind.mainGetPeerOptionSync(id: peer.id, key: 'alias'); - return Obx( + final child = Obx( () => Container( foregroundDecoration: deco.value, child: Row( @@ -199,7 +200,7 @@ class _PeerCardState extends State<_PeerCard> overflow: TextOverflow.ellipsis, style: Theme.of(context).textTheme.titleSmall, )), - ]).marginOnly(bottom: 2), + ]).marginOnly(bottom: 0, top: 2), Align( alignment: Alignment.centerLeft, child: Text( @@ -221,13 +222,29 @@ class _PeerCardState extends State<_PeerCard> ), ), ); + final colors = _frontN(peer.tags, 25).map((e) => str2color2(e)).toList(); + return Tooltip( + message: peer.tags.isNotEmpty + ? '${translate('Tags')}: ${peer.tags.join(', ')}' + : '', + child: Stack(children: [ + child, + Positioned( + top: 2, + right: 10, + child: CustomPaint( + painter: TagPainter(radius: 3, colors: colors), + ), + ) + ]), + ); } Widget _buildPeerCard( BuildContext context, Peer peer, Rx deco) { final name = '${peer.username}${peer.username.isNotEmpty && peer.hostname.isNotEmpty ? '@' : ''}${peer.hostname}'; - return Card( + final child = Card( color: Colors.transparent, elevation: 0, margin: EdgeInsets.zero, @@ -253,7 +270,7 @@ class _PeerCardState extends State<_PeerCard> padding: const EdgeInsets.all(6), child: getPlatformImage(peer.platform, size: 60), - ), + ).marginOnly(top: 4), Row( children: [ Expanded( @@ -304,6 +321,31 @@ class _PeerCardState extends State<_PeerCard> ), ), ); + + final colors = _frontN(peer.tags, 25).map((e) => str2color2(e)).toList(); + return Tooltip( + message: peer.tags.isNotEmpty + ? '${translate('Tags')}: ${peer.tags.join(', ')}' + : '', + child: Stack(children: [ + child, + Positioned( + top: 4, + right: 12, + child: CustomPaint( + painter: TagPainter(radius: 4, colors: colors), + ), + ) + ]), + ); + } + + List _frontN(List list, int n) { + if (list.length <= n) { + return list; + } else { + return list.sublist(0, n); + } } Widget checkBoxOrActionMoreMobile(Peer peer) { @@ -1193,3 +1235,41 @@ Widget build_more(BuildContext context, {bool invert = false}) { ?.color ?.withOpacity(0.5))))); } + +class TagPainter extends CustomPainter { + final double radius; + late final List colors; + + TagPainter({required this.radius, required List colors}) { + this.colors = colors.reversed.toList(); + } + + @override + void paint(Canvas canvas, Size size) { + double x = 0; + double y = radius; + for (int i = 0; i < colors.length; i++) { + Paint paint = Paint(); + paint.color = colors[i]; + x -= radius + 1; + if (i == colors.length - 1) { + canvas.drawCircle(Offset(x, y), radius, paint); + } else { + Path path = Path(); + path.addArc(Rect.fromCircle(center: Offset(x, y), radius: radius), + math.pi * 4 / 3, math.pi * 4 / 3); + path.addArc( + Rect.fromCircle(center: Offset(x - radius, y), radius: radius), + math.pi * 5 / 3, + math.pi * 2 / 3); + path.fillType = PathFillType.evenOdd; + canvas.drawPath(path, paint); + } + } + } + + @override + bool shouldRepaint(covariant CustomPainter oldDelegate) { + return true; + } +}