This commit is contained in:
lollipopkit
2023-09-13 14:28:02 +08:00
parent 6c84d2f52b
commit 278d5984b2
55 changed files with 528 additions and 481 deletions

View File

@@ -70,7 +70,7 @@ class Backup {
static Future<void> backup() async {
final result = _diyEncrtpt(json.encode(Backup.loadFromStore()));
await File(await backupPath).writeAsString(result);
await File(await Paths.bak).writeAsString(result);
}
Future<void> restore() async {

View File

@@ -1,6 +1,5 @@
import 'package:flutter/widgets.dart';
import '../../../core/extension/context.dart';
import 'package:toolbox/core/extension/context/common.dart';
class DynamicColor {
/// 白天模式显示的颜色

View File

@@ -1,7 +1,8 @@
import '../../res/build_data.dart';
import '../../res/server_cmd.dart';
import '../server/system.dart';
const seperator = 'SrvBoxSep';
const _cmdDivider = '\necho $seperator\n\t';
const _serverBoxDir = r'$HOME/.config/server_box';

View File

@@ -20,7 +20,7 @@ Conn? parseConn(String raw) {
final idx = lines.lastWhere((element) => element.startsWith('Tcp:'),
orElse: () => '');
if (idx != '') {
final vals = idx.split(numReg);
final vals = idx.split(Miscs.numReg);
return Conn(
maxConn: vals[5].i,
active: vals[6].i,

View File

@@ -27,7 +27,7 @@ List<Disk> parseDisk(String raw) {
if (item.isEmpty) {
continue;
}
final vals = item.split(numReg);
final vals = item.split(Miscs.numReg);
if (vals.length == 1) {
pathCache = vals[0];
continue;

View File

@@ -93,7 +93,7 @@ class Proc {
@override
String toString() {
return jsonEncoder.convert(toJson());
return Miscs.jsonEncoder.convert(toJson());
}
String get binary {

View File

@@ -52,9 +52,9 @@ class DebugProvider extends ChangeNotifier {
void _addWidget(Widget widget) {
widgets.add(widget);
widgets.add(height13);
if (widgets.length > maxDebugLogLines) {
widgets.removeRange(0, widgets.length - maxDebugLogLines);
widgets.add(UIs.height13);
if (widgets.length > Miscs.maxDebugLogLines) {
widgets.removeRange(0, widgets.length - Miscs.maxDebugLogLines);
}
notifyListeners();
}

View File

@@ -12,8 +12,6 @@ import 'package:toolbox/data/res/logger.dart';
import 'package:toolbox/data/store/docker.dart';
import 'package:toolbox/locator.dart';
import '../res/server_cmd.dart';
final _dockerNotFound = RegExp(r'command not found|Unknown command');
final _versionReg = RegExp(r'(Version:)\s+([0-9]+\.[0-9]+\.[0-9]+)');
// eg: `Docker Engine - Community`

View File

@@ -14,7 +14,6 @@ import '../model/server/server_private_info.dart';
import '../model/server/server_status_update_req.dart';
import '../model/server/snippet.dart';
import '../model/server/try_limiter.dart';
import '../res/server_cmd.dart';
import '../res/status.dart';
import '../store/server.dart';
import '../store/setting.dart';

View File

@@ -4,6 +4,8 @@ import '../model/app/dynamic_color.dart';
late Color primaryColor;
const contentColor = DynamicColor(Colors.black87, Colors.white70);
const bgColor = DynamicColor(Colors.white, Colors.black);
const progressColor = DynamicColor(Colors.black12, Colors.white10);
class DynamicColors {
static const content = DynamicColor(Colors.black87, Colors.white70);
static const bg = DynamicColor(Colors.white, Colors.black);
static const progress = DynamicColor(Colors.black12, Colors.white10);
}

View File

@@ -2,48 +2,50 @@ import 'dart:ui';
import 'package:toolbox/data/model/ssh/virtual_key.dart';
// default server details page cards order
const defaultDetailCardOrder = [
'uptime',
'cpu',
'mem',
'swap',
'disk',
'net',
'temp'
];
class Defaults {
// default server details page cards order
static const detailCardOrder = [
'uptime',
'cpu',
'mem',
'swap',
'disk',
'net',
'temp'
];
const defaultDiskIgnorePath = [
'udev',
'tmpfs',
'devtmpfs',
'overlay',
'run',
'none',
];
static const diskIgnorePath = [
'udev',
'tmpfs',
'devtmpfs',
'overlay',
'run',
'none',
];
const defaultSSHVirtKeys = [
VirtKey.esc,
VirtKey.alt,
VirtKey.home,
VirtKey.up,
VirtKey.end,
VirtKey.sftp,
VirtKey.snippet,
VirtKey.tab,
VirtKey.ctrl,
VirtKey.left,
VirtKey.down,
VirtKey.right,
VirtKey.clipboard,
VirtKey.ime,
];
static const sshVirtKeys = [
VirtKey.esc,
VirtKey.alt,
VirtKey.home,
VirtKey.up,
VirtKey.end,
VirtKey.sftp,
VirtKey.snippet,
VirtKey.tab,
VirtKey.ctrl,
VirtKey.left,
VirtKey.down,
VirtKey.right,
VirtKey.clipboard,
VirtKey.ime,
];
const defaultPrimaryColor = Color.fromARGB(255, 145, 58, 31);
static const primaryColor = Color.fromARGB(255, 145, 58, 31);
const defaultLaunchPageIdx = 0;
static const launchPageIdx = 0;
const defaultUpdateInterval = 3;
static const updateInterval = 3;
const defaultEditorTheme = 'a11y-light';
const defaultEditorDarkTheme = 'monokai';
static const editorTheme = 'a11y-light';
static const editorDarkTheme = 'monokai';
}

View 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',
};
}

View File

@@ -1,4 +1,3 @@
import 'package:highlight/highlight_core.dart';
import 'package:highlight/languages/accesslog.dart';
import 'package:highlight/languages/awk.dart';
import 'package:highlight/languages/bash.dart';
@@ -33,52 +32,48 @@ import 'package:highlight/languages/vim.dart';
import 'package:highlight/languages/xml.dart';
import 'package:highlight/languages/yaml.dart';
// KEY: fileNameSuffix
// VAL: highlight
final suffix2HighlightMap = {
'dart': dart,
'go': go,
'rust': rust,
'lua': lua,
'sh': bash,
'py': python,
'js': javascript,
'ts': typescript,
'java': java,
'kt': kotlin,
'swift': swift,
'c': cpp,
'oc': objectivec,
'ruby': ruby,
'perl': perl,
'php': php,
'nix': nix,
'lisp': lisp,
'sql': sql,
'powershell': powershell,
'log': accesslog,
'ini': ini,
'cmake': cmake,
'awk': awk,
'json': json,
'yaml': yaml,
'xml': xml,
'cpp': cpp,
'diff': diff,
'css': css,
'html': htmlbars,
'tex': tex,
'vim': vim,
'plaintext': plaintext,
};
class Highlights {
/// - KEY: fileNameSuffix
/// - VAL: highlight
static final all = {
'dart': dart,
'go': go,
'rust': rust,
'lua': lua,
'sh': bash,
'py': python,
'js': javascript,
'ts': typescript,
'java': java,
'kt': kotlin,
'swift': swift,
'c': cpp,
'oc': objectivec,
'ruby': ruby,
'perl': perl,
'php': php,
'nix': nix,
'lisp': lisp,
'sql': sql,
'powershell': powershell,
'log': accesslog,
'ini': ini,
'cmake': cmake,
'awk': awk,
'json': json,
'yaml': yaml,
'xml': xml,
'cpp': cpp,
'diff': diff,
'css': css,
'html': htmlbars,
'tex': tex,
'vim': vim,
'plaintext': plaintext,
};
extension HighlightString on String? {
Mode? get highlight {
return suffix2HighlightMap[highlightCode];
}
String? get highlightCode {
if (this == null) return null;
return this!.split('.').last;
static String? getCode(String? fileName) {
if (fileName == null) return null;
return fileName.split('.').last;
}
}

View File

@@ -2,61 +2,26 @@ import 'dart:convert';
import 'package:flutter/services.dart';
import '../model/app/github_id.dart';
class Miscs {
/// RegExp for number
static final numReg = RegExp(r'\s{1,}');
/// RegExp for number
final numReg = RegExp(r'\s{1,}');
/// RegExp for password request
static final pwdRequestWithUserReg = RegExp(r'\[sudo\] password for (.+):');
/// RegExp for password request
final pwdRequestWithUserReg = RegExp(r'\[sudo\] password for (.+):');
/// Private Key max allowed size is 20kb
const privateKeyMaxSize = 20 * 1024;
/// Private Key max allowed size is 20kb
static const privateKeyMaxSize = 20 * 1024;
// Editor max allowed size is 1mb
const editorMaxSize = 1024 * 1024;
static const editorMaxSize = 1024 * 1024;
/// Max debug log lines
const maxDebugLogLines = 100;
/// Max debug log lines
static const maxDebugLogLines = 100;
/// Method Channels
const pkgName = 'tech.lolli.toolbox';
const bgRunChannel = MethodChannel('$pkgName/app_retain');
const homeWidgetChannel = MethodChannel('$pkgName/home_widget');
/// Method Channels
static const pkgName = 'tech.lolli.toolbox';
static const bgRunChannel = MethodChannel('$pkgName/app_retain');
static const homeWidgetChannel = MethodChannel('$pkgName/home_widget');
// Thanks
// If you want to change the url, please open an issue.
const contributors = <GhId>{
'its-tom',
'RainSunMe',
'kalashnikov',
'azkadev',
'calvinweb',
'Liloupar'
};
const participants = <GhId>{
'jaychoubaby',
'fecture',
'Tao173',
'QingAnLe',
'wxdjs',
'Aeorq',
'allonmymind',
'Yuuki-Rin',
'LittleState',
'karuboniru',
'whosphp',
'Climit',
'dianso',
'Jasondeepny',
'kaliwell',
'ymxkiss',
'Ealrang',
'hange33',
'yuchen1204',
'xgzxmytx',
'wind057',
'a1564471347',
};
const jsonEncoder = JsonEncoder.withIndent(' ');
static const jsonEncoder = JsonEncoder.withIndent(' ');
}

View File

@@ -3,45 +3,49 @@ import 'dart:io';
import 'package:path_provider/path_provider.dart';
import 'package:toolbox/core/utils/platform.dart';
String? _docDir;
String? _sftpDir;
String? _fontDir;
class Paths {
static String? _docDir;
static String? _sftpDir;
static String? _fontDir;
Future<String> get docDir async {
if (_docDir != null) {
return _docDir!;
}
if (isAndroid) {
final dir = await getExternalStorageDirectory();
if (dir != null) {
_docDir = dir.path;
return dir.path;
static Future<String> get doc async {
if (_docDir != null) {
return _docDir!;
}
// fallthrough to getApplicationDocumentsDirectory
if (isAndroid) {
final dir = await getExternalStorageDirectory();
if (dir != null) {
_docDir = dir.path;
return dir.path;
}
// fallthrough to getApplicationDocumentsDirectory
}
final dir = await getApplicationDocumentsDirectory();
_docDir = dir.path;
return dir.path;
}
final dir = await getApplicationDocumentsDirectory();
_docDir = dir.path;
return dir.path;
}
Future<String> get sftpDir async {
if (_sftpDir != null) {
static Future<String> get sftp async {
if (_sftpDir != null) {
return _sftpDir!;
}
_sftpDir = '${await doc}/sftp';
final dir = Directory(_sftpDir!);
await dir.create(recursive: true);
return _sftpDir!;
}
_sftpDir = '${await docDir}/sftp';
final dir = Directory(_sftpDir!);
await dir.create(recursive: true);
return _sftpDir!;
}
Future<String> get fontDir async {
if (_fontDir != null) {
static Future<String> get font async {
if (_fontDir != null) {
return _fontDir!;
}
_fontDir = '${await doc}/font';
final dir = Directory(_fontDir!);
await dir.create(recursive: true);
return _fontDir!;
}
_fontDir = '${await docDir}/font';
final dir = Directory(_fontDir!);
await dir.create(recursive: true);
return _fontDir!;
}
Future<String> get backupPath async => '${await docDir}/srvbox_bak.json';
static Future<String> get bak async => '${await doc}/srvbox_bak.json';
static Future<String> get dl async => joinPath(await doc, 'dl');
}

View File

@@ -1 +0,0 @@
const seperator = 'SrvBoxSep';

View File

@@ -1,52 +1,55 @@
import 'package:flutter/material.dart';
/// Font style
class UIs {
/// Font style
const textSize9Grey = TextStyle(color: Colors.grey, fontSize: 9);
const textSize11 = TextStyle(fontSize: 11);
const textSize11Grey = TextStyle(color: Colors.grey, fontSize: 11);
const textSize13 = TextStyle(fontSize: 13);
const textSize13Bold = TextStyle(fontSize: 13, fontWeight: FontWeight.bold);
const textSize13Grey = TextStyle(color: Colors.grey, fontSize: 13);
const textSize15 = TextStyle(fontSize: 15);
const textSize18 = TextStyle(fontSize: 18);
const textSize27 = TextStyle(fontSize: 27);
static const textSize9Grey = TextStyle(color: Colors.grey, fontSize: 9);
static const textSize11 = TextStyle(fontSize: 11);
static const textSize11Grey = TextStyle(color: Colors.grey, fontSize: 11);
static const textSize13 = TextStyle(fontSize: 13);
static const textSize13Bold =
TextStyle(fontSize: 13, fontWeight: FontWeight.bold);
static const textSize13Grey = TextStyle(color: Colors.grey, fontSize: 13);
static const textSize15 = TextStyle(fontSize: 15);
static const textSize18 = TextStyle(fontSize: 18);
static const textSize27 = TextStyle(fontSize: 27);
static const textGrey = TextStyle(color: Colors.grey);
static const textRed = TextStyle(color: Colors.red);
const grey = TextStyle(color: Colors.grey);
const textRed = TextStyle(color: Colors.red);
/// Icon
/// Icon
static final appIcon = Image.asset('assets/app_icon.png');
final appIcon = Image.asset('assets/app_icon.png');
/// Padding
/// Padding
static const roundRectCardPadding =
EdgeInsets.symmetric(horizontal: 17, vertical: 13);
const roundRectCardPadding = EdgeInsets.symmetric(horizontal: 17, vertical: 13);
/// SizedBox
/// SizedBox
static const placeholder = SizedBox();
static const height13 = SizedBox(height: 13);
static const height77 = SizedBox(height: 77);
static const width13 = SizedBox(width: 13);
static const width7 = SizedBox(width: 7);
const placeholder = SizedBox();
const height13 = SizedBox(height: 13);
const height77 = SizedBox(height: 77);
const width13 = SizedBox(width: 13);
const width7 = SizedBox(width: 7);
/// Misc
/// Misc
static const popMenuChild = Padding(
padding: EdgeInsets.only(left: 7),
child: Icon(
Icons.more_vert,
size: 21,
),
);
const popMenuChild = Padding(
padding: EdgeInsets.only(left: 7),
child: Icon(
Icons.more_vert,
size: 21,
),
);
static const centerLoading = Center(child: CircularProgressIndicator());
const centerLoading = Center(child: CircularProgressIndicator());
const centerSizedLoading = SizedBox(
width: 77,
height: 77,
child: Center(
child: CircularProgressIndicator(),
),
);
static const centerSizedLoading = SizedBox(
width: 77,
height: 77,
child: Center(
child: CircularProgressIndicator(),
),
);
}

View File

@@ -1,4 +1,6 @@
const baseResUrl = 'https://res.lolli.tech/serverbox';
const myGithub = 'https://github.com/lollipopkit';
const appHelpUrl = '$myGithub/flutter_server_box#-help';
const appWikiUrl = '$myGithub/flutter_server_box/wiki';
class Urls {
static const resBase = 'https://res.lolli.tech/serverbox';
static const myGithub = 'https://github.com/lollipopkit';
static const appHelp = '$myGithub/flutter_server_box#-help';
static const appWiki = '$myGithub/flutter_server_box/wiki';
}

View File

@@ -5,7 +5,7 @@ import '../res/url.dart';
class AppService {
Future<AppUpdate> getUpdate() async {
final resp = await Dio().get('$baseResUrl/update.json');
final resp = await Dio().get('${Urls.resBase}/update.json');
return AppUpdate.fromJson(resp.data);
}
}

View File

@@ -52,12 +52,12 @@ class SettingStore extends PersistentStore {
late final launchPage = StoreProperty(
box,
'launchPage',
defaultLaunchPageIdx,
Defaults.launchPageIdx,
);
/// Server detail disk ignore path
late final diskIgnorePath =
StoreListProperty(box, 'diskIgnorePath', defaultDiskIgnorePath);
StoreListProperty(box, 'diskIgnorePath', Defaults.diskIgnorePath);
/// Use double column servers page on Desktop
late final doubleColumnServersPage = StoreProperty(
@@ -77,7 +77,7 @@ class SettingStore extends PersistentStore {
late final serverStatusUpdateInterval = StoreProperty(
box,
'serverStatusUpdateInterval',
defaultUpdateInterval,
Defaults.updateInterval,
);
// Max retry count when connect to server
@@ -99,7 +99,7 @@ class SettingStore extends PersistentStore {
// Server details page cards order
late final detailCardOrder =
StoreListProperty(box, 'detailCardPrder', defaultDetailCardOrder);
StoreListProperty(box, 'detailCardPrder', Defaults.detailCardOrder);
// SSH term font size
late final termFontSize = StoreProperty(box, 'termFontSize', 13.0);
@@ -117,13 +117,13 @@ class SettingStore extends PersistentStore {
late final editorTheme = StoreProperty(
box,
'editorTheme',
defaultEditorTheme,
Defaults.editorTheme,
);
late final editorDarkTheme = StoreProperty(
box,
'editorDarkTheme',
defaultEditorDarkTheme,
Defaults.editorDarkTheme,
);
late final fullScreen = StoreProperty(
@@ -153,7 +153,7 @@ class SettingStore extends PersistentStore {
late final sshVirtKeys = StoreListProperty(
box,
'sshVirtKeys',
defaultSSHVirtKeys,
Defaults.sshVirtKeys,
);
late final netViewType = StoreProperty(