new: snippet fmt

This commit is contained in:
lollipopkit
2024-01-21 17:42:43 +08:00
parent 07cc0a22e8
commit 7414dcc8da
28 changed files with 229 additions and 178 deletions

View File

@@ -1414,6 +1414,12 @@ abstract class S {
/// **'Success'** /// **'Success'**
String get 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. /// No description provided for @suspend.
/// ///
/// In en, this message translates to: /// In en, this message translates to:

View File

@@ -691,6 +691,9 @@ class SDe extends S {
@override @override
String get success => 'Erfolgreich'; String get success => 'Erfolgreich';
@override
String get supportFmtArgs => 'Die folgenden Formatierungsparameter werden unterstützt:';
@override @override
String get suspend => 'Suspend'; String get suspend => 'Suspend';

View File

@@ -691,6 +691,9 @@ class SEn extends S {
@override @override
String get success => 'Success'; String get success => 'Success';
@override
String get supportFmtArgs => 'The following formatting parameters are supported:';
@override @override
String get suspend => 'Suspend'; String get suspend => 'Suspend';

View File

@@ -691,6 +691,9 @@ class SFr extends S {
@override @override
String get success => 'Succès'; String get success => 'Succès';
@override
String get supportFmtArgs => 'Les paramètres de formatage suivants sont pris en charge:';
@override @override
String get suspend => 'Suspendre'; String get suspend => 'Suspendre';

View File

@@ -691,6 +691,9 @@ class SId extends S {
@override @override
String get success => 'Kesuksesan'; String get success => 'Kesuksesan';
@override
String get supportFmtArgs => 'Parameter pemformatan berikut ini didukung:';
@override @override
String get suspend => 'Suspend'; String get suspend => 'Suspend';

View File

@@ -691,6 +691,9 @@ class SZh extends S {
@override @override
String get success => '成功'; String get success => '成功';
@override
String get supportFmtArgs => '支持以下格式化参数:';
@override @override
String get suspend => '挂起'; String get suspend => '挂起';
@@ -1527,6 +1530,9 @@ class SZhTw extends SZh {
@override @override
String get success => '成功'; String get success => '成功';
@override
String get supportFmtArgs => '支援以下格式化參數:';
@override @override
String get suspend => '挂起'; String get suspend => '挂起';

View File

@@ -586,7 +586,7 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
CURRENT_PROJECT_VERSION = 709; CURRENT_PROJECT_VERSION = 712;
DEVELOPMENT_TEAM = BA88US33G6; DEVELOPMENT_TEAM = BA88US33G6;
ENABLE_BITCODE = NO; ENABLE_BITCODE = NO;
INFOPLIST_FILE = "Runner/Info-$(CONFIGURATION).plist"; INFOPLIST_FILE = "Runner/Info-$(CONFIGURATION).plist";
@@ -596,7 +596,7 @@
"$(inherited)", "$(inherited)",
"@executable_path/Frameworks", "@executable_path/Frameworks",
); );
MARKETING_VERSION = 1.0.709; MARKETING_VERSION = 1.0.712;
PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
@@ -720,7 +720,7 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
CURRENT_PROJECT_VERSION = 709; CURRENT_PROJECT_VERSION = 712;
DEVELOPMENT_TEAM = BA88US33G6; DEVELOPMENT_TEAM = BA88US33G6;
ENABLE_BITCODE = NO; ENABLE_BITCODE = NO;
INFOPLIST_FILE = "Runner/Info-$(CONFIGURATION).plist"; INFOPLIST_FILE = "Runner/Info-$(CONFIGURATION).plist";
@@ -730,7 +730,7 @@
"$(inherited)", "$(inherited)",
"@executable_path/Frameworks", "@executable_path/Frameworks",
); );
MARKETING_VERSION = 1.0.709; MARKETING_VERSION = 1.0.712;
PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
@@ -748,7 +748,7 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
CURRENT_PROJECT_VERSION = 709; CURRENT_PROJECT_VERSION = 712;
DEVELOPMENT_TEAM = BA88US33G6; DEVELOPMENT_TEAM = BA88US33G6;
ENABLE_BITCODE = NO; ENABLE_BITCODE = NO;
INFOPLIST_FILE = "Runner/Info-$(CONFIGURATION).plist"; INFOPLIST_FILE = "Runner/Info-$(CONFIGURATION).plist";
@@ -758,7 +758,7 @@
"$(inherited)", "$(inherited)",
"@executable_path/Frameworks", "@executable_path/Frameworks",
); );
MARKETING_VERSION = 1.0.709; MARKETING_VERSION = 1.0.712;
PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
@@ -779,7 +779,7 @@
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 709; CURRENT_PROJECT_VERSION = 712;
DEVELOPMENT_TEAM = BA88US33G6; DEVELOPMENT_TEAM = BA88US33G6;
GCC_C_LANGUAGE_STANDARD = gnu11; GCC_C_LANGUAGE_STANDARD = gnu11;
GENERATE_INFOPLIST_FILE = YES; GENERATE_INFOPLIST_FILE = YES;
@@ -792,7 +792,7 @@
"@executable_path/Frameworks", "@executable_path/Frameworks",
"@executable_path/../../Frameworks", "@executable_path/../../Frameworks",
); );
MARKETING_VERSION = 1.0.709; MARKETING_VERSION = 1.0.712;
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES; MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.StatusWidget; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.StatusWidget;
@@ -818,7 +818,7 @@
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 709; CURRENT_PROJECT_VERSION = 712;
DEVELOPMENT_TEAM = BA88US33G6; DEVELOPMENT_TEAM = BA88US33G6;
GCC_C_LANGUAGE_STANDARD = gnu11; GCC_C_LANGUAGE_STANDARD = gnu11;
GENERATE_INFOPLIST_FILE = YES; GENERATE_INFOPLIST_FILE = YES;
@@ -831,7 +831,7 @@
"@executable_path/Frameworks", "@executable_path/Frameworks",
"@executable_path/../../Frameworks", "@executable_path/../../Frameworks",
); );
MARKETING_VERSION = 1.0.709; MARKETING_VERSION = 1.0.712;
MTL_FAST_MATH = YES; MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.StatusWidget; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.StatusWidget;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
@@ -854,7 +854,7 @@
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 709; CURRENT_PROJECT_VERSION = 712;
DEVELOPMENT_TEAM = BA88US33G6; DEVELOPMENT_TEAM = BA88US33G6;
GCC_C_LANGUAGE_STANDARD = gnu11; GCC_C_LANGUAGE_STANDARD = gnu11;
GENERATE_INFOPLIST_FILE = YES; GENERATE_INFOPLIST_FILE = YES;
@@ -867,7 +867,7 @@
"@executable_path/Frameworks", "@executable_path/Frameworks",
"@executable_path/../../Frameworks", "@executable_path/../../Frameworks",
); );
MARKETING_VERSION = 1.0.709; MARKETING_VERSION = 1.0.712;
MTL_FAST_MATH = YES; MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.StatusWidget; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.StatusWidget;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
@@ -890,7 +890,7 @@
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 709; CURRENT_PROJECT_VERSION = 712;
DEVELOPMENT_ASSET_PATHS = ""; DEVELOPMENT_ASSET_PATHS = "";
DEVELOPMENT_TEAM = BA88US33G6; DEVELOPMENT_TEAM = BA88US33G6;
ENABLE_PREVIEWS = YES; ENABLE_PREVIEWS = YES;
@@ -902,7 +902,7 @@
"$(inherited)", "$(inherited)",
"@executable_path/Frameworks", "@executable_path/Frameworks",
); );
MARKETING_VERSION = 1.0.709; MARKETING_VERSION = 1.0.712;
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES; MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.WatchEnd; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.WatchEnd;
@@ -931,7 +931,7 @@
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 709; CURRENT_PROJECT_VERSION = 712;
DEVELOPMENT_ASSET_PATHS = ""; DEVELOPMENT_ASSET_PATHS = "";
DEVELOPMENT_TEAM = BA88US33G6; DEVELOPMENT_TEAM = BA88US33G6;
ENABLE_PREVIEWS = YES; ENABLE_PREVIEWS = YES;
@@ -943,7 +943,7 @@
"$(inherited)", "$(inherited)",
"@executable_path/Frameworks", "@executable_path/Frameworks",
); );
MARKETING_VERSION = 1.0.709; MARKETING_VERSION = 1.0.712;
MTL_FAST_MATH = YES; MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.WatchEnd; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.WatchEnd;
PRODUCT_NAME = ServerBox; PRODUCT_NAME = ServerBox;
@@ -969,7 +969,7 @@
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 709; CURRENT_PROJECT_VERSION = 712;
DEVELOPMENT_ASSET_PATHS = ""; DEVELOPMENT_ASSET_PATHS = "";
DEVELOPMENT_TEAM = BA88US33G6; DEVELOPMENT_TEAM = BA88US33G6;
ENABLE_PREVIEWS = YES; ENABLE_PREVIEWS = YES;
@@ -981,7 +981,7 @@
"$(inherited)", "$(inherited)",
"@executable_path/Frameworks", "@executable_path/Frameworks",
); );
MARKETING_VERSION = 1.0.709; MARKETING_VERSION = 1.0.712;
MTL_FAST_MATH = YES; MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.WatchEnd; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.WatchEnd;
PRODUCT_NAME = ServerBox; PRODUCT_NAME = ServerBox;

