From b950dd2d68c9fbf55a14f2dd0866794db5e3d48e Mon Sep 17 00:00:00 2001 From: lollipopkit <10864310+lollipopkit@users.noreply.github.com> Date: Fri, 7 Jun 2024 21:09:17 +0800 Subject: [PATCH 1/7] fix: ssh tab --- lib/view/page/ssh/tab.dart | 216 +++++++++++++++++++++++-------------- pubspec.lock | 4 +- pubspec.yaml | 2 +- 3 files changed, 141 insertions(+), 81 deletions(-) diff --git a/lib/view/page/ssh/tab.dart b/lib/view/page/ssh/tab.dart index 290e1996c..f5072c31b 100644 --- a/lib/view/page/ssh/tab.dart +++ b/lib/view/page/ssh/tab.dart @@ -15,37 +15,37 @@ class SSHTabPage extends StatefulWidget { State createState() => _SSHTabPageState(); } +typedef _TabMap = Map; + class _SSHTabPageState extends State with TickerProviderStateMixin, AutomaticKeepAliveClientMixin { - late final _tabMap = { + late final _TabMap _tabMap = { l10n.add: (page: _buildAddPage()), }; - late var _tabController = TabController( - length: _tabMap.length, - vsync: this, - ); - final _fabRN = ValueNotifier(0); + final _pageCtrl = PageController(); + final _fabVN = 0.vn; + final _tabRN = RNode(); @override Widget build(BuildContext context) { super.build(context); return Scaffold( - appBar: TabBar( - controller: _tabController, - tabs: _tabMap.keys.map(_buildTabItem).toList(), - isScrollable: true, - tabAlignment: TabAlignment.start, - dividerColor: Colors.transparent, - onTap: (value) { - _fabRN.value = value; - FocusScope.of(context).unfocus(); + appBar: PreferredSizeListenBuilder( + listenable: _tabRN, + builder: () { + return _TabBar( + idxVN: _fabVN, + map: _tabMap, + onTap: _onTapTab, + onClose: _onTapClose, + ); }, ), body: _buildBody(), floatingActionButton: ListenableBuilder( - listenable: _fabRN, + listenable: _fabVN, builder: (_, __) { - if (_fabRN.value != 0) return const SizedBox(); + if (_fabVN.value != 0) return const SizedBox(); return FloatingActionButton( heroTag: 'sshAddServer', onPressed: () => AppRoutes.serverEdit().go(context), @@ -57,49 +57,40 @@ class _SSHTabPageState extends State ); } - Widget _buildTabItem(String e) { - if (e == l10n.add) { - return Tab(child: Text(e)); - } - return Tab( - child: Row( - children: [ - Text(e), - UIs.width7, - IconBtn( - icon: Icons.close, - onTap: () async { - final confirm = await showDialog( - context: context, - builder: (context) { - return AlertDialog( - title: Text(l10n.attention), - content: Text('${l10n.close} SSH ${l10n.conn}($e) ?'), - actions: [ - TextButton( - onPressed: () => context.pop(true), - child: Text(l10n.ok, style: UIs.textRed), - ), - TextButton( - onPressed: () => context.pop(false), - child: Text(l10n.cancel), - ), - ], - ); - }, - ); - Future.delayed(const Duration(milliseconds: 50), - FocusScope.of(context).unfocus); - if (confirm != true) { - return; - } - _tabMap.remove(e); - _refreshTabs(); - }, - ), - ], - ), + void _onTapTab(int idx) async { + await _toPage(idx); + _fabVN.value = idx; + FocusScope.of(context).unfocus(); + } + + void _onTapClose(String name) async { + final confirm = await showDialog( + context: context, + builder: (context) { + return AlertDialog( + title: Text(l10n.attention), + content: Text('${l10n.close} SSH ${l10n.conn}($name) ?'), + actions: [ + TextButton( + onPressed: () => context.pop(true), + child: Text(l10n.ok, style: UIs.textRed), + ), + TextButton( + onPressed: () => context.pop(false), + child: Text(l10n.cancel), + ), + ], + ); + }, ); + Future.delayed( + const Duration(milliseconds: 50), FocusScope.of(context).unfocus); + if (confirm != true) { + return; + } + + _tabMap.remove(name); + _tabRN.build(); } Widget _buildAddPage() { @@ -134,44 +125,113 @@ class _SSHTabPageState extends State } Widget _buildBody() { - return TabBarView( - physics: const NeverScrollableScrollPhysics(), - controller: _tabController, - children: _tabMap.values.map((e) => e.page).toList(), + return ListenBuilder( + listenable: _tabRN, + builder: () { + return PageView.builder( + physics: const NeverScrollableScrollPhysics(), + controller: _pageCtrl, + itemCount: _tabMap.length, + itemBuilder: (_, idx) { + final name = _tabMap.keys.elementAt(idx); + return _tabMap[name]?.page ?? UIs.placeholder; + }, + ); + }, ); } - void _onTapInitCard(ServerPrivateInfo spi) { + void _onTapInitCard(ServerPrivateInfo spi) async { final name = () { - if (_tabMap.containsKey(spi.name)) { - return '${spi.name}(${_tabMap.length + 1})'; + final count = _tabMap.keys.where((e) => e.contains(spi.name)).length; + if (count > 0) { + return '${spi.name}(${count + 1})'; } return spi.name; }(); _tabMap[name] = ( page: SSHPage( + // Keep it, or the Flutter will works unexpectedly + key: ValueKey(spi.id), spi: spi, notFromTab: false, onSessionEnd: () { _tabMap.remove(name); - _refreshTabs(); }, ), ); - _refreshTabs(); - final idx = _tabMap.length - 1; - _tabController.animateTo(idx); - _fabRN.value = idx; + final idx = _tabMap.keys.toList().indexOf(name); + _tabRN.build(); + await _toPage(idx); + _fabVN.value = idx; } - void _refreshTabs() { - _tabController = TabController( - length: _tabMap.length, - vsync: this, - ); - setState(() {}); - } + Future _toPage(int idx) => _pageCtrl.animateToPage(idx, + duration: Durations.short3, curve: Curves.fastEaseInToSlowEaseOut); @override bool get wantKeepAlive => true; } + +final class _TabBar extends StatelessWidget implements PreferredSizeWidget { + const _TabBar({ + required this.idxVN, + required this.map, + required this.onTap, + required this.onClose, + }); + + final ValueNotifier idxVN; + final _TabMap map; + final void Function(int idx) onTap; + final void Function(String name) onClose; + + List get names => map.keys.toList(); + + @override + Size get preferredSize => const Size.fromHeight(48); + + @override + Widget build(BuildContext context) { + return ListenBuilder( + listenable: idxVN, + builder: () { + return ListView.builder( + scrollDirection: Axis.horizontal, + padding: const EdgeInsets.symmetric(horizontal: 11, vertical: 5), + itemCount: names.length, + itemBuilder: (_, idx) => _buillItem(idx), + ); + }, + ); + } + + Widget _buillItem(int idx) { + final name = names[idx]; + return InkWell( + borderRadius: BorderRadius.circular(13), + onTap: () => onTap(idx), + child: SizedBox( + width: idx == 0 ? 80 : 130, + child: Row( + mainAxisSize: MainAxisSize.min, + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + SizedBox( + width: idx == 0 ? 35 : 85, + child: Text(name), + ), + if (idxVN.value == idx && idx != 0) FadeIn(child: UIs.dot()), + idx == 0 + // Use [IconBtn] for same size + ? IconBtn(icon: Icons.add, onTap: () {}) + : IconBtn( + icon: Icons.close, + onTap: () => onClose(name), + ), + ], + ), + ).paddingOnly(left: 17, right: 3), + ).paddingSymmetric(horizontal: 3); + } +} diff --git a/pubspec.lock b/pubspec.lock index 743b14b90..14b302153 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -401,8 +401,8 @@ packages: dependency: "direct main" description: path: "." - ref: "v1.0.33" - resolved-ref: "7c4fdde33ec7c9ee226bfe0fd0c148f2d3f3ca54" + ref: "v1.0.39" + resolved-ref: "49fc10b39e390f4ecc3ee4f16f0926460b77adac" url: "https://github.com/lppcg/fl_lib" source: git version: "0.0.1" diff --git a/pubspec.yaml b/pubspec.yaml index 626bcc1de..cfe5a1684 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -53,7 +53,7 @@ dependencies: fl_lib: git: url: https://github.com/lppcg/fl_lib - ref: v1.0.33 + ref: v1.0.39 dependency_overrides: # dartssh2: From e7c7fc81868d01d269d26a08119d76dec0ab6a2a Mon Sep 17 00:00:00 2001 From: lollipopkit <10864310+lollipopkit@users.noreply.github.com> Date: Fri, 7 Jun 2024 21:43:38 +0800 Subject: [PATCH 2/7] fix: ssh tab name generaton --- ios/Runner.xcodeproj/project.pbxproj | 36 +++++++++++++------------- lib/data/res/build_data.dart | 4 +-- lib/view/page/ssh/page.dart | 4 +-- lib/view/page/ssh/tab.dart | 30 ++++++++++++--------- macos/Runner.xcodeproj/project.pbxproj | 12 ++++----- 5 files changed, 46 insertions(+), 40 deletions(-) diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index 2df37a201..4babe7f1a 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -690,7 +690,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; - CURRENT_PROJECT_VERSION = 936; + CURRENT_PROJECT_VERSION = 938; DEVELOPMENT_TEAM = BA88US33G6; ENABLE_BITCODE = NO; INFOPLIST_FILE = "Runner/Info-$(CONFIGURATION).plist"; @@ -700,7 +700,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.0.936; + MARKETING_VERSION = 1.0.938; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; @@ -826,7 +826,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; - CURRENT_PROJECT_VERSION = 936; + CURRENT_PROJECT_VERSION = 938; DEVELOPMENT_TEAM = BA88US33G6; ENABLE_BITCODE = NO; INFOPLIST_FILE = "Runner/Info-$(CONFIGURATION).plist"; @@ -836,7 +836,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.0.936; + MARKETING_VERSION = 1.0.938; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; @@ -854,7 +854,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; - CURRENT_PROJECT_VERSION = 936; + CURRENT_PROJECT_VERSION = 938; DEVELOPMENT_TEAM = BA88US33G6; ENABLE_BITCODE = NO; INFOPLIST_FILE = "Runner/Info-$(CONFIGURATION).plist"; @@ -864,7 +864,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.0.936; + MARKETING_VERSION = 1.0.938; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; @@ -885,7 +885,7 @@ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 936; + CURRENT_PROJECT_VERSION = 938; DEVELOPMENT_TEAM = BA88US33G6; GCC_C_LANGUAGE_STANDARD = gnu11; GENERATE_INFOPLIST_FILE = YES; @@ -898,7 +898,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 1.0.936; + MARKETING_VERSION = 1.0.938; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.StatusWidget; @@ -924,7 +924,7 @@ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 936; + CURRENT_PROJECT_VERSION = 938; DEVELOPMENT_TEAM = BA88US33G6; GCC_C_LANGUAGE_STANDARD = gnu11; GENERATE_INFOPLIST_FILE = YES; @@ -937,7 +937,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 1.0.936; + MARKETING_VERSION = 1.0.938; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.StatusWidget; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -960,7 +960,7 @@ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 936; + CURRENT_PROJECT_VERSION = 938; DEVELOPMENT_TEAM = BA88US33G6; GCC_C_LANGUAGE_STANDARD = gnu11; GENERATE_INFOPLIST_FILE = YES; @@ -973,7 +973,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 1.0.936; + MARKETING_VERSION = 1.0.938; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.StatusWidget; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -996,7 +996,7 @@ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 936; + CURRENT_PROJECT_VERSION = 938; DEVELOPMENT_ASSET_PATHS = ""; DEVELOPMENT_TEAM = BA88US33G6; ENABLE_PREVIEWS = YES; @@ -1008,7 +1008,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.0.936; + MARKETING_VERSION = 1.0.938; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.WatchEnd; @@ -1037,7 +1037,7 @@ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 936; + CURRENT_PROJECT_VERSION = 938; DEVELOPMENT_ASSET_PATHS = ""; DEVELOPMENT_TEAM = BA88US33G6; ENABLE_PREVIEWS = YES; @@ -1049,7 +1049,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.0.936; + MARKETING_VERSION = 1.0.938; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.WatchEnd; PRODUCT_NAME = ServerBox; @@ -1075,7 +1075,7 @@ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 936; + CURRENT_PROJECT_VERSION = 938; DEVELOPMENT_ASSET_PATHS = ""; DEVELOPMENT_TEAM = BA88US33G6; ENABLE_PREVIEWS = YES; @@ -1087,7 +1087,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.0.936; + MARKETING_VERSION = 1.0.938; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.WatchEnd; PRODUCT_NAME = ServerBox; diff --git a/lib/data/res/build_data.dart b/lib/data/res/build_data.dart index 5e8a176c1..e57fb6d02 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 = 936; + static const int build = 938; static const String engine = "3.22.1"; - static const String buildAt = "2024-06-06 16:18:25"; + static const String buildAt = "2024-06-07 21:09:41"; static const int modifications = 2; static const int script = 48; } diff --git a/lib/view/page/ssh/page.dart b/lib/view/page/ssh/page.dart index 9eac3e9e1..c20bf876c 100644 --- a/lib/view/page/ssh/page.dart +++ b/lib/view/page/ssh/page.dart @@ -42,12 +42,12 @@ class SSHPage extends StatefulWidget { }); @override - State createState() => _SSHPageState(); + State createState() => SSHPageState(); } const _horizonPadding = 7.0; -class _SSHPageState extends State with AutomaticKeepAliveClientMixin { +class SSHPageState extends State with AutomaticKeepAliveClientMixin { final _keyboard = VirtKeyProvider(); late final _terminal = Terminal(inputHandler: _keyboard); final TerminalController _terminalController = TerminalController(); diff --git a/lib/view/page/ssh/tab.dart b/lib/view/page/ssh/tab.dart index f5072c31b..ba56cc268 100644 --- a/lib/view/page/ssh/tab.dart +++ b/lib/view/page/ssh/tab.dart @@ -15,12 +15,12 @@ class SSHTabPage extends StatefulWidget { State createState() => _SSHTabPageState(); } -typedef _TabMap = Map; +typedef _TabMap = Map? key})>; class _SSHTabPageState extends State with TickerProviderStateMixin, AutomaticKeepAliveClientMixin { late final _TabMap _tabMap = { - l10n.add: (page: _buildAddPage()), + l10n.add: (page: _buildAddPage(), key: null), }; final _pageCtrl = PageController(); final _fabVN = 0.vn; @@ -83,13 +83,11 @@ class _SSHTabPageState extends State ); }, ); - Future.delayed( - const Duration(milliseconds: 50), FocusScope.of(context).unfocus); - if (confirm != true) { - return; - } + Future.delayed(Durations.short1, FocusScope.of(context).unfocus); + if (confirm != true) return; - _tabMap.remove(name); + final item = _tabMap.remove(name); + print(item?.key?.currentState); _tabRN.build(); } @@ -143,22 +141,30 @@ class _SSHTabPageState extends State void _onTapInitCard(ServerPrivateInfo spi) async { final name = () { - final count = _tabMap.keys.where((e) => e.contains(spi.name)).length; - if (count > 0) { - return '${spi.name}(${count + 1})'; + final reg = RegExp(r'\((\d+)\)'); + final idxs = _tabMap.keys.map((e) => reg.firstMatch(e)).toList(); + final biggest = idxs + .map((e) => e?.group(1)) + .where((e) => e != null) + .reduce((a, b) => a!.length > b!.length ? a : b); + final biggestInt = int.tryParse(biggest ?? '0'); + if (biggestInt != null && biggestInt > 0) { + return '${spi.name}(${biggestInt + 1})'; } return spi.name; }(); + final key = GlobalKey(); _tabMap[name] = ( page: SSHPage( // Keep it, or the Flutter will works unexpectedly - key: ValueKey(spi.id), + key: key, spi: spi, notFromTab: false, onSessionEnd: () { _tabMap.remove(name); }, ), + key: key, ); final idx = _tabMap.keys.toList().indexOf(name); _tabRN.build(); diff --git a/macos/Runner.xcodeproj/project.pbxproj b/macos/Runner.xcodeproj/project.pbxproj index 12d9d675c..ab73f7ada 100644 --- a/macos/Runner.xcodeproj/project.pbxproj +++ b/macos/Runner.xcodeproj/project.pbxproj @@ -471,7 +471,7 @@ CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; - CURRENT_PROJECT_VERSION = 936; + CURRENT_PROJECT_VERSION = 938; DEVELOPMENT_TEAM = BA88US33G6; INFOPLIST_FILE = Runner/Info.plist; INFOPLIST_KEY_CFBundleDisplayName = "Server Box"; @@ -481,7 +481,7 @@ "@executable_path/../Frameworks", ); MACOSX_DEPLOYMENT_TARGET = 10.15; - MARKETING_VERSION = 1.0.936; + MARKETING_VERSION = 1.0.938; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox; PRODUCT_NAME = "Server Box"; PROVISIONING_PROFILE_SPECIFIER = ""; @@ -608,7 +608,7 @@ CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; - CURRENT_PROJECT_VERSION = 936; + CURRENT_PROJECT_VERSION = 938; DEVELOPMENT_TEAM = BA88US33G6; INFOPLIST_FILE = Runner/Info.plist; INFOPLIST_KEY_CFBundleDisplayName = "Server Box"; @@ -618,7 +618,7 @@ "@executable_path/../Frameworks", ); MACOSX_DEPLOYMENT_TARGET = 10.15; - MARKETING_VERSION = 1.0.936; + MARKETING_VERSION = 1.0.938; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox; PRODUCT_NAME = "Server Box"; PROVISIONING_PROFILE_SPECIFIER = ""; @@ -638,7 +638,7 @@ "CODE_SIGN_IDENTITY[sdk=macosx*]" = "3rd Party Mac Developer Application"; CODE_SIGN_STYLE = Manual; COMBINE_HIDPI_IMAGES = YES; - CURRENT_PROJECT_VERSION = 936; + CURRENT_PROJECT_VERSION = 938; DEVELOPMENT_TEAM = ""; "DEVELOPMENT_TEAM[sdk=macosx*]" = BA88US33G6; INFOPLIST_FILE = Runner/Info.plist; @@ -649,7 +649,7 @@ "@executable_path/../Frameworks", ); MACOSX_DEPLOYMENT_TARGET = 10.15; - MARKETING_VERSION = 1.0.936; + MARKETING_VERSION = 1.0.938; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox; PRODUCT_NAME = "Server Box"; PROVISIONING_PROFILE_SPECIFIER = ""; From 41f9da6bf835ff76221a32916d71456efec5cb76 Mon Sep 17 00:00:00 2001 From: lollipopkit <10864310+lollipopkit@users.noreply.github.com> Date: Fri, 7 Jun 2024 21:51:00 +0800 Subject: [PATCH 3/7] fix: ssh tab PageView `animteToPage` --- lib/view/page/ssh/tab.dart | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/lib/view/page/ssh/tab.dart b/lib/view/page/ssh/tab.dart index ba56cc268..fcbecac61 100644 --- a/lib/view/page/ssh/tab.dart +++ b/lib/view/page/ssh/tab.dart @@ -86,8 +86,7 @@ class _SSHTabPageState extends State Future.delayed(Durations.short1, FocusScope.of(context).unfocus); if (confirm != true) return; - final item = _tabMap.remove(name); - print(item?.key?.currentState); + _tabMap.remove(name); _tabRN.build(); } @@ -166,8 +165,10 @@ class _SSHTabPageState extends State ), key: key, ); - final idx = _tabMap.keys.toList().indexOf(name); _tabRN.build(); + // Wait for the page to be built + await Future.delayed(Durations.short3); + final idx = _tabMap.keys.toList().indexOf(name); await _toPage(idx); _fabVN.value = idx; } @@ -223,11 +224,6 @@ final class _TabBar extends StatelessWidget implements PreferredSizeWidget { mainAxisSize: MainAxisSize.min, mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - SizedBox( - width: idx == 0 ? 35 : 85, - child: Text(name), - ), - if (idxVN.value == idx && idx != 0) FadeIn(child: UIs.dot()), idx == 0 // Use [IconBtn] for same size ? IconBtn(icon: Icons.add, onTap: () {}) @@ -235,9 +231,16 @@ final class _TabBar extends StatelessWidget implements PreferredSizeWidget { icon: Icons.close, onTap: () => onClose(name), ), + SizedBox( + width: idx == 0 ? 35 : 85, + child: Text(name), + ), + (idxVN.value == idx && idx != 0) + ? FadeIn(child: UIs.dot()) + : const SizedBox(width: 7), ], ), - ).paddingOnly(left: 17, right: 3), + ).paddingOnly(left: 3, right: 17), ).paddingSymmetric(horizontal: 3); } } From b167287c5bf50531857f3efa7fa10553c578d8c7 Mon Sep 17 00:00:00 2001 From: lollipopkit <10864310+lollipopkit@users.noreply.github.com> Date: Fri, 7 Jun 2024 23:53:13 +0800 Subject: [PATCH 4/7] opt.: ssh tab page's tab bar --- ios/Runner.xcodeproj/project.pbxproj | 36 +++++------ lib/data/res/build_data.dart | 4 +- lib/view/page/ssh/tab.dart | 89 +++++++++++++++++--------- macos/Runner.xcodeproj/project.pbxproj | 12 ++-- 4 files changed, 86 insertions(+), 55 deletions(-) diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index 4babe7f1a..e9602bcb0 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -690,7 +690,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; - CURRENT_PROJECT_VERSION = 938; + CURRENT_PROJECT_VERSION = 940; DEVELOPMENT_TEAM = BA88US33G6; ENABLE_BITCODE = NO; INFOPLIST_FILE = "Runner/Info-$(CONFIGURATION).plist"; @@ -700,7 +700,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.0.938; + MARKETING_VERSION = 1.0.940; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; @@ -826,7 +826,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; - CURRENT_PROJECT_VERSION = 938; + CURRENT_PROJECT_VERSION = 940; DEVELOPMENT_TEAM = BA88US33G6; ENABLE_BITCODE = NO; INFOPLIST_FILE = "Runner/Info-$(CONFIGURATION).plist"; @@ -836,7 +836,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.0.938; + MARKETING_VERSION = 1.0.940; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; @@ -854,7 +854,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; - CURRENT_PROJECT_VERSION = 938; + CURRENT_PROJECT_VERSION = 940; DEVELOPMENT_TEAM = BA88US33G6; ENABLE_BITCODE = NO; INFOPLIST_FILE = "Runner/Info-$(CONFIGURATION).plist"; @@ -864,7 +864,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.0.938; + MARKETING_VERSION = 1.0.940; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; @@ -885,7 +885,7 @@ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 938; + CURRENT_PROJECT_VERSION = 940; DEVELOPMENT_TEAM = BA88US33G6; GCC_C_LANGUAGE_STANDARD = gnu11; GENERATE_INFOPLIST_FILE = YES; @@ -898,7 +898,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 1.0.938; + MARKETING_VERSION = 1.0.940; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.StatusWidget; @@ -924,7 +924,7 @@ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 938; + CURRENT_PROJECT_VERSION = 940; DEVELOPMENT_TEAM = BA88US33G6; GCC_C_LANGUAGE_STANDARD = gnu11; GENERATE_INFOPLIST_FILE = YES; @@ -937,7 +937,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 1.0.938; + MARKETING_VERSION = 1.0.940; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.StatusWidget; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -960,7 +960,7 @@ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 938; + CURRENT_PROJECT_VERSION = 940; DEVELOPMENT_TEAM = BA88US33G6; GCC_C_LANGUAGE_STANDARD = gnu11; GENERATE_INFOPLIST_FILE = YES; @@ -973,7 +973,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 1.0.938; + MARKETING_VERSION = 1.0.940; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.StatusWidget; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -996,7 +996,7 @@ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 938; + CURRENT_PROJECT_VERSION = 940; DEVELOPMENT_ASSET_PATHS = ""; DEVELOPMENT_TEAM = BA88US33G6; ENABLE_PREVIEWS = YES; @@ -1008,7 +1008,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.0.938; + MARKETING_VERSION = 1.0.940; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.WatchEnd; @@ -1037,7 +1037,7 @@ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 938; + CURRENT_PROJECT_VERSION = 940; DEVELOPMENT_ASSET_PATHS = ""; DEVELOPMENT_TEAM = BA88US33G6; ENABLE_PREVIEWS = YES; @@ -1049,7 +1049,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.0.938; + MARKETING_VERSION = 1.0.940; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.WatchEnd; PRODUCT_NAME = ServerBox; @@ -1075,7 +1075,7 @@ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 938; + CURRENT_PROJECT_VERSION = 940; DEVELOPMENT_ASSET_PATHS = ""; DEVELOPMENT_TEAM = BA88US33G6; ENABLE_PREVIEWS = YES; @@ -1087,7 +1087,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.0.938; + MARKETING_VERSION = 1.0.940; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.WatchEnd; PRODUCT_NAME = ServerBox; diff --git a/lib/data/res/build_data.dart b/lib/data/res/build_data.dart index e57fb6d02..5098c95b3 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 = 938; + static const int build = 940; static const String engine = "3.22.1"; - static const String buildAt = "2024-06-07 21:09:41"; + static const String buildAt = "2024-06-07 21:51:18"; static const int modifications = 2; static const int script = 48; } diff --git a/lib/view/page/ssh/tab.dart b/lib/view/page/ssh/tab.dart index fcbecac61..f46123635 100644 --- a/lib/view/page/ssh/tab.dart +++ b/lib/view/page/ssh/tab.dart @@ -141,11 +141,12 @@ class _SSHTabPageState extends State void _onTapInitCard(ServerPrivateInfo spi) async { final name = () { final reg = RegExp(r'\((\d+)\)'); - final idxs = _tabMap.keys.map((e) => reg.firstMatch(e)).toList(); - final biggest = idxs + final idxs = _tabMap.keys + .map((e) => reg.firstMatch(e)) .map((e) => e?.group(1)) - .where((e) => e != null) - .reduce((a, b) => a!.length > b!.length ? a : b); + .where((e) => e != null); + if (idxs.isEmpty) return spi.name; + final biggest = idxs.reduce((a, b) => a!.length > b!.length ? a : b); final biggestInt = int.tryParse(biggest ?? '0'); if (biggestInt != null && biggestInt > 0) { return '${spi.name}(${biggestInt + 1})'; @@ -203,11 +204,18 @@ final class _TabBar extends StatelessWidget implements PreferredSizeWidget { return ListenBuilder( listenable: idxVN, builder: () { - return ListView.builder( + return ListView.separated( scrollDirection: Axis.horizontal, padding: const EdgeInsets.symmetric(horizontal: 11, vertical: 5), itemCount: names.length, itemBuilder: (_, idx) => _buillItem(idx), + separatorBuilder: (_, __) => Padding( + padding: const EdgeInsets.symmetric(vertical: 17), + child: Container( + color: const Color.fromARGB(61, 158, 158, 158), + width: 3, + ), + ), ); }, ); @@ -215,32 +223,55 @@ final class _TabBar extends StatelessWidget implements PreferredSizeWidget { Widget _buillItem(int idx) { final name = names[idx]; + final selected = idxVN.value == idx; + final color = + selected ? const Color.fromARGB(240, 255, 255, 255) : Colors.grey; + + final Widget child; + if (idx == 0) { + child = Padding( + padding: const EdgeInsets.symmetric(horizontal: 13), + child: Icon(Icons.add, size: 17, color: color), + ); + } else { + final text = Text( + name, + maxLines: 1, + overflow: TextOverflow.ellipsis, + style: TextStyle(color: color), + softWrap: false, + textAlign: TextAlign.center, + textWidthBasis: TextWidthBasis.parent, + ); + child = AnimatedContainer( + width: selected ? 90 : 50, + duration: Durations.medium3, + curve: Curves.fastEaseInToSlowEaseOut, + child: switch (selected) { + true => Row( + mainAxisSize: MainAxisSize.min, + mainAxisAlignment: MainAxisAlignment.start, + children: [ + SizedBox(width: 55, child: text), + if (selected) + FadeIn( + child: IconBtn( + icon: Icons.close, + color: color, + onTap: () => onClose(name), + ), + ), + ], + ), + false => Center(child: text), + }, + ).paddingOnly(left: 3, right: 3); + } + return InkWell( borderRadius: BorderRadius.circular(13), onTap: () => onTap(idx), - child: SizedBox( - width: idx == 0 ? 80 : 130, - child: Row( - mainAxisSize: MainAxisSize.min, - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - idx == 0 - // Use [IconBtn] for same size - ? IconBtn(icon: Icons.add, onTap: () {}) - : IconBtn( - icon: Icons.close, - onTap: () => onClose(name), - ), - SizedBox( - width: idx == 0 ? 35 : 85, - child: Text(name), - ), - (idxVN.value == idx && idx != 0) - ? FadeIn(child: UIs.dot()) - : const SizedBox(width: 7), - ], - ), - ).paddingOnly(left: 3, right: 17), - ).paddingSymmetric(horizontal: 3); + child: child, + ).paddingSymmetric(horizontal: 13); } } diff --git a/macos/Runner.xcodeproj/project.pbxproj b/macos/Runner.xcodeproj/project.pbxproj index ab73f7ada..cc7d88c62 100644 --- a/macos/Runner.xcodeproj/project.pbxproj +++ b/macos/Runner.xcodeproj/project.pbxproj @@ -471,7 +471,7 @@ CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; - CURRENT_PROJECT_VERSION = 938; + CURRENT_PROJECT_VERSION = 940; DEVELOPMENT_TEAM = BA88US33G6; INFOPLIST_FILE = Runner/Info.plist; INFOPLIST_KEY_CFBundleDisplayName = "Server Box"; @@ -481,7 +481,7 @@ "@executable_path/../Frameworks", ); MACOSX_DEPLOYMENT_TARGET = 10.15; - MARKETING_VERSION = 1.0.938; + MARKETING_VERSION = 1.0.940; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox; PRODUCT_NAME = "Server Box"; PROVISIONING_PROFILE_SPECIFIER = ""; @@ -608,7 +608,7 @@ CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; - CURRENT_PROJECT_VERSION = 938; + CURRENT_PROJECT_VERSION = 940; DEVELOPMENT_TEAM = BA88US33G6; INFOPLIST_FILE = Runner/Info.plist; INFOPLIST_KEY_CFBundleDisplayName = "Server Box"; @@ -618,7 +618,7 @@ "@executable_path/../Frameworks", ); MACOSX_DEPLOYMENT_TARGET = 10.15; - MARKETING_VERSION = 1.0.938; + MARKETING_VERSION = 1.0.940; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox; PRODUCT_NAME = "Server Box"; PROVISIONING_PROFILE_SPECIFIER = ""; @@ -638,7 +638,7 @@ "CODE_SIGN_IDENTITY[sdk=macosx*]" = "3rd Party Mac Developer Application"; CODE_SIGN_STYLE = Manual; COMBINE_HIDPI_IMAGES = YES; - CURRENT_PROJECT_VERSION = 938; + CURRENT_PROJECT_VERSION = 940; DEVELOPMENT_TEAM = ""; "DEVELOPMENT_TEAM[sdk=macosx*]" = BA88US33G6; INFOPLIST_FILE = Runner/Info.plist; @@ -649,7 +649,7 @@ "@executable_path/../Frameworks", ); MACOSX_DEPLOYMENT_TARGET = 10.15; - MARKETING_VERSION = 1.0.938; + MARKETING_VERSION = 1.0.940; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox; PRODUCT_NAME = "Server Box"; PROVISIONING_PROFILE_SPECIFIER = ""; From da48d1f66c3fddc6ad65999bd9f2bc3d8b2983d0 Mon Sep 17 00:00:00 2001 From: lollipopkit <10864310+lollipopkit@users.noreply.github.com> Date: Sat, 8 Jun 2024 13:53:23 +0800 Subject: [PATCH 5/7] opt.: IME popup after opening drawer if ssh term is focusing --- ios/Runner.xcodeproj/project.pbxproj | 36 +++++++++++++------------- lib/data/res/build_data.dart | 6 ++--- lib/view/page/home/home.dart | 2 ++ lib/view/page/ssh/page.dart | 3 +++ lib/view/page/ssh/tab.dart | 8 +++--- macos/Runner.xcodeproj/project.pbxproj | 12 ++++----- 6 files changed, 36 insertions(+), 31 deletions(-) diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index e9602bcb0..bf3fa19fd 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -690,7 +690,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; - CURRENT_PROJECT_VERSION = 940; + CURRENT_PROJECT_VERSION = 941; DEVELOPMENT_TEAM = BA88US33G6; ENABLE_BITCODE = NO; INFOPLIST_FILE = "Runner/Info-$(CONFIGURATION).plist"; @@ -700,7 +700,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.0.940; + MARKETING_VERSION = 1.0.941; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; @@ -826,7 +826,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; - CURRENT_PROJECT_VERSION = 940; + CURRENT_PROJECT_VERSION = 941; DEVELOPMENT_TEAM = BA88US33G6; ENABLE_BITCODE = NO; INFOPLIST_FILE = "Runner/Info-$(CONFIGURATION).plist"; @@ -836,7 +836,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.0.940; + MARKETING_VERSION = 1.0.941; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; @@ -854,7 +854,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; - CURRENT_PROJECT_VERSION = 940; + CURRENT_PROJECT_VERSION = 941; DEVELOPMENT_TEAM = BA88US33G6; ENABLE_BITCODE = NO; INFOPLIST_FILE = "Runner/Info-$(CONFIGURATION).plist"; @@ -864,7 +864,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.0.940; + MARKETING_VERSION = 1.0.941; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; @@ -885,7 +885,7 @@ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 940; + CURRENT_PROJECT_VERSION = 941; DEVELOPMENT_TEAM = BA88US33G6; GCC_C_LANGUAGE_STANDARD = gnu11; GENERATE_INFOPLIST_FILE = YES; @@ -898,7 +898,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 1.0.940; + MARKETING_VERSION = 1.0.941; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.StatusWidget; @@ -924,7 +924,7 @@ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 940; + CURRENT_PROJECT_VERSION = 941; DEVELOPMENT_TEAM = BA88US33G6; GCC_C_LANGUAGE_STANDARD = gnu11; GENERATE_INFOPLIST_FILE = YES; @@ -937,7 +937,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 1.0.940; + MARKETING_VERSION = 1.0.941; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.StatusWidget; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -960,7 +960,7 @@ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 940; + CURRENT_PROJECT_VERSION = 941; DEVELOPMENT_TEAM = BA88US33G6; GCC_C_LANGUAGE_STANDARD = gnu11; GENERATE_INFOPLIST_FILE = YES; @@ -973,7 +973,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 1.0.940; + MARKETING_VERSION = 1.0.941; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.StatusWidget; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -996,7 +996,7 @@ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 940; + CURRENT_PROJECT_VERSION = 941; DEVELOPMENT_ASSET_PATHS = ""; DEVELOPMENT_TEAM = BA88US33G6; ENABLE_PREVIEWS = YES; @@ -1008,7 +1008,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.0.940; + MARKETING_VERSION = 1.0.941; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.WatchEnd; @@ -1037,7 +1037,7 @@ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 940; + CURRENT_PROJECT_VERSION = 941; DEVELOPMENT_ASSET_PATHS = ""; DEVELOPMENT_TEAM = BA88US33G6; ENABLE_PREVIEWS = YES; @@ -1049,7 +1049,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.0.940; + MARKETING_VERSION = 1.0.941; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.WatchEnd; PRODUCT_NAME = ServerBox; @@ -1075,7 +1075,7 @@ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 940; + CURRENT_PROJECT_VERSION = 941; DEVELOPMENT_ASSET_PATHS = ""; DEVELOPMENT_TEAM = BA88US33G6; ENABLE_PREVIEWS = YES; @@ -1087,7 +1087,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.0.940; + MARKETING_VERSION = 1.0.941; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.WatchEnd; PRODUCT_NAME = ServerBox; diff --git a/lib/data/res/build_data.dart b/lib/data/res/build_data.dart index 5098c95b3..364932ed0 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 = 940; + static const int build = 941; static const String engine = "3.22.1"; - static const String buildAt = "2024-06-07 21:51:18"; - static const int modifications = 2; + static const String buildAt = "2024-06-07 23:57:38"; + static const int modifications = 4; static const int script = 48; } diff --git a/lib/view/page/home/home.dart b/lib/view/page/home/home.dart index ab4a7d7f8..0e944f482 100644 --- a/lib/view/page/home/home.dart +++ b/lib/view/page/home/home.dart @@ -17,6 +17,7 @@ import 'package:toolbox/data/res/misc.dart'; import 'package:toolbox/data/res/provider.dart'; import 'package:toolbox/data/res/store.dart'; import 'package:toolbox/data/res/url.dart'; +import 'package:toolbox/view/page/ssh/page.dart'; import 'package:wakelock_plus/wakelock_plus.dart'; part 'appbar.dart'; @@ -151,6 +152,7 @@ class _HomePageState extends State physics: const NeverScrollableScrollPhysics(), itemBuilder: (_, index) => AppTab.values[index].page, onPageChanged: (value) { + SSHPage.focusNode.unfocus(); if (!_switchingPage) { _selectIndex.value = value; } diff --git a/lib/view/page/ssh/page.dart b/lib/view/page/ssh/page.dart index c20bf876c..95f99fdbb 100644 --- a/lib/view/page/ssh/page.dart +++ b/lib/view/page/ssh/page.dart @@ -41,6 +41,8 @@ class SSHPage extends StatefulWidget { this.terminalKey, }); + static final focusNode = FocusNode(); + @override State createState() => SSHPageState(); } @@ -159,6 +161,7 @@ class SSHPageState extends State with AutomaticKeepAliveClientMixin { CustomAppBar.barHeight ?? _media.padding.top, ), hideScrollBar: false, + focusNode: SSHPage.focusNode, ), ), ); diff --git a/lib/view/page/ssh/tab.dart b/lib/view/page/ssh/tab.dart index f46123635..cacd26a9f 100644 --- a/lib/view/page/ssh/tab.dart +++ b/lib/view/page/ssh/tab.dart @@ -1,5 +1,6 @@ import 'package:fl_lib/fl_lib.dart'; import 'package:flutter/material.dart'; +import 'package:icons_plus/icons_plus.dart'; import 'package:provider/provider.dart'; import 'package:toolbox/core/extension/context/locale.dart'; import 'package:toolbox/core/route.dart'; @@ -224,14 +225,13 @@ final class _TabBar extends StatelessWidget implements PreferredSizeWidget { Widget _buillItem(int idx) { final name = names[idx]; final selected = idxVN.value == idx; - final color = - selected ? const Color.fromARGB(240, 255, 255, 255) : Colors.grey; + final color = selected ? null : Colors.grey; final Widget child; if (idx == 0) { child = Padding( padding: const EdgeInsets.symmetric(horizontal: 13), - child: Icon(Icons.add, size: 17, color: color), + child: Icon(MingCute.add_circle_fill, size: 17, color: color), ); } else { final text = Text( @@ -256,7 +256,7 @@ final class _TabBar extends StatelessWidget implements PreferredSizeWidget { if (selected) FadeIn( child: IconBtn( - icon: Icons.close, + icon: MingCute.close_circle_fill, color: color, onTap: () => onClose(name), ), diff --git a/macos/Runner.xcodeproj/project.pbxproj b/macos/Runner.xcodeproj/project.pbxproj index cc7d88c62..bbc204344 100644 --- a/macos/Runner.xcodeproj/project.pbxproj +++ b/macos/Runner.xcodeproj/project.pbxproj @@ -471,7 +471,7 @@ CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; - CURRENT_PROJECT_VERSION = 940; + CURRENT_PROJECT_VERSION = 941; DEVELOPMENT_TEAM = BA88US33G6; INFOPLIST_FILE = Runner/Info.plist; INFOPLIST_KEY_CFBundleDisplayName = "Server Box"; @@ -481,7 +481,7 @@ "@executable_path/../Frameworks", ); MACOSX_DEPLOYMENT_TARGET = 10.15; - MARKETING_VERSION = 1.0.940; + MARKETING_VERSION = 1.0.941; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox; PRODUCT_NAME = "Server Box"; PROVISIONING_PROFILE_SPECIFIER = ""; @@ -608,7 +608,7 @@ CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; - CURRENT_PROJECT_VERSION = 940; + CURRENT_PROJECT_VERSION = 941; DEVELOPMENT_TEAM = BA88US33G6; INFOPLIST_FILE = Runner/Info.plist; INFOPLIST_KEY_CFBundleDisplayName = "Server Box"; @@ -618,7 +618,7 @@ "@executable_path/../Frameworks", ); MACOSX_DEPLOYMENT_TARGET = 10.15; - MARKETING_VERSION = 1.0.940; + MARKETING_VERSION = 1.0.941; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox; PRODUCT_NAME = "Server Box"; PROVISIONING_PROFILE_SPECIFIER = ""; @@ -638,7 +638,7 @@ "CODE_SIGN_IDENTITY[sdk=macosx*]" = "3rd Party Mac Developer Application"; CODE_SIGN_STYLE = Manual; COMBINE_HIDPI_IMAGES = YES; - CURRENT_PROJECT_VERSION = 940; + CURRENT_PROJECT_VERSION = 941; DEVELOPMENT_TEAM = ""; "DEVELOPMENT_TEAM[sdk=macosx*]" = BA88US33G6; INFOPLIST_FILE = Runner/Info.plist; @@ -649,7 +649,7 @@ "@executable_path/../Frameworks", ); MACOSX_DEPLOYMENT_TARGET = 10.15; - MARKETING_VERSION = 1.0.940; + MARKETING_VERSION = 1.0.941; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox; PRODUCT_NAME = "Server Box"; PROVISIONING_PROFILE_SPECIFIER = ""; From 8121eef83974eafaa78f45e23d294f98776552b9 Mon Sep 17 00:00:00 2001 From: lollipopkit <10864310+lollipopkit@users.noreply.github.com> Date: Sat, 8 Jun 2024 15:35:19 +0800 Subject: [PATCH 6/7] opt.: `RNode` --- lib/app.dart | 2 +- lib/data/model/app/backup.dart | 2 +- lib/data/model/app/github_id.dart | 5 ----- lib/data/model/app/rebuild.dart | 23 ----------------------- lib/data/res/github_id.dart | 8 ++++++-- lib/data/res/rebuild.dart | 9 +++++---- lib/view/page/home/home.dart | 1 - lib/view/page/setting/entry.dart | 14 +++++++------- 8 files changed, 20 insertions(+), 44 deletions(-) delete mode 100644 lib/data/model/app/github_id.dart delete mode 100644 lib/data/model/app/rebuild.dart diff --git a/lib/app.dart b/lib/app.dart index ca669926d..8be9842b0 100644 --- a/lib/app.dart +++ b/lib/app.dart @@ -15,7 +15,7 @@ class MyApp extends StatelessWidget { Widget build(BuildContext context) { _setup(context); return ListenableBuilder( - listenable: RebuildNodes.app, + listenable: RNodes.app, builder: (context, _) { if (!Stores.setting.useSystemPrimaryColor.fetch()) { UIs.colorSeed = Color(Stores.setting.primaryColor.fetch()); diff --git a/lib/data/model/app/backup.dart b/lib/data/model/app/backup.dart index 8d296778d..4bd4a3038 100644 --- a/lib/data/model/app/backup.dart +++ b/lib/data/model/app/backup.dart @@ -170,7 +170,7 @@ class Backup { } Pros.reload(); - RebuildNodes.app.rebuild(); + RNodes.app.build(); _logger.info('Restore success'); } diff --git a/lib/data/model/app/github_id.dart b/lib/data/model/app/github_id.dart deleted file mode 100644 index 757bc1a92..000000000 --- a/lib/data/model/app/github_id.dart +++ /dev/null @@ -1,5 +0,0 @@ -typedef GhId = String; - -extension GhIdX on GhId { - String get url => 'https://github.com/$this'; -} diff --git a/lib/data/model/app/rebuild.dart b/lib/data/model/app/rebuild.dart deleted file mode 100644 index 5f160865d..000000000 --- a/lib/data/model/app/rebuild.dart +++ /dev/null @@ -1,23 +0,0 @@ -import 'package:flutter/foundation.dart'; - -class RebuildNode implements Listenable { - final List _listeners = []; - - RebuildNode(); - - @override - void addListener(VoidCallback listener) { - _listeners.add(listener); - } - - @override - void removeListener(VoidCallback listener) { - _listeners.remove(listener); - } - - void rebuild() { - for (var listener in _listeners) { - listener(); - } - } -} diff --git a/lib/data/res/github_id.dart b/lib/data/res/github_id.dart index 73df0fedf..01ee0ba33 100644 --- a/lib/data/res/github_id.dart +++ b/lib/data/res/github_id.dart @@ -1,5 +1,3 @@ -import 'package:toolbox/data/model/app/github_id.dart'; - abstract final class GithubIds { // Thanks // If you want to change your Github ID, please open an issue. @@ -75,3 +73,9 @@ abstract final class GithubIds { 'Jasonzhu1207', }; } + +typedef GhId = String; + +extension GhIdX on GhId { + String get url => 'https://github.com/$this'; +} diff --git a/lib/data/res/rebuild.dart b/lib/data/res/rebuild.dart index f78cd8a4f..e37453a07 100644 --- a/lib/data/res/rebuild.dart +++ b/lib/data/res/rebuild.dart @@ -1,5 +1,6 @@ -import 'package:toolbox/data/model/app/rebuild.dart'; +import 'package:fl_lib/fl_lib.dart'; -abstract final class RebuildNodes { - static final app = RebuildNode(); -} +abstract final class RNodes { + static final app = RNode(); + static final dark = false.vn; +} \ No newline at end of file diff --git a/lib/view/page/home/home.dart b/lib/view/page/home/home.dart index 0e944f482..8a61b1b85 100644 --- a/lib/view/page/home/home.dart +++ b/lib/view/page/home/home.dart @@ -9,7 +9,6 @@ import 'package:toolbox/core/channel/home_widget.dart'; import 'package:toolbox/core/extension/build.dart'; import 'package:toolbox/core/extension/context/locale.dart'; import 'package:toolbox/core/route.dart'; -import 'package:toolbox/data/model/app/github_id.dart'; import 'package:toolbox/data/model/app/tab.dart'; import 'package:toolbox/data/res/build_data.dart'; import 'package:toolbox/data/res/github_id.dart'; diff --git a/lib/view/page/setting/entry.dart b/lib/view/page/setting/entry.dart index f1d3eb601..dbcffe7a7 100644 --- a/lib/view/page/setting/entry.dart +++ b/lib/view/page/setting/entry.dart @@ -305,7 +305,7 @@ class _SettingPageState extends State { _setting.primaryColor.put(color.value); context.pop(); context.pop(); - RebuildNodes.app.rebuild(); + RNodes.app.build(); } // Widget _buildLaunchPage() { @@ -393,7 +393,7 @@ class _SettingPageState extends State { ); if (selected != null) { _setting.themeMode.put(selected); - RebuildNodes.app.rebuild(); + RNodes.app.build(); } }, trailing: ValBuilder( @@ -442,7 +442,7 @@ class _SettingPageState extends State { onPressed: () { _setting.fontPath.delete(); context.pop(); - RebuildNodes.app.rebuild(); + RNodes.app.build(); }, child: Text(l10n.clear), ) @@ -466,7 +466,7 @@ class _SettingPageState extends State { } context.pop(); - RebuildNodes.app.rebuild(); + RNodes.app.build(); } Widget _buildTermFontSize() { @@ -536,7 +536,7 @@ class _SettingPageState extends State { if (selected != null) { _setting.locale.put(selected.code); context.pop(); - RebuildNodes.app.rebuild(); + RNodes.app.build(); } }, trailing: ListenBuilder( @@ -609,7 +609,7 @@ class _SettingPageState extends State { subtitle: Text(l10n.fullScreenTip, style: UIs.textGrey), trailing: StoreSwitch( prop: _setting.fullScreen, - callback: (_) => RebuildNodes.app.rebuild(), + callback: (_) => RNodes.app.build(), ), ); } @@ -820,7 +820,7 @@ class _SettingPageState extends State { return; } _setting.textFactor.put(val); - RebuildNodes.app.rebuild(); + RNodes.app.build(); context.pop(); } From 9f34021c901d9b077d20bc4d706757e0f1471335 Mon Sep 17 00:00:00 2001 From: lollipopkit <10864310+lollipopkit@users.noreply.github.com> Date: Sat, 8 Jun 2024 20:57:56 +0800 Subject: [PATCH 7/7] fix: docker ps parse if id/name is too long --- .gitignore | 2 +- ios/Runner.xcodeproj/project.pbxproj | 36 +++++++++++++------------- lib/data/model/container/ps.dart | 7 +++-- lib/data/provider/container.dart | 6 ++++- lib/data/res/build_data.dart | 6 ++--- lib/data/res/rebuild.dart | 2 +- macos/Runner.xcodeproj/project.pbxproj | 12 ++++----- test/container_test.dart | 32 +++++++++++++++++++++++ 8 files changed, 69 insertions(+), 34 deletions(-) create mode 100644 test/container_test.dart diff --git a/.gitignore b/.gitignore index d270852d4..04c35875e 100644 --- a/.gitignore +++ b/.gitignore @@ -57,7 +57,7 @@ test.dart # Linux release linux.AppDir -ServerBox-x86_64.AppImage +**/*.AppImage untranlated.json diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index bf3fa19fd..2e54e59ed 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -690,7 +690,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; - CURRENT_PROJECT_VERSION = 941; + CURRENT_PROJECT_VERSION = 943; DEVELOPMENT_TEAM = BA88US33G6; ENABLE_BITCODE = NO; INFOPLIST_FILE = "Runner/Info-$(CONFIGURATION).plist"; @@ -700,7 +700,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.0.941; + MARKETING_VERSION = 1.0.943; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; @@ -826,7 +826,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; - CURRENT_PROJECT_VERSION = 941; + CURRENT_PROJECT_VERSION = 943; DEVELOPMENT_TEAM = BA88US33G6; ENABLE_BITCODE = NO; INFOPLIST_FILE = "Runner/Info-$(CONFIGURATION).plist"; @@ -836,7 +836,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.0.941; + MARKETING_VERSION = 1.0.943; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; @@ -854,7 +854,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; - CURRENT_PROJECT_VERSION = 941; + CURRENT_PROJECT_VERSION = 943; DEVELOPMENT_TEAM = BA88US33G6; ENABLE_BITCODE = NO; INFOPLIST_FILE = "Runner/Info-$(CONFIGURATION).plist"; @@ -864,7 +864,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.0.941; + MARKETING_VERSION = 1.0.943; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; @@ -885,7 +885,7 @@ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 941; + CURRENT_PROJECT_VERSION = 943; DEVELOPMENT_TEAM = BA88US33G6; GCC_C_LANGUAGE_STANDARD = gnu11; GENERATE_INFOPLIST_FILE = YES; @@ -898,7 +898,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 1.0.941; + MARKETING_VERSION = 1.0.943; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.StatusWidget; @@ -924,7 +924,7 @@ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 941; + CURRENT_PROJECT_VERSION = 943; DEVELOPMENT_TEAM = BA88US33G6; GCC_C_LANGUAGE_STANDARD = gnu11; GENERATE_INFOPLIST_FILE = YES; @@ -937,7 +937,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 1.0.941; + MARKETING_VERSION = 1.0.943; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.StatusWidget; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -960,7 +960,7 @@ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 941; + CURRENT_PROJECT_VERSION = 943; DEVELOPMENT_TEAM = BA88US33G6; GCC_C_LANGUAGE_STANDARD = gnu11; GENERATE_INFOPLIST_FILE = YES; @@ -973,7 +973,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 1.0.941; + MARKETING_VERSION = 1.0.943; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.StatusWidget; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -996,7 +996,7 @@ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 941; + CURRENT_PROJECT_VERSION = 943; DEVELOPMENT_ASSET_PATHS = ""; DEVELOPMENT_TEAM = BA88US33G6; ENABLE_PREVIEWS = YES; @@ -1008,7 +1008,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.0.941; + MARKETING_VERSION = 1.0.943; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.WatchEnd; @@ -1037,7 +1037,7 @@ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 941; + CURRENT_PROJECT_VERSION = 943; DEVELOPMENT_ASSET_PATHS = ""; DEVELOPMENT_TEAM = BA88US33G6; ENABLE_PREVIEWS = YES; @@ -1049,7 +1049,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.0.941; + MARKETING_VERSION = 1.0.943; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.WatchEnd; PRODUCT_NAME = ServerBox; @@ -1075,7 +1075,7 @@ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 941; + CURRENT_PROJECT_VERSION = 943; DEVELOPMENT_ASSET_PATHS = ""; DEVELOPMENT_TEAM = BA88US33G6; ENABLE_PREVIEWS = YES; @@ -1087,7 +1087,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.0.941; + MARKETING_VERSION = 1.0.943; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.WatchEnd; PRODUCT_NAME = ServerBox; diff --git a/lib/data/model/container/ps.dart b/lib/data/model/container/ps.dart index 30d639dd2..3cc620f6c 100644 --- a/lib/data/model/container/ps.dart +++ b/lib/data/model/container/ps.dart @@ -143,7 +143,6 @@ final class DockerPs implements ContainerPs { @override bool get running { if (state?.contains('Exited') == true) return false; - if (state?.contains('Up') == true) return true; return true; } @@ -162,9 +161,9 @@ final class DockerPs implements ContainerPs { final parts = raw.split(Miscs.multiBlankreg); return DockerPs( id: parts[0], - names: parts[1], - image: parts[2], - state: parts[3].trim(), + state: parts[1], + names: parts[2], + image: parts[3].trim(), ); } } diff --git a/lib/data/provider/container.dart b/lib/data/provider/container.dart index 2371906ce..4541a4851 100644 --- a/lib/data/provider/container.dart +++ b/lib/data/provider/container.dart @@ -276,9 +276,13 @@ enum ContainerCmdType { return switch (this) { ContainerCmdType.version => '$prefix version $_jsonFmt', ContainerCmdType.ps => switch (type) { + /// TODO: Rollback to json format when permformance recovers. /// Use [_jsonFmt] in Docker will cause the operation to slow down. ContainerType.docker => '$prefix ps -a --format "table {{printf \\"' - '%-15.15s ${"%-30.30s " * 3}\\" .ID .Names .Image .Status}}"', + '%-15.15s ' + '%-30.30s ' + '${"%-50.50s " * 2}\\"' + ' .ID .Status .Names .Image}}"', ContainerType.podman => '$prefix ps -a $_jsonFmt', }, ContainerCmdType.stats => diff --git a/lib/data/res/build_data.dart b/lib/data/res/build_data.dart index 364932ed0..adfe5a894 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 = 941; + static const int build = 943; static const String engine = "3.22.1"; - static const String buildAt = "2024-06-07 23:57:38"; - static const int modifications = 4; + static const String buildAt = "2024-06-08 19:28:01"; + static const int modifications = 7; static const int script = 48; } diff --git a/lib/data/res/rebuild.dart b/lib/data/res/rebuild.dart index e37453a07..71c4019f4 100644 --- a/lib/data/res/rebuild.dart +++ b/lib/data/res/rebuild.dart @@ -3,4 +3,4 @@ import 'package:fl_lib/fl_lib.dart'; abstract final class RNodes { static final app = RNode(); static final dark = false.vn; -} \ No newline at end of file +} diff --git a/macos/Runner.xcodeproj/project.pbxproj b/macos/Runner.xcodeproj/project.pbxproj index bbc204344..fb05ea711 100644 --- a/macos/Runner.xcodeproj/project.pbxproj +++ b/macos/Runner.xcodeproj/project.pbxproj @@ -471,7 +471,7 @@ CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; - CURRENT_PROJECT_VERSION = 941; + CURRENT_PROJECT_VERSION = 943; DEVELOPMENT_TEAM = BA88US33G6; INFOPLIST_FILE = Runner/Info.plist; INFOPLIST_KEY_CFBundleDisplayName = "Server Box"; @@ -481,7 +481,7 @@ "@executable_path/../Frameworks", ); MACOSX_DEPLOYMENT_TARGET = 10.15; - MARKETING_VERSION = 1.0.941; + MARKETING_VERSION = 1.0.943; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox; PRODUCT_NAME = "Server Box"; PROVISIONING_PROFILE_SPECIFIER = ""; @@ -608,7 +608,7 @@ CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; - CURRENT_PROJECT_VERSION = 941; + CURRENT_PROJECT_VERSION = 943; DEVELOPMENT_TEAM = BA88US33G6; INFOPLIST_FILE = Runner/Info.plist; INFOPLIST_KEY_CFBundleDisplayName = "Server Box"; @@ -618,7 +618,7 @@ "@executable_path/../Frameworks", ); MACOSX_DEPLOYMENT_TARGET = 10.15; - MARKETING_VERSION = 1.0.941; + MARKETING_VERSION = 1.0.943; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox; PRODUCT_NAME = "Server Box"; PROVISIONING_PROFILE_SPECIFIER = ""; @@ -638,7 +638,7 @@ "CODE_SIGN_IDENTITY[sdk=macosx*]" = "3rd Party Mac Developer Application"; CODE_SIGN_STYLE = Manual; COMBINE_HIDPI_IMAGES = YES; - CURRENT_PROJECT_VERSION = 941; + CURRENT_PROJECT_VERSION = 943; DEVELOPMENT_TEAM = ""; "DEVELOPMENT_TEAM[sdk=macosx*]" = BA88US33G6; INFOPLIST_FILE = Runner/Info.plist; @@ -649,7 +649,7 @@ "@executable_path/../Frameworks", ); MACOSX_DEPLOYMENT_TARGET = 10.15; - MARKETING_VERSION = 1.0.941; + MARKETING_VERSION = 1.0.943; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox; PRODUCT_NAME = "Server Box"; PROVISIONING_PROFILE_SPECIFIER = ""; diff --git a/test/container_test.dart b/test/container_test.dart new file mode 100644 index 000000000..16a355afa --- /dev/null +++ b/test/container_test.dart @@ -0,0 +1,32 @@ +import 'package:flutter_test/flutter_test.dart'; +import 'package:toolbox/data/model/container/ps.dart'; + +void main() { + test('docker ps parse', () { + const raw = ''' +CONTAINER ID STATUS NAMES IMAGE +0e9e2ef860d2 Up 2 hours hbbs rustdesk/rustdesk-server:latest +9a4df3ed340c Up 41 minutes hbbr rustdesk/rustdesk-server:latest +fa1215b4be74 Up 12 hours firefly uusec/firefly:latest +'''; + final lines = raw.split('\n'); + const ids = ['0e9e2ef860d2', '9a4df3ed340c', 'fa1215b4be74']; + const names = ['hbbs', 'hbbr', 'firefly']; + const images = [ + 'rustdesk/rustdesk-server:latest', + 'rustdesk/rustdesk-server:latest', + 'uusec/firefly:latest' + ]; + const states = ['Up 2 hours', 'Up 41 minutes', 'Up 12 hours']; + for (var idx = 1; idx < lines.length; idx++) { + final raw = lines[idx]; + if (raw.isEmpty) continue; + final ps = DockerPs.parse(raw); + expect(ps.id, ids[idx - 1]); + expect(ps.names, names[idx - 1]); + expect(ps.image, images[idx - 1]); + expect(ps.state, states[idx - 1]); + expect(ps.running, true); + } + }); +}