- optimize TextField
- opt apt pwd req times
- use logger in update.dart
This commit is contained in:
Junyuan Feng
2022-05-15 13:48:57 +08:00
parent 282443a548
commit 36d7dc7bb2
15 changed files with 90 additions and 83 deletions

View File

@@ -354,7 +354,7 @@
buildSettings = { buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_MODULES = YES;
CURRENT_PROJECT_VERSION = 134; CURRENT_PROJECT_VERSION = 135;
DEVELOPMENT_TEAM = BA88US33G6; DEVELOPMENT_TEAM = BA88US33G6;
ENABLE_BITCODE = NO; ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist; INFOPLIST_FILE = Runner/Info.plist;
@@ -362,7 +362,7 @@
"$(inherited)", "$(inherited)",
"@executable_path/Frameworks", "@executable_path/Frameworks",
); );
MARKETING_VERSION = 1.0.134; MARKETING_VERSION = 1.0.135;
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";
@@ -484,7 +484,7 @@
buildSettings = { buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_MODULES = YES;
CURRENT_PROJECT_VERSION = 134; CURRENT_PROJECT_VERSION = 135;
DEVELOPMENT_TEAM = BA88US33G6; DEVELOPMENT_TEAM = BA88US33G6;
ENABLE_BITCODE = NO; ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist; INFOPLIST_FILE = Runner/Info.plist;
@@ -492,7 +492,7 @@
"$(inherited)", "$(inherited)",
"@executable_path/Frameworks", "@executable_path/Frameworks",
); );
MARKETING_VERSION = 1.0.134; MARKETING_VERSION = 1.0.135;
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";
@@ -508,7 +508,7 @@
buildSettings = { buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_MODULES = YES;
CURRENT_PROJECT_VERSION = 134; CURRENT_PROJECT_VERSION = 135;
DEVELOPMENT_TEAM = BA88US33G6; DEVELOPMENT_TEAM = BA88US33G6;
ENABLE_BITCODE = NO; ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist; INFOPLIST_FILE = Runner/Info.plist;
@@ -516,7 +516,7 @@
"$(inherited)", "$(inherited)",
"@executable_path/Frameworks", "@executable_path/Frameworks",
); );
MARKETING_VERSION = 1.0.134; MARKETING_VERSION = 1.0.135;
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";

View File

