diff --git a/.dart_tool/flutter_gen/gen_l10n/l10n.dart b/.dart_tool/flutter_gen/gen_l10n/l10n.dart index 85458064..088dd4b7 100644 --- a/.dart_tool/flutter_gen/gen_l10n/l10n.dart +++ b/.dart_tool/flutter_gen/gen_l10n/l10n.dart @@ -1019,6 +1019,12 @@ abstract class S { /// **'Are you sure to delete server [{server}]?'** String sureToDeleteServer(Object server); + /// No description provided for @terminal. + /// + /// In en, this message translates to: + /// **'Terminal'** + String get terminal; + /// No description provided for @theme. /// /// In en, this message translates to: diff --git a/.dart_tool/flutter_gen/gen_l10n/l10n_de.dart b/.dart_tool/flutter_gen/gen_l10n/l10n_de.dart index 1fd125f5..eba3c58d 100644 --- a/.dart_tool/flutter_gen/gen_l10n/l10n_de.dart +++ b/.dart_tool/flutter_gen/gen_l10n/l10n_de.dart @@ -500,6 +500,9 @@ class SDe extends S { return 'Bist du sicher, dass du [$server] löschen willst?'; } + @override + String get terminal => 'Terminal'; + @override String get theme => 'Themen'; diff --git a/.dart_tool/flutter_gen/gen_l10n/l10n_en.dart b/.dart_tool/flutter_gen/gen_l10n/l10n_en.dart index a3083f06..8d4fd0fd 100644 --- a/.dart_tool/flutter_gen/gen_l10n/l10n_en.dart +++ b/.dart_tool/flutter_gen/gen_l10n/l10n_en.dart @@ -500,6 +500,9 @@ class SEn extends S { return 'Are you sure to delete server [$server]?'; } + @override + String get terminal => 'Terminal'; + @override String get theme => 'Theme'; diff --git a/.dart_tool/flutter_gen/gen_l10n/l10n_zh.dart b/.dart_tool/flutter_gen/gen_l10n/l10n_zh.dart index e7c2a042..5595a125 100644 --- a/.dart_tool/flutter_gen/gen_l10n/l10n_zh.dart +++ b/.dart_tool/flutter_gen/gen_l10n/l10n_zh.dart @@ -500,6 +500,9 @@ class SZh extends S { return '你确定要删除服务器 [$server] 吗?'; } + @override + String get terminal => '终端'; + @override String get theme => '主题'; diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index 6840725f..c02a8d18 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -360,7 +360,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; - CURRENT_PROJECT_VERSION = 320; + CURRENT_PROJECT_VERSION = 321; DEVELOPMENT_TEAM = BA88US33G6; ENABLE_BITCODE = NO; INFOPLIST_FILE = "Runner/Info-$(CONFIGURATION).plist"; @@ -368,7 +368,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.0.320; + MARKETING_VERSION = 1.0.321; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; @@ -491,7 +491,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; - CURRENT_PROJECT_VERSION = 320; + CURRENT_PROJECT_VERSION = 321; DEVELOPMENT_TEAM = BA88US33G6; ENABLE_BITCODE = NO; INFOPLIST_FILE = "Runner/Info-$(CONFIGURATION).plist"; @@ -499,7 +499,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.0.320; + MARKETING_VERSION = 1.0.321; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; @@ -516,7 +516,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; - CURRENT_PROJECT_VERSION = 320; + CURRENT_PROJECT_VERSION = 321; DEVELOPMENT_TEAM = BA88US33G6; ENABLE_BITCODE = NO; INFOPLIST_FILE = "Runner/Info-$(CONFIGURATION).plist"; @@ -524,7 +524,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.0.320; + MARKETING_VERSION = 1.0.321; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; diff --git a/lib/data/model/app/menu.dart b/lib/data/model/app/menu.dart index a36c2876..62d9a74f 100644 --- a/lib/data/model/app/menu.dart +++ b/lib/data/model/app/menu.dart @@ -46,7 +46,8 @@ enum DockerMenuType { stop, restart, rm, - logs; + logs, + terminal; static List items(bool running) { if (running) { @@ -68,6 +69,8 @@ enum DockerMenuType { return Icons.delete; case DockerMenuType.logs: return Icons.logo_dev; + case DockerMenuType.terminal: + return Icons.terminal; } } @@ -83,6 +86,8 @@ enum DockerMenuType { return s.delete; case DockerMenuType.logs: return s.log; + case DockerMenuType.terminal: + return s.terminal; } } diff --git a/lib/data/res/build_data.dart b/lib/data/res/build_data.dart index 088dec13..a2ca1095 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 = 320; + static const int build = 321; static const String engine = "3.10.2"; - static const String buildAt = "2023-05-26 20:00:35.224841"; - static const int modifications = 5; + static const String buildAt = "2023-05-26 20:09:33.821996"; + static const int modifications = 2; } diff --git a/lib/l10n/app_de.arb b/lib/l10n/app_de.arb index 936355ae..34f26d95 100644 --- a/lib/l10n/app_de.arb +++ b/lib/l10n/app_de.arb @@ -153,6 +153,7 @@ "sureDirEmpty": "Stelle sicher, dass der Ordner leer ist.", "sureNoPwd": "Bist du sicher, dass du kein Passwort verwenden willst?", "sureToDeleteServer": "Bist du sicher, dass du [{server}] löschen willst?", + "terminal": "Terminal", "theme": "Themen", "themeMode": "Thememodus", "times": "x", diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index 46545e2a..3fdb9212 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -153,6 +153,7 @@ "sureDirEmpty": "Make sure dir is empty.", "sureNoPwd": "Are you sure to use no password?", "sureToDeleteServer": "Are you sure to delete server [{server}]?", + "terminal": "Terminal", "theme": "Theme", "themeMode": "Theme mode", "times": "Times", diff --git a/lib/l10n/app_zh.arb b/lib/l10n/app_zh.arb index 5b069969..c3613c79 100644 --- a/lib/l10n/app_zh.arb +++ b/lib/l10n/app_zh.arb @@ -153,6 +153,7 @@ "sureDirEmpty": "请确保文件夹为空", "sureNoPwd": "确认使用无密码?", "sureToDeleteServer": "你确定要删除服务器 [{server}] 吗?", + "terminal": "终端", "theme": "主题", "themeMode": "主题模式", "times": "次", diff --git a/lib/view/page/docker.dart b/lib/view/page/docker.dart index 393ffa57..f35d1a5a 100644 --- a/lib/view/page/docker.dart +++ b/lib/view/page/docker.dart @@ -2,7 +2,9 @@ import 'package:flutter/material.dart'; import 'package:flutter_gen/gen_l10n/l10n.dart'; import 'package:provider/provider.dart'; import 'package:toolbox/core/extension/navigator.dart'; +import 'package:toolbox/core/route.dart'; import 'package:toolbox/core/utils/misc.dart'; +import 'package:toolbox/view/page/ssh.dart'; import 'package:toolbox/view/widget/input_field.dart'; import '../../core/utils/ui.dart'; @@ -499,6 +501,9 @@ class _DockerManagePageState extends State { case DockerMenuType.stop: _docker.stop(dItem.containerId); break; + case DockerMenuType.restart: + _docker.restart(dItem.containerId); + break; case DockerMenuType.logs: final logs = await _docker.logs(dItem.containerId); showRoundDialog( @@ -514,9 +519,14 @@ class _DockerManagePageState extends State { ], ); break; - case DockerMenuType.restart: - _docker.restart(dItem.containerId); - break; + case DockerMenuType.terminal: + AppRoute( + SSHPage( + spi: widget.spi, + initCmd: 'docker exec -it ${dItem.containerId} /bin/sh', + ), + 'Docker terminal', + ).go(context); } }, ); diff --git a/lib/view/page/ssh.dart b/lib/view/page/ssh.dart index 4512932e..84333648 100644 --- a/lib/view/page/ssh.dart +++ b/lib/view/page/ssh.dart @@ -25,7 +25,8 @@ import '../../locator.dart'; class SSHPage extends StatefulWidget { final ServerPrivateInfo spi; - const SSHPage({Key? key, required this.spi}) : super(key: key); + final String? initCmd; + const SSHPage({Key? key, required this.spi, this.initCmd}) : super(key: key); @override _SSHPageState createState() => _SSHPageState(); @@ -341,6 +342,11 @@ class _SSHPageState extends State { _listen(session.stdout); _listen(session.stderr); + if (widget.initCmd != null) { + _terminal.write(widget.initCmd!); + _terminal.keyInput(TerminalKey.enter); + } + await session.done; if (mounted) { context.pop(); diff --git a/macos/Runner.xcodeproj/project.pbxproj b/macos/Runner.xcodeproj/project.pbxproj index fffb623f..751acbe6 100644 --- a/macos/Runner.xcodeproj/project.pbxproj +++ b/macos/Runner.xcodeproj/project.pbxproj @@ -475,9 +475,9 @@ baseConfigurationReference = C1C758C41C4E208965A68933 /* Pods-RunnerTests.debug.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; - CURRENT_PROJECT_VERSION = 320; + CURRENT_PROJECT_VERSION = 321; GENERATE_INFOPLIST_FILE = YES; - MARKETING_VERSION = 1.0.320; + MARKETING_VERSION = 1.0.321; PRODUCT_BUNDLE_IDENTIFIER = tech.lolli.serverBox.RunnerTests; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_VERSION = 5.0; @@ -490,9 +490,9 @@ baseConfigurationReference = 15AF97DF993E8968098D6EBE /* Pods-RunnerTests.release.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; - CURRENT_PROJECT_VERSION = 320; + CURRENT_PROJECT_VERSION = 321; GENERATE_INFOPLIST_FILE = YES; - MARKETING_VERSION = 1.0.320; + MARKETING_VERSION = 1.0.321; PRODUCT_BUNDLE_IDENTIFIER = tech.lolli.serverBox.RunnerTests; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_VERSION = 5.0; @@ -505,9 +505,9 @@ baseConfigurationReference = 7CFA7DE7FABA75685DFB6948 /* Pods-RunnerTests.profile.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; - CURRENT_PROJECT_VERSION = 320; + CURRENT_PROJECT_VERSION = 321; GENERATE_INFOPLIST_FILE = YES; - MARKETING_VERSION = 1.0.320; + MARKETING_VERSION = 1.0.321; PRODUCT_BUNDLE_IDENTIFIER = tech.lolli.serverBox.RunnerTests; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_VERSION = 5.0;