diff --git a/lib/core/extension/stringx.dart b/lib/core/extension/stringx.dart index 656c24f9..0490c422 100644 --- a/lib/core/extension/stringx.dart +++ b/lib/core/extension/stringx.dart @@ -58,4 +58,6 @@ extension StringX on String { ); }); } + + String get withLangExport => 'export LANG=en_US.UTF-8 && $this'; } diff --git a/lib/data/provider/apt.dart b/lib/data/provider/apt.dart index ca44e040..86fc9fad 100644 --- a/lib/data/provider/apt.dart +++ b/lib/data/provider/apt.dart @@ -4,6 +4,7 @@ import 'dart:typed_data'; import 'package:dartssh2/dartssh2.dart'; import 'package:logging/logging.dart'; +import 'package:toolbox/core/extension/stringx.dart'; import 'package:toolbox/core/extension/uint8list.dart'; import 'package:toolbox/core/provider_base.dart'; import 'package:toolbox/data/model/apt/upgrade_pkg_info.dart'; @@ -101,7 +102,7 @@ class AptProvider extends BusyProvider { onUpdate!(); }); await session.done; - return await client!.run('apt list --upgradeable').string; + return await client!.run('apt list --upgradeable'.withLangExport).string; } } diff --git a/lib/data/provider/docker.dart b/lib/data/provider/docker.dart index 2f534324..20695627 100644 --- a/lib/data/provider/docker.dart +++ b/lib/data/provider/docker.dart @@ -1,9 +1,10 @@ import 'package:dartssh2/dartssh2.dart'; +import 'package:toolbox/core/extension/stringx.dart'; import 'package:toolbox/core/extension/uint8list.dart'; import 'package:toolbox/core/provider_base.dart'; import 'package:toolbox/data/model/docker/ps.dart'; -final dockerNotFound = RegExp('(command not found | Unknown command)'); +final dockerNotFound = RegExp(r'command not found|Unknown command'); class DockerProvider extends BusyProvider { SSHClient? client; @@ -29,7 +30,8 @@ class DockerProvider extends BusyProvider { return; } - final verRaw = await client!.run('docker version').string; + final verRaw = await client!.run('docker version'.withLangExport).string; + print(verRaw); if (verRaw.contains(dockerNotFound)) { error = 'docker not found'; notifyListeners(); @@ -39,16 +41,18 @@ class DockerProvider extends BusyProvider { if (verSplit.length < 3) { error = 'invalid version'; notifyListeners(); + return; } else { try { version = verSplit[1].split(' ').last; edition = verSplit[0].split(': ')[1]; } catch (e) { error = e.toString(); + return; } } - final raw = await client!.run('docker ps -a').string; + final raw = await client!.run('docker ps -a'.withLangExport).string; final lines = raw.split('\n'); lines.removeAt(0); lines.removeWhere((element) => element.isEmpty); diff --git a/lib/data/res/build_data.dart b/lib/data/res/build_data.dart index 1cc19405..a0b5397a 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 = 129; + static const int build = 133; static const String engine = "Flutter 2.10.5 • channel stable • https://github.com/flutter/flutter.git\nFramework • revision 5464c5bac7 (3 weeks ago) • 2022-04-18 09:55:37 -0700\nEngine • revision 57d3bac3dd\nTools • Dart 2.16.2 • DevTools 2.9.2\n"; - static const String buildAt = "2022-05-08 08:37:10.208726"; - static const int modifications = 14; + static const String buildAt = "2022-05-10 21:49:33.780998"; + static const int modifications = 1; } diff --git a/lib/data/res/url.dart b/lib/data/res/url.dart index 9001297e..fab305c5 100644 --- a/lib/data/res/url.dart +++ b/lib/data/res/url.dart @@ -3,3 +3,4 @@ const baseUrl = backendUrl + '/toolbox'; const joinQQGroupUrl = 'https://jq.qq.com/?_wv=1027&k=G0hUmPAq'; const myGithub = 'https://github.com/LollipopKit'; const rainSunMeGithub = 'https://github.com/RainSunMe'; +const issueUrl = 'https://github.com/LollipopKit/flutter_server_box/issues'; diff --git a/lib/generated/intl/messages_en.dart b/lib/generated/intl/messages_en.dart index 29b9fe24..589b9fab 100644 --- a/lib/generated/intl/messages_en.dart +++ b/lib/generated/intl/messages_en.dart @@ -36,21 +36,26 @@ class MessageLookup extends MessageLookupByLibrary { static String m6(code) => "request failed, status code: ${code}"; - static String m7(myGithub) => "\nMade with ❤️ by ${myGithub}"; + static String m7(url) => + "Please make sure that docker is installed correctly, or that you are using a non-self-compiled version. If you don\'t have the above issues, please submit an issue on ${url}."; - static String m8(user) => "Password for ${user}"; + static String m8(myGithub) => "\nMade with ❤️ by ${myGithub}"; - static String m9(time) => "Spent time: ${time}"; + static String m9(user) => "Password for ${user}"; - static String m10(name) => "Are you sure to delete [${name}]?"; + static String m10(url) => "Please report bugs on ${url}"; - static String m11(server) => "Are you sure to delete server [${server}]?"; + static String m11(time) => "Spent time: ${time}"; - static String m12(build) => "Found: v1.0.${build}, click to update"; + static String m12(name) => "Are you sure to delete [${name}]?"; - static String m13(build) => "Current: v1.0.${build}"; + static String m13(server) => "Are you sure to delete server [${server}]?"; - static String m14(build) => "Current: v1.0.${build}, is up to date"; + static String m14(build) => "Found: v1.0.${build}, click to update"; + + static String m15(build) => "Current: v1.0.${build}"; + + static String m16(build) => "Current: v1.0.${build}, is up to date"; final messages = _notInlinedMessages(_notInlinedMessages); static Map _notInlinedMessages(_) => { @@ -113,6 +118,7 @@ class MessageLookup extends MessageLookupByLibrary { "install": MessageLookupByLibrary.simpleMessage("install"), "installDockerWithUrl": MessageLookupByLibrary.simpleMessage( "Please https://docs.docker.com/engine/install docker first."), + "invalidVersionHelp": m7, "keepForeground": MessageLookupByLibrary.simpleMessage("Keep app foreground!"), "keyAuth": MessageLookupByLibrary.simpleMessage("Key Auth"), @@ -121,12 +127,13 @@ class MessageLookup extends MessageLookupByLibrary { "loadingFiles": MessageLookupByLibrary.simpleMessage("Loading files..."), "loss": MessageLookupByLibrary.simpleMessage("Loss"), - "madeWithLove": m7, + "madeWithLove": m8, "max": MessageLookupByLibrary.simpleMessage("max"), "min": MessageLookupByLibrary.simpleMessage("min"), "ms": MessageLookupByLibrary.simpleMessage("ms"), "name": MessageLookupByLibrary.simpleMessage("Name"), "noClient": MessageLookupByLibrary.simpleMessage("No client"), + "noInterface": MessageLookupByLibrary.simpleMessage("No interface"), "noResult": MessageLookupByLibrary.simpleMessage("No result"), "noSavedPrivateKey": MessageLookupByLibrary.simpleMessage("No saved private keys."), @@ -153,10 +160,9 @@ class MessageLookup extends MessageLookupByLibrary { "port": MessageLookupByLibrary.simpleMessage("Port"), "privateKey": MessageLookupByLibrary.simpleMessage("Private Key"), "pwd": MessageLookupByLibrary.simpleMessage("Password"), - "pwdForUser": m8, + "pwdForUser": m9, "rename": MessageLookupByLibrary.simpleMessage("Rename"), - "reportBugsOnGithubIssue": MessageLookupByLibrary.simpleMessage( - "Please report bugs on https://github.com/LollipopKit/flutter_server_box/issues"), + "reportBugsOnGithubIssue": m10, "result": MessageLookupByLibrary.simpleMessage("Result"), "run": MessageLookupByLibrary.simpleMessage("Run"), "save": MessageLookupByLibrary.simpleMessage("Save"), @@ -180,11 +186,11 @@ class MessageLookup extends MessageLookupByLibrary { "sftpSSHConnected": MessageLookupByLibrary.simpleMessage("SFTP Connected"), "snippet": MessageLookupByLibrary.simpleMessage("Snippet"), - "spentTime": m9, + "spentTime": m11, "start": MessageLookupByLibrary.simpleMessage("Start"), "stop": MessageLookupByLibrary.simpleMessage("Stop"), - "sureDelete": m10, - "sureToDeleteServer": m11, + "sureDelete": m12, + "sureToDeleteServer": m13, "ttl": MessageLookupByLibrary.simpleMessage("TTL"), "unknown": MessageLookupByLibrary.simpleMessage("unknown"), "unknownError": MessageLookupByLibrary.simpleMessage("Unknown error"), @@ -198,9 +204,9 @@ class MessageLookup extends MessageLookupByLibrary { "upsideDown": MessageLookupByLibrary.simpleMessage("Upside Down"), "urlOrJson": MessageLookupByLibrary.simpleMessage("URL or JSON"), "user": MessageLookupByLibrary.simpleMessage("User"), - "versionHaveUpdate": m12, - "versionUnknownUpdate": m13, - "versionUpdated": m14, + "versionHaveUpdate": m14, + "versionUnknownUpdate": m15, + "versionUpdated": m16, "waitConnection": MessageLookupByLibrary.simpleMessage( "Please wait for the connection to be established."), "willTakEeffectImmediately": diff --git a/lib/generated/intl/messages_zh.dart b/lib/generated/intl/messages_zh.dart index c16dd2c1..78664bb1 100644 --- a/lib/generated/intl/messages_zh.dart +++ b/lib/generated/intl/messages_zh.dart @@ -36,21 +36,26 @@ class MessageLookup extends MessageLookupByLibrary { static String m6(code) => "请求失败, 状态码: ${code}"; - static String m7(myGithub) => "\n用❤️制作 by ${myGithub}"; + static String m7(url) => + "请确保正确安装了docker,或者使用的非自编译版本。如果没有以上问题,请在 ${url} 提交问题。"; - static String m8(user) => "用户${user}的密码"; + static String m8(myGithub) => "\n用❤️制作 by ${myGithub}"; - static String m9(time) => "耗时: ${time}"; + static String m9(user) => "用户${user}的密码"; - static String m10(name) => "确定删除[${name}]?"; + static String m10(url) => "请到 ${url} 提交问题"; - static String m11(server) => "你确定要删除服务器 [${server}] 吗?"; + static String m11(time) => "耗时: ${time}"; - static String m12(build) => "找到新版本:v1.0.${build}, 点击更新"; + static String m12(name) => "确定删除[${name}]?"; - static String m13(build) => "当前:v1.0.${build}"; + static String m13(server) => "你确定要删除服务器 [${server}] 吗?"; - static String m14(build) => "当前:v1.0.${build}, 已是最新版本"; + static String m14(build) => "找到新版本:v1.0.${build}, 点击更新"; + + static String m15(build) => "当前:v1.0.${build}"; + + static String m16(build) => "当前:v1.0.${build}, 已是最新版本"; final messages = _notInlinedMessages(_notInlinedMessages); static Map _notInlinedMessages(_) => { @@ -102,18 +107,20 @@ class MessageLookup extends MessageLookupByLibrary { "install": MessageLookupByLibrary.simpleMessage("安装"), "installDockerWithUrl": MessageLookupByLibrary.simpleMessage( "请先 https://docs.docker.com/engine/install docker"), + "invalidVersionHelp": m7, "keepForeground": MessageLookupByLibrary.simpleMessage("请保持应用处于前台!"), "keyAuth": MessageLookupByLibrary.simpleMessage("公钥认证"), "launchPage": MessageLookupByLibrary.simpleMessage("启动页"), "license": MessageLookupByLibrary.simpleMessage("开源证书"), "loadingFiles": MessageLookupByLibrary.simpleMessage("正在加载目录。。。"), "loss": MessageLookupByLibrary.simpleMessage("丢包率"), - "madeWithLove": m7, + "madeWithLove": m8, "max": MessageLookupByLibrary.simpleMessage("最大"), "min": MessageLookupByLibrary.simpleMessage("最小"), "ms": MessageLookupByLibrary.simpleMessage("毫秒"), "name": MessageLookupByLibrary.simpleMessage("名称"), "noClient": MessageLookupByLibrary.simpleMessage("没有SSH连接"), + "noInterface": MessageLookupByLibrary.simpleMessage("没有可用的接口"), "noResult": MessageLookupByLibrary.simpleMessage("无结果"), "noSavedPrivateKey": MessageLookupByLibrary.simpleMessage("没有已保存的私钥。"), "noSavedSnippet": MessageLookupByLibrary.simpleMessage("没有已保存的代码片段。"), @@ -132,10 +139,9 @@ class MessageLookup extends MessageLookupByLibrary { "port": MessageLookupByLibrary.simpleMessage("端口"), "privateKey": MessageLookupByLibrary.simpleMessage("私钥"), "pwd": MessageLookupByLibrary.simpleMessage("密码"), - "pwdForUser": m8, + "pwdForUser": m9, "rename": MessageLookupByLibrary.simpleMessage("重命名"), - "reportBugsOnGithubIssue": MessageLookupByLibrary.simpleMessage( - "请到 https://github.com/LollipopKit/flutter_server_box/issues 提交问题"), + "reportBugsOnGithubIssue": m10, "result": MessageLookupByLibrary.simpleMessage("结果"), "run": MessageLookupByLibrary.simpleMessage("运行"), "save": MessageLookupByLibrary.simpleMessage("保存"), @@ -154,11 +160,11 @@ class MessageLookup extends MessageLookupByLibrary { "sftpSSHConnected": MessageLookupByLibrary.simpleMessage("SFTP 已连接,即将开始下载..."), "snippet": MessageLookupByLibrary.simpleMessage("代码片段"), - "spentTime": m9, + "spentTime": m11, "start": MessageLookupByLibrary.simpleMessage("开始"), "stop": MessageLookupByLibrary.simpleMessage("停止"), - "sureDelete": m10, - "sureToDeleteServer": m11, + "sureDelete": m12, + "sureToDeleteServer": m13, "ttl": MessageLookupByLibrary.simpleMessage("缓存时间"), "unknown": MessageLookupByLibrary.simpleMessage("未知"), "unknownError": MessageLookupByLibrary.simpleMessage("未知错误"), @@ -171,9 +177,9 @@ class MessageLookup extends MessageLookupByLibrary { "upsideDown": MessageLookupByLibrary.simpleMessage("上下交换"), "urlOrJson": MessageLookupByLibrary.simpleMessage("链接或JSON"), "user": MessageLookupByLibrary.simpleMessage("用户"), - "versionHaveUpdate": m12, - "versionUnknownUpdate": m13, - "versionUpdated": m14, + "versionHaveUpdate": m14, + "versionUnknownUpdate": m15, + "versionUpdated": m16, "waitConnection": MessageLookupByLibrary.simpleMessage("请等待连接建立"), "willTakEeffectImmediately": MessageLookupByLibrary.simpleMessage("更改将会立即生效") diff --git a/lib/generated/l10n.dart b/lib/generated/l10n.dart index b0c7ab59..ba85c229 100644 --- a/lib/generated/l10n.dart +++ b/lib/generated/l10n.dart @@ -1141,13 +1141,13 @@ class S { ); } - /// `Please report bugs on https://github.com/LollipopKit/flutter_server_box/issues` - String get reportBugsOnGithubIssue { + /// `Please report bugs on {url}` + String reportBugsOnGithubIssue(Object url) { return Intl.message( - 'Please report bugs on https://github.com/LollipopKit/flutter_server_box/issues', + 'Please report bugs on $url', name: 'reportBugsOnGithubIssue', desc: '', - args: [], + args: [url], ); } @@ -1200,6 +1200,26 @@ class S { args: [], ); } + + /// `Please make sure that docker is installed correctly, or that you are using a non-self-compiled version. If you don't have the above issues, please submit an issue on {url}.` + String invalidVersionHelp(Object url) { + return Intl.message( + 'Please make sure that docker is installed correctly, or that you are using a non-self-compiled version. If you don\'t have the above issues, please submit an issue on $url.', + name: 'invalidVersionHelp', + desc: '', + args: [url], + ); + } + + /// `No interface` + String get noInterface { + return Intl.message( + 'No interface', + name: 'noInterface', + desc: '', + args: [], + ); + } } class AppLocalizationDelegate extends LocalizationsDelegate { diff --git a/lib/l10n/intl_en.arb b/lib/l10n/intl_en.arb index 1c1013aa..3bcaccac 100644 --- a/lib/l10n/intl_en.arb +++ b/lib/l10n/intl_en.arb @@ -108,10 +108,12 @@ "disconnected": "Disconnected", "files": "Files", "experimentalFeature": "Experimental feature", - "reportBugsOnGithubIssue": "Please report bugs on https://github.com/LollipopKit/flutter_server_box/issues", + "reportBugsOnGithubIssue": "Please report bugs on {url}", "noUpdateAvailable": "No update available", "foundNUpdate": "Found {count} update", "updateAll": "Update all", "pwdForUser": "Password for {user}", - "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.", + "invalidVersionHelp": "Please make sure that docker is installed correctly, or that you are using a non-self-compiled version. If you don't have the above issues, please submit an issue on {url}.", + "noInterface": "No interface" } \ No newline at end of file diff --git a/lib/l10n/intl_zh.arb b/lib/l10n/intl_zh.arb index 91956d5d..17a6efb5 100644 --- a/lib/l10n/intl_zh.arb +++ b/lib/l10n/intl_zh.arb @@ -108,10 +108,12 @@ "disconnected": "连接断开", "files": "文件", "experimentalFeature": "实验性功能", - "reportBugsOnGithubIssue": "请到 https://github.com/LollipopKit/flutter_server_box/issues 提交问题", + "reportBugsOnGithubIssue": "请到 {url} 提交问题", "noUpdateAvailable": "没有可用更新", "foundNUpdate": "找到 {count} 个更新", "updateAll": "更新全部", "pwdForUser": "用户{user}的密码", - "platformNotSupportUpdate": "当前平台不支持更新,请编译最新源码后手动安装" + "platformNotSupportUpdate": "当前平台不支持更新,请编译最新源码后手动安装", + "invalidVersionHelp": "请确保正确安装了docker,或者使用的非自编译版本。如果没有以上问题,请在 {url} 提交问题。", + "noInterface": "没有可用的接口" } \ No newline at end of file diff --git a/lib/view/page/apt.dart b/lib/view/page/apt.dart index c83f1970..a5c5b4c5 100644 --- a/lib/view/page/apt.dart +++ b/lib/view/page/apt.dart @@ -6,6 +6,7 @@ import 'package:toolbox/data/model/apt/upgrade_pkg_info.dart'; import 'package:toolbox/data/model/server/server_private_info.dart'; import 'package:toolbox/data/provider/apt.dart'; import 'package:toolbox/data/provider/server.dart'; +import 'package:toolbox/data/res/url.dart'; import 'package:toolbox/generated/l10n.dart'; import 'package:toolbox/locator.dart'; import 'package:toolbox/view/widget/center_loading.dart'; @@ -152,7 +153,7 @@ class _AptManagePageState extends State Padding( padding: const EdgeInsets.all(17), child: UrlText( - text: '${s.experimentalFeature}\n${s.reportBugsOnGithubIssue}', + text: '${s.experimentalFeature}\n${s.reportBugsOnGithubIssue(issueUrl)}', replace: 'Github Issue', textAlign: TextAlign.center, ), diff --git a/lib/view/page/docker.dart b/lib/view/page/docker.dart index 412d0d71..3897ab65 100644 --- a/lib/view/page/docker.dart +++ b/lib/view/page/docker.dart @@ -7,6 +7,7 @@ import 'package:toolbox/data/model/docker/ps.dart'; import 'package:toolbox/data/model/server/server_private_info.dart'; import 'package:toolbox/data/provider/docker.dart'; import 'package:toolbox/data/provider/server.dart'; +import 'package:toolbox/data/res/url.dart'; import 'package:toolbox/generated/l10n.dart'; import 'package:toolbox/locator.dart'; import 'package:toolbox/view/widget/center_loading.dart'; @@ -71,16 +72,17 @@ class _DockerManagePageState extends State { return Consumer(builder: (_, docker, __) { final running = docker.items; if (docker.error != null && running == null) { - return Center( - child: Column( + return SizedBox.expand(child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, children: [ - SizedBox( - height: _media.size.height * 0.43, - ), + const Icon(Icons.error, size: 37,), + const SizedBox(height: 27), Text(docker.error!), - _buildSolution(docker.error!) + const SizedBox(height: 27), + Padding(padding: const EdgeInsets.all(17), child: _buildSolution(docker.error!),) ], - )); + ),); } if (running == null) { _docker.refresh(); @@ -106,6 +108,8 @@ class _DockerManagePageState extends State { ); case 'no client': return Text(s.waitConnection); + case 'invalid version': + return UrlText(text: s.invalidVersionHelp(issueUrl), replace: 'Github',); default: return Text(s.unknownError); } diff --git a/lib/view/page/server/detail.dart b/lib/view/page/server/detail.dart index b5476e1e..ebfddb44 100644 --- a/lib/view/page/server/detail.dart +++ b/lib/view/page/server/detail.dart @@ -9,6 +9,7 @@ import 'package:toolbox/data/res/color.dart'; import 'package:toolbox/data/res/font_style.dart'; import 'package:toolbox/data/res/icon/linux_icons.dart'; import 'package:toolbox/data/res/padding.dart'; +import 'package:toolbox/generated/l10n.dart'; import 'package:toolbox/view/widget/round_rect_card.dart'; const style11 = TextStyle(fontSize: 11); @@ -26,11 +27,13 @@ class ServerDetailPage extends StatefulWidget { class _ServerDetailPageState extends State with SingleTickerProviderStateMixin { late MediaQueryData _media; + late S s; @override void didChangeDependencies() { super.didChangeDependencies(); _media = MediaQuery.of(context); + s = S.of(context); } @override @@ -298,10 +301,10 @@ class _ServerDetailPageState extends State ) ]; if (ns.devices.isEmpty) { - children.add(const Center( + children.add(Center( child: Text( - 'No interface.', - style: TextStyle(color: Colors.grey), + s.noInterface, + style: const TextStyle(color: Colors.grey, fontSize: 13), ), )); } else {