@@ -1,9 +1,8 @@
// ignore_for_file: avoid_print
import 'dart:io'; import 'dart:io';
import 'package:dio/dio.dart'; import 'package:dio/dio.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:logging/logging.dart';
import 'package:r_upgrade/r_upgrade.dart'; import 'package:r_upgrade/r_upgrade.dart';
import 'package:toolbox/core/utils.dart'; import 'package:toolbox/core/utils.dart';
import 'package:toolbox/data/provider/app.dart'; import 'package:toolbox/data/provider/app.dart';
@@ -12,12 +11,14 @@ import 'package:toolbox/data/service/app.dart';
import 'package:toolbox/generated/l10n.dart'; import 'package:toolbox/generated/l10n.dart';
import 'package:toolbox/locator.dart'; import 'package:toolbox/locator.dart';
final logger = Logger('UPDATE');
Future<bool> isFileAvailable(String url) async { Future<bool> isFileAvailable(String url) async {
try { try {
final resp = await Dio().head(url); final resp = await Dio().head(url);
return resp.statusCode == 200; return resp.statusCode == 200;
} catch (e) { } catch (e) {
print('update file not available: $e'); logger.warning('update file not available: $e');
return false; return false;
} }
} }
@@ -39,11 +40,11 @@ Future<void> doUpdate(BuildContext context, {bool force = false}) async {
}(); }();
if (!force && newest <= BuildData.build) { if (!force && newest <= BuildData.build) {
print('Update ignored due to current: ${BuildData.build}, ' logger.info('Update ignored due to current: ${BuildData.build}, '
'update: $newest'); 'update: $newest');
return; return;
} }
print('Update available: $newest'); logger.info('Update available: $newest');
if (Platform.isAndroid && !await isFileAvailable(update.android)) { if (Platform.isAndroid && !await isFileAvailable(update.android)) {
return; return;

View File

@@ -10,7 +10,8 @@ import 'package:toolbox/core/provider_base.dart';
import 'package:toolbox/data/model/apt/upgrade_pkg_info.dart'; import 'package:toolbox/data/model/apt/upgrade_pkg_info.dart';
import 'package:toolbox/data/model/distribution.dart'; import 'package:toolbox/data/model/distribution.dart';
typedef PwdRequestFunc = Future<String> Function(String? userName); typedef PwdRequestFunc = Future<String> Function(
bool lastTimes, String? userName);
final pwdRequestWithUserReg = RegExp(r'\[sudo\] password for (.+):'); final pwdRequestWithUserReg = RegExp(r'\[sudo\] password for (.+):');
class AptProvider extends BusyProvider { class AptProvider extends BusyProvider {
@@ -27,7 +28,8 @@ class AptProvider extends BusyProvider {
String? error; String? error;
String? upgradeLog; String? upgradeLog;
String? updateLog; String? updateLog;
String? savedPwd; String lastLog = '';
int triedTimes = 0;
AptProvider(); AptProvider();
@@ -49,10 +51,10 @@ class AptProvider extends BusyProvider {
error = null; error = null;
upgradeLog = null; upgradeLog = null;
updateLog = whoami = null; updateLog = whoami = null;
savedPwd = null;
onUpgrade = null; onUpgrade = null;
onUpdate = null; onUpdate = null;
onPasswordRequest = null; onPasswordRequest = null;
triedTimes = 0;
} }
Future<void> refreshInstalled() async { Future<void> refreshInstalled() async {
@@ -128,7 +130,10 @@ class AptProvider extends BusyProvider {
session.stderr.listen((e) => _onPwd(e, session.stdin)); session.stderr.listen((e) => _onPwd(e, session.stdin));
session.stdout.listen((data) async { session.stdout.listen((data) async {
upgradeLog = (upgradeLog ?? '') + data.string; final log = data.string;
if (lastLog == log.trim()) return;
upgradeLog = (upgradeLog ?? '') + log;
lastLog = log.trim();
notifyListeners(); notifyListeners();
onUpgrade!(); onUpgrade!();
}); });
@@ -143,16 +148,12 @@ class AptProvider extends BusyProvider {
if (event.contains('[sudo] password for ')) { if (event.contains('[sudo] password for ')) {
final user = pwdRequestWithUserReg.firstMatch(event)?.group(1); final user = pwdRequestWithUserReg.firstMatch(event)?.group(1);
logger.info('sudo password request for $user'); logger.info('sudo password request for $user');
final pwd = await () async { triedTimes++;
if (savedPwd != null) return savedPwd!; final pwd =
final inputPwd = await (onPasswordRequest ?? (_) async => '')(user); await (onPasswordRequest ?? (_) async => '')(triedTimes == 3, user);
if (inputPwd.isNotEmpty) {
savedPwd = inputPwd;
}
return inputPwd;
}();
if (pwd.isEmpty) { if (pwd.isEmpty) {
logger.info('sudo password request cancelled'); logger.info('sudo password request cancelled');
return;
} }
stdin.add(Uint8List.fromList(utf8.encode('$pwd\n'))); stdin.add(Uint8List.fromList(utf8.encode('$pwd\n')));
} }

View File

@@ -2,9 +2,9 @@
class BuildData { class BuildData {
static const String name = "ServerBox"; static const String name = "ServerBox";
static const int build = 134; static const int build = 135;
static const String engine = static const String engine =
"Flutter 3.0.0 • channel stable • https://github.com/flutter/flutter.git\nFramework • revision ee4e09cce0 (2 days ago) • 2022-05-09 16:45:18 -0700\nEngine • revision d1b9a6938a\nTools • Dart 2.17.0 • DevTools 2.12.2\n"; "Flutter 3.0.0 • channel stable • https://github.com/flutter/flutter.git\nFramework • revision ee4e09cce0 (3 days ago) • 2022-05-09 16:45:18 -0700\nEngine • revision d1b9a6938a\nTools • Dart 2.17.0 • DevTools 2.12.2\n";
static const String buildAt = "2022-05-12 14:31:57.568409"; static const String buildAt = "2022-05-13 09:32:15.654170";
static const int modifications = 37; static const int modifications = 15;
} }

View File

@@ -41,21 +41,19 @@ class MessageLookup extends MessageLookupByLibrary {
static String m8(myGithub) => "\nMade with ❤️ by ${myGithub}"; static String m8(myGithub) => "\nMade with ❤️ by ${myGithub}";
static String m9(user) => "Password for ${user}"; static String m9(url) => "Please report bugs on ${url}";
static String m10(url) => "Please report bugs on ${url}"; static String m10(time) => "Spent time: ${time}";
static String m11(time) => "Spent time: ${time}"; static String m11(name) => "Are you sure to delete [${name}]?";
static String m12(name) => "Are you sure to delete [${name}]?"; static String m12(server) => "Are you sure to delete server [${server}]?";
static String m13(server) => "Are you sure to delete server [${server}]?"; static String m13(build) => "Found: v1.0.${build}, click to update";
static String m14(build) => "Found: v1.0.${build}, click to update"; static String m14(build) => "Current: v1.0.${build}";
static String m15(build) => "Current: v1.0.${build}"; static String m15(build) => "Current: v1.0.${build}, is up to date";
static String m16(build) => "Current: v1.0.${build}, is up to date";
final messages = _notInlinedMessages(_notInlinedMessages); final messages = _notInlinedMessages(_notInlinedMessages);
static Map<String, Function> _notInlinedMessages(_) => <String, Function>{ static Map<String, Function> _notInlinedMessages(_) => <String, Function>{
@@ -122,6 +120,7 @@ class MessageLookup extends MessageLookupByLibrary {
"keepForeground": "keepForeground":
MessageLookupByLibrary.simpleMessage("Keep app foreground!"), MessageLookupByLibrary.simpleMessage("Keep app foreground!"),
"keyAuth": MessageLookupByLibrary.simpleMessage("Key Auth"), "keyAuth": MessageLookupByLibrary.simpleMessage("Key Auth"),
"lastTry": MessageLookupByLibrary.simpleMessage("Last try!"),
"launchPage": MessageLookupByLibrary.simpleMessage("Launch page"), "launchPage": MessageLookupByLibrary.simpleMessage("Launch page"),
"license": MessageLookupByLibrary.simpleMessage("License"), "license": MessageLookupByLibrary.simpleMessage("License"),
"loadingFiles": "loadingFiles":
@@ -160,9 +159,8 @@ class MessageLookup extends MessageLookupByLibrary {
"port": MessageLookupByLibrary.simpleMessage("Port"), "port": MessageLookupByLibrary.simpleMessage("Port"),
"privateKey": MessageLookupByLibrary.simpleMessage("Private Key"), "privateKey": MessageLookupByLibrary.simpleMessage("Private Key"),
"pwd": MessageLookupByLibrary.simpleMessage("Password"), "pwd": MessageLookupByLibrary.simpleMessage("Password"),
"pwdForUser": m9,
"rename": MessageLookupByLibrary.simpleMessage("Rename"), "rename": MessageLookupByLibrary.simpleMessage("Rename"),
"reportBugsOnGithubIssue": m10, "reportBugsOnGithubIssue": m9,
"result": MessageLookupByLibrary.simpleMessage("Result"), "result": MessageLookupByLibrary.simpleMessage("Result"),
"run": MessageLookupByLibrary.simpleMessage("Run"), "run": MessageLookupByLibrary.simpleMessage("Run"),
"save": MessageLookupByLibrary.simpleMessage("Save"), "save": MessageLookupByLibrary.simpleMessage("Save"),
@@ -186,11 +184,11 @@ class MessageLookup extends MessageLookupByLibrary {
"sftpSSHConnected": "sftpSSHConnected":
MessageLookupByLibrary.simpleMessage("SFTP Connected"), MessageLookupByLibrary.simpleMessage("SFTP Connected"),
"snippet": MessageLookupByLibrary.simpleMessage("Snippet"), "snippet": MessageLookupByLibrary.simpleMessage("Snippet"),
"spentTime": m11, "spentTime": m10,
"start": MessageLookupByLibrary.simpleMessage("Start"), "start": MessageLookupByLibrary.simpleMessage("Start"),
"stop": MessageLookupByLibrary.simpleMessage("Stop"), "stop": MessageLookupByLibrary.simpleMessage("Stop"),
"sureDelete": m12, "sureDelete": m11,
"sureToDeleteServer": m13, "sureToDeleteServer": m12,
"ttl": MessageLookupByLibrary.simpleMessage("TTL"), "ttl": MessageLookupByLibrary.simpleMessage("TTL"),
"unknown": MessageLookupByLibrary.simpleMessage("unknown"), "unknown": MessageLookupByLibrary.simpleMessage("unknown"),
"unknownError": MessageLookupByLibrary.simpleMessage("Unknown error"), "unknownError": MessageLookupByLibrary.simpleMessage("Unknown error"),
@@ -204,9 +202,9 @@ class MessageLookup extends MessageLookupByLibrary {
"upsideDown": MessageLookupByLibrary.simpleMessage("Upside Down"), "upsideDown": MessageLookupByLibrary.simpleMessage("Upside Down"),
"urlOrJson": MessageLookupByLibrary.simpleMessage("URL or JSON"), "urlOrJson": MessageLookupByLibrary.simpleMessage("URL or JSON"),
"user": MessageLookupByLibrary.simpleMessage("User"), "user": MessageLookupByLibrary.simpleMessage("User"),
"versionHaveUpdate": m14, "versionHaveUpdate": m13,
"versionUnknownUpdate": m15, "versionUnknownUpdate": m14,
"versionUpdated": m16, "versionUpdated": m15,
"waitConnection": MessageLookupByLibrary.simpleMessage( "waitConnection": MessageLookupByLibrary.simpleMessage(
"Please wait for the connection to be established."), "Please wait for the connection to be established."),
"willTakEeffectImmediately": "willTakEeffectImmediately":

View File

@@ -41,21 +41,19 @@ class MessageLookup extends MessageLookupByLibrary {
static String m8(myGithub) => "\n用❤️制作 by ${myGithub}"; static String m8(myGithub) => "\n用❤️制作 by ${myGithub}";
static String m9(user) => "${user}的密码"; static String m9(url) => "请到 ${url} 提交问题";
static String m10(url) => "请到 ${url} 提交问题"; static String m10(time) => "耗时: ${time}";
static String m11(time) => "耗时: ${time}"; static String m11(name) => "确定删除[${name}]";
static String m12(name) => "确定删除[${name}]"; static String m12(server) => "确定删除服务器 [${server}]";
static String m13(server) => "你确定要删除服务器 [${server}] 吗?"; static String m13(build) => "找到新版本v1.0.${build}, 点击更新";
static String m14(build) => "找到新版本v1.0.${build}, 点击更新"; static String m14(build) => "当前v1.0.${build}";
static String m15(build) => "当前v1.0.${build}"; static String m15(build) => "当前v1.0.${build}, 已是最新版本";
static String m16(build) => "当前v1.0.${build}, 已是最新版本";
final messages = _notInlinedMessages(_notInlinedMessages); final messages = _notInlinedMessages(_notInlinedMessages);
static Map<String, Function> _notInlinedMessages(_) => <String, Function>{ static Map<String, Function> _notInlinedMessages(_) => <String, Function>{
@@ -110,6 +108,7 @@ class MessageLookup extends MessageLookupByLibrary {
"invalidVersionHelp": m7, "invalidVersionHelp": m7,
"keepForeground": MessageLookupByLibrary.simpleMessage("请保持应用处于前台!"), "keepForeground": MessageLookupByLibrary.simpleMessage("请保持应用处于前台!"),
"keyAuth": MessageLookupByLibrary.simpleMessage("公钥认证"), "keyAuth": MessageLookupByLibrary.simpleMessage("公钥认证"),
"lastTry": MessageLookupByLibrary.simpleMessage("最后尝试"),
"launchPage": MessageLookupByLibrary.simpleMessage("启动页"), "launchPage": MessageLookupByLibrary.simpleMessage("启动页"),
"license": MessageLookupByLibrary.simpleMessage("开源证书"), "license": MessageLookupByLibrary.simpleMessage("开源证书"),
"loadingFiles": MessageLookupByLibrary.simpleMessage("正在加载目录。。。"), "loadingFiles": MessageLookupByLibrary.simpleMessage("正在加载目录。。。"),
@@ -139,9 +138,8 @@ class MessageLookup extends MessageLookupByLibrary {
"port": MessageLookupByLibrary.simpleMessage("端口"), "port": MessageLookupByLibrary.simpleMessage("端口"),
"privateKey": MessageLookupByLibrary.simpleMessage("私钥"), "privateKey": MessageLookupByLibrary.simpleMessage("私钥"),
"pwd": MessageLookupByLibrary.simpleMessage("密码"), "pwd": MessageLookupByLibrary.simpleMessage("密码"),
"pwdForUser": m9,
"rename": MessageLookupByLibrary.simpleMessage("重命名"), "rename": MessageLookupByLibrary.simpleMessage("重命名"),
"reportBugsOnGithubIssue": m10, "reportBugsOnGithubIssue": m9,
"result": MessageLookupByLibrary.simpleMessage("结果"), "result": MessageLookupByLibrary.simpleMessage("结果"),
"run": MessageLookupByLibrary.simpleMessage("运行"), "run": MessageLookupByLibrary.simpleMessage("运行"),
"save": MessageLookupByLibrary.simpleMessage("保存"), "save": MessageLookupByLibrary.simpleMessage("保存"),
@@ -160,11 +158,11 @@ class MessageLookup extends MessageLookupByLibrary {
"sftpSSHConnected": "sftpSSHConnected":
MessageLookupByLibrary.simpleMessage("SFTP 已连接,即将开始下载..."), MessageLookupByLibrary.simpleMessage("SFTP 已连接,即将开始下载..."),
"snippet": MessageLookupByLibrary.simpleMessage("代码片段"), "snippet": MessageLookupByLibrary.simpleMessage("代码片段"),
"spentTime": m11, "spentTime": m10,
"start": MessageLookupByLibrary.simpleMessage("开始"), "start": MessageLookupByLibrary.simpleMessage("开始"),
"stop": MessageLookupByLibrary.simpleMessage("停止"), "stop": MessageLookupByLibrary.simpleMessage("停止"),
"sureDelete": m12, "sureDelete": m11,
"sureToDeleteServer": m13, "sureToDeleteServer": m12,
"ttl": MessageLookupByLibrary.simpleMessage("缓存时间"), "ttl": MessageLookupByLibrary.simpleMessage("缓存时间"),
"unknown": MessageLookupByLibrary.simpleMessage("未知"), "unknown": MessageLookupByLibrary.simpleMessage("未知"),
"unknownError": MessageLookupByLibrary.simpleMessage("未知错误"), "unknownError": MessageLookupByLibrary.simpleMessage("未知错误"),
@@ -177,9 +175,9 @@ class MessageLookup extends MessageLookupByLibrary {
"upsideDown": MessageLookupByLibrary.simpleMessage("上下交换"), "upsideDown": MessageLookupByLibrary.simpleMessage("上下交换"),
"urlOrJson": MessageLookupByLibrary.simpleMessage("链接或JSON"), "urlOrJson": MessageLookupByLibrary.simpleMessage("链接或JSON"),
"user": MessageLookupByLibrary.simpleMessage("用户"), "user": MessageLookupByLibrary.simpleMessage("用户"),
"versionHaveUpdate": m14, "versionHaveUpdate": m13,
"versionUnknownUpdate": m15, "versionUnknownUpdate": m14,
"versionUpdated": m16, "versionUpdated": m15,
"waitConnection": MessageLookupByLibrary.simpleMessage("请等待连接建立"), "waitConnection": MessageLookupByLibrary.simpleMessage("请等待连接建立"),
"willTakEeffectImmediately": "willTakEeffectImmediately":
MessageLookupByLibrary.simpleMessage("更改将会立即生效") MessageLookupByLibrary.simpleMessage("更改将会立即生效")

View File

@@ -1181,16 +1181,6 @@ class S {
); );
} }
/// `Password for {user}`
String pwdForUser(Object user) {
return Intl.message(
'Password for $user',
name: 'pwdForUser',
desc: '',
args: [user],
);
}
/// `Current platform does not support in app update.\nPlease build from source and install it.` /// `Current platform does not support in app update.\nPlease build from source and install it.`
String get platformNotSupportUpdate { String get platformNotSupportUpdate {
return Intl.message( return Intl.message(
@@ -1220,6 +1210,16 @@ class S {
args: [], args: [],
); );
} }
/// `Last try!`
String get lastTry {
return Intl.message(
'Last try!',
name: 'lastTry',
desc: '',
args: [],
);
}
} }
class AppLocalizationDelegate extends LocalizationsDelegate<S> { class AppLocalizationDelegate extends LocalizationsDelegate<S> {

View File

@@ -112,8 +112,8 @@
"noUpdateAvailable": "No update available", "noUpdateAvailable": "No update available",
"foundNUpdate": "Found {count} update", "foundNUpdate": "Found {count} update",
"updateAll": "Update all", "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}.", "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" "noInterface": "No interface",
"lastTry": "Last try!"
} }

View File

@@ -112,8 +112,8 @@
"noUpdateAvailable": "没有可用更新", "noUpdateAvailable": "没有可用更新",
"foundNUpdate": "找到 {count} 个更新", "foundNUpdate": "找到 {count} 个更新",
"updateAll": "更新全部", "updateAll": "更新全部",
"pwdForUser": "{user}的密码",
"platformNotSupportUpdate": "当前平台不支持更新,请编译最新源码后手动安装", "platformNotSupportUpdate": "当前平台不支持更新,请编译最新源码后手动安装",
"invalidVersionHelp": "请确保正确安装了docker或者使用的非自编译版本。如果没有以上问题请在 {url} 提交问题。", "invalidVersionHelp": "请确保正确安装了docker或者使用的非自编译版本。如果没有以上问题请在 {url} 提交问题。",
"noInterface": "没有可用的接口" "noInterface": "没有可用的接口",
"lastTry": "最后尝试"
} }

View File

@@ -59,16 +59,17 @@ class _AptManagePageState extends State<AptManagePage>
} }
// ignore: prefer_function_declarations_over_variables // ignore: prefer_function_declarations_over_variables
PwdRequestFunc onPwdRequest = (user) async { PwdRequestFunc onPwdRequest = (lastTime, user) async {
if (!mounted) return ''; if (!mounted) return '';
final textController = TextEditingController(); final textController = TextEditingController();
await showRoundDialog( await showRoundDialog(
context, context,
s.pwdForUser(user ?? s.unknown), lastTime ? s.lastTry : (user ?? s.unknown),
TextField( TextField(
controller: textController, controller: textController,
keyboardType: TextInputType.visiblePassword, keyboardType: TextInputType.visiblePassword,
obscureText: true, obscureText: true,
onSubmitted: (_) => textController.text.trim(),
decoration: InputDecoration( decoration: InputDecoration(
labelText: s.pwd, labelText: s.pwd,
), ),

View File

@@ -89,7 +89,8 @@ class _ConvertPageState extends State<ConvertPage>
Widget _buildInputTop() { Widget _buildInputTop() {
return SizedBox( return SizedBox(
height: _media.size.height * 0.33, height: _media.size.height * 0.33,
child: buildInput(context, _textEditingController), child: buildInput(context, _textEditingController,
onSubmitted: (_) => _textEditingControllerResult.text = doConvert()),
); );
} }

View File

@@ -48,7 +48,8 @@ class _PingPageState extends State<PingPage>
padding: const EdgeInsets.symmetric(horizontal: 7), padding: const EdgeInsets.symmetric(horizontal: 7),
child: Column(children: [ child: Column(children: [
const SizedBox(height: 13), const SizedBox(height: 13),
buildInput(context, _textEditingController, maxLines: 1), buildInput(context, _textEditingController,
maxLines: 1, onSubmitted: (_) => doPing()),
_buildControl(), _buildControl(),
SizedBox( SizedBox(
width: double.infinity, width: double.infinity,

View File

@@ -209,7 +209,8 @@ class _ServerPageState extends State<ServerPage>
_buildExplainText('Net'), _buildExplainText('Net'),
_buildExplainText('Disk'), _buildExplainText('Disk'),
], ],
) ),
const SizedBox(height: 3),
], ],
); );
} }
@@ -218,7 +219,7 @@ class _ServerPageState extends State<ServerPage>
return DropdownButtonHideUnderline( return DropdownButtonHideUnderline(
child: DropdownButton2( child: DropdownButton2(
customButton: const Padding( customButton: const Padding(
padding: EdgeInsets.only(left: 7), padding: EdgeInsets.symmetric(horizontal: 5, vertical: 1.7),
child: Icon( child: Icon(
Icons.more_vert, Icons.more_vert,
size: 17, size: 17,

View File

@@ -2,16 +2,21 @@ import 'package:flutter/material.dart';
import 'package:toolbox/view/widget/round_rect_card.dart'; import 'package:toolbox/view/widget/round_rect_card.dart';
Widget buildInput(BuildContext context, TextEditingController controller, Widget buildInput(BuildContext context, TextEditingController controller,
{int maxLines = 20, String? hint}) { {int maxLines = 20,
String? hint,
Function(String)? onSubmitted,
bool? obscureText}) {
return RoundRectCard( return RoundRectCard(
TextField( TextField(
maxLines: maxLines, maxLines: maxLines,
onSubmitted: onSubmitted,
decoration: InputDecoration( decoration: InputDecoration(
fillColor: Theme.of(context).cardColor, fillColor: Theme.of(context).cardColor,
hintText: hint, hintText: hint,
filled: true, filled: true,
border: InputBorder.none), border: InputBorder.none),
controller: controller, controller: controller,
obscureText: obscureText ?? false,
), ),
); );
} }