From ab09fa66148ce35e6a18642045e5187d54694276 Mon Sep 17 00:00:00 2001 From: lollipopkit Date: Sun, 3 Sep 2023 15:43:08 +0800 Subject: [PATCH] fix: server card height --- ios/Runner.xcodeproj/project.pbxproj | 24 ++++++------ lib/core/extension/ssh_client.dart | 3 +- lib/core/utils/ui.dart | 38 ++++++++++++++++++ lib/data/provider/docker.dart | 11 +----- lib/data/provider/pkg.dart | 13 +------ lib/data/res/build_data.dart | 4 +- lib/data/res/misc.dart | 3 ++ lib/view/page/docker.dart | 54 +++----------------------- lib/view/page/pkg.dart | 51 +----------------------- lib/view/page/server/tab.dart | 14 +++---- macos/Runner.xcodeproj/project.pbxproj | 12 +++--- 11 files changed, 80 insertions(+), 147 deletions(-) diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index eb18dd2e..0597fe91 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -470,7 +470,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; - CURRENT_PROJECT_VERSION = 520; + CURRENT_PROJECT_VERSION = 522; DEVELOPMENT_TEAM = BA88US33G6; ENABLE_BITCODE = NO; INFOPLIST_FILE = "Runner/Info-$(CONFIGURATION).plist"; @@ -478,7 +478,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.0.520; + MARKETING_VERSION = 1.0.522; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; @@ -602,7 +602,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; - CURRENT_PROJECT_VERSION = 520; + CURRENT_PROJECT_VERSION = 522; DEVELOPMENT_TEAM = BA88US33G6; ENABLE_BITCODE = NO; INFOPLIST_FILE = "Runner/Info-$(CONFIGURATION).plist"; @@ -610,7 +610,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.0.520; + MARKETING_VERSION = 1.0.522; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; @@ -628,7 +628,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; - CURRENT_PROJECT_VERSION = 520; + CURRENT_PROJECT_VERSION = 522; DEVELOPMENT_TEAM = BA88US33G6; ENABLE_BITCODE = NO; INFOPLIST_FILE = "Runner/Info-$(CONFIGURATION).plist"; @@ -636,7 +636,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.0.520; + MARKETING_VERSION = 1.0.522; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; @@ -657,7 +657,7 @@ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 520; + CURRENT_PROJECT_VERSION = 522; DEVELOPMENT_TEAM = BA88US33G6; GCC_C_LANGUAGE_STANDARD = gnu11; GENERATE_INFOPLIST_FILE = YES; @@ -670,7 +670,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 1.0.520; + MARKETING_VERSION = 1.0.522; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.StatusWidget; @@ -696,7 +696,7 @@ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 520; + CURRENT_PROJECT_VERSION = 522; DEVELOPMENT_TEAM = BA88US33G6; GCC_C_LANGUAGE_STANDARD = gnu11; GENERATE_INFOPLIST_FILE = YES; @@ -709,7 +709,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 1.0.520; + MARKETING_VERSION = 1.0.522; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.StatusWidget; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -732,7 +732,7 @@ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 520; + CURRENT_PROJECT_VERSION = 522; DEVELOPMENT_TEAM = BA88US33G6; GCC_C_LANGUAGE_STANDARD = gnu11; GENERATE_INFOPLIST_FILE = YES; @@ -745,7 +745,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 1.0.520; + MARKETING_VERSION = 1.0.522; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.StatusWidget; PRODUCT_NAME = "$(TARGET_NAME)"; diff --git a/lib/core/extension/ssh_client.dart b/lib/core/extension/ssh_client.dart index 8fda9b3b..38f85b4f 100644 --- a/lib/core/extension/ssh_client.dart +++ b/lib/core/extension/ssh_client.dart @@ -7,8 +7,7 @@ import 'package:toolbox/core/extension/uint8list.dart'; typedef OnStd = void Function(String data, StreamSink sink); typedef OnStdin = void Function(StreamSink sink); -typedef PwdRequestFunc = Future Function(); -final pwdRequestWithUserReg = RegExp(r'\[sudo\] password for (.+):'); +typedef PwdRequestFunc = Future Function(String? user); extension SSHClientX on SSHClient { Future exec( diff --git a/lib/core/utils/ui.dart b/lib/core/utils/ui.dart index b0e32959..69e74e20 100644 --- a/lib/core/utils/ui.dart +++ b/lib/core/utils/ui.dart @@ -1,16 +1,20 @@ +import 'dart:async'; import 'dart:io'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_gen/gen_l10n/l10n.dart'; import 'package:toolbox/core/extension/context.dart'; +import 'package:toolbox/core/extension/ssh_client.dart'; import 'package:toolbox/data/model/app/tab.dart'; import 'package:url_launcher/url_launcher.dart'; import '../../data/model/server/snippet.dart'; import '../../data/provider/snippet.dart'; +import '../../data/res/misc.dart'; import '../../data/res/ui.dart'; import '../../locator.dart'; +import '../../view/widget/input_field.dart'; import '../../view/widget/picker.dart'; import '../persistant_store.dart'; import '../route.dart'; @@ -74,6 +78,40 @@ void showLoadingDialog(BuildContext context, {bool barrierDismiss = false}) { ); } +Future showPwdDialog( + BuildContext context, + String? user, +) async { + if (!context.mounted) return null; + final s = S.of(context)!; + return await showRoundDialog( + context: context, + title: Text(user ?? s.pwd), + child: Input( + autoFocus: true, + type: TextInputType.visiblePassword, + obscureText: true, + onSubmitted: (val) => context.pop(val.trim()), + label: s.pwd, + ), + ); +} + +Future onPwd( + String event, + StreamSink stdin, + PwdRequestFunc? onPwdReq, +) async { + if (event.contains('[sudo] password for ')) { + final user = pwdRequestWithUserReg.firstMatch(event)?.group(1); + final pwd = await onPwdReq?.call(user); + if (pwd == null || pwd.isEmpty) { + return; + } + stdin.add('$pwd\n'.uint8List); + } +} + Widget buildSwitch( BuildContext context, StorePropertyBase prop, { diff --git a/lib/data/provider/docker.dart b/lib/data/provider/docker.dart index b15c032a..619768a9 100644 --- a/lib/data/provider/docker.dart +++ b/lib/data/provider/docker.dart @@ -6,6 +6,7 @@ import 'package:flutter/material.dart'; import 'package:logging/logging.dart'; import 'package:toolbox/core/extension/ssh_client.dart'; import 'package:toolbox/core/extension/stringx.dart'; +import 'package:toolbox/core/utils/ui.dart'; import 'package:toolbox/data/model/app/shell_func.dart'; import 'package:toolbox/data/model/docker/image.dart'; import 'package:toolbox/data/model/docker/ps.dart'; @@ -147,15 +148,7 @@ class DockerProvider extends ChangeNotifier { Future _onPwd(String event, StreamSink stdin) async { if (isRequestingPwd) return; isRequestingPwd = true; - if (event.contains('[sudo] password for ')) { - _logger.info('sudo password request for $userName'); - final pwd = await onPwdReq!(); - if (pwd.isEmpty) { - _logger.info('sudo password request cancelled'); - return; - } - stdin.add('$pwd\n'.uint8List); - } + await onPwd(event, stdin, onPwdReq); isRequestingPwd = false; } diff --git a/lib/data/provider/pkg.dart b/lib/data/provider/pkg.dart index a19e816b..4c4a38a7 100644 --- a/lib/data/provider/pkg.dart +++ b/lib/data/provider/pkg.dart @@ -5,8 +5,8 @@ import 'package:dartssh2/dartssh2.dart'; import 'package:flutter/material.dart'; import 'package:logging/logging.dart'; import 'package:toolbox/core/extension/ssh_client.dart'; -import 'package:toolbox/core/extension/stringx.dart'; import 'package:toolbox/core/extension/uint8list.dart'; +import 'package:toolbox/core/utils/ui.dart'; import 'package:toolbox/data/model/pkg/manager.dart'; import 'package:toolbox/data/model/pkg/upgrade_info.dart'; import 'package:toolbox/data/model/server/dist.dart'; @@ -124,16 +124,7 @@ class PkgProvider extends ChangeNotifier { Future _onPwd(String event, StreamSink stdin) async { if (isRequestingPwd) return; isRequestingPwd = true; - if (event.contains('[sudo] password for ')) { - final user = pwdRequestWithUserReg.firstMatch(event)?.group(1); - logger.info('sudo password request for $user'); - final pwd = await onPasswordRequest!(); - if (pwd.isEmpty) { - logger.info('sudo password request cancelled'); - return; - } - stdin.add('$pwd\n'.uint8List); - } + await onPwd(event, stdin, onPasswordRequest); isRequestingPwd = false; } diff --git a/lib/data/res/build_data.dart b/lib/data/res/build_data.dart index 6f7128f8..25a4b2ef 100644 --- a/lib/data/res/build_data.dart +++ b/lib/data/res/build_data.dart @@ -2,8 +2,8 @@ class BuildData { static const String name = "ServerBox"; - static const int build = 520; + static const int build = 522; static const String engine = "3.13.1"; - static const String buildAt = "2023-08-30 19:21:56.317609"; + static const String buildAt = "2023-09-01 12:58:00.909396"; static const int modifications = 2; } diff --git a/lib/data/res/misc.dart b/lib/data/res/misc.dart index 1fb0fe40..9ecfcfb6 100644 --- a/lib/data/res/misc.dart +++ b/lib/data/res/misc.dart @@ -7,6 +7,9 @@ import '../model/app/github_id.dart'; /// RegExp for number final numReg = RegExp(r'\s{1,}'); +/// RegExp for password request +final pwdRequestWithUserReg = RegExp(r'\[sudo\] password for (.+):'); + /// Private Key max allowed size is 20kb const privateKeyMaxSize = 20 * 1024; diff --git a/lib/view/page/docker.dart b/lib/view/page/docker.dart index 3e7dfd29..7de3811a 100644 --- a/lib/view/page/docker.dart +++ b/lib/view/page/docker.dart @@ -57,7 +57,12 @@ class _DockerManagePageState extends State { if (client == null) { return; } - _docker.init(client, widget.spi.user, onPwdRequest, widget.spi.id); + _docker.init( + client, + widget.spi.user, + (user) async => await showPwdDialog(context, user), + widget.spi.id, + ); } @override @@ -183,53 +188,6 @@ class _DockerManagePageState extends State { return 'docker run -itd --name $name $suffix'; } - void onSubmitted() { - context.pop(); - if (_textController.text == '') { - showRoundDialog( - context: context, - title: Text(_s.attention), - child: Text(_s.fieldMustNotEmpty), - actions: [ - TextButton( - onPressed: () => context.pop(), - child: Text(_s.ok), - ), - ], - ); - return; - } - } - - Future onPwdRequest() async { - if (!mounted) return ''; - await showRoundDialog( - context: context, - title: Text(widget.spi.user), - child: Input( - controller: _textController, - type: TextInputType.visiblePassword, - obscureText: true, - onSubmitted: (_) => onSubmitted(), - label: _s.pwd, - ), - actions: [ - TextButton( - onPressed: () { - context.pop(); - context.pop(); - }, - child: Text(_s.cancel), - ), - TextButton( - onPressed: onSubmitted, - child: Text(_s.ok, style: textRed), - ), - ], - ); - return _textController.text.trim(); - } - Widget _buildMain() { if (_docker.error != null && _docker.items == null) { return SizedBox.expand( diff --git a/lib/view/page/pkg.dart b/lib/view/page/pkg.dart index f28f059c..bf20e9d8 100644 --- a/lib/view/page/pkg.dart +++ b/lib/view/page/pkg.dart @@ -1,8 +1,6 @@ import 'package:flutter/material.dart'; import 'package:flutter_gen/gen_l10n/l10n.dart'; import 'package:provider/provider.dart'; -import 'package:toolbox/core/extension/context.dart'; -import 'package:toolbox/view/widget/input_field.dart'; import '../../data/model/pkg/upgrade_info.dart'; import '../../data/model/server/dist.dart'; @@ -63,7 +61,7 @@ class _PkgManagePageState extends State _scrollController.jumpTo(_scrollController.position.maxScrollExtent), () => _scrollControllerUpdate .jumpTo(_scrollController.position.maxScrollExtent), - onPwdRequest, + (user) async => await showPwdDialog(context, user), widget.spi.user, ); _pkgProvider.refresh(); @@ -83,53 +81,6 @@ class _PkgManagePageState extends State }); } - void onSubmitted() { - if (_textController.text == '') { - showRoundDialog( - context: context, - title: Text(_s.attention), - child: Text(_s.fieldMustNotEmpty), - actions: [ - TextButton( - onPressed: () => context.pop(), - child: Text(_s.ok), - ), - ], - ); - return; - } - context.pop(); - } - - Future onPwdRequest() async { - if (!mounted) return ''; - await showRoundDialog( - context: context, - title: Text(widget.spi.user), - child: Input( - autoFocus: true, - controller: _textController, - type: TextInputType.visiblePassword, - obscureText: true, - onSubmitted: (_) => onSubmitted(), - label: _s.pwd, - ), - actions: [ - TextButton( - onPressed: () { - context.pop(); - context.pop(); - }, - child: Text(_s.cancel)), - TextButton( - onPressed: () => onSubmitted(), - child: Text(_s.ok, style: textRed), - ), - ], - ); - return _textController.text.trim(); - } - Widget? _buildFAB(PkgProvider pkg) { if (pkg.upgradeable?.isEmpty ?? true) { return null; diff --git a/lib/view/page/server/tab.dart b/lib/view/page/server/tab.dart index e80aedac..adff31cb 100644 --- a/lib/view/page/server/tab.dart +++ b/lib/view/page/server/tab.dart @@ -218,11 +218,10 @@ class _ServerPageState extends State Widget _buildRealServerCard(Server srv) { final title = _buildServerCardTitle(srv.status, srv.state, srv.spi); final List children = [title]; - if (srv.state != ServerState.finished) { - // Do nothing - } else if (_flipedCardIds.contains(srv.spi.id)) { + + if (_flipedCardIds.contains(srv.spi.id)) { children.addAll(_buildFlipedCard(srv)); - } else { + } else if (srv.state == ServerState.finished) { children.addAll(_buildNormalCard(srv.status, srv.spi)); } @@ -245,6 +244,7 @@ class _ServerPageState extends State Row( mainAxisAlignment: MainAxisAlignment.spaceAround, children: [ + // TODO: sudo | on pwd request IconButton( onPressed: () => srv.client?.run('shutdown -h now'), icon: const Icon(Icons.power_off), @@ -482,12 +482,12 @@ class _ServerPageState extends State } double _calcCardHeight(ServerState cs, String id) { - if (cs != ServerState.finished) { - return 23.0; - } if (_flipedCardIds.contains(id)) { return 77.0; } + if (cs != ServerState.finished) { + return 23.0; + } if (_settingStore.moveOutServerTabFuncBtns.fetch() && // Discussion #146 !_settingStore.serverTabUseOldUI.fetch()) { diff --git a/macos/Runner.xcodeproj/project.pbxproj b/macos/Runner.xcodeproj/project.pbxproj index 72bac61c..bb7cd5f9 100644 --- a/macos/Runner.xcodeproj/project.pbxproj +++ b/macos/Runner.xcodeproj/project.pbxproj @@ -474,9 +474,9 @@ baseConfigurationReference = C1C758C41C4E208965A68933 /* Pods-RunnerTests.debug.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; - CURRENT_PROJECT_VERSION = 520; + CURRENT_PROJECT_VERSION = 522; GENERATE_INFOPLIST_FILE = YES; - MARKETING_VERSION = 1.0.520; + MARKETING_VERSION = 1.0.522; PRODUCT_BUNDLE_IDENTIFIER = tech.lolli.serverBox.RunnerTests; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_VERSION = 5.0; @@ -489,9 +489,9 @@ baseConfigurationReference = 15AF97DF993E8968098D6EBE /* Pods-RunnerTests.release.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; - CURRENT_PROJECT_VERSION = 520; + CURRENT_PROJECT_VERSION = 522; GENERATE_INFOPLIST_FILE = YES; - MARKETING_VERSION = 1.0.520; + MARKETING_VERSION = 1.0.522; PRODUCT_BUNDLE_IDENTIFIER = tech.lolli.serverBox.RunnerTests; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_VERSION = 5.0; @@ -504,9 +504,9 @@ baseConfigurationReference = 7CFA7DE7FABA75685DFB6948 /* Pods-RunnerTests.profile.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; - CURRENT_PROJECT_VERSION = 520; + CURRENT_PROJECT_VERSION = 522; GENERATE_INFOPLIST_FILE = YES; - MARKETING_VERSION = 1.0.520; + MARKETING_VERSION = 1.0.522; PRODUCT_BUNDLE_IDENTIFIER = tech.lolli.serverBox.RunnerTests; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_VERSION = 5.0;