mirror of
https://github.com/lollipopkit/flutter_server_box.git
synced 2025-12-17 07:14:28 +01:00
opt.
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
import 'package:dynamic_color/dynamic_color.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
||||
import 'package:toolbox/core/extension/context.dart';
|
||||
import 'package:toolbox/core/extension/context/common.dart';
|
||||
import 'package:toolbox/core/extension/locale.dart';
|
||||
|
||||
import 'core/utils/ui.dart';
|
||||
|
||||
11
lib/core/extension/context/common.dart
Normal file
11
lib/core/extension/context/common.dart
Normal file
@@ -0,0 +1,11 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
extension ContextX on BuildContext {
|
||||
void pop<T extends Object?>([T? result]) {
|
||||
Navigator.of(this).pop<T>(result);
|
||||
}
|
||||
|
||||
bool get canPop => Navigator.of(this).canPop();
|
||||
|
||||
bool get isDark => Theme.of(this).brightness == Brightness.dark;
|
||||
}
|
||||
@@ -1,55 +1,14 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
||||
import 'package:toolbox/view/widget/rebuild.dart';
|
||||
import 'package:toolbox/core/extension/context/common.dart';
|
||||
|
||||
import '../../data/model/server/snippet.dart';
|
||||
import '../../data/provider/snippet.dart';
|
||||
import '../../data/res/ui.dart';
|
||||
import '../../locator.dart';
|
||||
import '../../view/widget/input_field.dart';
|
||||
import '../../view/widget/picker.dart';
|
||||
import '../route.dart';
|
||||
|
||||
extension ContextX on BuildContext {
|
||||
void pop<T extends Object?>([T? result]) {
|
||||
Navigator.of(this).pop<T>(result);
|
||||
}
|
||||
|
||||
bool get canPop => Navigator.of(this).canPop();
|
||||
|
||||
bool get isDark => Theme.of(this).brightness == Brightness.dark;
|
||||
}
|
||||
|
||||
extension SnackBarX on BuildContext {
|
||||
void showSnackBar(String text) =>
|
||||
ScaffoldMessenger.of(this).showSnackBar(SnackBar(
|
||||
content: Text(text),
|
||||
behavior: SnackBarBehavior.floating,
|
||||
));
|
||||
|
||||
void showSnackBarWithAction(
|
||||
String content,
|
||||
String action,
|
||||
GestureTapCallback onTap,
|
||||
) {
|
||||
ScaffoldMessenger.of(this).showSnackBar(SnackBar(
|
||||
content: Text(content),
|
||||
behavior: SnackBarBehavior.floating,
|
||||
action: SnackBarAction(
|
||||
label: action,
|
||||
onPressed: onTap,
|
||||
),
|
||||
));
|
||||
}
|
||||
|
||||
void showRestartSnackbar({String? btn, String? msg}) {
|
||||
showSnackBarWithAction(
|
||||
msg ?? 'Need restart to take effect',
|
||||
btn ?? 'Restart',
|
||||
() => RebuildWidget.restartApp(this),
|
||||
);
|
||||
}
|
||||
}
|
||||
import '../../../data/model/server/snippet.dart';
|
||||
import '../../../data/provider/snippet.dart';
|
||||
import '../../../data/res/ui.dart';
|
||||
import '../../../locator.dart';
|
||||
import '../../../view/widget/input_field.dart';
|
||||
import '../../../view/widget/picker.dart';
|
||||
import '../../route.dart';
|
||||
|
||||
extension DialogX on BuildContext {
|
||||
Future<T?> showRoundDialog<T>({
|
||||
@@ -74,7 +33,7 @@ extension DialogX on BuildContext {
|
||||
|
||||
void showLoadingDialog({bool barrierDismiss = false}) {
|
||||
showRoundDialog(
|
||||
child: centerSizedLoading,
|
||||
child: UIs.centerSizedLoading,
|
||||
barrierDismiss: barrierDismiss,
|
||||
);
|
||||
}
|
||||
33
lib/core/extension/context/snackbar.dart
Normal file
33
lib/core/extension/context/snackbar.dart
Normal file
@@ -0,0 +1,33 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:toolbox/view/widget/rebuild.dart';
|
||||
|
||||
extension SnackBarX on BuildContext {
|
||||
void showSnackBar(String text) =>
|
||||
ScaffoldMessenger.of(this).showSnackBar(SnackBar(
|
||||
content: Text(text),
|
||||
behavior: SnackBarBehavior.floating,
|
||||
));
|
||||
|
||||
void showSnackBarWithAction(
|
||||
String content,
|
||||
String action,
|
||||
GestureTapCallback onTap,
|
||||
) {
|
||||
ScaffoldMessenger.of(this).showSnackBar(SnackBar(
|
||||
content: Text(content),
|
||||
behavior: SnackBarBehavior.floating,
|
||||
action: SnackBarAction(
|
||||
label: action,
|
||||
onPressed: onTap,
|
||||
),
|
||||
));
|
||||
}
|
||||
|
||||
void showRestartSnackbar({String? btn, String? msg}) {
|
||||
showSnackBarWithAction(
|
||||
msg ?? 'Need restart to take effect',
|
||||
btn ?? 'Restart',
|
||||
() => RebuildWidget.restartApp(this),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,7 @@ import 'dart:async';
|
||||
import 'package:dartssh2/dartssh2.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:toolbox/core/extension/context.dart';
|
||||
import 'package:toolbox/core/extension/context/dialog.dart';
|
||||
import 'package:toolbox/core/extension/stringx.dart';
|
||||
import 'package:toolbox/core/extension/uint8list.dart';
|
||||
|
||||
@@ -70,7 +70,7 @@ extension SSHClientX on SSHClient {
|
||||
if (isRequestingPwd) return;
|
||||
isRequestingPwd = true;
|
||||
if (data.contains('[sudo] password for ')) {
|
||||
final user = pwdRequestWithUserReg.firstMatch(data)?.group(1);
|
||||
final user = Miscs.pwdRequestWithUserReg.firstMatch(data)?.group(1);
|
||||
if (context == null) return;
|
||||
final pwd = await context.showPwdDialog(user);
|
||||
if (pwd == null || pwd.isEmpty) {
|
||||
|
||||
@@ -4,7 +4,9 @@ import 'package:dio/dio.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
||||
import 'package:r_upgrade/r_upgrade.dart';
|
||||
import 'package:toolbox/core/extension/context.dart';
|
||||
import 'package:toolbox/core/extension/context/common.dart';
|
||||
import 'package:toolbox/core/extension/context/dialog.dart';
|
||||
import 'package:toolbox/core/extension/context/snackbar.dart';
|
||||
import 'package:toolbox/data/model/app/update.dart';
|
||||
import 'package:toolbox/data/res/logger.dart';
|
||||
import 'package:toolbox/data/res/path.dart';
|
||||
@@ -103,10 +105,8 @@ Future<void> _doUpdate(AppUpdate update, BuildContext context, S? s) async {
|
||||
// rmdir Download
|
||||
Future<void> _rmDownloadApks() async {
|
||||
if (!isAndroid) return;
|
||||
final dlDir = Directory(await _dlDir);
|
||||
final dlDir = Directory(await Paths.dl);
|
||||
if (await dlDir.exists()) {
|
||||
await dlDir.delete(recursive: true);
|
||||
}
|
||||
}
|
||||
|
||||
Future<String> get _dlDir async => joinPath(await docDir, 'Download');
|
||||
|
||||
@@ -29,7 +29,7 @@ class ICloud {
|
||||
final completer = Completer<ICloudErr?>();
|
||||
await ICloudStorage.upload(
|
||||
containerId: _containerId,
|
||||
filePath: localPath ?? '${await docDir}/$relativePath',
|
||||
filePath: localPath ?? '${await Paths.doc}/$relativePath',
|
||||
destinationRelativePath: relativePath,
|
||||
onProgress: (stream) {
|
||||
stream.listen(
|
||||
@@ -73,7 +73,7 @@ class ICloud {
|
||||
await ICloudStorage.download(
|
||||
containerId: _containerId,
|
||||
relativePath: relativePath,
|
||||
destinationFilePath: localPath ?? '${await docDir}/$relativePath',
|
||||
destinationFilePath: localPath ?? '${await Paths.doc}/$relativePath',
|
||||
onProgress: (stream) {
|
||||
stream.listen(
|
||||
null,
|
||||
@@ -122,7 +122,7 @@ class ICloud {
|
||||
}
|
||||
}));
|
||||
|
||||
final docPath = await docDir;
|
||||
final docPath = await Paths.doc;
|
||||
|
||||
/// compare files in iCloud and local
|
||||
mission.addAll(allFiles.map((file) async {
|
||||
@@ -176,7 +176,7 @@ class ICloud {
|
||||
|
||||
static Future<void> syncDb() async {
|
||||
if (!isIOS && !isMacOS) return;
|
||||
final docPath = await docDir;
|
||||
final docPath = await Paths.doc;
|
||||
final dir = Directory(docPath);
|
||||
final files = await dir.list().toList();
|
||||
// filter out non-hive(db) files
|
||||
|
||||
@@ -70,7 +70,7 @@ class Backup {
|
||||
|
||||
static Future<void> backup() async {
|
||||
final result = _diyEncrtpt(json.encode(Backup.loadFromStore()));
|
||||
await File(await backupPath).writeAsString(result);
|
||||
await File(await Paths.bak).writeAsString(result);
|
||||
}
|
||||
|
||||
Future<void> restore() async {
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import 'package:flutter/widgets.dart';
|
||||
|
||||
import '../../../core/extension/context.dart';
|
||||
import 'package:toolbox/core/extension/context/common.dart';
|
||||
|
||||
class DynamicColor {
|
||||
/// 白天模式显示的颜色
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import '../../res/build_data.dart';
|
||||
import '../../res/server_cmd.dart';
|
||||
import '../server/system.dart';
|
||||
|
||||
const seperator = 'SrvBoxSep';
|
||||
|
||||
const _cmdDivider = '\necho $seperator\n\t';
|
||||
|
||||
const _serverBoxDir = r'$HOME/.config/server_box';
|
||||
|
||||
@@ -20,7 +20,7 @@ Conn? parseConn(String raw) {
|
||||
final idx = lines.lastWhere((element) => element.startsWith('Tcp:'),
|
||||
orElse: () => '');
|
||||
if (idx != '') {
|
||||
final vals = idx.split(numReg);
|
||||
final vals = idx.split(Miscs.numReg);
|
||||
return Conn(
|
||||
maxConn: vals[5].i,
|
||||
active: vals[6].i,
|
||||
|
||||
@@ -27,7 +27,7 @@ List<Disk> parseDisk(String raw) {
|
||||
if (item.isEmpty) {
|
||||
continue;
|
||||
}
|
||||
final vals = item.split(numReg);
|
||||
final vals = item.split(Miscs.numReg);
|
||||
if (vals.length == 1) {
|
||||
pathCache = vals[0];
|
||||
continue;
|
||||
|
||||
@@ -93,7 +93,7 @@ class Proc {
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return jsonEncoder.convert(toJson());
|
||||
return Miscs.jsonEncoder.convert(toJson());
|
||||
}
|
||||
|
||||
String get binary {
|
||||
|
||||
@@ -52,9 +52,9 @@ class DebugProvider extends ChangeNotifier {
|
||||
|
||||
void _addWidget(Widget widget) {
|
||||
widgets.add(widget);
|
||||
widgets.add(height13);
|
||||
if (widgets.length > maxDebugLogLines) {
|
||||
widgets.removeRange(0, widgets.length - maxDebugLogLines);
|
||||
widgets.add(UIs.height13);
|
||||
if (widgets.length > Miscs.maxDebugLogLines) {
|
||||
widgets.removeRange(0, widgets.length - Miscs.maxDebugLogLines);
|
||||
}
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
@@ -12,8 +12,6 @@ import 'package:toolbox/data/res/logger.dart';
|
||||
import 'package:toolbox/data/store/docker.dart';
|
||||
import 'package:toolbox/locator.dart';
|
||||
|
||||
import '../res/server_cmd.dart';
|
||||
|
||||
final _dockerNotFound = RegExp(r'command not found|Unknown command');
|
||||
final _versionReg = RegExp(r'(Version:)\s+([0-9]+\.[0-9]+\.[0-9]+)');
|
||||
// eg: `Docker Engine - Community`
|
||||
|
||||
@@ -14,7 +14,6 @@ import '../model/server/server_private_info.dart';
|
||||
import '../model/server/server_status_update_req.dart';
|
||||
import '../model/server/snippet.dart';
|
||||
import '../model/server/try_limiter.dart';
|
||||
import '../res/server_cmd.dart';
|
||||
import '../res/status.dart';
|
||||
import '../store/server.dart';
|
||||
import '../store/setting.dart';
|
||||
|
||||
@@ -4,6 +4,8 @@ import '../model/app/dynamic_color.dart';
|
||||
|
||||
late Color primaryColor;
|
||||
|
||||
const contentColor = DynamicColor(Colors.black87, Colors.white70);
|
||||
const bgColor = DynamicColor(Colors.white, Colors.black);
|
||||
const progressColor = DynamicColor(Colors.black12, Colors.white10);
|
||||
class DynamicColors {
|
||||
static const content = DynamicColor(Colors.black87, Colors.white70);
|
||||
static const bg = DynamicColor(Colors.white, Colors.black);
|
||||
static const progress = DynamicColor(Colors.black12, Colors.white10);
|
||||
}
|
||||
|
||||
@@ -2,48 +2,50 @@ import 'dart:ui';
|
||||
|
||||
import 'package:toolbox/data/model/ssh/virtual_key.dart';
|
||||
|
||||
// default server details page cards order
|
||||
const defaultDetailCardOrder = [
|
||||
'uptime',
|
||||
'cpu',
|
||||
'mem',
|
||||
'swap',
|
||||
'disk',
|
||||
'net',
|
||||
'temp'
|
||||
];
|
||||
class Defaults {
|
||||
// default server details page cards order
|
||||
static const detailCardOrder = [
|
||||
'uptime',
|
||||
'cpu',
|
||||
'mem',
|
||||
'swap',
|
||||
'disk',
|
||||
'net',
|
||||
'temp'
|
||||
];
|
||||
|
||||
const defaultDiskIgnorePath = [
|
||||
'udev',
|
||||
'tmpfs',
|
||||
'devtmpfs',
|
||||
'overlay',
|
||||
'run',
|
||||
'none',
|
||||
];
|
||||
static const diskIgnorePath = [
|
||||
'udev',
|
||||
'tmpfs',
|
||||
'devtmpfs',
|
||||
'overlay',
|
||||
'run',
|
||||
'none',
|
||||
];
|
||||
|
||||
const defaultSSHVirtKeys = [
|
||||
VirtKey.esc,
|
||||
VirtKey.alt,
|
||||
VirtKey.home,
|
||||
VirtKey.up,
|
||||
VirtKey.end,
|
||||
VirtKey.sftp,
|
||||
VirtKey.snippet,
|
||||
VirtKey.tab,
|
||||
VirtKey.ctrl,
|
||||
VirtKey.left,
|
||||
VirtKey.down,
|
||||
VirtKey.right,
|
||||
VirtKey.clipboard,
|
||||
VirtKey.ime,
|
||||
];
|
||||
static const sshVirtKeys = [
|
||||
VirtKey.esc,
|
||||
VirtKey.alt,
|
||||
VirtKey.home,
|
||||
VirtKey.up,
|
||||
VirtKey.end,
|
||||
VirtKey.sftp,
|
||||
VirtKey.snippet,
|
||||
VirtKey.tab,
|
||||
VirtKey.ctrl,
|
||||
VirtKey.left,
|
||||
VirtKey.down,
|
||||
VirtKey.right,
|
||||
VirtKey.clipboard,
|
||||
VirtKey.ime,
|
||||
];
|
||||
|
||||
const defaultPrimaryColor = Color.fromARGB(255, 145, 58, 31);
|
||||
static const primaryColor = Color.fromARGB(255, 145, 58, 31);
|
||||
|
||||
const defaultLaunchPageIdx = 0;
|
||||
static const launchPageIdx = 0;
|
||||
|
||||
const defaultUpdateInterval = 3;
|
||||
static const updateInterval = 3;
|
||||
|
||||
const defaultEditorTheme = 'a11y-light';
|
||||
const defaultEditorDarkTheme = 'monokai';
|
||||
static const editorTheme = 'a11y-light';
|
||||
static const editorDarkTheme = 'monokai';
|
||||
}
|
||||
|
||||
38
lib/data/res/github_id.dart
Normal file
38
lib/data/res/github_id.dart
Normal file
@@ -0,0 +1,38 @@
|
||||
import 'package:toolbox/data/model/app/github_id.dart';
|
||||
|
||||
class GithubIds {
|
||||
// Thanks
|
||||
// If you want to change the url, please open an issue.
|
||||
static const contributors = <GhId>{
|
||||
'its-tom',
|
||||
'RainSunMe',
|
||||
'kalashnikov',
|
||||
'azkadev',
|
||||
'calvinweb',
|
||||
'Liloupar'
|
||||
};
|
||||
static const participants = <GhId>{
|
||||
'jaychoubaby',
|
||||
'fecture',
|
||||
'Tao173',
|
||||
'QingAnLe',
|
||||
'wxdjs',
|
||||
'Aeorq',
|
||||
'allonmymind',
|
||||
'Yuuki-Rin',
|
||||
'LittleState',
|
||||
'karuboniru',
|
||||
'whosphp',
|
||||
'Climit',
|
||||
'dianso',
|
||||
'Jasondeepny',
|
||||
'kaliwell',
|
||||
'ymxkiss',
|
||||
'Ealrang',
|
||||
'hange33',
|
||||
'yuchen1204',
|
||||
'xgzxmytx',
|
||||
'wind057',
|
||||
'a1564471347',
|
||||
};
|
||||
}
|
||||
@@ -1,4 +1,3 @@
|
||||
import 'package:highlight/highlight_core.dart';
|
||||
import 'package:highlight/languages/accesslog.dart';
|
||||
import 'package:highlight/languages/awk.dart';
|
||||
import 'package:highlight/languages/bash.dart';
|
||||
@@ -33,52 +32,48 @@ import 'package:highlight/languages/vim.dart';
|
||||
import 'package:highlight/languages/xml.dart';
|
||||
import 'package:highlight/languages/yaml.dart';
|
||||
|
||||
// KEY: fileNameSuffix
|
||||
// VAL: highlight
|
||||
final suffix2HighlightMap = {
|
||||
'dart': dart,
|
||||
'go': go,
|
||||
'rust': rust,
|
||||
'lua': lua,
|
||||
'sh': bash,
|
||||
'py': python,
|
||||
'js': javascript,
|
||||
'ts': typescript,
|
||||
'java': java,
|
||||
'kt': kotlin,
|
||||
'swift': swift,
|
||||
'c': cpp,
|
||||
'oc': objectivec,
|
||||
'ruby': ruby,
|
||||
'perl': perl,
|
||||
'php': php,
|
||||
'nix': nix,
|
||||
'lisp': lisp,
|
||||
'sql': sql,
|
||||
'powershell': powershell,
|
||||
'log': accesslog,
|
||||
'ini': ini,
|
||||
'cmake': cmake,
|
||||
'awk': awk,
|
||||
'json': json,
|
||||
'yaml': yaml,
|
||||
'xml': xml,
|
||||
'cpp': cpp,
|
||||
'diff': diff,
|
||||
'css': css,
|
||||
'html': htmlbars,
|
||||
'tex': tex,
|
||||
'vim': vim,
|
||||
'plaintext': plaintext,
|
||||
};
|
||||
class Highlights {
|
||||
/// - KEY: fileNameSuffix
|
||||
/// - VAL: highlight
|
||||
static final all = {
|
||||
'dart': dart,
|
||||
'go': go,
|
||||
'rust': rust,
|
||||
'lua': lua,
|
||||
'sh': bash,
|
||||
'py': python,
|
||||
'js': javascript,
|
||||
'ts': typescript,
|
||||
'java': java,
|
||||
'kt': kotlin,
|
||||
'swift': swift,
|
||||
'c': cpp,
|
||||
'oc': objectivec,
|
||||
'ruby': ruby,
|
||||
'perl': perl,
|
||||
'php': php,
|
||||
'nix': nix,
|
||||
'lisp': lisp,
|
||||
'sql': sql,
|
||||
'powershell': powershell,
|
||||
'log': accesslog,
|
||||
'ini': ini,
|
||||
'cmake': cmake,
|
||||
'awk': awk,
|
||||
'json': json,
|
||||
'yaml': yaml,
|
||||
'xml': xml,
|
||||
'cpp': cpp,
|
||||
'diff': diff,
|
||||
'css': css,
|
||||
'html': htmlbars,
|
||||
'tex': tex,
|
||||
'vim': vim,
|
||||
'plaintext': plaintext,
|
||||
};
|
||||
|
||||
extension HighlightString on String? {
|
||||
Mode? get highlight {
|
||||
return suffix2HighlightMap[highlightCode];
|
||||
}
|
||||
|
||||
String? get highlightCode {
|
||||
if (this == null) return null;
|
||||
return this!.split('.').last;
|
||||
static String? getCode(String? fileName) {
|
||||
if (fileName == null) return null;
|
||||
return fileName.split('.').last;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,61 +2,26 @@ import 'dart:convert';
|
||||
|
||||
import 'package:flutter/services.dart';
|
||||
|
||||
import '../model/app/github_id.dart';
|
||||
class Miscs {
|
||||
/// RegExp for number
|
||||
static final numReg = RegExp(r'\s{1,}');
|
||||
|
||||
/// RegExp for number
|
||||
final numReg = RegExp(r'\s{1,}');
|
||||
/// RegExp for password request
|
||||
static final pwdRequestWithUserReg = RegExp(r'\[sudo\] password for (.+):');
|
||||
|
||||
/// RegExp for password request
|
||||
final pwdRequestWithUserReg = RegExp(r'\[sudo\] password for (.+):');
|
||||
|
||||
/// Private Key max allowed size is 20kb
|
||||
const privateKeyMaxSize = 20 * 1024;
|
||||
/// Private Key max allowed size is 20kb
|
||||
static const privateKeyMaxSize = 20 * 1024;
|
||||
|
||||
// Editor max allowed size is 1mb
|
||||
const editorMaxSize = 1024 * 1024;
|
||||
static const editorMaxSize = 1024 * 1024;
|
||||
|
||||
/// Max debug log lines
|
||||
const maxDebugLogLines = 100;
|
||||
/// Max debug log lines
|
||||
static const maxDebugLogLines = 100;
|
||||
|
||||
/// Method Channels
|
||||
const pkgName = 'tech.lolli.toolbox';
|
||||
const bgRunChannel = MethodChannel('$pkgName/app_retain');
|
||||
const homeWidgetChannel = MethodChannel('$pkgName/home_widget');
|
||||
/// Method Channels
|
||||
static const pkgName = 'tech.lolli.toolbox';
|
||||
static const bgRunChannel = MethodChannel('$pkgName/app_retain');
|
||||
static const homeWidgetChannel = MethodChannel('$pkgName/home_widget');
|
||||
|
||||
// Thanks
|
||||
// If you want to change the url, please open an issue.
|
||||
const contributors = <GhId>{
|
||||
'its-tom',
|
||||
'RainSunMe',
|
||||
'kalashnikov',
|
||||
'azkadev',
|
||||
'calvinweb',
|
||||
'Liloupar'
|
||||
};
|
||||
const participants = <GhId>{
|
||||
'jaychoubaby',
|
||||
'fecture',
|
||||
'Tao173',
|
||||
'QingAnLe',
|
||||
'wxdjs',
|
||||
'Aeorq',
|
||||
'allonmymind',
|
||||
'Yuuki-Rin',
|
||||
'LittleState',
|
||||
'karuboniru',
|
||||
'whosphp',
|
||||
'Climit',
|
||||
'dianso',
|
||||
'Jasondeepny',
|
||||
'kaliwell',
|
||||
'ymxkiss',
|
||||
'Ealrang',
|
||||
'hange33',
|
||||
'yuchen1204',
|
||||
'xgzxmytx',
|
||||
'wind057',
|
||||
'a1564471347',
|
||||
};
|
||||
|
||||
const jsonEncoder = JsonEncoder.withIndent(' ');
|
||||
static const jsonEncoder = JsonEncoder.withIndent(' ');
|
||||
}
|
||||
|
||||
@@ -3,45 +3,49 @@ import 'dart:io';
|
||||
import 'package:path_provider/path_provider.dart';
|
||||
import 'package:toolbox/core/utils/platform.dart';
|
||||
|
||||
String? _docDir;
|
||||
String? _sftpDir;
|
||||
String? _fontDir;
|
||||
class Paths {
|
||||
static String? _docDir;
|
||||
static String? _sftpDir;
|
||||
static String? _fontDir;
|
||||
|
||||
Future<String> get docDir async {
|
||||
if (_docDir != null) {
|
||||
return _docDir!;
|
||||
}
|
||||
if (isAndroid) {
|
||||
final dir = await getExternalStorageDirectory();
|
||||
if (dir != null) {
|
||||
_docDir = dir.path;
|
||||
return dir.path;
|
||||
static Future<String> get doc async {
|
||||
if (_docDir != null) {
|
||||
return _docDir!;
|
||||
}
|
||||
// fallthrough to getApplicationDocumentsDirectory
|
||||
if (isAndroid) {
|
||||
final dir = await getExternalStorageDirectory();
|
||||
if (dir != null) {
|
||||
_docDir = dir.path;
|
||||
return dir.path;
|
||||
}
|
||||
// fallthrough to getApplicationDocumentsDirectory
|
||||
}
|
||||
final dir = await getApplicationDocumentsDirectory();
|
||||
_docDir = dir.path;
|
||||
return dir.path;
|
||||
}
|
||||
final dir = await getApplicationDocumentsDirectory();
|
||||
_docDir = dir.path;
|
||||
return dir.path;
|
||||
}
|
||||
|
||||
Future<String> get sftpDir async {
|
||||
if (_sftpDir != null) {
|
||||
static Future<String> get sftp async {
|
||||
if (_sftpDir != null) {
|
||||
return _sftpDir!;
|
||||
}
|
||||
_sftpDir = '${await doc}/sftp';
|
||||
final dir = Directory(_sftpDir!);
|
||||
await dir.create(recursive: true);
|
||||
return _sftpDir!;
|
||||
}
|
||||
_sftpDir = '${await docDir}/sftp';
|
||||
final dir = Directory(_sftpDir!);
|
||||
await dir.create(recursive: true);
|
||||
return _sftpDir!;
|
||||
}
|
||||
|
||||
Future<String> get fontDir async {
|
||||
if (_fontDir != null) {
|
||||
static Future<String> get font async {
|
||||
if (_fontDir != null) {
|
||||
return _fontDir!;
|
||||
}
|
||||
_fontDir = '${await doc}/font';
|
||||
final dir = Directory(_fontDir!);
|
||||
await dir.create(recursive: true);
|
||||
return _fontDir!;
|
||||
}
|
||||
_fontDir = '${await docDir}/font';
|
||||
final dir = Directory(_fontDir!);
|
||||
await dir.create(recursive: true);
|
||||
return _fontDir!;
|
||||
}
|
||||
|
||||
Future<String> get backupPath async => '${await docDir}/srvbox_bak.json';
|
||||
static Future<String> get bak async => '${await doc}/srvbox_bak.json';
|
||||
|
||||
static Future<String> get dl async => joinPath(await doc, 'dl');
|
||||
}
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
const seperator = 'SrvBoxSep';
|
||||
@@ -1,52 +1,55 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
/// Font style
|
||||
class UIs {
|
||||
/// Font style
|
||||
|
||||
const textSize9Grey = TextStyle(color: Colors.grey, fontSize: 9);
|
||||
const textSize11 = TextStyle(fontSize: 11);
|
||||
const textSize11Grey = TextStyle(color: Colors.grey, fontSize: 11);
|
||||
const textSize13 = TextStyle(fontSize: 13);
|
||||
const textSize13Bold = TextStyle(fontSize: 13, fontWeight: FontWeight.bold);
|
||||
const textSize13Grey = TextStyle(color: Colors.grey, fontSize: 13);
|
||||
const textSize15 = TextStyle(fontSize: 15);
|
||||
const textSize18 = TextStyle(fontSize: 18);
|
||||
const textSize27 = TextStyle(fontSize: 27);
|
||||
static const textSize9Grey = TextStyle(color: Colors.grey, fontSize: 9);
|
||||
static const textSize11 = TextStyle(fontSize: 11);
|
||||
static const textSize11Grey = TextStyle(color: Colors.grey, fontSize: 11);
|
||||
static const textSize13 = TextStyle(fontSize: 13);
|
||||
static const textSize13Bold =
|
||||
TextStyle(fontSize: 13, fontWeight: FontWeight.bold);
|
||||
static const textSize13Grey = TextStyle(color: Colors.grey, fontSize: 13);
|
||||
static const textSize15 = TextStyle(fontSize: 15);
|
||||
static const textSize18 = TextStyle(fontSize: 18);
|
||||
static const textSize27 = TextStyle(fontSize: 27);
|
||||
static const textGrey = TextStyle(color: Colors.grey);
|
||||
static const textRed = TextStyle(color: Colors.red);
|
||||
|
||||
const grey = TextStyle(color: Colors.grey);
|
||||
const textRed = TextStyle(color: Colors.red);
|
||||
/// Icon
|
||||
|
||||
/// Icon
|
||||
static final appIcon = Image.asset('assets/app_icon.png');
|
||||
|
||||
final appIcon = Image.asset('assets/app_icon.png');
|
||||
/// Padding
|
||||
|
||||
/// Padding
|
||||
static const roundRectCardPadding =
|
||||
EdgeInsets.symmetric(horizontal: 17, vertical: 13);
|
||||
|
||||
const roundRectCardPadding = EdgeInsets.symmetric(horizontal: 17, vertical: 13);
|
||||
/// SizedBox
|
||||
|
||||
/// SizedBox
|
||||
static const placeholder = SizedBox();
|
||||
static const height13 = SizedBox(height: 13);
|
||||
static const height77 = SizedBox(height: 77);
|
||||
static const width13 = SizedBox(width: 13);
|
||||
static const width7 = SizedBox(width: 7);
|
||||
|
||||
const placeholder = SizedBox();
|
||||
const height13 = SizedBox(height: 13);
|
||||
const height77 = SizedBox(height: 77);
|
||||
const width13 = SizedBox(width: 13);
|
||||
const width7 = SizedBox(width: 7);
|
||||
/// Misc
|
||||
|
||||
/// Misc
|
||||
static const popMenuChild = Padding(
|
||||
padding: EdgeInsets.only(left: 7),
|
||||
child: Icon(
|
||||
Icons.more_vert,
|
||||
size: 21,
|
||||
),
|
||||
);
|
||||
|
||||
const popMenuChild = Padding(
|
||||
padding: EdgeInsets.only(left: 7),
|
||||
child: Icon(
|
||||
Icons.more_vert,
|
||||
size: 21,
|
||||
),
|
||||
);
|
||||
static const centerLoading = Center(child: CircularProgressIndicator());
|
||||
|
||||
const centerLoading = Center(child: CircularProgressIndicator());
|
||||
|
||||
const centerSizedLoading = SizedBox(
|
||||
width: 77,
|
||||
height: 77,
|
||||
child: Center(
|
||||
child: CircularProgressIndicator(),
|
||||
),
|
||||
);
|
||||
static const centerSizedLoading = SizedBox(
|
||||
width: 77,
|
||||
height: 77,
|
||||
child: Center(
|
||||
child: CircularProgressIndicator(),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
const baseResUrl = 'https://res.lolli.tech/serverbox';
|
||||
const myGithub = 'https://github.com/lollipopkit';
|
||||
const appHelpUrl = '$myGithub/flutter_server_box#-help';
|
||||
const appWikiUrl = '$myGithub/flutter_server_box/wiki';
|
||||
class Urls {
|
||||
static const resBase = 'https://res.lolli.tech/serverbox';
|
||||
static const myGithub = 'https://github.com/lollipopkit';
|
||||
static const appHelp = '$myGithub/flutter_server_box#-help';
|
||||
static const appWiki = '$myGithub/flutter_server_box/wiki';
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ import '../res/url.dart';
|
||||
|
||||
class AppService {
|
||||
Future<AppUpdate> getUpdate() async {
|
||||
final resp = await Dio().get('$baseResUrl/update.json');
|
||||
final resp = await Dio().get('${Urls.resBase}/update.json');
|
||||
return AppUpdate.fromJson(resp.data);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,12 +52,12 @@ class SettingStore extends PersistentStore {
|
||||
late final launchPage = StoreProperty(
|
||||
box,
|
||||
'launchPage',
|
||||
defaultLaunchPageIdx,
|
||||
Defaults.launchPageIdx,
|
||||
);
|
||||
|
||||
/// Server detail disk ignore path
|
||||
late final diskIgnorePath =
|
||||
StoreListProperty(box, 'diskIgnorePath', defaultDiskIgnorePath);
|
||||
StoreListProperty(box, 'diskIgnorePath', Defaults.diskIgnorePath);
|
||||
|
||||
/// Use double column servers page on Desktop
|
||||
late final doubleColumnServersPage = StoreProperty(
|
||||
@@ -77,7 +77,7 @@ class SettingStore extends PersistentStore {
|
||||
late final serverStatusUpdateInterval = StoreProperty(
|
||||
box,
|
||||
'serverStatusUpdateInterval',
|
||||
defaultUpdateInterval,
|
||||
Defaults.updateInterval,
|
||||
);
|
||||
|
||||
// Max retry count when connect to server
|
||||
@@ -99,7 +99,7 @@ class SettingStore extends PersistentStore {
|
||||
|
||||
// Server details page cards order
|
||||
late final detailCardOrder =
|
||||
StoreListProperty(box, 'detailCardPrder', defaultDetailCardOrder);
|
||||
StoreListProperty(box, 'detailCardPrder', Defaults.detailCardOrder);
|
||||
|
||||
// SSH term font size
|
||||
late final termFontSize = StoreProperty(box, 'termFontSize', 13.0);
|
||||
@@ -117,13 +117,13 @@ class SettingStore extends PersistentStore {
|
||||
late final editorTheme = StoreProperty(
|
||||
box,
|
||||
'editorTheme',
|
||||
defaultEditorTheme,
|
||||
Defaults.editorTheme,
|
||||
);
|
||||
|
||||
late final editorDarkTheme = StoreProperty(
|
||||
box,
|
||||
'editorDarkTheme',
|
||||
defaultEditorDarkTheme,
|
||||
Defaults.editorDarkTheme,
|
||||
);
|
||||
|
||||
late final fullScreen = StoreProperty(
|
||||
@@ -153,7 +153,7 @@ class SettingStore extends PersistentStore {
|
||||
late final sshVirtKeys = StoreListProperty(
|
||||
box,
|
||||
'sshVirtKeys',
|
||||
defaultSSHVirtKeys,
|
||||
Defaults.sshVirtKeys,
|
||||
);
|
||||
|
||||
late final netViewType = StoreProperty(
|
||||
|
||||
@@ -100,7 +100,7 @@ Future<void> initApp() async {
|
||||
if (isAndroid) {
|
||||
// Only start service when [bgRun] is true.
|
||||
if (locator<SettingStore>().bgRun.fetch()) {
|
||||
bgRunChannel.invokeMethod('startService');
|
||||
Miscs.bgRunChannel.invokeMethod('startService');
|
||||
}
|
||||
// SharedPreferences is only used on Android for saving home widgets settings.
|
||||
SharedPreferences.setPrefix('');
|
||||
|
||||
@@ -4,7 +4,9 @@ import 'dart:io';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
||||
import 'package:toolbox/core/extension/context.dart';
|
||||
import 'package:toolbox/core/extension/context/common.dart';
|
||||
import 'package:toolbox/core/extension/context/dialog.dart';
|
||||
import 'package:toolbox/core/extension/context/snackbar.dart';
|
||||
import 'package:toolbox/core/utils/platform.dart';
|
||||
import 'package:toolbox/data/model/app/backup.dart';
|
||||
import 'package:toolbox/data/res/logger.dart';
|
||||
@@ -28,7 +30,7 @@ class BackupPage extends StatelessWidget {
|
||||
final s = S.of(context)!;
|
||||
return Scaffold(
|
||||
appBar: CustomAppBar(
|
||||
title: Text(s.backupAndRestore, style: textSize18),
|
||||
title: Text(s.backupAndRestore, style: UIs.textSize18),
|
||||
),
|
||||
body: _buildBody(context, s),
|
||||
);
|
||||
@@ -40,7 +42,7 @@ class BackupPage extends StatelessWidget {
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
if (isMacOS || isIOS) _buildIcloudSync(context, s),
|
||||
height13,
|
||||
UIs.height13,
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(37),
|
||||
child: Text(
|
||||
@@ -48,24 +50,24 @@ class BackupPage extends StatelessWidget {
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
),
|
||||
height77,
|
||||
UIs.height77,
|
||||
_buildCard(
|
||||
s.restore,
|
||||
Icons.download,
|
||||
() => _onRestore(context, s),
|
||||
),
|
||||
height13,
|
||||
UIs.height13,
|
||||
const SizedBox(
|
||||
width: 37,
|
||||
child: Divider(),
|
||||
),
|
||||
height13,
|
||||
UIs.height13,
|
||||
_buildCard(
|
||||
s.backup,
|
||||
Icons.save,
|
||||
() async {
|
||||
await Backup.backup();
|
||||
await shareFiles(context, [await backupPath]);
|
||||
await shareFiles(context, [await Paths.bak]);
|
||||
},
|
||||
)
|
||||
],
|
||||
@@ -87,7 +89,7 @@ class BackupPage extends StatelessWidget {
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Icon(icon, size: 20),
|
||||
width7,
|
||||
UIs.width7,
|
||||
Text(text),
|
||||
],
|
||||
),
|
||||
@@ -104,7 +106,7 @@ class BackupPage extends StatelessWidget {
|
||||
'iCloud',
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
width13,
|
||||
UIs.width13,
|
||||
// Hive db only save data into local file after app exit,
|
||||
// so this button is useless
|
||||
// IconButton(
|
||||
|
||||
@@ -3,7 +3,7 @@ import 'dart:convert';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
||||
import 'package:toolbox/core/extension/context.dart';
|
||||
import 'package:toolbox/core/extension/context/snackbar.dart';
|
||||
import 'package:toolbox/data/res/ui.dart';
|
||||
import 'package:toolbox/view/widget/value_notifier.dart';
|
||||
|
||||
@@ -61,7 +61,7 @@ class _ConvertPageState extends State<ConvertPage>
|
||||
controller: ScrollController(),
|
||||
child: Column(
|
||||
children: [
|
||||
height13,
|
||||
UIs.height13,
|
||||
_buildInputTop(),
|
||||
_buildMiddleBtns(),
|
||||
_buildResult(),
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:toolbox/core/extension/context.dart';
|
||||
import 'package:toolbox/core/extension/context/common.dart';
|
||||
import 'package:toolbox/data/provider/debug.dart';
|
||||
|
||||
import '../widget/custom_appbar.dart';
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:toolbox/core/extension/context.dart';
|
||||
import 'package:toolbox/core/extension/context/common.dart';
|
||||
import 'package:toolbox/core/extension/context/dialog.dart';
|
||||
import 'package:toolbox/core/extension/context/snackbar.dart';
|
||||
import 'package:toolbox/core/route.dart';
|
||||
import 'package:toolbox/data/model/docker/image.dart';
|
||||
import 'package:toolbox/view/widget/input_field.dart';
|
||||
@@ -214,7 +216,7 @@ class _DockerManagePageState extends State<DockerManagePage> {
|
||||
_docker.refresh();
|
||||
}
|
||||
});
|
||||
return centerLoading;
|
||||
return UIs.centerLoading;
|
||||
}
|
||||
|
||||
final items = <Widget>[
|
||||
@@ -236,7 +238,7 @@ class _DockerManagePageState extends State<DockerManagePage> {
|
||||
title: Text(_s.imagesList),
|
||||
subtitle: Text(
|
||||
_s.dockerImagesFmt(_docker.images!.length),
|
||||
style: grey,
|
||||
style: UIs.textGrey,
|
||||
),
|
||||
),
|
||||
];
|
||||
@@ -247,7 +249,7 @@ class _DockerManagePageState extends State<DockerManagePage> {
|
||||
Widget _buildImageItem(DockerImage e) {
|
||||
return ListTile(
|
||||
title: Text(e.repo),
|
||||
subtitle: Text('${e.tag} - ${e.size}', style: grey),
|
||||
subtitle: Text('${e.tag} - ${e.size}', style: UIs.textGrey),
|
||||
trailing: IconButton(
|
||||
padding: EdgeInsets.zero,
|
||||
alignment: Alignment.centerRight,
|
||||
@@ -276,14 +278,14 @@ class _DockerManagePageState extends State<DockerManagePage> {
|
||||
context.showSnackBar(result.message ?? _s.unknownError);
|
||||
}
|
||||
},
|
||||
child: Text(_s.ok, style: textRed),
|
||||
child: Text(_s.ok, style: UIs.textRed),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildLoading() {
|
||||
if (_docker.runLog == null) return placeholder;
|
||||
if (_docker.runLog == null) return UIs.placeholder;
|
||||
return Padding(
|
||||
padding: const EdgeInsets.all(17),
|
||||
child: Column(
|
||||
@@ -291,7 +293,7 @@ class _DockerManagePageState extends State<DockerManagePage> {
|
||||
const Center(
|
||||
child: CircularProgressIndicator(),
|
||||
),
|
||||
height13,
|
||||
UIs.height13,
|
||||
Text(_docker.runLog ?? '...'),
|
||||
],
|
||||
),
|
||||
@@ -309,7 +311,7 @@ class _DockerManagePageState extends State<DockerManagePage> {
|
||||
return Text(_s.waitConnection);
|
||||
case DockerErrType.invalidVersion:
|
||||
return UrlText(
|
||||
text: _s.invalidVersionHelp(appHelpUrl),
|
||||
text: _s.invalidVersionHelp(Urls.appHelp),
|
||||
replace: 'Github',
|
||||
);
|
||||
case DockerErrType.parseImages:
|
||||
@@ -344,7 +346,10 @@ class _DockerManagePageState extends State<DockerManagePage> {
|
||||
final items = <Widget>[
|
||||
ListTile(
|
||||
title: Text(_s.containerStatus),
|
||||
subtitle: Text(_buildPsCardSubtitle(_docker.items!), style: grey),
|
||||
subtitle: Text(
|
||||
_buildPsCardSubtitle(_docker.items!),
|
||||
style: UIs.textGrey,
|
||||
),
|
||||
),
|
||||
];
|
||||
items.addAll(_docker.items!.map(_buildPsItem));
|
||||
@@ -359,7 +364,7 @@ class _DockerManagePageState extends State<DockerManagePage> {
|
||||
title: Text(item.image),
|
||||
subtitle: Text(
|
||||
'${item.name} - ${item.status}',
|
||||
style: textSize13Grey,
|
||||
style: UIs.textSize13Grey,
|
||||
),
|
||||
trailing: _buildMoreBtn(item),
|
||||
);
|
||||
|
||||
@@ -7,7 +7,8 @@ import 'package:flutter_gen/gen_l10n/l10n.dart';
|
||||
import 'package:flutter_highlight/theme_map.dart';
|
||||
import 'package:flutter_highlight/themes/a11y-light.dart';
|
||||
import 'package:flutter_highlight/themes/monokai.dart';
|
||||
import 'package:toolbox/core/extension/context.dart';
|
||||
import 'package:toolbox/core/extension/context/common.dart';
|
||||
import 'package:toolbox/core/extension/context/dialog.dart';
|
||||
import 'package:toolbox/core/utils/misc.dart';
|
||||
import 'package:toolbox/data/res/highlight.dart';
|
||||
import 'package:toolbox/data/store/setting.dart';
|
||||
@@ -58,9 +59,9 @@ class _EditorPageState extends State<EditorPage> {
|
||||
super.initState();
|
||||
|
||||
/// Higher priority than [path]
|
||||
_langCode = widget.langCode ?? widget.path.highlightCode;
|
||||
_langCode = widget.langCode ?? Highlights.getCode(widget.path);
|
||||
_controller = CodeController(
|
||||
language: suffix2HighlightMap[_langCode],
|
||||
language: Highlights.all[_langCode],
|
||||
);
|
||||
|
||||
/// TODO: This is a temporary solution to avoid the loading stuck
|
||||
@@ -131,12 +132,12 @@ class _EditorPageState extends State<EditorPage> {
|
||||
PopupMenuButton<String>(
|
||||
icon: const Icon(Icons.language),
|
||||
onSelected: (value) {
|
||||
_controller.language = suffix2HighlightMap[value];
|
||||
_controller.language = Highlights.all[value];
|
||||
_langCode = value;
|
||||
},
|
||||
initialValue: _langCode,
|
||||
itemBuilder: (BuildContext context) {
|
||||
return suffix2HighlightMap.keys.map((e) {
|
||||
return Highlights.all.keys.map((e) {
|
||||
return PopupMenuItem(
|
||||
value: e,
|
||||
child: Text(e),
|
||||
|
||||
@@ -213,7 +213,7 @@ class _FullScreenPageState extends State<FullScreenPage> with AfterLayoutMixin {
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
height13,
|
||||
UIs.height13,
|
||||
Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
@@ -232,7 +232,7 @@ class _FullScreenPageState extends State<FullScreenPage> with AfterLayoutMixin {
|
||||
)
|
||||
],
|
||||
),
|
||||
height13,
|
||||
UIs.height13,
|
||||
_buildTopRightText(ss, cs),
|
||||
],
|
||||
),
|
||||
@@ -248,7 +248,7 @@ class _FullScreenPageState extends State<FullScreenPage> with AfterLayoutMixin {
|
||||
);
|
||||
return Text(
|
||||
topRightStr,
|
||||
style: textSize11Grey,
|
||||
style: UIs.textSize11Grey,
|
||||
textScaleFactor: 1.0,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -4,7 +4,8 @@ import 'package:after_layout/after_layout.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
||||
import 'package:get_it/get_it.dart';
|
||||
import 'package:toolbox/core/extension/context.dart';
|
||||
import 'package:toolbox/core/extension/context/dialog.dart';
|
||||
import 'package:toolbox/data/res/github_id.dart';
|
||||
import 'package:toolbox/data/res/logger.dart';
|
||||
|
||||
import '../../core/analysis.dart';
|
||||
@@ -93,7 +94,7 @@ class _HomePageState extends State<HomePage>
|
||||
// Keep running in background on Android device
|
||||
if (isAndroid && _setting.bgRun.fetch()) {
|
||||
if (_app.moveBg) {
|
||||
bgRunChannel.invokeMethod('sendToBackground');
|
||||
Miscs.bgRunChannel.invokeMethod('sendToBackground');
|
||||
}
|
||||
} else {
|
||||
_serverProvider.setDisconnected();
|
||||
@@ -214,7 +215,7 @@ class _HomePageState extends State<HomePage>
|
||||
child: Text(
|
||||
'${BuildData.name}\n$_versionStr',
|
||||
textAlign: TextAlign.center,
|
||||
style: textSize13,
|
||||
style: UIs.textSize13,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 37),
|
||||
@@ -271,11 +272,11 @@ class _HomePageState extends State<HomePage>
|
||||
child: _buildAboutContent(),
|
||||
actions: [
|
||||
TextButton(
|
||||
onPressed: () => openUrl(appWikiUrl),
|
||||
onPressed: () => openUrl(Urls.appWiki),
|
||||
child: const Text('Wiki'),
|
||||
),
|
||||
TextButton(
|
||||
onPressed: () => openUrl(appHelpUrl),
|
||||
onPressed: () => openUrl(Urls.appHelp),
|
||||
child: Text(_s.feedback),
|
||||
),
|
||||
TextButton(
|
||||
@@ -293,23 +294,23 @@ class _HomePageState extends State<HomePage>
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
UrlText(
|
||||
text: _s.madeWithLove(myGithub),
|
||||
text: _s.madeWithLove(Urls.myGithub),
|
||||
replace: 'lollipopkit',
|
||||
),
|
||||
height13,
|
||||
UIs.height13,
|
||||
// Use [UrlText] for same text style
|
||||
Text(_s.aboutThanks),
|
||||
height13,
|
||||
UIs.height13,
|
||||
const Text('Contributors:'),
|
||||
...contributors.map(
|
||||
...GithubIds.contributors.map(
|
||||
(name) => UrlText(
|
||||
text: name.url,
|
||||
replace: name,
|
||||
),
|
||||
),
|
||||
height13,
|
||||
UIs.height13,
|
||||
const Text('Participants:'),
|
||||
...participants.map(
|
||||
...GithubIds.participants.map(
|
||||
(name) => UrlText(
|
||||
text: name.url,
|
||||
replace: name,
|
||||
@@ -323,7 +324,7 @@ class _HomePageState extends State<HomePage>
|
||||
Widget _buildIcon() {
|
||||
return ConstrainedBox(
|
||||
constraints: const BoxConstraints(maxHeight: 57, maxWidth: 57),
|
||||
child: appIcon,
|
||||
child: UIs.appIcon,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -354,7 +355,7 @@ class _HomePageState extends State<HomePage>
|
||||
|
||||
void updateHomeWidget() {
|
||||
if (_setting.autoUpdateHomeWidget.fetch()) {
|
||||
homeWidgetChannel.invokeMethod('update');
|
||||
Miscs.homeWidgetChannel.invokeMethod('update');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -362,7 +363,7 @@ class _HomePageState extends State<HomePage>
|
||||
/// Encode [map] to String with indent `\t`
|
||||
final map = _setting.toJson();
|
||||
final keys = map.keys;
|
||||
final text = jsonEncoder.convert(map);
|
||||
final text = Miscs.jsonEncoder.convert(map);
|
||||
final result = await AppRoute.editor(
|
||||
text: text,
|
||||
langCode: 'json',
|
||||
|
||||
@@ -3,7 +3,9 @@ import 'dart:async';
|
||||
import 'package:after_layout/after_layout.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
||||
import 'package:toolbox/core/extension/context.dart';
|
||||
import 'package:toolbox/core/extension/context/common.dart';
|
||||
import 'package:toolbox/core/extension/context/dialog.dart';
|
||||
import 'package:toolbox/core/extension/context/snackbar.dart';
|
||||
import 'package:toolbox/core/utils/misc.dart';
|
||||
import 'package:toolbox/view/widget/value_notifier.dart';
|
||||
|
||||
@@ -140,7 +142,7 @@ class _PingPageState extends State<PingPage>
|
||||
),
|
||||
subtitle: Text(
|
||||
_buildPingSummary(result, unknown, ms),
|
||||
style: textSize11,
|
||||
style: UIs.textSize11,
|
||||
),
|
||||
trailing: Text(
|
||||
'${_s.pingAvg}${result.statistic?.avg?.toStringAsFixed(2) ?? _s.unknown} $ms',
|
||||
|
||||
@@ -4,7 +4,9 @@ import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
||||
import 'package:toolbox/core/extension/context.dart';
|
||||
import 'package:toolbox/core/extension/context/common.dart';
|
||||
import 'package:toolbox/core/extension/context/dialog.dart';
|
||||
import 'package:toolbox/core/extension/context/snackbar.dart';
|
||||
import 'package:toolbox/core/extension/numx.dart';
|
||||
import 'package:toolbox/core/utils/misc.dart';
|
||||
import 'package:toolbox/data/res/misc.dart';
|
||||
@@ -103,7 +105,7 @@ class _PrivateKeyEditPageState extends State<PrivateKeyEditPage> {
|
||||
},
|
||||
child: Text(
|
||||
_s.ok,
|
||||
style: textRed,
|
||||
style: UIs.textRed,
|
||||
),
|
||||
),
|
||||
],
|
||||
@@ -113,7 +115,7 @@ class _PrivateKeyEditPageState extends State<PrivateKeyEditPage> {
|
||||
)
|
||||
];
|
||||
return CustomAppBar(
|
||||
title: Text(_s.edit, style: textSize18),
|
||||
title: Text(_s.edit, style: UIs.textSize18),
|
||||
actions: widget.pki == null ? null : actions,
|
||||
);
|
||||
}
|
||||
@@ -131,7 +133,7 @@ class _PrivateKeyEditPageState extends State<PrivateKeyEditPage> {
|
||||
}
|
||||
FocusScope.of(context).unfocus();
|
||||
setState(() {
|
||||
_loading = centerSizedLoading;
|
||||
_loading = UIs.centerSizedLoading;
|
||||
});
|
||||
try {
|
||||
final decrypted = await compute(decyptPem, [key, pwd]);
|
||||
@@ -192,12 +194,12 @@ class _PrivateKeyEditPageState extends State<PrivateKeyEditPage> {
|
||||
return;
|
||||
}
|
||||
final size = (await file.stat()).size;
|
||||
if (size > privateKeyMaxSize) {
|
||||
if (size > Miscs.privateKeyMaxSize) {
|
||||
context.showSnackBar(
|
||||
_s.fileTooLarge(
|
||||
path,
|
||||
size.convertBytes,
|
||||
privateKeyMaxSize.convertBytes,
|
||||
Miscs.privateKeyMaxSize.convertBytes,
|
||||
),
|
||||
);
|
||||
return;
|
||||
@@ -216,7 +218,7 @@ class _PrivateKeyEditPageState extends State<PrivateKeyEditPage> {
|
||||
icon: Icons.password,
|
||||
),
|
||||
SizedBox(height: MediaQuery.of(context).size.height * 0.1),
|
||||
_loading ?? placeholder,
|
||||
_loading ?? UIs.placeholder,
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
@@ -4,7 +4,8 @@ import 'package:after_layout/after_layout.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:toolbox/core/extension/context.dart';
|
||||
import 'package:toolbox/core/extension/context/common.dart';
|
||||
import 'package:toolbox/core/extension/context/dialog.dart';
|
||||
import 'package:toolbox/data/store/private_key.dart';
|
||||
import 'package:toolbox/locator.dart';
|
||||
|
||||
@@ -37,7 +38,7 @@ class _PrivateKeyListState extends State<PrivateKeysListPage>
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: CustomAppBar(
|
||||
title: Text(_s.privateKey, style: textSize18),
|
||||
title: Text(_s.privateKey, style: UIs.textSize18),
|
||||
),
|
||||
body: _buildBody(),
|
||||
floatingActionButton: FloatingActionButton(
|
||||
@@ -70,7 +71,7 @@ class _PrivateKeyListState extends State<PrivateKeysListPage>
|
||||
),
|
||||
),
|
||||
title: Text(item.id),
|
||||
subtitle: Text(item.type ?? _s.unknown, style: grey),
|
||||
subtitle: Text(item.type ?? _s.unknown, style: UIs.textGrey),
|
||||
onTap: () => AppRoute.keyEdit(pki: item).go(context),
|
||||
trailing: const Icon(Icons.edit),
|
||||
),
|
||||
|
||||
@@ -3,7 +3,9 @@ import 'dart:async';
|
||||
import 'package:dartssh2/dartssh2.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
||||
import 'package:toolbox/core/extension/context.dart';
|
||||
import 'package:toolbox/core/extension/context/common.dart';
|
||||
import 'package:toolbox/core/extension/context/dialog.dart';
|
||||
import 'package:toolbox/core/extension/context/snackbar.dart';
|
||||
import 'package:toolbox/core/extension/uint8list.dart';
|
||||
import 'package:toolbox/core/utils/misc.dart';
|
||||
|
||||
@@ -126,7 +128,7 @@ class _ProcessPageState extends State<ProcessPage> {
|
||||
}
|
||||
Widget child;
|
||||
if (_result.procs.isEmpty) {
|
||||
child = centerLoading;
|
||||
child = UIs.centerLoading;
|
||||
} else {
|
||||
child = ListView.builder(
|
||||
itemCount: _result.procs.length,
|
||||
@@ -157,7 +159,7 @@ class _ProcessPageState extends State<ProcessPage> {
|
||||
title: Text(proc.binary),
|
||||
subtitle: Text(
|
||||
proc.command,
|
||||
style: grey,
|
||||
style: UIs.textGrey,
|
||||
maxLines: 3,
|
||||
overflow: TextOverflow.fade,
|
||||
),
|
||||
@@ -198,7 +200,7 @@ class _ProcessPageState extends State<ProcessPage> {
|
||||
up: proc.cpu!.toStringAsFixed(1),
|
||||
down: 'cpu',
|
||||
),
|
||||
width13,
|
||||
UIs.width13,
|
||||
if (proc.mem != null)
|
||||
TwoLineText(
|
||||
up: proc.mem!.toStringAsFixed(1),
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:toolbox/core/extension/context.dart';
|
||||
import 'package:toolbox/core/extension/context/common.dart';
|
||||
import 'package:toolbox/core/extension/order.dart';
|
||||
import 'package:toolbox/data/model/server/cpu.dart';
|
||||
import 'package:toolbox/data/model/server/server_private_info.dart';
|
||||
@@ -41,7 +41,7 @@ class _ServerDetailPageState extends State<ServerDetailPage>
|
||||
late final _textFactor = _setting.textFactor.fetch();
|
||||
|
||||
late final _cardBuildMap = Map.fromIterables(
|
||||
defaultDetailCardOrder,
|
||||
Defaults.detailCardOrder,
|
||||
[
|
||||
_buildUpTimeAndSys,
|
||||
_buildCPUView,
|
||||
@@ -85,7 +85,7 @@ class _ServerDetailPageState extends State<ServerDetailPage>
|
||||
final buildFuncs = !_setting.moveOutServerTabFuncBtns.fetch();
|
||||
return Scaffold(
|
||||
appBar: CustomAppBar(
|
||||
title: Text(si.spi.name, style: textSize18),
|
||||
title: Text(si.spi.name, style: UIs.textSize18),
|
||||
actions: [
|
||||
IconButton(
|
||||
icon: const Icon(Icons.edit),
|
||||
@@ -120,21 +120,21 @@ class _ServerDetailPageState extends State<ServerDetailPage>
|
||||
final percent = ss.cpu.usedPercent(coreIdx: 0).toInt();
|
||||
final details = [
|
||||
_buildDetailPercent(ss.cpu.user, 'user'),
|
||||
width13,
|
||||
UIs.width13,
|
||||
_buildDetailPercent(ss.cpu.idle, 'idle')
|
||||
];
|
||||
if (ss.system == SystemType.linux) {
|
||||
details.addAll([
|
||||
width13,
|
||||
UIs.width13,
|
||||
_buildDetailPercent(ss.cpu.sys, 'sys'),
|
||||
width13,
|
||||
UIs.width13,
|
||||
_buildDetailPercent(ss.cpu.iowait, 'io'),
|
||||
]);
|
||||
}
|
||||
|
||||
return RoundRectCard(
|
||||
Padding(
|
||||
padding: roundRectCardPadding,
|
||||
padding: UIs.roundRectCardPadding,
|
||||
child: Column(mainAxisAlignment: MainAxisAlignment.center, children: [
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
@@ -142,14 +142,14 @@ class _ServerDetailPageState extends State<ServerDetailPage>
|
||||
_buildAnimatedText(
|
||||
ValueKey(percent),
|
||||
'$percent%',
|
||||
textSize27,
|
||||
UIs.textSize27,
|
||||
),
|
||||
Row(
|
||||
children: details,
|
||||
)
|
||||
],
|
||||
),
|
||||
height13,
|
||||
UIs.height13,
|
||||
_buildCPUProgress(ss.cpu)
|
||||
]),
|
||||
),
|
||||
@@ -196,7 +196,7 @@ class _ServerDetailPageState extends State<ServerDetailPage>
|
||||
return LinearProgressIndicator(
|
||||
value: percentWithinOne,
|
||||
minHeight: 7,
|
||||
backgroundColor: progressColor.resolve(context),
|
||||
backgroundColor: DynamicColors.progress.resolve(context),
|
||||
color: primaryColor,
|
||||
);
|
||||
}
|
||||
@@ -204,14 +204,18 @@ class _ServerDetailPageState extends State<ServerDetailPage>
|
||||
Widget _buildUpTimeAndSys(ServerStatus ss) {
|
||||
return RoundRectCard(
|
||||
Padding(
|
||||
padding: roundRectCardPadding,
|
||||
padding: UIs.roundRectCardPadding,
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(ss.sysVer, style: textSize11, textScaleFactor: _textFactor),
|
||||
Text(
|
||||
ss.sysVer,
|
||||
style: UIs.textSize11,
|
||||
textScaleFactor: _textFactor,
|
||||
),
|
||||
Text(
|
||||
ss.uptime,
|
||||
style: textSize11,
|
||||
style: UIs.textSize11,
|
||||
textScaleFactor: _textFactor,
|
||||
),
|
||||
],
|
||||
@@ -228,7 +232,7 @@ class _ServerDetailPageState extends State<ServerDetailPage>
|
||||
|
||||
return RoundRectCard(
|
||||
Padding(
|
||||
padding: roundRectCardPadding,
|
||||
padding: UIs.roundRectCardPadding,
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
@@ -241,23 +245,25 @@ class _ServerDetailPageState extends State<ServerDetailPage>
|
||||
_buildAnimatedText(
|
||||
ValueKey(usedStr),
|
||||
'$usedStr%',
|
||||
textSize27,
|
||||
UIs.textSize27,
|
||||
),
|
||||
width7,
|
||||
Text('of ${(ss.mem.total * 1024).convertBytes}',
|
||||
style: textSize13Grey)
|
||||
UIs.width7,
|
||||
Text(
|
||||
'of ${(ss.mem.total * 1024).convertBytes}',
|
||||
style: UIs.textSize13Grey,
|
||||
)
|
||||
],
|
||||
),
|
||||
Row(
|
||||
children: [
|
||||
_buildDetailPercent(free, 'free'),
|
||||
width13,
|
||||
UIs.width13,
|
||||
_buildDetailPercent(avail, 'avail'),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
height13,
|
||||
UIs.height13,
|
||||
_buildProgress(used)
|
||||
],
|
||||
),
|
||||
@@ -266,12 +272,12 @@ class _ServerDetailPageState extends State<ServerDetailPage>
|
||||
}
|
||||
|
||||
Widget _buildSwapView(ServerStatus ss) {
|
||||
if (ss.swap.total == 0) return placeholder;
|
||||
if (ss.swap.total == 0) return UIs.placeholder;
|
||||
final used = ss.swap.usedPercent * 100;
|
||||
final cached = ss.swap.cached / ss.swap.total * 100;
|
||||
return RoundRectCard(
|
||||
Padding(
|
||||
padding: roundRectCardPadding,
|
||||
padding: UIs.roundRectCardPadding,
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
@@ -281,16 +287,18 @@ class _ServerDetailPageState extends State<ServerDetailPage>
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Text('${used.toStringAsFixed(0)}%', style: textSize27),
|
||||
width7,
|
||||
Text('of ${(ss.swap.total * 1024).convertBytes} ',
|
||||
style: textSize13Grey)
|
||||
Text('${used.toStringAsFixed(0)}%', style: UIs.textSize27),
|
||||
UIs.width7,
|
||||
Text(
|
||||
'of ${(ss.swap.total * 1024).convertBytes} ',
|
||||
style: UIs.textSize13Grey,
|
||||
)
|
||||
],
|
||||
),
|
||||
_buildDetailPercent(cached, 'cached'),
|
||||
],
|
||||
),
|
||||
height13,
|
||||
UIs.height13,
|
||||
_buildProgress(used)
|
||||
],
|
||||
),
|
||||
@@ -317,12 +325,12 @@ class _ServerDetailPageState extends State<ServerDetailPage>
|
||||
children: [
|
||||
Text(
|
||||
'${disk.usedPercent}% of ${disk.size}',
|
||||
style: textSize11,
|
||||
style: UIs.textSize11,
|
||||
textScaleFactor: _textFactor,
|
||||
),
|
||||
Text(
|
||||
disk.path,
|
||||
style: textSize11,
|
||||
style: UIs.textSize11,
|
||||
textScaleFactor: _textFactor,
|
||||
)
|
||||
],
|
||||
@@ -334,7 +342,7 @@ class _ServerDetailPageState extends State<ServerDetailPage>
|
||||
.toList();
|
||||
return RoundRectCard(
|
||||
Padding(
|
||||
padding: roundRectCardPadding,
|
||||
padding: UIs.roundRectCardPadding,
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: children,
|
||||
@@ -364,7 +372,7 @@ class _ServerDetailPageState extends State<ServerDetailPage>
|
||||
|
||||
return RoundRectCard(
|
||||
Padding(
|
||||
padding: roundRectCardPadding,
|
||||
padding: UIs.roundRectCardPadding,
|
||||
child: Column(
|
||||
children: children,
|
||||
),
|
||||
@@ -397,7 +405,7 @@ class _ServerDetailPageState extends State<ServerDetailPage>
|
||||
width: width,
|
||||
child: Text(
|
||||
device,
|
||||
style: textSize11,
|
||||
style: UIs.textSize11,
|
||||
textScaleFactor: _textFactor,
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
@@ -407,7 +415,7 @@ class _ServerDetailPageState extends State<ServerDetailPage>
|
||||
width: width,
|
||||
child: Text(
|
||||
'${ns.speedIn(device: device)} | ${ns.sizeIn(device: device)}',
|
||||
style: textSize11,
|
||||
style: UIs.textSize11,
|
||||
textAlign: TextAlign.center,
|
||||
textScaleFactor: 0.87 * _textFactor,
|
||||
),
|
||||
@@ -416,7 +424,7 @@ class _ServerDetailPageState extends State<ServerDetailPage>
|
||||
width: width,
|
||||
child: Text(
|
||||
'${ns.speedOut(device: device)} | ${ns.sizeOut(device: device)}',
|
||||
style: textSize11,
|
||||
style: UIs.textSize11,
|
||||
textAlign: TextAlign.right,
|
||||
textScaleFactor: 0.87 * _textFactor,
|
||||
),
|
||||
@@ -429,7 +437,7 @@ class _ServerDetailPageState extends State<ServerDetailPage>
|
||||
Widget _buildTemperature(ServerStatus ss) {
|
||||
final temps = ss.temps;
|
||||
if (temps.isEmpty) {
|
||||
return placeholder;
|
||||
return UIs.placeholder;
|
||||
}
|
||||
final List<Widget> children = [
|
||||
const Row(
|
||||
@@ -449,19 +457,19 @@ class _ServerDetailPageState extends State<ServerDetailPage>
|
||||
children: [
|
||||
Text(
|
||||
key,
|
||||
style: textSize11,
|
||||
style: UIs.textSize11,
|
||||
textScaleFactor: _textFactor,
|
||||
),
|
||||
Text(
|
||||
'${temps.get(key)}°C',
|
||||
style: textSize11,
|
||||
style: UIs.textSize11,
|
||||
textScaleFactor: _textFactor,
|
||||
),
|
||||
],
|
||||
)));
|
||||
return RoundRectCard(
|
||||
Padding(
|
||||
padding: roundRectCardPadding,
|
||||
padding: UIs.roundRectCardPadding,
|
||||
child: Column(children: children),
|
||||
),
|
||||
);
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:toolbox/core/extension/context.dart';
|
||||
import 'package:toolbox/core/extension/context/common.dart';
|
||||
import 'package:toolbox/core/extension/context/dialog.dart';
|
||||
import 'package:toolbox/core/extension/context/snackbar.dart';
|
||||
|
||||
import '../../../core/route.dart';
|
||||
import '../../../data/model/server/private_key_info.dart';
|
||||
@@ -123,7 +125,7 @@ class _ServerEditPageState extends State<ServerEditPage> {
|
||||
context.pop();
|
||||
context.pop(true);
|
||||
},
|
||||
child: Text(_s.ok, style: textRed),
|
||||
child: Text(_s.ok, style: UIs.textRed),
|
||||
),
|
||||
],
|
||||
);
|
||||
@@ -132,7 +134,7 @@ class _ServerEditPageState extends State<ServerEditPage> {
|
||||
);
|
||||
final actions = widget.spi != null ? [delBtn] : null;
|
||||
return CustomAppBar(
|
||||
title: Text(_s.edit, style: textSize18),
|
||||
title: Text(_s.edit, style: UIs.textSize18),
|
||||
actions: actions,
|
||||
);
|
||||
}
|
||||
@@ -271,7 +273,7 @@ class _ServerEditPageState extends State<ServerEditPage> {
|
||||
subtitle: Text(
|
||||
e.type ?? _s.unknown,
|
||||
textAlign: TextAlign.start,
|
||||
style: grey,
|
||||
style: UIs.textGrey,
|
||||
),
|
||||
trailing: _buildRadio(index, e),
|
||||
);
|
||||
|
||||
@@ -4,7 +4,7 @@ import 'package:flutter/material.dart';
|
||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
||||
import 'package:get_it/get_it.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:toolbox/core/extension/context.dart';
|
||||
import 'package:toolbox/core/extension/context/dialog.dart';
|
||||
import 'package:toolbox/core/extension/media_queryx.dart';
|
||||
import 'package:toolbox/core/extension/ssh_client.dart';
|
||||
import 'package:toolbox/data/model/app/shell_func.dart';
|
||||
@@ -127,7 +127,7 @@ class _ServerPageState extends State<ServerPage>
|
||||
if (index == 0 && buildTags) return _buildTagsSwitcher(provider);
|
||||
|
||||
// Issue #130
|
||||
if (index == count - 1) return height77;
|
||||
if (index == count - 1) return UIs.height77;
|
||||
|
||||
if (buildTags) index--;
|
||||
return _buildEachServerCard(provider.servers[filtered[index]]);
|
||||
@@ -173,7 +173,7 @@ class _ServerPageState extends State<ServerPage>
|
||||
|
||||
Widget _buildEachServerCard(Server? si) {
|
||||
if (si == null) {
|
||||
return placeholder;
|
||||
return UIs.placeholder;
|
||||
}
|
||||
|
||||
return RoundRectCard(
|
||||
@@ -243,7 +243,7 @@ class _ServerPageState extends State<ServerPage>
|
||||
|
||||
List<Widget> _buildFlipedCard(Server srv) {
|
||||
return [
|
||||
height13,
|
||||
UIs.height13,
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||||
children: [
|
||||
@@ -273,7 +273,7 @@ class _ServerPageState extends State<ServerPage>
|
||||
List<Widget> _buildNormalCard(ServerStatus ss, ServerPrivateInfo spi) {
|
||||
final rootDisk = findRootDisk(ss.disk);
|
||||
return [
|
||||
height13,
|
||||
UIs.height13,
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 13),
|
||||
child: Row(
|
||||
@@ -289,7 +289,7 @@ class _ServerPageState extends State<ServerPage>
|
||||
],
|
||||
),
|
||||
),
|
||||
height13,
|
||||
UIs.height13,
|
||||
if (_setting.moveOutServerTabFuncBtns.fetch() &&
|
||||
// Discussion #146
|
||||
!_setting.serverTabUseOldUI.fetch())
|
||||
@@ -330,7 +330,7 @@ class _ServerPageState extends State<ServerPage>
|
||||
children: [
|
||||
Text(
|
||||
spi.name,
|
||||
style: textSize13Bold,
|
||||
style: UIs.textSize13Bold,
|
||||
textScaleFactor: 1.0,
|
||||
),
|
||||
const Icon(
|
||||
@@ -363,14 +363,14 @@ class _ServerPageState extends State<ServerPage>
|
||||
onTap: () => _showFailReason(ss),
|
||||
child: Text(
|
||||
_s.viewErr,
|
||||
style: textSize11Grey,
|
||||
style: UIs.textSize11Grey,
|
||||
textScaleFactor: 1.0,
|
||||
),
|
||||
);
|
||||
}
|
||||
return Text(
|
||||
topRightStr,
|
||||
style: textSize11Grey,
|
||||
style: UIs.textSize11Grey,
|
||||
textScaleFactor: 1.0,
|
||||
);
|
||||
}
|
||||
@@ -409,14 +409,14 @@ class _ServerPageState extends State<ServerPage>
|
||||
const SizedBox(height: 5),
|
||||
Text(
|
||||
up,
|
||||
style: textSize9Grey,
|
||||
style: UIs.textSize9Grey,
|
||||
textAlign: TextAlign.center,
|
||||
textScaleFactor: 1.0,
|
||||
),
|
||||
const SizedBox(height: 3),
|
||||
Text(
|
||||
down,
|
||||
style: textSize9Grey,
|
||||
style: UIs.textSize9Grey,
|
||||
textAlign: TextAlign.center,
|
||||
textScaleFactor: 1.0,
|
||||
)
|
||||
@@ -444,7 +444,7 @@ class _ServerPageState extends State<ServerPage>
|
||||
child: Text(
|
||||
'${percent.toStringAsFixed(1)}%',
|
||||
textAlign: TextAlign.center,
|
||||
style: textSize11,
|
||||
style: UIs.textSize11,
|
||||
textScaleFactor: 1.0,
|
||||
),
|
||||
),
|
||||
|
||||
@@ -7,8 +7,10 @@ import 'package:flutter_highlight/theme_map.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
import 'package:toolbox/core/extension/colorx.dart';
|
||||
import 'package:toolbox/core/extension/context/common.dart';
|
||||
import 'package:toolbox/core/extension/context/snackbar.dart';
|
||||
import 'package:toolbox/core/extension/locale.dart';
|
||||
import 'package:toolbox/core/extension/context.dart';
|
||||
import 'package:toolbox/core/extension/context/dialog.dart';
|
||||
import 'package:toolbox/core/extension/stringx.dart';
|
||||
|
||||
import '../../../core/persistant_store.dart';
|
||||
@@ -153,7 +155,7 @@ class _SettingPageState extends State<SettingPage> {
|
||||
child: Center(
|
||||
child: Text(
|
||||
text,
|
||||
style: grey,
|
||||
style: UIs.textGrey,
|
||||
),
|
||||
),
|
||||
);
|
||||
@@ -245,7 +247,7 @@ class _SettingPageState extends State<SettingPage> {
|
||||
}
|
||||
return ListTile(
|
||||
title: Text(_s.autoCheckUpdate),
|
||||
subtitle: Text(display, style: grey),
|
||||
subtitle: Text(display, style: UIs.textGrey),
|
||||
onTap: () => doUpdate(ctx, force: true),
|
||||
trailing: StoreSwitch(prop: _setting.autoCheckAppUpdate),
|
||||
);
|
||||
@@ -269,7 +271,7 @@ class _SettingPageState extends State<SettingPage> {
|
||||
),
|
||||
subtitle: Text(
|
||||
_s.willTakEeffectImmediately,
|
||||
style: grey,
|
||||
style: UIs.textGrey,
|
||||
),
|
||||
onTap: () {
|
||||
_updateIntervalKey.currentState?.showButtonMenu();
|
||||
@@ -290,7 +292,7 @@ class _SettingPageState extends State<SettingPage> {
|
||||
},
|
||||
child: Text(
|
||||
'${_updateInterval.value} ${_s.second}',
|
||||
style: textSize15,
|
||||
style: UIs.textSize15,
|
||||
),
|
||||
),
|
||||
),
|
||||
@@ -422,7 +424,7 @@ class _SettingPageState extends State<SettingPage> {
|
||||
_s.maxRetryCount,
|
||||
textAlign: TextAlign.start,
|
||||
),
|
||||
subtitle: Text(help, style: grey),
|
||||
subtitle: Text(help, style: UIs.textGrey),
|
||||
onTap: () {
|
||||
_maxRetryKey.currentState?.showButtonMenu();
|
||||
},
|
||||
@@ -437,7 +439,7 @@ class _SettingPageState extends State<SettingPage> {
|
||||
},
|
||||
child: Text(
|
||||
'${_maxRetryCount.value} ${_s.times}',
|
||||
style: textSize15,
|
||||
style: UIs.textSize15,
|
||||
),
|
||||
),
|
||||
listenable: _maxRetryCount,
|
||||
@@ -477,7 +479,7 @@ class _SettingPageState extends State<SettingPage> {
|
||||
},
|
||||
child: Text(
|
||||
_buildThemeModeStr(_nightMode.value),
|
||||
style: textSize15,
|
||||
style: UIs.textSize15,
|
||||
),
|
||||
),
|
||||
),
|
||||
@@ -524,7 +526,7 @@ class _SettingPageState extends State<SettingPage> {
|
||||
_pushToken.value = text;
|
||||
return Text(
|
||||
text ?? _s.nullToken,
|
||||
style: grey,
|
||||
style: UIs.textGrey,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
maxLines: 1,
|
||||
);
|
||||
@@ -539,7 +541,7 @@ class _SettingPageState extends State<SettingPage> {
|
||||
title: Text(_s.font),
|
||||
trailing: Text(
|
||||
fontName ?? _s.notSelected,
|
||||
style: textSize15,
|
||||
style: UIs.textSize15,
|
||||
),
|
||||
onTap: () {
|
||||
context.showRoundDialog(
|
||||
@@ -574,7 +576,7 @@ class _SettingPageState extends State<SettingPage> {
|
||||
_setting.fontPath.put(path);
|
||||
} else {
|
||||
final fontFile = File(path);
|
||||
final newPath = '${await fontDir}/${path.split('/').last}';
|
||||
final newPath = '${await Paths.font}/${path.split('/').last}';
|
||||
await fontFile.copy(newPath);
|
||||
_setting.fontPath.put(newPath);
|
||||
}
|
||||
@@ -600,7 +602,7 @@ class _SettingPageState extends State<SettingPage> {
|
||||
title: Text(_s.fontSize),
|
||||
trailing: Text(
|
||||
_termFontSize.value.toString(),
|
||||
style: textSize15,
|
||||
style: UIs.textSize15,
|
||||
),
|
||||
onTap: () => _showFontSizeDialog(_termFontSize, _setting.termFontSize),
|
||||
),
|
||||
@@ -671,7 +673,7 @@ class _SettingPageState extends State<SettingPage> {
|
||||
},
|
||||
child: Text(
|
||||
_s.languageName,
|
||||
style: textSize15,
|
||||
style: UIs.textSize15,
|
||||
),
|
||||
),
|
||||
),
|
||||
@@ -681,7 +683,7 @@ class _SettingPageState extends State<SettingPage> {
|
||||
Widget _buildSSHVirtualKeyAutoOff() {
|
||||
return ListTile(
|
||||
title: Text(_s.sshVirtualKeyAutoOff),
|
||||
subtitle: const Text('Ctrl & Alt', style: grey),
|
||||
subtitle: const Text('Ctrl & Alt', style: UIs.textGrey),
|
||||
trailing: StoreSwitch(prop: _setting.sshVirtualKeyAutoOff),
|
||||
);
|
||||
}
|
||||
@@ -709,7 +711,7 @@ class _SettingPageState extends State<SettingPage> {
|
||||
},
|
||||
child: Text(
|
||||
_editorTheme.value,
|
||||
style: textSize15,
|
||||
style: UIs.textSize15,
|
||||
),
|
||||
),
|
||||
),
|
||||
@@ -742,7 +744,7 @@ class _SettingPageState extends State<SettingPage> {
|
||||
},
|
||||
child: Text(
|
||||
_editorDarkTheme.value,
|
||||
style: textSize15,
|
||||
style: UIs.textSize15,
|
||||
),
|
||||
),
|
||||
),
|
||||
@@ -768,7 +770,7 @@ class _SettingPageState extends State<SettingPage> {
|
||||
Widget _buildFullScreenJitter() {
|
||||
return ListTile(
|
||||
title: Text(_s.fullScreenJitter),
|
||||
subtitle: Text(_s.fullScreenJitterHelp, style: grey),
|
||||
subtitle: Text(_s.fullScreenJitterHelp, style: UIs.textGrey),
|
||||
trailing: StoreSwitch(prop: _setting.fullScreenJitter),
|
||||
);
|
||||
}
|
||||
@@ -799,7 +801,7 @@ class _SettingPageState extends State<SettingPage> {
|
||||
},
|
||||
child: Text(
|
||||
degrees[_rotateQuarter.value],
|
||||
style: textSize15,
|
||||
style: UIs.textSize15,
|
||||
),
|
||||
),
|
||||
),
|
||||
@@ -834,7 +836,7 @@ class _SettingPageState extends State<SettingPage> {
|
||||
).toList();
|
||||
return ListTile(
|
||||
title: Text(_s.keyboardType),
|
||||
subtitle: Text(_s.keyboardCompatibility, style: grey),
|
||||
subtitle: Text(_s.keyboardCompatibility, style: UIs.textGrey),
|
||||
trailing: ValueBuilder(
|
||||
listenable: _keyboardType,
|
||||
build: () => PopupMenuButton<int>(
|
||||
@@ -847,7 +849,7 @@ class _SettingPageState extends State<SettingPage> {
|
||||
},
|
||||
child: Text(
|
||||
names[_keyboardType.value],
|
||||
style: textSize15,
|
||||
style: UIs.textSize15,
|
||||
),
|
||||
),
|
||||
),
|
||||
@@ -939,7 +941,7 @@ class _SettingPageState extends State<SettingPage> {
|
||||
},
|
||||
child: Text(
|
||||
_netViewType.value.l10n(_s),
|
||||
style: textSize15,
|
||||
style: UIs.textSize15,
|
||||
),
|
||||
),
|
||||
),
|
||||
@@ -952,7 +954,7 @@ class _SettingPageState extends State<SettingPage> {
|
||||
Widget _buildAutoUpdateHomeWidget() {
|
||||
return ListTile(
|
||||
title: Text(_s.autoUpdateHomeWidget),
|
||||
subtitle: Text(_s.whenOpenApp, style: grey),
|
||||
subtitle: Text(_s.whenOpenApp, style: UIs.textGrey),
|
||||
trailing: StoreSwitch(prop: _setting.autoUpdateHomeWidget),
|
||||
);
|
||||
}
|
||||
@@ -993,7 +995,7 @@ class _SettingPageState extends State<SettingPage> {
|
||||
Widget _buildMoveOutServerFuncBtns() {
|
||||
return ListTile(
|
||||
title: Text(_s.moveOutServerFuncBtns),
|
||||
subtitle: Text(_s.moveOutServerFuncBtnsHelp, style: textSize13Grey),
|
||||
subtitle: Text(_s.moveOutServerFuncBtnsHelp, style: UIs.textSize13Grey),
|
||||
trailing: StoreSwitch(prop: _setting.moveOutServerTabFuncBtns),
|
||||
);
|
||||
}
|
||||
@@ -1021,7 +1023,7 @@ class _SettingPageState extends State<SettingPage> {
|
||||
title: Text(_s.fontSize),
|
||||
trailing: Text(
|
||||
_editorFontSize.value.toString(),
|
||||
style: textSize15,
|
||||
style: UIs.textSize15,
|
||||
),
|
||||
onTap: () =>
|
||||
_showFontSizeDialog(_editorFontSize, _setting.editorFontSize),
|
||||
@@ -1069,7 +1071,7 @@ class _SettingPageState extends State<SettingPage> {
|
||||
Widget _buildSftpRmrfDir() {
|
||||
return ListTile(
|
||||
title: const Text('rm -rf'),
|
||||
subtitle: Text(_s.sftpRmrfDirSummary, style: grey),
|
||||
subtitle: Text(_s.sftpRmrfDirSummary, style: UIs.textGrey),
|
||||
trailing: StoreSwitch(prop: _setting.sftpRmrfDir),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
||||
import 'package:toolbox/core/extension/context.dart';
|
||||
import 'package:toolbox/core/extension/context/snackbar.dart';
|
||||
import 'package:toolbox/core/extension/order.dart';
|
||||
import 'package:toolbox/core/utils/platform.dart';
|
||||
import 'package:toolbox/data/model/ssh/virtual_key.dart';
|
||||
@@ -55,7 +55,7 @@ class _SSHVirtKeySettingPageState extends State<SSHVirtKeySettingPage> {
|
||||
key: ValueKey(idx),
|
||||
ListTile(
|
||||
title: _buildTitle(key),
|
||||
subtitle: help == null ? null : Text(help, style: grey),
|
||||
subtitle: help == null ? null : Text(help, style: UIs.textGrey),
|
||||
leading: _buildCheckBox(keys, key, idx, idx < keys.length),
|
||||
trailing: isDesktop ? null : const Icon(Icons.drag_handle),
|
||||
),
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import 'package:after_layout/after_layout.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
||||
import 'package:toolbox/core/extension/context.dart';
|
||||
import 'package:toolbox/core/extension/context/common.dart';
|
||||
import 'package:toolbox/core/extension/context/snackbar.dart';
|
||||
import 'package:toolbox/view/widget/input_field.dart';
|
||||
|
||||
import '../../../data/model/server/snippet.dart';
|
||||
@@ -56,7 +57,7 @@ class _SnippetEditPageState extends State<SnippetEditPage>
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: CustomAppBar(
|
||||
title: Text(_s.edit, style: textSize18),
|
||||
title: Text(_s.edit, style: UIs.textSize18),
|
||||
actions: _buildAppBarActions(),
|
||||
),
|
||||
body: _buildBody(),
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:toolbox/core/extension/context.dart';
|
||||
import 'package:toolbox/core/extension/context/dialog.dart';
|
||||
import 'package:toolbox/core/extension/order.dart';
|
||||
|
||||
import '../../../core/utils/misc.dart';
|
||||
@@ -83,7 +83,7 @@ class _SnippetListPageState extends State<SnippetListPage> {
|
||||
all: _s.all,
|
||||
width: _media.size.width,
|
||||
),
|
||||
footer: height77,
|
||||
footer: UIs.height77,
|
||||
buildDefaultDragHandles: false,
|
||||
itemBuilder: (context, idx) {
|
||||
final snippet = filtered.elementAt(idx);
|
||||
@@ -111,7 +111,7 @@ class _SnippetListPageState extends State<SnippetListPage> {
|
||||
snippet.note ?? snippet.script,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
maxLines: 3,
|
||||
style: grey,
|
||||
style: UIs.textGrey,
|
||||
),
|
||||
trailing: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
|
||||
@@ -7,7 +7,9 @@ import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:toolbox/core/extension/context.dart';
|
||||
import 'package:toolbox/core/extension/context/common.dart';
|
||||
import 'package:toolbox/core/extension/context/dialog.dart';
|
||||
import 'package:toolbox/core/extension/context/snackbar.dart';
|
||||
import 'package:xterm/xterm.dart';
|
||||
|
||||
import '../../core/route.dart';
|
||||
|
||||
@@ -2,7 +2,9 @@ import 'dart:io';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
||||
import 'package:toolbox/core/extension/context.dart';
|
||||
import 'package:toolbox/core/extension/context/common.dart';
|
||||
import 'package:toolbox/core/extension/context/dialog.dart';
|
||||
import 'package:toolbox/core/extension/context/snackbar.dart';
|
||||
import 'package:toolbox/data/model/sftp/req.dart';
|
||||
import 'package:toolbox/data/provider/server.dart';
|
||||
import 'package:toolbox/data/provider/sftp.dart';
|
||||
@@ -47,7 +49,7 @@ class _LocalStoragePageState extends State<LocalStoragePage> {
|
||||
_path = LocalPath(widget.initDir!);
|
||||
});
|
||||
} else {
|
||||
sftpDir.then((dir) {
|
||||
Paths.sftp.then((dir) {
|
||||
setState(() {
|
||||
_path = LocalPath(dir);
|
||||
});
|
||||
@@ -165,12 +167,13 @@ class _LocalStoragePageState extends State<LocalStoragePage> {
|
||||
? const Icon(Icons.folder)
|
||||
: const Icon(Icons.insert_drive_file),
|
||||
title: Text(fileName),
|
||||
subtitle: isDir ? null : Text(stat.size.convertBytes, style: grey),
|
||||
subtitle:
|
||||
isDir ? null : Text(stat.size.convertBytes, style: UIs.textGrey),
|
||||
trailing: Text(
|
||||
stat.modified
|
||||
.toString()
|
||||
.substring(0, stat.modified.toString().length - 4),
|
||||
style: grey,
|
||||
style: UIs.textGrey,
|
||||
),
|
||||
onLongPress: () {
|
||||
if (!isDir) return;
|
||||
@@ -242,7 +245,7 @@ class _LocalStoragePageState extends State<LocalStoragePage> {
|
||||
onTap: () async {
|
||||
context.pop();
|
||||
final stat = await file.stat();
|
||||
if (stat.size > editorMaxSize) {
|
||||
if (stat.size > Miscs.editorMaxSize) {
|
||||
context.showRoundDialog(
|
||||
title: Text(_s.attention),
|
||||
child: Text(_s.fileTooLarge(fileName, stat.size, '1m')),
|
||||
|
||||
@@ -4,7 +4,9 @@ import 'package:after_layout/after_layout.dart';
|
||||
import 'package:dartssh2/dartssh2.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
||||
import 'package:toolbox/core/extension/context.dart';
|
||||
import 'package:toolbox/core/extension/context/common.dart';
|
||||
import 'package:toolbox/core/extension/context/dialog.dart';
|
||||
import 'package:toolbox/core/extension/context/snackbar.dart';
|
||||
import 'package:toolbox/core/extension/sftpfile.dart';
|
||||
import 'package:toolbox/data/res/logger.dart';
|
||||
import 'package:toolbox/data/res/misc.dart';
|
||||
@@ -267,7 +269,7 @@ class _SftpPageState extends State<SftpPage> with AfterLayoutMixin {
|
||||
|
||||
Widget _buildFileView() {
|
||||
if (_status.files == null) {
|
||||
return centerLoading;
|
||||
return UIs.centerLoading;
|
||||
}
|
||||
|
||||
if (_status.files!.isEmpty) {
|
||||
@@ -293,7 +295,7 @@ class _SftpPageState extends State<SftpPage> with AfterLayoutMixin {
|
||||
final isDir = file.attr.isDirectory;
|
||||
final trailing = Text(
|
||||
'${getTime(file.attr.modifyTime)}\n${file.attr.mode?.str ?? ''}',
|
||||
style: grey,
|
||||
style: UIs.textGrey,
|
||||
textAlign: TextAlign.right,
|
||||
);
|
||||
return RoundRectCard(ListTile(
|
||||
@@ -304,7 +306,7 @@ class _SftpPageState extends State<SftpPage> with AfterLayoutMixin {
|
||||
? null
|
||||
: Text(
|
||||
(file.attr.size ?? 0).convertBytes,
|
||||
style: grey,
|
||||
style: UIs.textGrey,
|
||||
),
|
||||
onTap: () {
|
||||
if (isDir) {
|
||||
@@ -362,11 +364,11 @@ class _SftpPageState extends State<SftpPage> with AfterLayoutMixin {
|
||||
|
||||
Future<void> _edit(BuildContext context, SftpName name) async {
|
||||
final size = name.attr.size;
|
||||
if (size == null || size > editorMaxSize) {
|
||||
if (size == null || size > Miscs.editorMaxSize) {
|
||||
context.showSnackBar(_s.fileTooLarge(
|
||||
name.filename,
|
||||
size ?? 0,
|
||||
editorMaxSize,
|
||||
Miscs.editorMaxSize,
|
||||
));
|
||||
return;
|
||||
}
|
||||
@@ -469,7 +471,7 @@ class _SftpPageState extends State<SftpPage> with AfterLayoutMixin {
|
||||
}
|
||||
_listDir();
|
||||
},
|
||||
child: Text(_s.delete, style: textRed),
|
||||
child: Text(_s.delete, style: UIs.textRed),
|
||||
),
|
||||
],
|
||||
);
|
||||
@@ -510,7 +512,7 @@ class _SftpPageState extends State<SftpPage> with AfterLayoutMixin {
|
||||
context.pop();
|
||||
_listDir();
|
||||
},
|
||||
child: Text(_s.ok, style: textRed),
|
||||
child: Text(_s.ok, style: UIs.textRed),
|
||||
),
|
||||
],
|
||||
);
|
||||
@@ -550,7 +552,7 @@ class _SftpPageState extends State<SftpPage> with AfterLayoutMixin {
|
||||
context.pop();
|
||||
_listDir();
|
||||
},
|
||||
child: Text(_s.ok, style: textRed),
|
||||
child: Text(_s.ok, style: UIs.textRed),
|
||||
),
|
||||
],
|
||||
);
|
||||
@@ -588,7 +590,7 @@ class _SftpPageState extends State<SftpPage> with AfterLayoutMixin {
|
||||
context.pop();
|
||||
_listDir();
|
||||
},
|
||||
child: Text(_s.rename, style: textRed),
|
||||
child: Text(_s.rename, style: UIs.textRed),
|
||||
),
|
||||
],
|
||||
);
|
||||
@@ -623,7 +625,7 @@ class _SftpPageState extends State<SftpPage> with AfterLayoutMixin {
|
||||
}
|
||||
|
||||
Future<String> _getLocalPath(String remotePath) async {
|
||||
return '${await sftpDir}$remotePath';
|
||||
return '${await Paths.sftp}$remotePath';
|
||||
}
|
||||
|
||||
/// Only return true if the path is changed
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:toolbox/core/extension/context/common.dart';
|
||||
import 'package:toolbox/core/extension/datetime.dart';
|
||||
import 'package:toolbox/core/extension/context.dart';
|
||||
import 'package:toolbox/core/extension/context/dialog.dart';
|
||||
import 'package:toolbox/core/route.dart';
|
||||
import 'package:toolbox/locator.dart';
|
||||
|
||||
@@ -34,7 +35,7 @@ class _SftpMissionPageState extends State<SftpMissionPage> {
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: CustomAppBar(
|
||||
title: Text(_s.mission, style: textSize18),
|
||||
title: Text(_s.mission, style: UIs.textSize18),
|
||||
),
|
||||
body: _buildBody(),
|
||||
);
|
||||
@@ -134,12 +135,7 @@ class _SftpMissionPageState extends State<SftpMissionPage> {
|
||||
overflow: TextOverflow.ellipsis,
|
||||
maxLines: 1,
|
||||
),
|
||||
subtitle: subtitle == null
|
||||
? null
|
||||
: Text(
|
||||
subtitle,
|
||||
style: grey,
|
||||
),
|
||||
subtitle: subtitle == null ? null : Text(subtitle, style: UIs.textGrey),
|
||||
trailing: trailing,
|
||||
),
|
||||
);
|
||||
|
||||
@@ -12,7 +12,7 @@ class PopupMenu<T> extends StatelessWidget {
|
||||
super.key,
|
||||
required this.items,
|
||||
required this.onSelected,
|
||||
this.child = popMenuChild,
|
||||
this.child = UIs.popMenuChild,
|
||||
this.padding = const EdgeInsets.all(7),
|
||||
this.initialValue,
|
||||
});
|
||||
|
||||
@@ -2,7 +2,9 @@ import 'dart:io';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
||||
import 'package:toolbox/core/extension/context.dart';
|
||||
import 'package:toolbox/core/extension/context/common.dart';
|
||||
import 'package:toolbox/core/extension/context/dialog.dart';
|
||||
import 'package:toolbox/core/extension/context/snackbar.dart';
|
||||
import 'package:toolbox/core/extension/ssh_client.dart';
|
||||
import 'package:toolbox/core/extension/uint8list.dart';
|
||||
import 'package:toolbox/data/model/pkg/manager.dart';
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:toolbox/core/extension/context.dart';
|
||||
import 'package:toolbox/core/extension/context/common.dart';
|
||||
import 'package:toolbox/core/extension/context/dialog.dart';
|
||||
import 'package:toolbox/data/res/ui.dart';
|
||||
import 'package:toolbox/view/widget/input_field.dart';
|
||||
import 'package:toolbox/view/widget/round_rect_card.dart';
|
||||
@@ -29,7 +30,7 @@ class TagBtn extends StatelessWidget {
|
||||
content,
|
||||
textAlign: TextAlign.center,
|
||||
textScaleFactor: 1.0,
|
||||
style: isEnable ? textSize13 : textSize13Grey,
|
||||
style: isEnable ? UIs.textSize13 : UIs.textSize13Grey,
|
||||
),
|
||||
onTap: onTap,
|
||||
);
|
||||
@@ -107,7 +108,7 @@ class _TagEditorState extends State<TagEditor> {
|
||||
Text(
|
||||
'#$tag',
|
||||
textAlign: TextAlign.center,
|
||||
style: isAdd ? textSize13Grey : textSize13,
|
||||
style: isAdd ? UIs.textSize13Grey : UIs.textSize13,
|
||||
textScaleFactor: 1.0,
|
||||
),
|
||||
const SizedBox(width: 4.0),
|
||||
@@ -211,7 +212,7 @@ class _TagPickerState<T extends TagPickable> extends State<TagPicker<T>> {
|
||||
final children = <Widget>[];
|
||||
if (widget.tags.isNotEmpty) {
|
||||
children.add(Text(_s.tag));
|
||||
children.add(height13);
|
||||
children.add(UIs.height13);
|
||||
children.add(SizedBox(
|
||||
height: _kTagBtnHeight,
|
||||
width: _media.size.width * 0.7,
|
||||
@@ -220,7 +221,7 @@ class _TagPickerState<T extends TagPickable> extends State<TagPicker<T>> {
|
||||
}
|
||||
if (widget.items.isNotEmpty) {
|
||||
children.add(Text(_s.all));
|
||||
children.add(height13);
|
||||
children.add(UIs.height13);
|
||||
children.add(SizedBox(
|
||||
height: _kTagBtnHeight,
|
||||
width: _media.size.width * 0.7,
|
||||
@@ -313,7 +314,7 @@ class TagSwitcher extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
if (tags.isEmpty) return placeholder;
|
||||
if (tags.isEmpty) return UIs.placeholder;
|
||||
final items = <String?>[null, ...tags];
|
||||
return Container(
|
||||
height: _kTagBtnHeight,
|
||||
|
||||
@@ -15,12 +15,12 @@ class TwoLineText extends StatelessWidget {
|
||||
children: [
|
||||
Text(
|
||||
up,
|
||||
style: textSize15,
|
||||
style: UIs.textSize15,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
Text(
|
||||
down,
|
||||
style: textSize11,
|
||||
style: UIs.textSize11,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
)
|
||||
],
|
||||
|
||||
@@ -82,7 +82,9 @@ class UrlText extends StatelessWidget {
|
||||
Widget build(BuildContext context) {
|
||||
return RichText(
|
||||
textAlign: textAlign ?? TextAlign.start,
|
||||
text: TextSpan(children: getTextSpans(contentColor.resolve(context))),
|
||||
text: TextSpan(
|
||||
children: getTextSpans(DynamicColors.content.resolve(context)),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user