From 440dabfca8847aaf8b818084b4db2ab18294be8a Mon Sep 17 00:00:00 2001 From: lollipopkit Date: Sat, 2 Dec 2023 17:35:14 +0800 Subject: [PATCH] opt.: server tab --- ios/Runner.xcodeproj/project.pbxproj | 36 ++++----- lib/core/extension/listx.dart | 2 +- lib/data/res/build_data.dart | 10 +-- lib/view/page/server/tab.dart | 114 +++++++++++++++++---------- lib/view/page/ssh/page.dart | 10 +-- 5 files changed, 101 insertions(+), 71 deletions(-) diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index 7a7173cf..48aaeb5f 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -586,7 +586,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; - CURRENT_PROJECT_VERSION = 653; + CURRENT_PROJECT_VERSION = 654; DEVELOPMENT_TEAM = BA88US33G6; ENABLE_BITCODE = NO; INFOPLIST_FILE = "Runner/Info-$(CONFIGURATION).plist"; @@ -596,7 +596,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.0.653; + MARKETING_VERSION = 1.0.654; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; @@ -720,7 +720,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; - CURRENT_PROJECT_VERSION = 653; + CURRENT_PROJECT_VERSION = 654; DEVELOPMENT_TEAM = BA88US33G6; ENABLE_BITCODE = NO; INFOPLIST_FILE = "Runner/Info-$(CONFIGURATION).plist"; @@ -730,7 +730,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.0.653; + MARKETING_VERSION = 1.0.654; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; @@ -748,7 +748,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; - CURRENT_PROJECT_VERSION = 653; + CURRENT_PROJECT_VERSION = 654; DEVELOPMENT_TEAM = BA88US33G6; ENABLE_BITCODE = NO; INFOPLIST_FILE = "Runner/Info-$(CONFIGURATION).plist"; @@ -758,7 +758,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.0.653; + MARKETING_VERSION = 1.0.654; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; @@ -779,7 +779,7 @@ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 653; + CURRENT_PROJECT_VERSION = 654; DEVELOPMENT_TEAM = BA88US33G6; GCC_C_LANGUAGE_STANDARD = gnu11; GENERATE_INFOPLIST_FILE = YES; @@ -792,7 +792,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 1.0.653; + MARKETING_VERSION = 1.0.654; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.StatusWidget; @@ -818,7 +818,7 @@ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 653; + CURRENT_PROJECT_VERSION = 654; DEVELOPMENT_TEAM = BA88US33G6; GCC_C_LANGUAGE_STANDARD = gnu11; GENERATE_INFOPLIST_FILE = YES; @@ -831,7 +831,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 1.0.653; + MARKETING_VERSION = 1.0.654; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.StatusWidget; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -854,7 +854,7 @@ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 653; + CURRENT_PROJECT_VERSION = 654; DEVELOPMENT_TEAM = BA88US33G6; GCC_C_LANGUAGE_STANDARD = gnu11; GENERATE_INFOPLIST_FILE = YES; @@ -867,7 +867,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 1.0.653; + MARKETING_VERSION = 1.0.654; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.StatusWidget; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -890,7 +890,7 @@ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 653; + CURRENT_PROJECT_VERSION = 654; DEVELOPMENT_ASSET_PATHS = ""; DEVELOPMENT_TEAM = BA88US33G6; ENABLE_PREVIEWS = YES; @@ -902,7 +902,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.0.653; + MARKETING_VERSION = 1.0.654; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.WatchEnd; @@ -931,7 +931,7 @@ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 653; + CURRENT_PROJECT_VERSION = 654; DEVELOPMENT_ASSET_PATHS = ""; DEVELOPMENT_TEAM = BA88US33G6; ENABLE_PREVIEWS = YES; @@ -943,7 +943,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.0.653; + MARKETING_VERSION = 1.0.654; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.WatchEnd; PRODUCT_NAME = ServerBox; @@ -969,7 +969,7 @@ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 653; + CURRENT_PROJECT_VERSION = 654; DEVELOPMENT_ASSET_PATHS = ""; DEVELOPMENT_TEAM = BA88US33G6; ENABLE_PREVIEWS = YES; @@ -981,7 +981,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.0.653; + MARKETING_VERSION = 1.0.654; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.WatchEnd; PRODUCT_NAME = ServerBox; diff --git a/lib/core/extension/listx.dart b/lib/core/extension/listx.dart index c2a1401c..a828185e 100644 --- a/lib/core/extension/listx.dart +++ b/lib/core/extension/listx.dart @@ -6,4 +6,4 @@ extension ListX on List { } return list; } -} \ No newline at end of file +} diff --git a/lib/data/res/build_data.dart b/lib/data/res/build_data.dart index 276e6e83..61a4cd70 100644 --- a/lib/data/res/build_data.dart +++ b/lib/data/res/build_data.dart @@ -2,9 +2,9 @@ class BuildData { static const String name = "ServerBox"; - static const int build = 653; - static const String engine = "3.16.0"; - static const String buildAt = "2023-11-27 19:18:56"; - static const int modifications = 3; - static const int script = 30; + static const int build = 654; + static const String engine = "3.16.2"; + static const String buildAt = "2023-12-02 00:21:29"; + static const int modifications = 2; + static const int script = 31; } diff --git a/lib/view/page/server/tab.dart b/lib/view/page/server/tab.dart index ab9a82bc..44ee252d 100644 --- a/lib/view/page/server/tab.dart +++ b/lib/view/page/server/tab.dart @@ -39,12 +39,7 @@ class _ServerPageState extends State with AutomaticKeepAliveClientMixin, AfterLayoutMixin { late MediaQueryData _media; - final _flipedCardIds = {}; - - final _netViewType = {}; - - /// If true, display IO speed - final _diskViewSpeed = {}; + final _cardsStatus = {}; String? _tag; bool _useDoubleColumn = false; @@ -88,7 +83,7 @@ class _ServerPageState extends State final filtered = _filterServers(pro); if (_useDoubleColumn && Stores.setting.doubleColumnServersPage.fetch()) { - return _buildBodyMedium(pro); + return _buildBodyMedium(pro: pro, filtered: filtered); } return _buildBodySmall(provider: pro, filtered: filtered); }, @@ -138,8 +133,10 @@ class _ServerPageState extends State ); } - Widget _buildBodyMedium(ServerProvider pro) { - final filtered = _filterServers(pro); + Widget _buildBodyMedium({ + required ServerProvider pro, + required List filtered, + }) { final left = filtered.where((e) => filtered.indexOf(e) % 2 == 0).toList(); final right = filtered.where((e) => filtered.indexOf(e) % 2 == 1).toList(); return Column( @@ -191,13 +188,11 @@ class _ServerPageState extends State }, onLongPress: () { if (srv.state == ServerState.finished) { - setState(() { - if (_flipedCardIds.contains(srv.spi.id)) { - _flipedCardIds.remove(srv.spi.id); - } else { - _flipedCardIds.add(srv.spi.id); - } - }); + final id = srv.spi.id; + final cardStatus = getCardNoti(id); + cardStatus.value = cardStatus.value.copyWith( + flip: !cardStatus.value.flip, + ); } else { AppRoute.serverEdit(spi: srv.spi).go(context); } @@ -220,26 +215,32 @@ class _ServerPageState extends State } Widget _buildRealServerCard(Server srv) { + final id = srv.spi.id; + final cardStatus = getCardNoti(id); final title = _buildServerCardTitle(srv.status, srv.state, srv.spi); - final List children = [title]; - - if (srv.state == ServerState.finished) { - if (_flipedCardIds.contains(srv.spi.id)) { - children.addAll(_buildFlipedCard(srv)); - } else { - children.addAll(_buildNormalCard(srv.status, srv.spi)); - } - } return AnimatedContainer( duration: const Duration(milliseconds: 377), curve: Curves.fastEaseInToSlowEaseOut, - height: _calcCardHeight(srv.state, srv.spi.id), - child: Column( - mainAxisSize: MainAxisSize.min, - mainAxisAlignment: MainAxisAlignment.start, - crossAxisAlignment: CrossAxisAlignment.center, - children: children, + height: _calcCardHeight(srv.state, cardStatus.value.flip), + child: ValueBuilder( + listenable: cardStatus, + build: () { + final List children = [title]; + if (srv.state == ServerState.finished) { + if (cardStatus.value.flip) { + children.addAll(_buildFlipedCard(srv)); + } else { + children.addAll(_buildNormalCard(srv.status, srv.spi)); + } + } + return Column( + mainAxisSize: MainAxisSize.min, + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.center, + children: children, + ); + }, ), ); } @@ -431,11 +432,12 @@ class _ServerPageState extends State } Widget _buildDisk(ServerStatus ss, String id) { + final cardNoti = getCardNoti(id); return ValueBuilder( - listenable: Stores.setting.serverTabPreferDiskAmount.listenable(), + listenable: cardNoti, build: () { final rootDisk = findRootDisk(ss.disk); - final isSpeed = _diskViewSpeed[id] ?? + final isSpeed = cardNoti.value.diskIO ?? !Stores.setting.serverTabPreferDiskAmount.fetch(); final (r, w) = ss.diskIO.getAllSpeed(); @@ -449,9 +451,7 @@ class _ServerPageState extends State isSpeed ? '${l10n.read}:\n$r' : 'Total:\n${rootDisk?.size}', isSpeed ? '${l10n.write}:\n$w' : 'Used:\n${rootDisk?.usedPercent}%', onTap: () { - setState(() { - _diskViewSpeed[id] = !isSpeed; - }); + cardNoti.value = cardNoti.value.copyWith(diskIO: !isSpeed); }, key: ValueKey(isSpeed), ), @@ -461,7 +461,8 @@ class _ServerPageState extends State } Widget _buildNet(ServerStatus ss, String id) { - final type = _netViewType[id] ?? Stores.setting.netViewType.fetch(); + final cardNoti = getCardNoti(id); + final type = cardNoti.value.net ?? Stores.setting.netViewType.fetch(); final (a, b) = type.build(ss); return AnimatedSwitcher( duration: const Duration(milliseconds: 377), @@ -472,9 +473,7 @@ class _ServerPageState extends State a, b, onTap: () { - setState(() { - _netViewType[id] = type.next; - }); + cardNoti.value = cardNoti.value.copyWith(net: type.next); }, key: ValueKey(type), ), @@ -585,11 +584,11 @@ class _ServerPageState extends State } } - double _calcCardHeight(ServerState cs, String id) { + double _calcCardHeight(ServerState cs, bool flip) { if (cs != ServerState.finished) { return 23.0; } - if (_flipedCardIds.contains(id)) { + if (flip) { return 80.0; } if (Stores.setting.moveOutServerTabFuncBtns.fetch() && @@ -619,4 +618,35 @@ class _ServerPageState extends State ], ); } + + _CardNotifier getCardNoti(String id) => _cardsStatus.putIfAbsent( + id, + () => _CardNotifier(const _CardStatus()), + ); +} + +typedef _CardNotifier = ValueNotifier<_CardStatus>; + +class _CardStatus { + final bool flip; + final bool? diskIO; + final NetViewType? net; + + const _CardStatus({ + this.flip = false, + this.diskIO, + this.net, + }); + + _CardStatus copyWith({ + bool? flip, + bool? diskIO, + NetViewType? net, + }) { + return _CardStatus( + flip: flip ?? this.flip, + diskIO: diskIO ?? this.diskIO, + net: net ?? this.net, + ); + } } diff --git a/lib/view/page/ssh/page.dart b/lib/view/page/ssh/page.dart index 5660dca5..f05be428 100644 --- a/lib/view/page/ssh/page.dart +++ b/lib/view/page/ssh/page.dart @@ -312,7 +312,7 @@ class _SSHPageState extends State with AutomaticKeepAliveClientMixin { return _terminal.buffer.getText(range); } - void _write(String p0) { + void _writeLn(String p0) { _terminal.write('$p0\r\n'); } @@ -329,11 +329,11 @@ class _SSHPageState extends State with AutomaticKeepAliveClientMixin { } Future _initTerminal() async { - _write('Connecting...\r\n'); + _writeLn('Connecting...\r\n'); if (_client == null) { await Pros.server.refreshData(spi: widget.spi); } - _write('Starting shell...\r\n'); + _writeLn('Starting shell...\r\n'); final session = await _client?.shell( pty: SSHPtyConfig( @@ -345,7 +345,7 @@ class _SSHPageState extends State with AutomaticKeepAliveClientMixin { _setupDiscontinuityTimer(); if (session == null) { - _write(_server?.status.err ?? 'Null session'); + _writeLn(_server?.status.err ?? 'Null session'); return; } @@ -402,7 +402,7 @@ class _SSHPageState extends State with AutomaticKeepAliveClientMixin { void _catchTimeout() { _discontinuityTimer?.cancel(); if (!mounted) return; - _write('\n\nConnection lost\r\n'); + _writeLn('\n\nConnection lost\r\n'); context.showRoundDialog( title: Text(l10n.attention), child: Text('${l10n.disconnected}\n${l10n.goBackQ}'),