From e5ef28415befe96187b39cedb7cb6c4f9dbb5643 Mon Sep 17 00:00:00 2001 From: lollipopkit <10864310+lollipopkit@users.noreply.github.com> Date: Sat, 8 Jun 2024 21:39:42 +0800 Subject: [PATCH] opt.: ssh tab --- ios/Runner.xcodeproj/project.pbxproj | 36 ++++++++--------- lib/data/res/build_data.dart | 6 +-- lib/view/page/ssh/page.dart | 55 ++++++++++++++------------ lib/view/page/ssh/tab.dart | 21 ++++++---- macos/Runner.xcodeproj/project.pbxproj | 12 +++--- 5 files changed, 70 insertions(+), 60 deletions(-) diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index 2e54e59e..3399de89 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 = 943; + CURRENT_PROJECT_VERSION = 948; DEVELOPMENT_TEAM = BA88US33G6; ENABLE_BITCODE = NO; INFOPLIST_FILE = "Runner/Info-$(CONFIGURATION).plist"; @@ -700,7 +700,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.0.943; + MARKETING_VERSION = 1.0.948; 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 = 943; + CURRENT_PROJECT_VERSION = 948; DEVELOPMENT_TEAM = BA88US33G6; ENABLE_BITCODE = NO; INFOPLIST_FILE = "Runner/Info-$(CONFIGURATION).plist"; @@ -836,7 +836,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.0.943; + MARKETING_VERSION = 1.0.948; 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 = 943; + CURRENT_PROJECT_VERSION = 948; DEVELOPMENT_TEAM = BA88US33G6; ENABLE_BITCODE = NO; INFOPLIST_FILE = "Runner/Info-$(CONFIGURATION).plist"; @@ -864,7 +864,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.0.943; + MARKETING_VERSION = 1.0.948; 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 = 943; + CURRENT_PROJECT_VERSION = 948; 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.943; + MARKETING_VERSION = 1.0.948; 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 = 943; + CURRENT_PROJECT_VERSION = 948; 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.943; + MARKETING_VERSION = 1.0.948; 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 = 943; + CURRENT_PROJECT_VERSION = 948; 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.943; + MARKETING_VERSION = 1.0.948; 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 = 943; + CURRENT_PROJECT_VERSION = 948; DEVELOPMENT_ASSET_PATHS = ""; DEVELOPMENT_TEAM = BA88US33G6; ENABLE_PREVIEWS = YES; @@ -1008,7 +1008,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.0.943; + MARKETING_VERSION = 1.0.948; 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 = 943; + CURRENT_PROJECT_VERSION = 948; DEVELOPMENT_ASSET_PATHS = ""; DEVELOPMENT_TEAM = BA88US33G6; ENABLE_PREVIEWS = YES; @@ -1049,7 +1049,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.0.943; + MARKETING_VERSION = 1.0.948; 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 = 943; + CURRENT_PROJECT_VERSION = 948; DEVELOPMENT_ASSET_PATHS = ""; DEVELOPMENT_TEAM = BA88US33G6; ENABLE_PREVIEWS = YES; @@ -1087,7 +1087,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.0.943; + MARKETING_VERSION = 1.0.948; 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 adfe5a89..3c779442 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 = 943; + static const int build = 948; static const String engine = "3.22.1"; - static const String buildAt = "2024-06-08 19:28:01"; - static const int modifications = 7; + static const String buildAt = "2024-06-08 21:21:36"; + static const int modifications = 3; static const int script = 48; } diff --git a/lib/view/page/ssh/page.dart b/lib/view/page/ssh/page.dart index 95f99fdb..102237cf 100644 --- a/lib/view/page/ssh/page.dart +++ b/lib/view/page/ssh/page.dart @@ -1,6 +1,7 @@ import 'dart:async'; import 'dart:convert'; +import 'package:after_layout/after_layout.dart'; import 'package:dartssh2/dartssh2.dart'; import 'package:fl_lib/fl_lib.dart'; import 'package:flutter/material.dart'; @@ -49,7 +50,8 @@ class SSHPage extends StatefulWidget { const _horizonPadding = 7.0; -class SSHPageState extends State with AutomaticKeepAliveClientMixin { +class SSHPageState extends State + with AutomaticKeepAliveClientMixin, AfterLayoutMixin { final _keyboard = VirtKeyProvider(); late final _terminal = Terminal(inputHandler: _keyboard); final TerminalController _terminalController = TerminalController(); @@ -73,13 +75,6 @@ class SSHPageState extends State with AutomaticKeepAliveClientMixin { super.initState(); _initStoredCfg(); _initVirtKeys(); - - Future.delayed(const Duration(milliseconds: 77), () async { - _showHelp(); - await _initTerminal(); - - if (Stores.setting.sshWakeLock.fetch()) WakelockPlus.enable(); - }); } @override @@ -153,7 +148,7 @@ class SSHPageState extends State with AutomaticKeepAliveClientMixin { textStyle: _terminalStyle, theme: _terminalTheme, deleteDetection: isMobile, - autofocus: true, + autofocus: false, keyboardAppearance: _isDark ? Brightness.dark : Brightness.light, showToolbar: isMobile, viewOffset: Offset( @@ -432,6 +427,8 @@ class SSHPageState extends State with AutomaticKeepAliveClientMixin { } } + SSHPage.focusNode.requestFocus(); + await session.done; if (mounted && widget.notFromTab) { context.pop(); @@ -518,22 +515,30 @@ class SSHPageState extends State with AutomaticKeepAliveClientMixin { _terminalStyle = TerminalStyle.fromTextStyle(textStyle); } - void _showHelp() { - if (!Stores.setting.sshTermHelpShown.fetch()) { - context.showRoundDialog( - title: l10n.doc, - child: Text(l10n.sshTermHelp), - actions: [ - TextButton( - onPressed: () { - Stores.setting.sshTermHelpShown.put(true); - context.pop(); - }, - child: Text(l10n.noPromptAgain), - ), - ], - ); - } + Future _showHelp() async { + if (Stores.setting.sshTermHelpShown.fetch()) return; + + return await context.showRoundDialog( + title: l10n.doc, + child: Text(l10n.sshTermHelp), + actions: [ + TextButton( + onPressed: () { + Stores.setting.sshTermHelpShown.put(true); + context.pop(); + }, + child: Text(l10n.noPromptAgain), + ), + ], + ); + } + + @override + FutureOr afterFirstLayout(BuildContext context) async { + await _showHelp(); + await _initTerminal(); + + if (Stores.setting.sshWakeLock.fetch()) WakelockPlus.enable(); } } diff --git a/lib/view/page/ssh/tab.dart b/lib/view/page/ssh/tab.dart index cacd26a9..d790ee0b 100644 --- a/lib/view/page/ssh/tab.dart +++ b/lib/view/page/ssh/tab.dart @@ -43,10 +43,10 @@ class _SSHTabPageState extends State }, ), body: _buildBody(), - floatingActionButton: ListenableBuilder( + floatingActionButton: ValBuilder( listenable: _fabVN, - builder: (_, __) { - if (_fabVN.value != 0) return const SizedBox(); + builder: (idx) { + if (idx != 0) return const SizedBox(); return FloatingActionButton( heroTag: 'sshAddServer', onPressed: () => AppRoutes.serverEdit().go(context), @@ -60,11 +60,12 @@ class _SSHTabPageState extends State void _onTapTab(int idx) async { await _toPage(idx); - _fabVN.value = idx; - FocusScope.of(context).unfocus(); + SSHPage.focusNode.unfocus(); } void _onTapClose(String name) async { + SSHPage.focusNode.unfocus(); + final confirm = await showDialog( context: context, builder: (context) { @@ -89,6 +90,8 @@ class _SSHTabPageState extends State _tabMap.remove(name); _tabRN.build(); + _pageCtrl.previousPage( + duration: Durations.medium1, curve: Curves.fastEaseInToSlowEaseOut); } Widget _buildAddPage() { @@ -134,6 +137,7 @@ class _SSHTabPageState extends State final name = _tabMap.keys.elementAt(idx); return _tabMap[name]?.page ?? UIs.placeholder; }, + onPageChanged: (value) => _fabVN.value = value, ); }, ); @@ -141,12 +145,14 @@ class _SSHTabPageState extends State void _onTapInitCard(ServerPrivateInfo spi) async { final name = () { - final reg = RegExp(r'\((\d+)\)'); + final reg = RegExp('${spi.name}\\((\\d+)\\)'); final idxs = _tabMap.keys .map((e) => reg.firstMatch(e)) .map((e) => e?.group(1)) .where((e) => e != null); - if (idxs.isEmpty) return spi.name; + if (idxs.isEmpty) { + return _tabMap.keys.contains(spi.name) ? '${spi.name}(1)' : 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) { @@ -172,7 +178,6 @@ class _SSHTabPageState extends State await Future.delayed(Durations.short3); final idx = _tabMap.keys.toList().indexOf(name); await _toPage(idx); - _fabVN.value = idx; } Future _toPage(int idx) => _pageCtrl.animateToPage(idx, diff --git a/macos/Runner.xcodeproj/project.pbxproj b/macos/Runner.xcodeproj/project.pbxproj index fb05ea71..ae9c677b 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 = 943; + CURRENT_PROJECT_VERSION = 948; 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.943; + MARKETING_VERSION = 1.0.948; 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 = 943; + CURRENT_PROJECT_VERSION = 948; 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.943; + MARKETING_VERSION = 1.0.948; 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 = 943; + CURRENT_PROJECT_VERSION = 948; 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.943; + MARKETING_VERSION = 1.0.948; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox; PRODUCT_NAME = "Server Box"; PROVISIONING_PROFILE_SPECIFIER = "";