View File

@@ -46,7 +46,8 @@ enum ContainerErrType {
} }
class ContainerErr extends Err<ContainerErrType> { class ContainerErr extends Err<ContainerErrType> {
ContainerErr({required super.type, super.message}) : super(from: ErrFrom.docker); ContainerErr({required super.type, super.message})
: super(from: ErrFrom.docker);
@override @override
String toString() { String toString() {

View File

@@ -0,0 +1,18 @@
import 'package:flutter/material.dart';
abstract class PopMenu {
static PopupMenuItem<T> build<T>(T t, IconData icon, String text) {
return PopupMenuItem<T>(
value: t,
child: Row(
children: [
Icon(icon),
const SizedBox(
width: 10,
),
Text(text),
],
),
);
}
}

View File

@@ -1,49 +1,6 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:toolbox/core/extension/context/locale.dart'; import 'package:toolbox/core/extension/context/locale.dart';
import 'package:toolbox/data/model/app/menu/base.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;
}
}
}
enum ContainerMenu { enum ContainerMenu {
start, start,
@@ -108,20 +65,9 @@ enum ContainerMenu {
} }
} }
PopupMenuItem<ContainerMenu> get widget => _build(this, icon, toStr); PopupMenuItem<ContainerMenu> get widget => PopMenu.build(
} this,
icon,
PopupMenuItem<T> _build<T>(T t, IconData icon, String text) { toStr,
return PopupMenuItem<T>( );
value: t,
child: Row(
children: [
Icon(icon),
const SizedBox(
width: 10,
),
Text(text),
],
),
);
} }

