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