opt.: popupmenu

This commit is contained in:
lollipopkit
2023-05-09 22:04:45 +08:00
parent b4f3fce64a
commit c1d1af8c01
15 changed files with 145 additions and 211 deletions

View File

@@ -147,12 +147,6 @@ abstract class S {
/// **'Auto'** /// **'Auto'**
String get auto; String get auto;
/// No description provided for @backDir.
///
/// In en, this message translates to:
/// **'Back'**
String get backDir;
/// No description provided for @backup. /// No description provided for @backup.
/// ///
/// In en, this message translates to: /// In en, this message translates to:
@@ -201,12 +195,6 @@ abstract class S {
/// **'Choose'** /// **'Choose'**
String get choose; String get choose;
/// No description provided for @chooseDestination.
///
/// In en, this message translates to:
/// **'Choose destination'**
String get chooseDestination;
/// No description provided for @chooseFontFile. /// No description provided for @chooseFontFile.
/// ///
/// In en, this message translates to: /// In en, this message translates to:
@@ -243,6 +231,12 @@ abstract class S {
/// **'Command'** /// **'Command'**
String get cmd; String get cmd;
/// No description provided for @containerName.
///
/// In en, this message translates to:
/// **'Container name'**
String get containerName;
/// No description provided for @containerStatus. /// No description provided for @containerStatus.
/// ///
/// In en, this message translates to: /// In en, this message translates to:
@@ -279,12 +273,6 @@ abstract class S {
/// **'Create folder'** /// **'Create folder'**
String get createFolder; String get createFolder;
/// No description provided for @currentMode.
///
/// In en, this message translates to:
/// **'Current Mode'**
String get currentMode;
/// No description provided for @dark. /// No description provided for @dark.
/// ///
/// In en, this message translates to: /// In en, this message translates to:
@@ -318,15 +306,9 @@ abstract class S {
/// No description provided for @dl2Local. /// No description provided for @dl2Local.
/// ///
/// In en, this message translates to: /// In en, this message translates to:
/// **'Download [{fileName}] to local?'** /// **'Download {fileName} to local?'**
String dl2Local(Object fileName); String dl2Local(Object fileName);
/// No description provided for @dockerContainerName.
///
/// In en, this message translates to:
/// **'Container name'**
String get dockerContainerName;
/// No description provided for @dockerEditHost. /// No description provided for @dockerEditHost.
/// ///
/// In en, this message translates to: /// In en, this message translates to:
@@ -339,12 +321,6 @@ abstract class S {
/// **'No running container. \nIt may be that the env DOCKER_HOST is not read correctly. You can found it by running `echo \$DOCKER_HOST` in terminal.'** /// **'No running container. \nIt may be that the env DOCKER_HOST is not read correctly. You can found it by running `echo \$DOCKER_HOST` in terminal.'**
String get dockerEmptyRunningItems; String get dockerEmptyRunningItems;
/// No description provided for @dockerImage.
///
/// In en, this message translates to:
/// **'Image'**
String get dockerImage;
/// No description provided for @dockerImagesFmt. /// No description provided for @dockerImagesFmt.
/// ///
/// In en, this message translates to: /// In en, this message translates to:
@@ -489,12 +465,6 @@ abstract class S {
/// **'Getting token...'** /// **'Getting token...'**
String get gettingToken; String get gettingToken;
/// No description provided for @go.
///
/// In en, this message translates to:
/// **'Go'**
String get go;
/// No description provided for @goto. /// No description provided for @goto.
/// ///
/// In en, this message translates to: /// In en, this message translates to:
@@ -513,6 +483,12 @@ abstract class S {
/// **'request failed, status code: {code}'** /// **'request failed, status code: {code}'**
String httpFailedWithCode(Object code); String httpFailedWithCode(Object code);
/// No description provided for @image.
///
/// In en, this message translates to:
/// **'Image'**
String get image;
/// No description provided for @imagesList. /// No description provided for @imagesList.
/// ///
/// In en, this message translates to: /// In en, this message translates to:
@@ -582,7 +558,7 @@ abstract class S {
/// No description provided for @lastTry. /// No description provided for @lastTry.
/// ///
/// In en, this message translates to: /// In en, this message translates to:
/// **'Last try!'** /// **'Last try'**
String get lastTry; String get lastTry;
/// No description provided for @launchPage. /// No description provided for @launchPage.
@@ -735,12 +711,6 @@ abstract class S {
/// **'On server detail page'** /// **'On server detail page'**
String get onServerDetailPage; String get onServerDetailPage;
/// No description provided for @onlyIOS.
///
/// In en, this message translates to:
/// **'Only valid on iOS'**
String get onlyIOS;
/// No description provided for @open. /// No description provided for @open.
/// ///
/// In en, this message translates to: /// In en, this message translates to:
@@ -765,12 +735,6 @@ abstract class S {
/// **'Pick file'** /// **'Pick file'**
String get pickFile; String get pickFile;
/// No description provided for @ping.
///
/// In en, this message translates to:
/// **'Ping'**
String get ping;
/// No description provided for @pingAvg. /// No description provided for @pingAvg.
/// ///
/// In en, this message translates to: /// In en, this message translates to:
@@ -780,7 +744,7 @@ abstract class S {
/// No description provided for @pingInputIP. /// No description provided for @pingInputIP.
/// ///
/// In en, this message translates to: /// In en, this message translates to:
/// **'Please input a target IP/domain.'** /// **'Please input a target IP / domain.'**
String get pingInputIP; String get pingInputIP;
/// No description provided for @pingNoServer. /// No description provided for @pingNoServer.

View File

@@ -31,9 +31,6 @@ class SEn extends S {
@override @override
String get auto => 'Auto'; String get auto => 'Auto';
@override
String get backDir => 'Back';
@override @override
String get backup => 'Backup'; String get backup => 'Backup';
@@ -58,9 +55,6 @@ class SEn extends S {
@override @override
String get choose => 'Choose'; String get choose => 'Choose';
@override
String get chooseDestination => 'Choose destination';
@override @override
String get chooseFontFile => 'Choose a font file'; String get chooseFontFile => 'Choose a font file';
@@ -79,6 +73,9 @@ class SEn extends S {
@override @override
String get cmd => 'Command'; String get cmd => 'Command';
@override
String get containerName => 'Container name';
@override @override
String get containerStatus => 'Container status'; String get containerStatus => 'Container status';
@@ -97,9 +94,6 @@ class SEn extends S {
@override @override
String get createFolder => 'Create folder'; String get createFolder => 'Create folder';
@override
String get currentMode => 'Current Mode';
@override @override
String get dark => 'Dark'; String get dark => 'Dark';
@@ -117,21 +111,15 @@ class SEn extends S {
@override @override
String dl2Local(Object fileName) { String dl2Local(Object fileName) {
return 'Download [$fileName] to local?'; return 'Download $fileName to local?';
} }
@override
String get dockerContainerName => 'Container name';
@override @override
String get dockerEditHost => 'Edit DOCKER_HOST'; String get dockerEditHost => 'Edit DOCKER_HOST';
@override @override
String get dockerEmptyRunningItems => 'No running container. \nIt may be that the env DOCKER_HOST is not read correctly. You can found it by running `echo \$DOCKER_HOST` in terminal.'; String get dockerEmptyRunningItems => 'No running container. \nIt may be that the env DOCKER_HOST is not read correctly. You can found it by running `echo \$DOCKER_HOST` in terminal.';
@override
String get dockerImage => 'Image';
@override @override
String dockerImagesFmt(Object count) { String dockerImagesFmt(Object count) {
return '$count images'; return '$count images';
@@ -218,9 +206,6 @@ class SEn extends S {
@override @override
String get gettingToken => 'Getting token...'; String get gettingToken => 'Getting token...';
@override
String get go => 'Go';
@override @override
String get goto => 'Go to'; String get goto => 'Go to';
@@ -232,6 +217,9 @@ class SEn extends S {
return 'request failed, status code: $code'; return 'request failed, status code: $code';
} }
@override
String get image => 'Image';
@override @override
String get imagesList => 'Images list'; String get imagesList => 'Images list';
@@ -268,7 +256,7 @@ class SEn extends S {
String get keyAuth => 'Key Auth'; String get keyAuth => 'Key Auth';
@override @override
String get lastTry => 'Last try!'; String get lastTry => 'Last try';
@override @override
String get launchPage => 'Launch page'; String get launchPage => 'Launch page';
@@ -347,9 +335,6 @@ class SEn extends S {
@override @override
String get onServerDetailPage => 'On server detail page'; String get onServerDetailPage => 'On server detail page';
@override
String get onlyIOS => 'Only valid on iOS';
@override @override
String get open => 'Open'; String get open => 'Open';
@@ -362,14 +347,11 @@ class SEn extends S {
@override @override
String get pickFile => 'Pick file'; String get pickFile => 'Pick file';
@override
String get ping => 'Ping';
@override @override
String get pingAvg => 'Avg:'; String get pingAvg => 'Avg:';
@override @override
String get pingInputIP => 'Please input a target IP/domain.'; String get pingInputIP => 'Please input a target IP / domain.';
@override @override
String get pingNoServer => 'No server to ping.\nPlease add a server in server tab.'; String get pingNoServer => 'No server to ping.\nPlease add a server in server tab.';

View File

@@ -31,9 +31,6 @@ class SZh extends S {
@override @override
String get auto => '自动'; String get auto => '自动';
@override
String get backDir => '返回上一级';
@override @override
String get backup => '备份'; String get backup => '备份';
@@ -58,9 +55,6 @@ class SZh extends S {
@override @override
String get choose => '选择'; String get choose => '选择';
@override
String get chooseDestination => '选择目标';
@override @override
String get chooseFontFile => '选择字体文件'; String get chooseFontFile => '选择字体文件';
@@ -79,6 +73,9 @@ class SZh extends S {
@override @override
String get cmd => '命令'; String get cmd => '命令';
@override
String get containerName => '容器名';
@override @override
String get containerStatus => '容器状态'; String get containerStatus => '容器状态';
@@ -97,9 +94,6 @@ class SZh extends S {
@override @override
String get createFolder => '创建文件夹'; String get createFolder => '创建文件夹';
@override
String get currentMode => '当前模式';
@override @override
String get dark => ''; String get dark => '';
@@ -117,28 +111,22 @@ class SZh extends S {
@override @override
String dl2Local(Object fileName) { String dl2Local(Object fileName) {
return '下载 [$fileName] 到本地?'; return '下载 $fileName 到本地?';
} }
@override
String get dockerContainerName => '容器名';
@override @override
String get dockerEditHost => '编辑 DOCKER_HOST'; String get dockerEditHost => '编辑 DOCKER_HOST';
@override @override
String get dockerEmptyRunningItems => '没有正在运行的容器。\n这可能是因为环境变量 DOCKER_HOST 没有被正确读取。你可以通过在终端内运行 `echo \$DOCKER_HOST` 来获取。'; String get dockerEmptyRunningItems => '没有正在运行的容器。\n这可能是因为环境变量 DOCKER_HOST 没有被正确读取。你可以通过在终端内运行 `echo \$DOCKER_HOST` 来获取。';
@override
String get dockerImage => '镜像';
@override @override
String dockerImagesFmt(Object count) { String dockerImagesFmt(Object count) {
return '$count 个镜像'; return '$count 个镜像';
} }
@override @override
String get dockerNotInstalled => 'Docker未安装'; String get dockerNotInstalled => 'Docker 未安装';
@override @override
String dockerStatusRunningAndStoppedFmt(Object runningCount, Object stoppedCount) { String dockerStatusRunningAndStoppedFmt(Object runningCount, Object stoppedCount) {
@@ -154,7 +142,7 @@ class SZh extends S {
String get download => '下载'; String get download => '下载';
@override @override
String get downloadFinished => '下载完成'; String get downloadFinished => '下载完成';
@override @override
String downloadStatus(Object percent, Object size) { String downloadStatus(Object percent, Object size) {
@@ -168,7 +156,7 @@ class SZh extends S {
String get encode => '编码'; String get encode => '编码';
@override @override
String get error => '出错了'; String get error => '错误';
@override @override
String get exampleName => '名称示例'; String get exampleName => '名称示例';
@@ -218,9 +206,6 @@ class SZh extends S {
@override @override
String get gettingToken => '正在获取Token...'; String get gettingToken => '正在获取Token...';
@override
String get go => '开始';
@override @override
String get goto => '前往'; String get goto => '前往';
@@ -232,6 +217,9 @@ class SZh extends S {
return '请求失败, 状态码: $code'; return '请求失败, 状态码: $code';
} }
@override
String get image => '镜像';
@override @override
String get imagesList => '镜像列表'; String get imagesList => '镜像列表';
@@ -248,7 +236,7 @@ class SZh extends S {
String get installDockerWithUrl => '请先 https://docs.docker.com/engine/install docker'; String get installDockerWithUrl => '请先 https://docs.docker.com/engine/install docker';
@override @override
String get invalidJson => '无效的json存在格式问题'; String get invalidJson => '无效的 JSON';
@override @override
String get invalidVersion => '不支持的版本'; String get invalidVersion => '不支持的版本';
@@ -265,7 +253,7 @@ class SZh extends S {
String get keepForeground => '请保持应用处于前台!'; String get keepForeground => '请保持应用处于前台!';
@override @override
String get keyAuth => '钥认证'; String get keyAuth => '钥认证';
@override @override
String get lastTry => '最后尝试'; String get lastTry => '最后尝试';
@@ -347,9 +335,6 @@ class SZh extends S {
@override @override
String get onServerDetailPage => '在服务器详情页'; String get onServerDetailPage => '在服务器详情页';
@override
String get onlyIOS => '仅在iOS上有效';
@override @override
String get open => '打开'; String get open => '打开';
@@ -362,9 +347,6 @@ class SZh extends S {
@override @override
String get pickFile => '选择文件'; String get pickFile => '选择文件';
@override
String get ping => 'Ping';
@override @override
String get pingAvg => '平均:'; String get pingAvg => '平均:';

View File

@@ -25,16 +25,19 @@ extension ColorX on Color {
}); });
} }
MaterialColor get materialColor => MaterialColor(value, { MaterialColor get materialColor => MaterialColor(
50: withOpacity(0.05), value,
100: withOpacity(0.1), {
200: withOpacity(0.2), 50: withOpacity(0.05),
300: withOpacity(0.3), 100: withOpacity(0.1),
400: withOpacity(0.4), 200: withOpacity(0.2),
500: withOpacity(0.5), 300: withOpacity(0.3),
600: withOpacity(0.6), 400: withOpacity(0.4),
700: withOpacity(0.7), 500: withOpacity(0.5),
800: withOpacity(0.8), 600: withOpacity(0.6),
900: withOpacity(0.9), 700: withOpacity(0.7),
}); 800: withOpacity(0.8),
900: withOpacity(0.9),
},
);
} }

View File

@@ -4,7 +4,6 @@ import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart'; import 'package:flutter_gen/gen_l10n/l10n.dart';
import 'package:toolbox/core/extension/navigator.dart'; import 'package:toolbox/core/extension/navigator.dart';
import 'package:toolbox/data/res/ui.dart';
import 'package:url_launcher/url_launcher.dart'; import 'package:url_launcher/url_launcher.dart';
import '../../data/model/server/snippet.dart'; import '../../data/model/server/snippet.dart';
@@ -97,21 +96,6 @@ void setTransparentNavigationBar(BuildContext context) {
} }
} }
Widget buildPopuopMenu<T>({
required List<PopupMenuEntry<T>> items,
required void Function(T) onSelected,
Widget child = popMenuChild,
EdgeInsetsGeometry? padding,
}) {
return PopupMenuButton<T>(
itemBuilder: (_) => items,
onSelected: onSelected,
padding: padding ?? EdgeInsets.zero,
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)),
child: child,
);
}
String tabTitleName(BuildContext context, int i) { String tabTitleName(BuildContext context, int i) {
final s = S.of(context)!; final s = S.of(context)!;
switch (i) { switch (i) {
@@ -120,7 +104,7 @@ String tabTitleName(BuildContext context, int i) {
case 1: case 1:
return s.convert; return s.convert;
case 2: case 2:
return s.ping; return 'Ping';
default: default:
return ''; return '';
} }
@@ -165,7 +149,7 @@ void showSnippetDialog(
var snippet = provider.snippets.first; var snippet = provider.snippets.first;
showRoundDialog( showRoundDialog(
context: context, context: context,
title: Text(s.chooseDestination), title: Text(s.choose),
child: Picker( child: Picker(
items: provider.snippets.map((e) => Text(e.name)).toList(), items: provider.snippets.map((e) => Text(e.name)).toList(),
onSelected: (idx) => snippet = provider.snippets[idx], onSelected: (idx) => snippet = provider.snippets[idx],

View File

@@ -8,7 +8,6 @@
"appPrimaryColor": "App primary color", "appPrimaryColor": "App primary color",
"attention": "Attention", "attention": "Attention",
"auto": "Auto", "auto": "Auto",
"backDir": "Back",
"backup": "Backup", "backup": "Backup",
"backupAndRestore": "Backup and Restore", "backupAndRestore": "Backup and Restore",
"backupTip": "The exported data is simply encrypted. \nPlease keep it safe.", "backupTip": "The exported data is simply encrypted. \nPlease keep it safe.",
@@ -17,30 +16,27 @@
"canPullRefresh": "You can pull to refresh.", "canPullRefresh": "You can pull to refresh.",
"cancel": "Cancel", "cancel": "Cancel",
"choose": "Choose", "choose": "Choose",
"chooseDestination": "Choose destination",
"chooseFontFile": "Choose a font file", "chooseFontFile": "Choose a font file",
"choosePrivateKey": "Choose private key", "choosePrivateKey": "Choose private key",
"clear": "Clear", "clear": "Clear",
"clickSee": "Click here", "clickSee": "Click here",
"close": "Close", "close": "Close",
"cmd": "Command", "cmd": "Command",
"containerName": "Container name",
"containerStatus": "Container status", "containerStatus": "Container status",
"convert": "Convert", "convert": "Convert",
"copy": "Copy", "copy": "Copy",
"copyPath": "Copy path", "copyPath": "Copy path",
"createFile": "Create file", "createFile": "Create file",
"createFolder": "Create folder", "createFolder": "Create folder",
"currentMode": "Current Mode",
"dark": "Dark", "dark": "Dark",
"debug": "Debug", "debug": "Debug",
"decode": "Decode", "decode": "Decode",
"delete": "Delete", "delete": "Delete",
"disconnected": "Disconnected", "disconnected": "Disconnected",
"dl2Local": "Download [{fileName}] to local?", "dl2Local": "Download {fileName} to local?",
"dockerContainerName": "Container name",
"dockerEditHost": "Edit DOCKER_HOST", "dockerEditHost": "Edit DOCKER_HOST",
"dockerEmptyRunningItems": "No running container. \nIt may be that the env DOCKER_HOST is not read correctly. You can found it by running `echo $DOCKER_HOST` in terminal.", "dockerEmptyRunningItems": "No running container. \nIt may be that the env DOCKER_HOST is not read correctly. You can found it by running `echo $DOCKER_HOST` in terminal.",
"dockerImage": "Image",
"dockerImagesFmt": "{count} images", "dockerImagesFmt": "{count} images",
"dockerNotInstalled": "Docker not installed", "dockerNotInstalled": "Docker not installed",
"dockerStatusRunningAndStoppedFmt": "{runningCount} running, {stoppedCount} container stopped.", "dockerStatusRunningAndStoppedFmt": "{runningCount} running, {stoppedCount} container stopped.",
@@ -65,10 +61,10 @@
"foundNUpdate": "Found {count} update", "foundNUpdate": "Found {count} update",
"getPushTokenFailed": "Can't fetch push token", "getPushTokenFailed": "Can't fetch push token",
"gettingToken": "Getting token...", "gettingToken": "Getting token...",
"go": "Go",
"goto": "Go to", "goto": "Go to",
"host": "Host", "host": "Host",
"httpFailedWithCode": "request failed, status code: {code}", "httpFailedWithCode": "request failed, status code: {code}",
"image": "Image",
"imagesList": "Images list", "imagesList": "Images list",
"import": "Import", "import": "Import",
"inputDomainHere": "Input Domain here", "inputDomainHere": "Input Domain here",
@@ -80,7 +76,7 @@
"isBusy": "Is busy now", "isBusy": "Is busy now",
"keepForeground": "Keep app foreground!", "keepForeground": "Keep app foreground!",
"keyAuth": "Key Auth", "keyAuth": "Key Auth",
"lastTry": "Last try!", "lastTry": "Last try",
"launchPage": "Launch page", "launchPage": "Launch page",
"license": "License", "license": "License",
"light": "Light", "light": "Light",
@@ -106,14 +102,12 @@
"nullToken": "Null token", "nullToken": "Null token",
"ok": "OK", "ok": "OK",
"onServerDetailPage": "On server detail page", "onServerDetailPage": "On server detail page",
"onlyIOS": "Only valid on iOS",
"open": "Open", "open": "Open",
"paste": "Paste", "paste": "Paste",
"path": "Path", "path": "Path",
"pickFile": "Pick file", "pickFile": "Pick file",
"ping": "Ping",
"pingAvg": "Avg:", "pingAvg": "Avg:",
"pingInputIP": "Please input a target IP/domain.", "pingInputIP": "Please input a target IP / domain.",
"pingNoServer": "No server to ping.\nPlease add a server in server tab.", "pingNoServer": "No server to ping.\nPlease add a server in server tab.",
"pkg": "Pkg", "pkg": "Pkg",
"platformNotSupportUpdate": "Current platform does not support in app update.\nPlease build from source and install it.", "platformNotSupportUpdate": "Current platform does not support in app update.\nPlease build from source and install it.",

View File

@@ -8,7 +8,6 @@
"appPrimaryColor": "App主要色", "appPrimaryColor": "App主要色",
"attention": "注意", "attention": "注意",
"auto": "自动", "auto": "自动",
"backDir": "返回上一级",
"backup": "备份", "backup": "备份",
"backupAndRestore": "备份和恢复", "backupAndRestore": "备份和恢复",
"backupTip": "导出的数据仅进行了简单加密,请妥善保管。", "backupTip": "导出的数据仅进行了简单加密,请妥善保管。",
@@ -17,40 +16,37 @@
"canPullRefresh": "可以下拉刷新", "canPullRefresh": "可以下拉刷新",
"cancel": "取消", "cancel": "取消",
"choose": "选择", "choose": "选择",
"chooseDestination": "选择目标",
"chooseFontFile": "选择字体文件", "chooseFontFile": "选择字体文件",
"choosePrivateKey": "选择私钥", "choosePrivateKey": "选择私钥",
"clear": "清除", "clear": "清除",
"clickSee": "点击查看", "clickSee": "点击查看",
"close": "关闭", "close": "关闭",
"cmd": "命令", "cmd": "命令",
"containerName": "容器名",
"containerStatus": "容器状态", "containerStatus": "容器状态",
"convert": "转换", "convert": "转换",
"copy": "复制", "copy": "复制",
"copyPath": "复制路径", "copyPath": "复制路径",
"createFile": "创建文件", "createFile": "创建文件",
"createFolder": "创建文件夹", "createFolder": "创建文件夹",
"currentMode": "当前模式",
"dark": "暗", "dark": "暗",
"debug": "调试", "debug": "调试",
"decode": "解码", "decode": "解码",
"delete": "删除", "delete": "删除",
"disconnected": "连接断开", "disconnected": "连接断开",
"dl2Local": "下载 [{fileName}] 到本地?", "dl2Local": "下载 {fileName} 到本地?",
"dockerContainerName": "容器名",
"dockerEditHost": "编辑 DOCKER_HOST", "dockerEditHost": "编辑 DOCKER_HOST",
"dockerEmptyRunningItems": "没有正在运行的容器。\n这可能是因为环境变量 DOCKER_HOST 没有被正确读取。你可以通过在终端内运行 `echo $DOCKER_HOST` 来获取。", "dockerEmptyRunningItems": "没有正在运行的容器。\n这可能是因为环境变量 DOCKER_HOST 没有被正确读取。你可以通过在终端内运行 `echo $DOCKER_HOST` 来获取。",
"dockerImage": "镜像",
"dockerImagesFmt": "共 {count} 个镜像", "dockerImagesFmt": "共 {count} 个镜像",
"dockerNotInstalled": "Docker未安装", "dockerNotInstalled": "Docker 未安装",
"dockerStatusRunningAndStoppedFmt": "{runningCount}个正在运行, {stoppedCount}个已停止", "dockerStatusRunningAndStoppedFmt": "{runningCount}个正在运行, {stoppedCount}个已停止",
"dockerStatusRunningFmt": "{count}个容器正在运行", "dockerStatusRunningFmt": "{count}个容器正在运行",
"download": "下载", "download": "下载",
"downloadFinished": "下载完成", "downloadFinished": "下载完成",
"downloadStatus": "{size} 的 {percent}%", "downloadStatus": "{size} 的 {percent}%",
"edit": "编辑", "edit": "编辑",
"encode": "编码", "encode": "编码",
"error": "出错了", "error": "错误",
"exampleName": "名称示例", "exampleName": "名称示例",
"experimentalFeature": "实验性功能", "experimentalFeature": "实验性功能",
"export": "导出", "export": "导出",
@@ -65,21 +61,21 @@
"foundNUpdate": "找到 {count} 个更新", "foundNUpdate": "找到 {count} 个更新",
"getPushTokenFailed": "未能获取到推送token", "getPushTokenFailed": "未能获取到推送token",
"gettingToken": "正在获取Token...", "gettingToken": "正在获取Token...",
"go": "开始",
"goto": "前往", "goto": "前往",
"host": "主机", "host": "主机",
"httpFailedWithCode": "请求失败, 状态码: {code}", "httpFailedWithCode": "请求失败, 状态码: {code}",
"image": "镜像",
"imagesList": "镜像列表", "imagesList": "镜像列表",
"import": "导入", "import": "导入",
"inputDomainHere": "在这里输入域名", "inputDomainHere": "在这里输入域名",
"install": "安装", "install": "安装",
"installDockerWithUrl": "请先 https://docs.docker.com/engine/install docker", "installDockerWithUrl": "请先 https://docs.docker.com/engine/install docker",
"invalidJson": "无效的json存在格式问题", "invalidJson": "无效的 JSON",
"invalidVersion": "不支持的版本", "invalidVersion": "不支持的版本",
"invalidVersionHelp": "请确保正确安装了docker或者使用的非自编译版本。如果没有以上问题请在 {url} 提交问题。", "invalidVersionHelp": "请确保正确安装了docker或者使用的非自编译版本。如果没有以上问题请在 {url} 提交问题。",
"isBusy": "当前正忙", "isBusy": "当前正忙",
"keepForeground": "请保持应用处于前台!", "keepForeground": "请保持应用处于前台!",
"keyAuth": "钥认证", "keyAuth": "钥认证",
"lastTry": "最后尝试", "lastTry": "最后尝试",
"launchPage": "启动页", "launchPage": "启动页",
"license": "开源证书", "license": "开源证书",
@@ -106,12 +102,10 @@
"nullToken": "无Token", "nullToken": "无Token",
"ok": "好", "ok": "好",
"onServerDetailPage": "在服务器详情页", "onServerDetailPage": "在服务器详情页",
"onlyIOS": "仅在iOS上有效",
"open": "打开", "open": "打开",
"paste": "粘贴", "paste": "粘贴",
"path": "路径", "path": "路径",
"pickFile": "选择文件", "pickFile": "选择文件",
"ping": "Ping",
"pingAvg": "平均:", "pingAvg": "平均:",
"pingInputIP": "请输入目标IP或域名", "pingInputIP": "请输入目标IP或域名",
"pingNoServer": "没有服务器可用于Ping\n请在服务器tab添加服务器后再试", "pingNoServer": "没有服务器可用于Ping\n请在服务器tab添加服务器后再试",

View File

@@ -37,8 +37,7 @@ Future<void> initApp() async {
final settings = locator<SettingStore>(); final settings = locator<SettingStore>();
await loadFontFile(settings.fontPath.fetch()); await loadFontFile(settings.fontPath.fetch());
///设置Logger Logger.root.level = Level.ALL;
Logger.root.level = Level.ALL; // defaults to Level.INFO
Logger.root.onRecord.listen((record) { Logger.root.onRecord.listen((record) {
// ignore: avoid_print // ignore: avoid_print
print('[${record.loggerName}][${record.level.name}]: ${record.message}'); print('[${record.loggerName}][${record.level.name}]: ${record.message}');

View File

@@ -6,6 +6,7 @@ import 'package:flutter_gen/gen_l10n/l10n.dart';
import '../../core/utils/ui.dart'; import '../../core/utils/ui.dart';
import '../widget/input_field.dart'; import '../widget/input_field.dart';
import '../widget/popup_menu.dart';
import '../widget/round_rect_card.dart'; import '../widget/round_rect_card.dart';
class ConvertPage extends StatefulWidget { class ConvertPage extends StatefulWidget {
@@ -132,28 +133,30 @@ class _ConvertPageState extends State<ConvertPage>
) )
], ],
), ),
trailing: ConstrainedBox( trailing: PopupMenu<int>(
constraints: BoxConstraints(maxWidth: _media.size.width * 0.35), items: items,
child: buildPopuopMenu<int>( initialValue: _typeOptionIndex,
items: items, onSelected: (p0) {
onSelected: (p0) { setState(() {
setState(() { _typeOptionIndex = p0;
_typeOptionIndex = p0; });
}); },
}, child: Row(
child: Row( crossAxisAlignment: CrossAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.end,
mainAxisAlignment: MainAxisAlignment.end, mainAxisSize: MainAxisSize.min,
children: [ children: [
Text( Text(
typeOption[_typeOptionIndex], typeOption[_typeOptionIndex],
textScaleFactor: 1.0, textScaleFactor: 1.0,
textAlign: TextAlign.right, textAlign: TextAlign.right,
style: const TextStyle( style: const TextStyle(
fontWeight: FontWeight.w500, color: Colors.grey), fontWeight: FontWeight.w500,
color: Colors.grey,
), ),
], ),
), const Icon(Icons.keyboard_arrow_down, color: Colors.grey)
],
), ),
), ),
), ),

View File

@@ -16,6 +16,7 @@ import '../../data/res/url.dart';
import '../../data/store/docker.dart'; import '../../data/store/docker.dart';
import '../../locator.dart'; import '../../locator.dart';
import '../widget/dropdown_menu.dart'; import '../widget/dropdown_menu.dart';
import '../widget/popup_menu.dart';
import '../widget/round_rect_card.dart'; import '../widget/round_rect_card.dart';
import '../widget/two_line_text.dart'; import '../widget/two_line_text.dart';
import '../widget/url_text.dart'; import '../widget/url_text.dart';
@@ -96,14 +97,14 @@ class _DockerManagePageState extends State<DockerManagePage> {
children: [ children: [
Input( Input(
type: TextInputType.text, type: TextInputType.text,
label: _s.dockerImage, label: _s.image,
hint: 'xxx:1.1', hint: 'xxx:1.1',
controller: imageCtrl, controller: imageCtrl,
), ),
Input( Input(
type: TextInputType.text, type: TextInputType.text,
controller: nameCtrl, controller: nameCtrl,
label: _s.dockerContainerName, label: _s.containerName,
hint: 'xxx', hint: 'xxx',
), ),
Input( Input(
@@ -466,7 +467,7 @@ class _DockerManagePageState extends State<DockerManagePage> {
Widget _buildMoreBtn(DockerPsItem dItem, bool busy) { Widget _buildMoreBtn(DockerPsItem dItem, bool busy) {
final item = dItem.running ? DockerMenuItems.stop : DockerMenuItems.start; final item = dItem.running ? DockerMenuItems.stop : DockerMenuItems.start;
return buildPopuopMenu( return PopupMenu(
items: [ items: [
PopupMenuItem<DropdownBtnItem>( PopupMenuItem<DropdownBtnItem>(
value: item, value: item,

View File

@@ -154,9 +154,9 @@ class _MyHomePageState extends State<MyHomePage>
icon: const Icon(Icons.code), icon: const Icon(Icons.code),
label: _s.convert, label: _s.convert,
), ),
NavigationDestination( const NavigationDestination(
icon: const Icon(Icons.leak_add), icon: Icon(Icons.leak_add),
label: _s.ping, label: 'Ping',
), ),
], ],
); );

View File

@@ -20,6 +20,7 @@ import '../../../data/res/url.dart';
import '../../../data/store/setting.dart'; import '../../../data/store/setting.dart';
import '../../../locator.dart'; import '../../../locator.dart';
import '../../widget/dropdown_menu.dart'; import '../../widget/dropdown_menu.dart';
import '../../widget/popup_menu.dart';
import '../../widget/round_rect_card.dart'; import '../../widget/round_rect_card.dart';
import '../../widget/url_text.dart'; import '../../widget/url_text.dart';
import '../docker.dart'; import '../docker.dart';
@@ -258,7 +259,7 @@ class _ServerPageState extends State<ServerPage>
} }
Widget _buildMoreBtn(ServerPrivateInfo spi) { Widget _buildMoreBtn(ServerPrivateInfo spi) {
return buildPopuopMenu( return PopupMenu(
items: <PopupMenuEntry>[ items: <PopupMenuEntry>[
...ServerTabMenuItems.firstItems.map( ...ServerTabMenuItems.firstItems.map(
(item) => PopupMenuItem<DropdownBtnItem>( (item) => PopupMenuItem<DropdownBtnItem>(

View File

@@ -21,6 +21,7 @@ import '../../data/res/ui.dart';
import '../../data/store/setting.dart'; import '../../data/store/setting.dart';
import '../../locator.dart'; import '../../locator.dart';
import '../widget/future_widget.dart'; import '../widget/future_widget.dart';
import '../widget/popup_menu.dart';
import '../widget/round_rect_card.dart'; import '../widget/round_rect_card.dart';
class SettingPage extends StatefulWidget { class SettingPage extends StatefulWidget {
@@ -193,8 +194,9 @@ class _SettingPageState extends State<SettingPage> {
_s.willTakEeffectImmediately, _s.willTakEeffectImmediately,
style: grey, style: grey,
), ),
trailing: buildPopuopMenu<int>( trailing: PopupMenu<int>(
items: items, items: items,
initialValue: _updateInterval,
onSelected: (val) { onSelected: (val) {
setState(() { setState(() {
_updateInterval = val; _updateInterval = val;
@@ -263,8 +265,9 @@ class _SettingPageState extends State<SettingPage> {
title: Text( title: Text(
_s.launchPage, _s.launchPage,
), ),
trailing: buildPopuopMenu<int>( trailing: PopupMenu<int>(
items: items, items: items,
initialValue: _launchPageIdx,
onSelected: (idx) { onSelected: (idx) {
setState(() { setState(() {
_launchPageIdx = idx; _launchPageIdx = idx;
@@ -295,8 +298,9 @@ class _SettingPageState extends State<SettingPage> {
title: Text( title: Text(
_s.termTheme, _s.termTheme,
), ),
trailing: buildPopuopMenu<int>( trailing: PopupMenu<int>(
items: items, items: items,
initialValue: _termThemeIdx,
onSelected: (idx) { onSelected: (idx) {
setState(() { setState(() {
_termThemeIdx = idx; _termThemeIdx = idx;
@@ -326,8 +330,9 @@ class _SettingPageState extends State<SettingPage> {
_s.maxRetryCount, _s.maxRetryCount,
textAlign: TextAlign.start, textAlign: TextAlign.start,
), ),
trailing: buildPopuopMenu<int>( trailing: PopupMenu<int>(
items: items, items: items,
initialValue: _maxRetryCount,
onSelected: (val) { onSelected: (val) {
setState(() { setState(() {
_maxRetryCount = val; _maxRetryCount = val;
@@ -356,8 +361,9 @@ class _SettingPageState extends State<SettingPage> {
title: Text( title: Text(
_s.themeMode, _s.themeMode,
), ),
trailing: buildPopuopMenu<int>( trailing: PopupMenu<int>(
items: items, items: items,
initialValue: _nightMode,
onSelected: (idx) { onSelected: (idx) {
_nightMode = idx; _nightMode = idx;
_setting.themeMode.put(_nightMode); _setting.themeMode.put(_nightMode);

View File

@@ -0,0 +1,31 @@
import 'package:flutter/material.dart';
import 'package:toolbox/data/res/ui.dart';
class PopupMenu<T> extends StatelessWidget {
final List<PopupMenuEntry<T>> items;
final void Function(T) onSelected;
final Widget child;
final EdgeInsetsGeometry padding;
final T? initialValue;
const PopupMenu({
super.key,
required this.items,
required this.onSelected,
this.child = popMenuChild,
this.padding = const EdgeInsets.all(7),
this.initialValue,
});
@override
Widget build(BuildContext context) {
return PopupMenuButton<T>(
itemBuilder: (_) => items,
onSelected: onSelected,
initialValue: initialValue,
padding: padding,
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)),
child: child,
);
}
}

View File

@@ -59,8 +59,8 @@ dependencies:
xterm: xterm:
#path: ../xterm.dart #path: ../xterm.dart
git: git:
ref: master ref: master
url: https://github.com/lollipopkit/xterm.dart url: https://github.com/lollipopkit/xterm.dart
file_picker: ^5.2.5 file_picker: ^5.2.5
plain_notification_token: ^0.0.4 plain_notification_token: ^0.0.4
@@ -91,17 +91,7 @@ flutter:
# To add assets to your application, add an assets section, like this: # To add assets to your application, add an assets section, like this:
assets: assets:
- assets/app_icon.png - assets/app_icon.png
- assets/linux/centos.png - assets/linux/
- assets/linux/ubuntu.png
- assets/linux/debian.png
- assets/linux/kali.png
- assets/linux/arch.png
- assets/linux/fedora.png
- assets/linux/opensuse.png
- assets/linux/wrt.png
- assets/linux/armbian.png
- assets/linux/alpine.png
- assets/linux/rocky.png
# - images/a_dot_burr.jpeg # - images/a_dot_burr.jpeg
# - images/a_dot_ham.jpeg # - images/a_dot_ham.jpeg
# An image asset can refer to one or more resolution-specific "variants", see # An image asset can refer to one or more resolution-specific "variants", see