diff --git a/.dart_tool/flutter_gen/gen_l10n/l10n.dart b/.dart_tool/flutter_gen/gen_l10n/l10n.dart index 80e1e0c5..253e0ff0 100644 --- a/.dart_tool/flutter_gen/gen_l10n/l10n.dart +++ b/.dart_tool/flutter_gen/gen_l10n/l10n.dart @@ -1414,6 +1414,12 @@ abstract class S { /// **'Success'** String get success; + /// No description provided for @supportFmtArgs. + /// + /// In en, this message translates to: + /// **'The following formatting parameters are supported:'** + String get supportFmtArgs; + /// No description provided for @suspend. /// /// 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 1632c3ed..72fa4715 100644 --- a/.dart_tool/flutter_gen/gen_l10n/l10n_de.dart +++ b/.dart_tool/flutter_gen/gen_l10n/l10n_de.dart @@ -691,6 +691,9 @@ class SDe extends S { @override String get success => 'Erfolgreich'; + @override + String get supportFmtArgs => 'Die folgenden Formatierungsparameter werden unterstützt:'; + @override String get suspend => 'Suspend'; diff --git a/.dart_tool/flutter_gen/gen_l10n/l10n_en.dart b/.dart_tool/flutter_gen/gen_l10n/l10n_en.dart index 7f081207..1e3bca24 100644 --- a/.dart_tool/flutter_gen/gen_l10n/l10n_en.dart +++ b/.dart_tool/flutter_gen/gen_l10n/l10n_en.dart @@ -691,6 +691,9 @@ class SEn extends S { @override String get success => 'Success'; + @override + String get supportFmtArgs => 'The following formatting parameters are supported:'; + @override String get suspend => 'Suspend'; diff --git a/.dart_tool/flutter_gen/gen_l10n/l10n_fr.dart b/.dart_tool/flutter_gen/gen_l10n/l10n_fr.dart index 6262752c..582c5353 100644 --- a/.dart_tool/flutter_gen/gen_l10n/l10n_fr.dart +++ b/.dart_tool/flutter_gen/gen_l10n/l10n_fr.dart @@ -691,6 +691,9 @@ class SFr extends S { @override String get success => 'Succès'; + @override + String get supportFmtArgs => 'Les paramètres de formatage suivants sont pris en charge:'; + @override String get suspend => 'Suspendre'; diff --git a/.dart_tool/flutter_gen/gen_l10n/l10n_id.dart b/.dart_tool/flutter_gen/gen_l10n/l10n_id.dart index b5315470..ad2d0b15 100644 --- a/.dart_tool/flutter_gen/gen_l10n/l10n_id.dart +++ b/.dart_tool/flutter_gen/gen_l10n/l10n_id.dart @@ -691,6 +691,9 @@ class SId extends S { @override String get success => 'Kesuksesan'; + @override + String get supportFmtArgs => 'Parameter pemformatan berikut ini didukung:'; + @override String get suspend => 'Suspend'; diff --git a/.dart_tool/flutter_gen/gen_l10n/l10n_zh.dart b/.dart_tool/flutter_gen/gen_l10n/l10n_zh.dart index 534229e8..bd6c86e5 100644 --- a/.dart_tool/flutter_gen/gen_l10n/l10n_zh.dart +++ b/.dart_tool/flutter_gen/gen_l10n/l10n_zh.dart @@ -691,6 +691,9 @@ class SZh extends S { @override String get success => '成功'; + @override + String get supportFmtArgs => '支持以下格式化参数:'; + @override String get suspend => '挂起'; @@ -1527,6 +1530,9 @@ class SZhTw extends SZh { @override String get success => '成功'; + @override + String get supportFmtArgs => '支援以下格式化參數:'; + @override String get suspend => '挂起'; diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index 71d16916..6ad6fe81 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -586,7 +586,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; - CURRENT_PROJECT_VERSION = 709; + CURRENT_PROJECT_VERSION = 712; DEVELOPMENT_TEAM = BA88US33G6; ENABLE_BITCODE = NO; INFOPLIST_FILE = "Runner/Info-$(CONFIGURATION).plist"; @@ -596,7 +596,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.0.709; + MARKETING_VERSION = 1.0.712; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; @@ -720,7 +720,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; - CURRENT_PROJECT_VERSION = 709; + CURRENT_PROJECT_VERSION = 712; DEVELOPMENT_TEAM = BA88US33G6; ENABLE_BITCODE = NO; INFOPLIST_FILE = "Runner/Info-$(CONFIGURATION).plist"; @@ -730,7 +730,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.0.709; + MARKETING_VERSION = 1.0.712; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; @@ -748,7 +748,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; - CURRENT_PROJECT_VERSION = 709; + CURRENT_PROJECT_VERSION = 712; DEVELOPMENT_TEAM = BA88US33G6; ENABLE_BITCODE = NO; INFOPLIST_FILE = "Runner/Info-$(CONFIGURATION).plist"; @@ -758,7 +758,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.0.709; + MARKETING_VERSION = 1.0.712; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; @@ -779,7 +779,7 @@ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 709; + CURRENT_PROJECT_VERSION = 712; DEVELOPMENT_TEAM = BA88US33G6; GCC_C_LANGUAGE_STANDARD = gnu11; GENERATE_INFOPLIST_FILE = YES; @@ -792,7 +792,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 1.0.709; + MARKETING_VERSION = 1.0.712; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.StatusWidget; @@ -818,7 +818,7 @@ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 709; + CURRENT_PROJECT_VERSION = 712; DEVELOPMENT_TEAM = BA88US33G6; GCC_C_LANGUAGE_STANDARD = gnu11; GENERATE_INFOPLIST_FILE = YES; @@ -831,7 +831,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 1.0.709; + MARKETING_VERSION = 1.0.712; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.StatusWidget; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -854,7 +854,7 @@ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 709; + CURRENT_PROJECT_VERSION = 712; DEVELOPMENT_TEAM = BA88US33G6; GCC_C_LANGUAGE_STANDARD = gnu11; GENERATE_INFOPLIST_FILE = YES; @@ -867,7 +867,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 1.0.709; + MARKETING_VERSION = 1.0.712; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.StatusWidget; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -890,7 +890,7 @@ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 709; + CURRENT_PROJECT_VERSION = 712; DEVELOPMENT_ASSET_PATHS = ""; DEVELOPMENT_TEAM = BA88US33G6; ENABLE_PREVIEWS = YES; @@ -902,7 +902,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.0.709; + MARKETING_VERSION = 1.0.712; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.WatchEnd; @@ -931,7 +931,7 @@ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 709; + CURRENT_PROJECT_VERSION = 712; DEVELOPMENT_ASSET_PATHS = ""; DEVELOPMENT_TEAM = BA88US33G6; ENABLE_PREVIEWS = YES; @@ -943,7 +943,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.0.709; + MARKETING_VERSION = 1.0.712; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.WatchEnd; PRODUCT_NAME = ServerBox; @@ -969,7 +969,7 @@ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 709; + CURRENT_PROJECT_VERSION = 712; DEVELOPMENT_ASSET_PATHS = ""; DEVELOPMENT_TEAM = BA88US33G6; ENABLE_PREVIEWS = YES; @@ -981,7 +981,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.0.709; + MARKETING_VERSION = 1.0.712; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.WatchEnd; PRODUCT_NAME = ServerBox; diff --git a/lib/data/model/app/error.dart b/lib/data/model/app/error.dart index a0e7ad94..842acee3 100644 --- a/lib/data/model/app/error.dart +++ b/lib/data/model/app/error.dart @@ -46,7 +46,8 @@ enum ContainerErrType { } class ContainerErr extends Err { - ContainerErr({required super.type, super.message}) : super(from: ErrFrom.docker); + ContainerErr({required super.type, super.message}) + : super(from: ErrFrom.docker); @override String toString() { diff --git a/lib/data/model/app/menu/base.dart b/lib/data/model/app/menu/base.dart new file mode 100644 index 00000000..8fb116a1 --- /dev/null +++ b/lib/data/model/app/menu/base.dart @@ -0,0 +1,18 @@ +import 'package:flutter/material.dart'; + +abstract class PopMenu { + static PopupMenuItem build(T t, IconData icon, String text) { + return PopupMenuItem( + value: t, + child: Row( + children: [ + Icon(icon), + const SizedBox( + width: 10, + ), + Text(text), + ], + ), + ); + } +} diff --git a/lib/data/model/app/menu.dart b/lib/data/model/app/menu/container.dart similarity index 51% rename from lib/data/model/app/menu.dart rename to lib/data/model/app/menu/container.dart index ccf104f9..59b551ee 100644 --- a/lib/data/model/app/menu.dart +++ b/lib/data/model/app/menu/container.dart @@ -1,49 +1,6 @@ import 'package:flutter/material.dart'; import 'package:toolbox/core/extension/context/locale.dart'; - -enum ServerTabMenu { - terminal, - sftp, - container, - process, - pkg, - //snippet, - ; - - IconData get icon { - switch (this) { - case ServerTabMenu.sftp: - return Icons.insert_drive_file; - //case ServerTabMenuType.snippet: - //return Icons.code; - case ServerTabMenu.pkg: - return Icons.system_security_update; - case ServerTabMenu.container: - return Icons.view_agenda; - case ServerTabMenu.process: - return Icons.list_alt_outlined; - case ServerTabMenu.terminal: - return Icons.terminal; - } - } - - String get toStr { - switch (this) { - case ServerTabMenu.sftp: - return 'SFTP'; - //case ServerTabMenuType.snippet: - //return l10n.snippet; - case ServerTabMenu.pkg: - return l10n.pkg; - case ServerTabMenu.container: - return l10n.container; - case ServerTabMenu.process: - return l10n.process; - case ServerTabMenu.terminal: - return l10n.terminal; - } - } -} +import 'package:toolbox/data/model/app/menu/base.dart'; enum ContainerMenu { start, @@ -108,20 +65,9 @@ enum ContainerMenu { } } - PopupMenuItem get widget => _build(this, icon, toStr); -} - -PopupMenuItem _build(T t, IconData icon, String text) { - return PopupMenuItem( - value: t, - child: Row( - children: [ - Icon(icon), - const SizedBox( - width: 10, - ), - Text(text), - ], - ), - ); + PopupMenuItem get widget => PopMenu.build( + this, + icon, + toStr, + ); } diff --git a/lib/data/model/app/menu/server_func.dart b/lib/data/model/app/menu/server_func.dart new file mode 100644 index 00000000..9768ac42 --- /dev/null +++ b/lib/data/model/app/menu/server_func.dart @@ -0,0 +1,30 @@ +import 'package:flutter/material.dart'; +import 'package:toolbox/core/extension/context/locale.dart'; + +enum ServerTabMenu { + terminal, + sftp, + container, + process, + pkg, + snippet, + ; + + IconData get icon => switch (this) { + ServerTabMenu.sftp => Icons.insert_drive_file, + ServerTabMenu.snippet => Icons.code, + ServerTabMenu.pkg => Icons.system_security_update, + ServerTabMenu.container => Icons.view_agenda, + ServerTabMenu.process => Icons.list_alt_outlined, + ServerTabMenu.terminal => Icons.terminal, + }; + + String get toStr => switch (this) { + ServerTabMenu.sftp => 'SFTP', + ServerTabMenu.snippet => l10n.snippet, + ServerTabMenu.pkg => l10n.pkg, + ServerTabMenu.container => l10n.container, + ServerTabMenu.process => l10n.process, + ServerTabMenu.terminal => l10n.terminal, + }; +} \ No newline at end of file diff --git a/lib/data/model/container/type.dart b/lib/data/model/container/type.dart index e1c671ae..ed742c1a 100644 --- a/lib/data/model/container/type.dart +++ b/lib/data/model/container/type.dart @@ -15,4 +15,4 @@ enum ContainerType { ContainerType.docker => DockerImg.fromRawJson, ContainerType.podman => PodmanImg.fromRawJson, }; -} \ No newline at end of file +} diff --git a/lib/data/model/container/version.dart b/lib/data/model/container/version.dart index 8eee2aaf..5407e343 100644 --- a/lib/data/model/container/version.dart +++ b/lib/data/model/container/version.dart @@ -1,51 +1,54 @@ import 'dart:convert'; class Containerd { - final ContainerdClient client; + final ContainerdClient client; - Containerd({ - required this.client, - }); + Containerd({ + required this.client, + }); - factory Containerd.fromRawJson(String str) => Containerd.fromJson(json.decode(str)); + factory Containerd.fromRawJson(String str) => + Containerd.fromJson(json.decode(str)); - String toRawJson() => json.encode(toJson()); + String toRawJson() => json.encode(toJson()); - factory Containerd.fromJson(Map json) => Containerd( + factory Containerd.fromJson(Map json) => Containerd( client: ContainerdClient.fromJson(json["Client"]), - ); + ); - Map toJson() => { + Map toJson() => { "Client": client.toJson(), - }; + }; } class ContainerdClient { - final String apiVersion; - final String version; - final String goVersion; - final String gitCommit; - final String builtTime; - final int built; - final String osArch; - final String os; + final String apiVersion; + final String version; + final String goVersion; + final String gitCommit; + final String builtTime; + final int built; + final String osArch; + final String os; - ContainerdClient({ - required this.apiVersion, - required this.version, - required this.goVersion, - required this.gitCommit, - required this.builtTime, - required this.built, - required this.osArch, - required this.os, - }); + ContainerdClient({ + required this.apiVersion, + required this.version, + required this.goVersion, + required this.gitCommit, + required this.builtTime, + required this.built, + required this.osArch, + required this.os, + }); - factory ContainerdClient.fromRawJson(String str) => ContainerdClient.fromJson(json.decode(str)); + factory ContainerdClient.fromRawJson(String str) => + ContainerdClient.fromJson(json.decode(str)); - String toRawJson() => json.encode(toJson()); + String toRawJson() => json.encode(toJson()); - factory ContainerdClient.fromJson(Map json) => ContainerdClient( + factory ContainerdClient.fromJson(Map json) => + ContainerdClient( apiVersion: json["APIVersion"], version: json["Version"], goVersion: json["GoVersion"], @@ -54,9 +57,9 @@ class ContainerdClient { built: json["Built"], osArch: json["OsArch"], os: json["Os"], - ); + ); - Map toJson() => { + Map toJson() => { "APIVersion": apiVersion, "Version": version, "GoVersion": goVersion, @@ -65,5 +68,5 @@ class ContainerdClient { "Built": built, "OsArch": osArch, "Os": os, - }; + }; } diff --git a/lib/data/model/server/snippet.dart b/lib/data/model/server/snippet.dart index f56a44a8..4673d9f6 100644 --- a/lib/data/model/server/snippet.dart +++ b/lib/data/model/server/snippet.dart @@ -1,4 +1,5 @@ import 'package:hive_flutter/hive_flutter.dart'; +import 'package:toolbox/data/model/server/server_private_info.dart'; import '../app/tag_pickable.dart'; @@ -44,6 +45,30 @@ class Snippet implements TagPickable { @override String get tagName => name; + + String fmtWith(ServerPrivateInfo spi) { + final fmted = script.replaceAllMapped( + RegExp(r'\${.+?}'), + (match) { + final key = match.group(0); + final func = fmtArgs[key]; + if (func == null) { + return key!; + } + return func(spi); + }, + ); + return fmted; + } + + static final fmtArgs = { + r'${host}': (ServerPrivateInfo spi) => spi.ip, + r'${port}': (ServerPrivateInfo spi) => spi.port.toString(), + r'${user}': (ServerPrivateInfo spi) => spi.user, + r'${pwd}': (ServerPrivateInfo spi) => spi.pwd ?? '', + r'${id}': (ServerPrivateInfo spi) => spi.id, + r'${name}': (ServerPrivateInfo spi) => spi.name, + }; } class SnippetResult { diff --git a/lib/data/provider/server.dart b/lib/data/provider/server.dart index 4df1c39c..395b0bab 100644 --- a/lib/data/provider/server.dart +++ b/lib/data/provider/server.dart @@ -393,15 +393,14 @@ class ServerProvider extends ChangeNotifier { TryLimiter.reset(sid); } - Future runSnippets(String id, Snippet snippet) async { - final client = _servers[id]?.client; - if (client == null) { - return null; - } + Future runSnippet(String id, Snippet snippet) async { + final server = _servers[id]; + if (server == null) return null; final watch = Stopwatch()..start(); - final result = await client.run(snippet.script).string; + final result = await server.client?.run(snippet.fmtWith(server.spi)).string; final time = watch.elapsed; watch.stop(); + if (result == null) return null; return SnippetResult( dest: _servers[id]?.spi.name, result: result, @@ -409,10 +408,10 @@ class ServerProvider extends ChangeNotifier { ); } - Future> runSnippetsMulti( - List ids, - Snippet snippet, - ) async { - return await Future.wait(ids.map((id) async => runSnippets(id, snippet))); - } + // Future> runSnippetsMulti( + // List ids, + // Snippet snippet, + // ) async { + // return await Future.wait(ids.map((id) async => runSnippet(id, snippet))); + // } } diff --git a/lib/data/res/build_data.dart b/lib/data/res/build_data.dart index 0638fd86..181a2338 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 = 709; + static const int build = 712; static const String engine = "3.16.7"; - static const String buildAt = "2024-01-19 17:32:15"; - static const int modifications = 2; - static const int script = 34; + static const String buildAt = "2024-01-21 15:41:48"; + static const int modifications = 5; + static const int script = 35; } diff --git a/lib/data/res/github_id.dart b/lib/data/res/github_id.dart index 91bd6e80..4263610e 100644 --- a/lib/data/res/github_id.dart +++ b/lib/data/res/github_id.dart @@ -52,5 +52,6 @@ abstract final class GithubIds { 'luckyreny', 'aliuzzz', '58fly', + 'Potterli20', }; } diff --git a/lib/l10n/app_de.arb b/lib/l10n/app_de.arb index 4b4ea916..52cb3617 100644 --- a/lib/l10n/app_de.arb +++ b/lib/l10n/app_de.arb @@ -219,6 +219,7 @@ "stats": "Statistik", "stop": "Stop", "success": "Erfolgreich", + "supportFmtArgs": "Die folgenden Formatierungsparameter werden unterstützt:", "suspend": "Suspend", "suspendTip": "Die Suspend-Funktion erfordert Root-Rechte und systemd-Unterstützung.", "switchTo": "Wechseln zu {val}", diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index 3cce4393..2aef53cf 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -219,6 +219,7 @@ "stats": "Stats", "stop": "Stop", "success": "Success", + "supportFmtArgs": "The following formatting parameters are supported:", "suspend": "Suspend", "suspendTip": "The suspend function requires root privileges and systemd support.", "switchTo": "Switch to {val}", diff --git a/lib/l10n/app_fr.arb b/lib/l10n/app_fr.arb index 6d086ac6..f84b7abb 100644 --- a/lib/l10n/app_fr.arb +++ b/lib/l10n/app_fr.arb @@ -219,6 +219,7 @@ "stats": "Statistiques", "stop": "Arrêter", "success": "Succès", + "supportFmtArgs": "Les paramètres de formatage suivants sont pris en charge:", "suspend": "Suspendre", "suspendTip": "La fonction de suspension nécessite des privilèges root et la prise en charge de systemd.", "switchTo": "Passer à {val}", diff --git a/lib/l10n/app_id.arb b/lib/l10n/app_id.arb index b3903580..6fab183b 100644 --- a/lib/l10n/app_id.arb +++ b/lib/l10n/app_id.arb @@ -219,6 +219,7 @@ "stats": "Statistik", "stop": "Berhenti", "success": "Kesuksesan", + "supportFmtArgs": "Parameter pemformatan berikut ini didukung:", "suspend": "Suspend", "suspendTip": "Fungsi penangguhan memerlukan hak akses root dan dukungan systemd.", "switchTo": "Beralih ke {val}", diff --git a/lib/l10n/app_zh.arb b/lib/l10n/app_zh.arb index 70da75d1..804672b2 100644 --- a/lib/l10n/app_zh.arb +++ b/lib/l10n/app_zh.arb @@ -219,6 +219,7 @@ "stats": "统计", "stop": "停止", "success": "成功", + "supportFmtArgs": "支持以下格式化参数:", "suspend": "挂起", "suspendTip": "suspend 功能需要 root 权限及 systemd 支持。", "switchTo": "切换到 {val}", diff --git a/lib/l10n/app_zh_tw.arb b/lib/l10n/app_zh_tw.arb index 16dbd23b..ae68a933 100644 --- a/lib/l10n/app_zh_tw.arb +++ b/lib/l10n/app_zh_tw.arb @@ -219,6 +219,7 @@ "stats": "統計", "stop": "停止", "success": "成功", + "supportFmtArgs": "支援以下格式化參數:", "suspend": "挂起", "suspendTip": "suspend 功能需要 root 權限及 systemd 支持。", "switchTo": "切換到 {val}", diff --git a/lib/view/page/backup.dart b/lib/view/page/backup.dart index a2c65687..e9f989a7 100644 --- a/lib/view/page/backup.dart +++ b/lib/view/page/backup.dart @@ -206,7 +206,8 @@ class BackupPage extends StatelessWidget { try { context.showLoadingDialog(); - final backup = await Computer.shared.start(Backup.fromJsonString, text.trim()); + final backup = + await Computer.shared.start(Backup.fromJsonString, text.trim()); if (backupFormatVersion != backup.version) { context.showSnackBar(l10n.backupVersionNotMatch); return; diff --git a/lib/view/page/container.dart b/lib/view/page/container.dart index 75e3940f..3e4d10db 100644 --- a/lib/view/page/container.dart +++ b/lib/view/page/container.dart @@ -6,6 +6,7 @@ import 'package:toolbox/core/extension/context/locale.dart'; import 'package:toolbox/core/extension/context/snackbar.dart'; import 'package:toolbox/core/extension/stringx.dart'; import 'package:toolbox/core/route.dart'; +import 'package:toolbox/data/model/app/menu/container.dart'; import 'package:toolbox/data/model/container/image.dart'; import 'package:toolbox/data/model/container/type.dart'; import 'package:toolbox/data/res/store.dart'; @@ -15,7 +16,6 @@ import 'package:toolbox/view/widget/input_field.dart'; import '../../data/model/container/ps.dart'; import '../../data/model/server/server_private_info.dart'; import '../../data/provider/container.dart'; -import '../../data/model/app/menu.dart'; import '../../data/res/ui.dart'; import '../widget/appbar.dart'; import '../widget/popup_menu.dart'; diff --git a/lib/view/page/snippet/edit.dart b/lib/view/page/snippet/edit.dart index 898ffe33..11c9be11 100644 --- a/lib/view/page/snippet/edit.dart +++ b/lib/view/page/snippet/edit.dart @@ -1,10 +1,13 @@ import 'package:after_layout/after_layout.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_markdown/flutter_markdown.dart'; import 'package:toolbox/core/extension/context/common.dart'; import 'package:toolbox/core/extension/context/dialog.dart'; import 'package:toolbox/core/extension/context/locale.dart'; import 'package:toolbox/core/extension/context/snackbar.dart'; +import 'package:toolbox/core/extension/widget.dart'; import 'package:toolbox/data/res/provider.dart'; +import 'package:toolbox/view/widget/cardx.dart'; import 'package:toolbox/view/widget/input_field.dart'; import '../../../data/model/server/snippet.dart'; @@ -147,10 +150,21 @@ class _SnippetEditPageState extends State label: l10n.snippet, icon: Icons.code, ), + _buildTip(), ], ); } + Widget _buildTip() { + return CardX( + child: MarkdownBody(data: ''' +📌 ${l10n.supportFmtArgs} + +${Snippet.fmtArgs.keys.map((e) => '`$e`').join(', ')} +''').padding(const EdgeInsets.all(13)), + ); + } + @override void afterFirstLayout(BuildContext context) { if (widget.snippet != null) { diff --git a/lib/view/page/snippet/list.dart b/lib/view/page/snippet/list.dart index 7c59a0f7..651a5adf 100644 --- a/lib/view/page/snippet/list.dart +++ b/lib/view/page/snippet/list.dart @@ -1,12 +1,9 @@ import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; -import 'package:toolbox/core/extension/context/dialog.dart'; import 'package:toolbox/core/extension/context/locale.dart'; import 'package:toolbox/core/extension/order.dart'; -import 'package:toolbox/data/res/provider.dart'; import 'package:toolbox/data/res/store.dart'; -import '../../../data/model/server/server.dart'; import '../../../data/model/server/snippet.dart'; import '../../../data/res/ui.dart'; import '../../widget/tag.dart'; @@ -115,28 +112,24 @@ class _SnippetListPageState extends State { AppRoute.snippetEdit(snippet: snippet).go(context), icon: const Icon(Icons.edit), ), - IconButton( - onPressed: () => _runSnippet(snippet), - icon: const Icon(Icons.play_arrow), - ), ], ), ), ); } - Future _runSnippet(Snippet snippet) async { - final servers = await context.showPickDialog( - items: Pros.server.servers.toList(), - name: (e) => e.spi.name, - ); - if (servers == null) { - return; - } - final ids = servers.map((e) => e.spi.id).toList(); - final results = await Pros.server.runSnippetsMulti(ids, snippet); - if (results.isNotEmpty) { - AppRoute.snippetResult(results: results).go(context); - } - } + // Future _runSnippet(Snippet snippet) async { + // final servers = await context.showPickDialog( + // items: Pros.server.servers.toList(), + // name: (e) => e.spi.name, + // ); + // if (servers == null) { + // return; + // } + // final ids = servers.map((e) => e.spi.id).toList(); + // final results = await Pros.server.runSnippetsMulti(ids, snippet); + // if (results.isNotEmpty) { + // AppRoute.snippetResult(results: results).go(context); + // } + // } } diff --git a/lib/view/widget/server_func_btns.dart b/lib/view/widget/server_func_btns.dart index d5487be9..1539955c 100644 --- a/lib/view/widget/server_func_btns.dart +++ b/lib/view/widget/server_func_btns.dart @@ -9,15 +9,16 @@ import 'package:toolbox/core/extension/ssh_client.dart'; import 'package:toolbox/core/extension/uint8list.dart'; import 'package:toolbox/core/utils/platform/base.dart'; import 'package:toolbox/core/utils/platform/path.dart'; +import 'package:toolbox/data/model/app/menu/server_func.dart'; import 'package:toolbox/data/model/app/shell_func.dart'; import 'package:toolbox/data/model/pkg/manager.dart'; import 'package:toolbox/data/model/server/dist.dart'; +import 'package:toolbox/data/model/server/snippet.dart'; import 'package:toolbox/data/res/path.dart'; import 'package:toolbox/data/res/provider.dart'; import '../../core/route.dart'; import '../../core/utils/server.dart'; -import '../../data/model/app/menu.dart'; import '../../data/model/pkg/upgrade_info.dart'; import '../../data/model/server/server_private_info.dart'; import 'popup_menu.dart'; @@ -98,7 +99,7 @@ class ServerFuncBtns extends StatelessWidget { (e) => IconButton( onPressed: () => _onTapMoreBtns(e, spi, context), padding: EdgeInsets.zero, - tooltip: e.name, + tooltip: e.toStr, icon: Icon(e.icon, size: iconSize ?? 15), ), ) @@ -122,29 +123,18 @@ void _onTapMoreBtns( check: () => _checkClient(context, spi.id), ); break; - // case ServerTabMenuType.snippet: - // final snippets = await context.showPickDialog( - // items: Pros.snippet.snippets, - // name: (e) => e.name, - // multi: false - // ); - // if (snippets == null || snippets.isEmpty) { - // return; - // } - // final result = await Pros.server.runSnippets(spi.id, snippets.first); - // if (result != null && result.isNotEmpty) { - // context.showRoundDialog( - // title: Text(l10n.result), - // child: Text(result), - // actions: [ - // TextButton( - // onPressed: () => copy2Clipboard(result), - // child: Text(l10n.copy), - // ) - // ], - // ); - // } - // break; + case ServerTabMenu.snippet: + final snippet = await context.showPickSingleDialog( + items: Pros.snippet.snippets, + name: (e) => e.name, + ); + if (snippet == null) return; + + AppRoute.ssh(spi: spi, initCmd: snippet.fmtWith(spi)).checkGo( + context: context, + check: () => _checkClient(context, spi.id), + ); + break; case ServerTabMenu.container: AppRoute.docker(spi: spi).checkGo( context: context,