View File

@@ -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,
};
}

View File

@@ -1,51 +1,54 @@
import 'dart:convert'; import 'dart:convert';
class Containerd { class Containerd {
final ContainerdClient client; final ContainerdClient client;
Containerd({ Containerd({
required this.client, 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<String, dynamic> json) => Containerd( factory Containerd.fromJson(Map<String, dynamic> json) => Containerd(
client: ContainerdClient.fromJson(json["Client"]), client: ContainerdClient.fromJson(json["Client"]),
); );
Map<String, dynamic> toJson() => { Map<String, dynamic> toJson() => {
"Client": client.toJson(), "Client": client.toJson(),
}; };
} }
class ContainerdClient { class ContainerdClient {
final String apiVersion; final String apiVersion;
final String version; final String version;
final String goVersion; final String goVersion;
final String gitCommit; final String gitCommit;
final String builtTime; final String builtTime;
final int built; final int built;
final String osArch; final String osArch;
final String os; final String os;
ContainerdClient({ ContainerdClient({
required this.apiVersion, required this.apiVersion,
required this.version, required this.version,
required this.goVersion, required this.goVersion,
required this.gitCommit, required this.gitCommit,
required this.builtTime, required this.builtTime,
required this.built, required this.built,
required this.osArch, required this.osArch,
required this.os, 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<String, dynamic> json) => ContainerdClient( factory ContainerdClient.fromJson(Map<String, dynamic> json) =>
ContainerdClient(
apiVersion: json["APIVersion"], apiVersion: json["APIVersion"],
version: json["Version"], version: json["Version"],
goVersion: json["GoVersion"], goVersion: json["GoVersion"],
@@ -54,9 +57,9 @@ class ContainerdClient {
built: json["Built"], built: json["Built"],
osArch: json["OsArch"], osArch: json["OsArch"],
os: json["Os"], os: json["Os"],
); );
Map<String, dynamic> toJson() => { Map<String, dynamic> toJson() => {
"APIVersion": apiVersion, "APIVersion": apiVersion,
"Version": version, "Version": version,
"GoVersion": goVersion, "GoVersion": goVersion,
@@ -65,5 +68,5 @@ class ContainerdClient {
"Built": built, "Built": built,
"OsArch": osArch, "OsArch": osArch,
"Os": os, "Os": os,
}; };
} }

View File

@@ -1,4 +1,5 @@
import 'package:hive_flutter/hive_flutter.dart'; import 'package:hive_flutter/hive_flutter.dart';
import 'package:toolbox/data/model/server/server_private_info.dart';
import '../app/tag_pickable.dart'; import '../app/tag_pickable.dart';
@@ -44,6 +45,30 @@ class Snippet implements TagPickable {
@override @override
String get tagName => name; 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 { class SnippetResult {

View File

@@ -393,15 +393,14 @@ class ServerProvider extends ChangeNotifier {
TryLimiter.reset(sid); TryLimiter.reset(sid);
} }
Future<SnippetResult?> runSnippets(String id, Snippet snippet) async { Future<SnippetResult?> runSnippet(String id, Snippet snippet) async {
final client = _servers[id]?.client; final server = _servers[id];
if (client == null) { if (server == null) return null;
return null;
}
final watch = Stopwatch()..start(); 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; final time = watch.elapsed;
watch.stop(); watch.stop();
if (result == null) return null;
return SnippetResult( return SnippetResult(
dest: _servers[id]?.spi.name, dest: _servers[id]?.spi.name,
result: result, result: result,
@@ -409,10 +408,10 @@ class ServerProvider extends ChangeNotifier {
); );
} }
Future<List<SnippetResult?>> runSnippetsMulti( // Future<List<SnippetResult?>> runSnippetsMulti(
List<String> ids, // List<String> ids,
Snippet snippet, // Snippet snippet,
) async { // ) async {
return await Future.wait(ids.map((id) async => runSnippets(id, snippet))); // return await Future.wait(ids.map((id) async => runSnippet(id, snippet)));
} // }
} }

View File

@@ -2,9 +2,9 @@
class BuildData { class BuildData {
static const String name = "ServerBox"; 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 engine = "3.16.7";
static const String buildAt = "2024-01-19 17:32:15"; static const String buildAt = "2024-01-21 15:41:48";
static const int modifications = 2; static const int modifications = 5;
static const int script = 34; static const int script = 35;
} }

View File

@@ -52,5 +52,6 @@ abstract final class GithubIds {
'luckyreny', 'luckyreny',
'aliuzzz', 'aliuzzz',
'58fly', '58fly',
'Potterli20',
}; };
} }

View File

@@ -219,6 +219,7 @@
"stats": "Statistik", "stats": "Statistik",
"stop": "Stop", "stop": "Stop",
"success": "Erfolgreich", "success": "Erfolgreich",
"supportFmtArgs": "Die folgenden Formatierungsparameter werden unterstützt:",
"suspend": "Suspend", "suspend": "Suspend",
"suspendTip": "Die Suspend-Funktion erfordert Root-Rechte und systemd-Unterstützung.", "suspendTip": "Die Suspend-Funktion erfordert Root-Rechte und systemd-Unterstützung.",
"switchTo": "Wechseln zu {val}", "switchTo": "Wechseln zu {val}",

View File

@@ -219,6 +219,7 @@
"stats": "Stats", "stats": "Stats",
"stop": "Stop", "stop": "Stop",
"success": "Success", "success": "Success",
"supportFmtArgs": "The following formatting parameters are supported:",
"suspend": "Suspend", "suspend": "Suspend",
"suspendTip": "The suspend function requires root privileges and systemd support.", "suspendTip": "The suspend function requires root privileges and systemd support.",
"switchTo": "Switch to {val}", "switchTo": "Switch to {val}",

View File

@@ -219,6 +219,7 @@
"stats": "Statistiques", "stats": "Statistiques",
"stop": "Arrêter", "stop": "Arrêter",
"success": "Succès", "success": "Succès",
"supportFmtArgs": "Les paramètres de formatage suivants sont pris en charge:",
"suspend": "Suspendre", "suspend": "Suspendre",
"suspendTip": "La fonction de suspension nécessite des privilèges root et la prise en charge de systemd.", "suspendTip": "La fonction de suspension nécessite des privilèges root et la prise en charge de systemd.",
"switchTo": "Passer à {val}", "switchTo": "Passer à {val}",

View File

@@ -219,6 +219,7 @@
"stats": "Statistik", "stats": "Statistik",
"stop": "Berhenti", "stop": "Berhenti",
"success": "Kesuksesan", "success": "Kesuksesan",
"supportFmtArgs": "Parameter pemformatan berikut ini didukung:",
"suspend": "Suspend", "suspend": "Suspend",
"suspendTip": "Fungsi penangguhan memerlukan hak akses root dan dukungan systemd.", "suspendTip": "Fungsi penangguhan memerlukan hak akses root dan dukungan systemd.",
"switchTo": "Beralih ke {val}", "switchTo": "Beralih ke {val}",

View File

@@ -219,6 +219,7 @@
"stats": "统计", "stats": "统计",
"stop": "停止", "stop": "停止",
"success": "成功", "success": "成功",
"supportFmtArgs": "支持以下格式化参数:",
"suspend": "挂起", "suspend": "挂起",
"suspendTip": "suspend 功能需要 root 权限及 systemd 支持。", "suspendTip": "suspend 功能需要 root 权限及 systemd 支持。",
"switchTo": "切换到 {val}", "switchTo": "切换到 {val}",

View File

@@ -219,6 +219,7 @@
"stats": "統計", "stats": "統計",
"stop": "停止", "stop": "停止",
"success": "成功", "success": "成功",
"supportFmtArgs": "支援以下格式化參數:",
"suspend": "挂起", "suspend": "挂起",
"suspendTip": "suspend 功能需要 root 權限及 systemd 支持。", "suspendTip": "suspend 功能需要 root 權限及 systemd 支持。",
"switchTo": "切換到 {val}", "switchTo": "切換到 {val}",

View File

@@ -206,7 +206,8 @@ class BackupPage extends StatelessWidget {
try { try {
context.showLoadingDialog(); 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) { if (backupFormatVersion != backup.version) {
context.showSnackBar(l10n.backupVersionNotMatch); context.showSnackBar(l10n.backupVersionNotMatch);
return; return;

View File

@@ -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/context/snackbar.dart';
import 'package:toolbox/core/extension/stringx.dart'; import 'package:toolbox/core/extension/stringx.dart';
import 'package:toolbox/core/route.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/image.dart';
import 'package:toolbox/data/model/container/type.dart'; import 'package:toolbox/data/model/container/type.dart';
import 'package:toolbox/data/res/store.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/container/ps.dart';
import '../../data/model/server/server_private_info.dart'; import '../../data/model/server/server_private_info.dart';
import '../../data/provider/container.dart'; import '../../data/provider/container.dart';
import '../../data/model/app/menu.dart';
import '../../data/res/ui.dart'; import '../../data/res/ui.dart';
import '../widget/appbar.dart'; import '../widget/appbar.dart';
import '../widget/popup_menu.dart'; import '../widget/popup_menu.dart';

View File

@@ -1,10 +1,13 @@
import 'package:after_layout/after_layout.dart'; import 'package:after_layout/after_layout.dart';
import 'package:flutter/material.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/common.dart';
import 'package:toolbox/core/extension/context/dialog.dart'; import 'package:toolbox/core/extension/context/dialog.dart';
import 'package:toolbox/core/extension/context/locale.dart'; import 'package:toolbox/core/extension/context/locale.dart';
import 'package:toolbox/core/extension/context/snackbar.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/data/res/provider.dart';
import 'package:toolbox/view/widget/cardx.dart';
import 'package:toolbox/view/widget/input_field.dart'; import 'package:toolbox/view/widget/input_field.dart';
import '../../../data/model/server/snippet.dart'; import '../../../data/model/server/snippet.dart';
@@ -147,10 +150,21 @@ class _SnippetEditPageState extends State<SnippetEditPage>
label: l10n.snippet, label: l10n.snippet,
icon: Icons.code, 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 @override
void afterFirstLayout(BuildContext context) { void afterFirstLayout(BuildContext context) {
if (widget.snippet != null) { if (widget.snippet != null) {

View File

@@ -1,12 +1,9 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:provider/provider.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/context/locale.dart';
import 'package:toolbox/core/extension/order.dart'; import 'package:toolbox/core/extension/order.dart';
import 'package:toolbox/data/res/provider.dart';
import 'package:toolbox/data/res/store.dart'; import 'package:toolbox/data/res/store.dart';
import '../../../data/model/server/server.dart';
import '../../../data/model/server/snippet.dart'; import '../../../data/model/server/snippet.dart';
import '../../../data/res/ui.dart'; import '../../../data/res/ui.dart';
import '../../widget/tag.dart'; import '../../widget/tag.dart';
@@ -115,28 +112,24 @@ class _SnippetListPageState extends State<SnippetListPage> {
AppRoute.snippetEdit(snippet: snippet).go(context), AppRoute.snippetEdit(snippet: snippet).go(context),
icon: const Icon(Icons.edit), icon: const Icon(Icons.edit),
), ),
IconButton(
onPressed: () => _runSnippet(snippet),
icon: const Icon(Icons.play_arrow),
),
], ],
), ),
), ),
); );
} }
Future<void> _runSnippet(Snippet snippet) async { // Future<void> _runSnippet(Snippet snippet) async {
final servers = await context.showPickDialog<Server>( // final servers = await context.showPickDialog<Server>(
items: Pros.server.servers.toList(), // items: Pros.server.servers.toList(),
name: (e) => e.spi.name, // name: (e) => e.spi.name,
); // );
if (servers == null) { // if (servers == null) {
return; // return;
} // }
final ids = servers.map((e) => e.spi.id).toList(); // final ids = servers.map((e) => e.spi.id).toList();
final results = await Pros.server.runSnippetsMulti(ids, snippet); // final results = await Pros.server.runSnippetsMulti(ids, snippet);
if (results.isNotEmpty) { // if (results.isNotEmpty) {
AppRoute.snippetResult(results: results).go(context); // AppRoute.snippetResult(results: results).go(context);
} // }
} // }
} }

View File

@@ -9,15 +9,16 @@ import 'package:toolbox/core/extension/ssh_client.dart';
import 'package:toolbox/core/extension/uint8list.dart'; import 'package:toolbox/core/extension/uint8list.dart';
import 'package:toolbox/core/utils/platform/base.dart'; import 'package:toolbox/core/utils/platform/base.dart';
import 'package:toolbox/core/utils/platform/path.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/app/shell_func.dart';
import 'package:toolbox/data/model/pkg/manager.dart'; import 'package:toolbox/data/model/pkg/manager.dart';
import 'package:toolbox/data/model/server/dist.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/path.dart';
import 'package:toolbox/data/res/provider.dart'; import 'package:toolbox/data/res/provider.dart';
import '../../core/route.dart'; import '../../core/route.dart';
import '../../core/utils/server.dart'; import '../../core/utils/server.dart';
import '../../data/model/app/menu.dart';
import '../../data/model/pkg/upgrade_info.dart'; import '../../data/model/pkg/upgrade_info.dart';
import '../../data/model/server/server_private_info.dart'; import '../../data/model/server/server_private_info.dart';
import 'popup_menu.dart'; import 'popup_menu.dart';
@@ -98,7 +99,7 @@ class ServerFuncBtns extends StatelessWidget {
(e) => IconButton( (e) => IconButton(
onPressed: () => _onTapMoreBtns(e, spi, context), onPressed: () => _onTapMoreBtns(e, spi, context),
padding: EdgeInsets.zero, padding: EdgeInsets.zero,
tooltip: e.name, tooltip: e.toStr,
icon: Icon(e.icon, size: iconSize ?? 15), icon: Icon(e.icon, size: iconSize ?? 15),
), ),
) )
@@ -122,29 +123,18 @@ void _onTapMoreBtns(
check: () => _checkClient(context, spi.id), check: () => _checkClient(context, spi.id),
); );
break; break;
// case ServerTabMenuType.snippet: case ServerTabMenu.snippet:
// final snippets = await context.showPickDialog<Snippet>( final snippet = await context.showPickSingleDialog<Snippet>(
// items: Pros.snippet.snippets, items: Pros.snippet.snippets,
// name: (e) => e.name, name: (e) => e.name,
// multi: false );
// ); if (snippet == null) return;
// if (snippets == null || snippets.isEmpty) {
// return; AppRoute.ssh(spi: spi, initCmd: snippet.fmtWith(spi)).checkGo(
// } context: context,
// final result = await Pros.server.runSnippets(spi.id, snippets.first); check: () => _checkClient(context, spi.id),
// if (result != null && result.isNotEmpty) { );
// context.showRoundDialog( break;
// title: Text(l10n.result),
// child: Text(result),
// actions: [
// TextButton(
// onPressed: () => copy2Clipboard(result),
// child: Text(l10n.copy),
// )
// ],
// );
// }
// break;
case ServerTabMenu.container: case ServerTabMenu.container:
AppRoute.docker(spi: spi).checkGo( AppRoute.docker(spi: spi).checkGo(
context: context, context: context,