This commit is contained in:
lollipopkit
2023-05-26 17:01:52 +08:00
parent c1c009863d
commit 20ef9d4575
28 changed files with 126 additions and 149 deletions

View File

@@ -30,7 +30,7 @@ Especially thanks to <a href="https://github.com/TerminalStudio/dartssh2">dartss
- [x] `Docker & Pkg` Manager - [x] `Docker & Pkg` Manager
- [x] Status charts - [x] Status charts
- [x] `Ping` and etc. - [x] `Ping` and etc.
- [x] i18n (English, Chinese) - [x] i18n (English, 简体中文, Deutsch)
- Welcome contribution :), [How to contribute?](#l10n-guide) - Welcome contribution :), [How to contribute?](#l10n-guide)
- [x] Desktop support - [x] Desktop support

View File

@@ -30,7 +30,7 @@
- [x] `Docker & 包` 管理器 - [x] `Docker & 包` 管理器
- [x] 状态图表 - [x] 状态图表
- [x] `Ping` 和 更多 - [x] `Ping` 和 更多
- [x] 本地化 ( 英语, 中文 ) - [x] 本地化 ( English, 简体中文, Deutsch )
- 欢迎贡献 :)[怎么贡献?](#l10n) - 欢迎贡献 :)[怎么贡献?](#l10n)
- [x] 桌面端支持 - [x] 桌面端支持

File diff suppressed because one or more lines are too long

View File

@@ -360,7 +360,7 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
CURRENT_PROJECT_VERSION = 314; CURRENT_PROJECT_VERSION = 318;
DEVELOPMENT_TEAM = BA88US33G6; DEVELOPMENT_TEAM = BA88US33G6;
ENABLE_BITCODE = NO; ENABLE_BITCODE = NO;
INFOPLIST_FILE = "Runner/Info-$(CONFIGURATION).plist"; INFOPLIST_FILE = "Runner/Info-$(CONFIGURATION).plist";
@@ -368,7 +368,7 @@
"$(inherited)", "$(inherited)",
"@executable_path/Frameworks", "@executable_path/Frameworks",
); );
MARKETING_VERSION = 1.0.314; MARKETING_VERSION = 1.0.318;
PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
@@ -491,7 +491,7 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
CURRENT_PROJECT_VERSION = 314; CURRENT_PROJECT_VERSION = 318;
DEVELOPMENT_TEAM = BA88US33G6; DEVELOPMENT_TEAM = BA88US33G6;
ENABLE_BITCODE = NO; ENABLE_BITCODE = NO;
INFOPLIST_FILE = "Runner/Info-$(CONFIGURATION).plist"; INFOPLIST_FILE = "Runner/Info-$(CONFIGURATION).plist";
@@ -499,7 +499,7 @@
"$(inherited)", "$(inherited)",
"@executable_path/Frameworks", "@executable_path/Frameworks",
); );
MARKETING_VERSION = 1.0.314; MARKETING_VERSION = 1.0.318;
PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
@@ -516,7 +516,7 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
CURRENT_PROJECT_VERSION = 314; CURRENT_PROJECT_VERSION = 318;
DEVELOPMENT_TEAM = BA88US33G6; DEVELOPMENT_TEAM = BA88US33G6;
ENABLE_BITCODE = NO; ENABLE_BITCODE = NO;
INFOPLIST_FILE = "Runner/Info-$(CONFIGURATION).plist"; INFOPLIST_FILE = "Runner/Info-$(CONFIGURATION).plist";
@@ -524,7 +524,7 @@
"$(inherited)", "$(inherited)",
"@executable_path/Frameworks", "@executable_path/Frameworks",
); );
MARKETING_VERSION = 1.0.314; MARKETING_VERSION = 1.0.318;
PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";

View File

@@ -1,6 +1,6 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
const Set<MaterialState> interactiveStates = <MaterialState>{ const _interactiveStates = <MaterialState>{
MaterialState.pressed, MaterialState.pressed,
MaterialState.hovered, MaterialState.hovered,
MaterialState.focused, MaterialState.focused,
@@ -18,7 +18,7 @@ extension ColorX on Color {
MaterialStateProperty<Color?> get materialStateColor { MaterialStateProperty<Color?> get materialStateColor {
return MaterialStateProperty.resolveWith((states) { return MaterialStateProperty.resolveWith((states) {
if (states.any(interactiveStates.contains)) { if (states.any(_interactiveStates.contains)) {
return this; return this;
} }
return null; return null;

View File

@@ -11,8 +11,12 @@ typedef PwdRequestFunc = Future<String> Function();
final pwdRequestWithUserReg = RegExp(r'\[sudo\] password for (.+):'); final pwdRequestWithUserReg = RegExp(r'\[sudo\] password for (.+):');
extension SSHClientX on SSHClient { extension SSHClientX on SSHClient {
Future<int?> exec(String cmd, Future<int?> exec(
{OnStd? onStderr, OnStd? onStdout, OnStdin? stdin}) async { String cmd, {
OnStd? onStderr,
OnStd? onStdout,
OnStdin? stdin,
}) async {
final session = await execute(cmd); final session = await execute(cmd);
final stdoutDone = Completer<void>(); final stdoutDone = Completer<void>();

View File

@@ -10,8 +10,11 @@ extension StringX on String {
return Uri.parse(this); return Uri.parse(this);
} }
Widget omitStartStr( Widget omitStartStr({
{TextStyle? style, TextOverflow? overflow, int? maxLines}) { TextStyle? style,
TextOverflow? overflow,
int? maxLines,
}) {
return LayoutBuilder(builder: (context, size) { return LayoutBuilder(builder: (context, size) {
bool exceeded = false; bool exceeded = false;
int len = 0; int len = 0;

View File

@@ -11,14 +11,14 @@ class Backup {
final List<PrivateKeyInfo> keys; final List<PrivateKeyInfo> keys;
final Map<String, String> dockerHosts; final Map<String, String> dockerHosts;
Backup( Backup({
this.version, required this.version,
this.date, required this.date,
this.spis, required this.spis,
this.snippets, required this.snippets,
this.keys, required this.keys,
this.dockerHosts, required this.dockerHosts,
); });
Backup.fromJson(Map<String, dynamic> json) Backup.fromJson(Map<String, dynamic> json)
: version = json['version'] as int, : version = json['version'] as int,

View File

@@ -4,6 +4,7 @@ enum ErrFrom {
docker, docker,
sftp, sftp,
ssh, ssh,
status;
} }
abstract class Err<T> { abstract class Err<T> {
@@ -25,4 +26,9 @@ enum DockerErrType {
class DockerErr extends Err<DockerErrType> { class DockerErr extends Err<DockerErrType> {
DockerErr({required DockerErrType type, String? message}) DockerErr({required DockerErrType type, String? message})
: super(from: ErrFrom.docker, type: type, message: message); : super(from: ErrFrom.docker, type: type, message: message);
@override
String toString() {
return 'DockerErr<$type>: $message';
}
} }

View File

@@ -1,16 +1,10 @@
class PathWithPrefix { class PathWithPrefix {
late String _prefixPath; final String _prefixPath;
String _path = '/'; String _path = '/';
String? _prePath; String? _prePath;
String get path => _prefixPath + _path; String get path => _prefixPath + _path;
PathWithPrefix(String prefixPath) { PathWithPrefix(String prefixPath) : _prefixPath = _trimSuffix(prefixPath);
if (prefixPath.endsWith('/')) {
_prefixPath = prefixPath.substring(0, prefixPath.length - 1);
} else {
_prefixPath = prefixPath;
}
}
void update(String newPath) { void update(String newPath) {
_prePath = _path; _prePath = _path;
@@ -36,3 +30,10 @@ class PathWithPrefix {
return true; return true;
} }
} }
String _trimSuffix(String prefixPath) {
if (prefixPath.endsWith('/')) {
return prefixPath.substring(0, prefixPath.length - 1);
}
return prefixPath;
}

View File

@@ -2,26 +2,17 @@ import '../../../core/extension/stringx.dart';
import '../../res/misc.dart'; import '../../res/misc.dart';
class ConnStatus { class ConnStatus {
/* final int maxConn;
{ final int active;
"maxConn": 0, final int passive;
"active": 1, final int fail;
"passive": 2,
"fail": 3
}
*/
late int maxConn; ConnStatus({
late int active; required this.maxConn,
late int passive; required this.active,
late int fail; required this.passive,
required this.fail,
ConnStatus( });
this.maxConn,
this.active,
this.passive,
this.fail,
);
} }
ConnStatus? parseConn(String raw) { ConnStatus? parseConn(String raw) {
@@ -30,7 +21,12 @@ ConnStatus? parseConn(String raw) {
orElse: () => ''); orElse: () => '');
if (idx != '') { if (idx != '') {
final vals = idx.split(numReg); final vals = idx.split(numReg);
return ConnStatus(vals[5].i, vals[6].i, vals[7].i, vals[8].i); return ConnStatus(
maxConn: vals[5].i,
active: vals[6].i,
passive: vals[7].i,
fail: vals[8].i,
);
} }
return null; return null;
} }

View File

@@ -1,21 +1,21 @@
import '../../res/misc.dart'; import '../../res/misc.dart';
class DiskInfo { class DiskInfo {
late String path; final String path;
late String loc; final String loc;
late int usedPercent; final int usedPercent;
late String used; final String used;
late String size; final String size;
late String avail; final String avail;
DiskInfo( DiskInfo({
this.path, required this.path,
this.loc, required this.loc,
this.usedPercent, required this.usedPercent,
this.used, required this.used,
this.size, required this.size,
this.avail, required this.avail,
); });
} }
List<DiskInfo> parseDisk(String raw) { List<DiskInfo> parseDisk(String raw) {
@@ -37,12 +37,12 @@ List<DiskInfo> parseDisk(String raw) {
pathCache = ''; pathCache = '';
} }
list.add(DiskInfo( list.add(DiskInfo(
vals[0], path: vals[0],
vals[5], loc: vals[5],
int.parse(vals[4].replaceFirst('%', '')), usedPercent: int.parse(vals[4].replaceFirst('%', '')),
vals[2], used: vals[2],
vals[1], size: vals[1],
vals[3], avail: vals[3],
)); ));
} }
return list; return list;

View File

@@ -1,8 +1,8 @@
class Memory { class Memory {
int total; final int total;
int free; final int free;
int cache; final int cache;
int avail; final int avail;
Memory({ Memory({
required this.total, required this.total,

View File

@@ -1,5 +1,3 @@
import 'dart:convert';
import 'package:hive_flutter/hive_flutter.dart'; import 'package:hive_flutter/hive_flutter.dart';
part 'private_key_info.g.dart'; part 'private_key_info.g.dart';
@@ -31,15 +29,3 @@ class PrivateKeyInfo {
return data; return data;
} }
} }
List<PrivateKeyInfo> getPrivateKeyInfoList(dynamic data) {
List<PrivateKeyInfo> ss = [];
if (data is String) {
data = json.decode(data);
}
for (var t in data) {
ss.add(PrivateKeyInfo.fromJson(t));
}
return ss;
}

View File

@@ -1,5 +1,3 @@
import 'dart:convert';
import 'package:hive_flutter/hive_flutter.dart'; import 'package:hive_flutter/hive_flutter.dart';
part 'server_private_info.g.dart'; part 'server_private_info.g.dart';
@@ -51,15 +49,3 @@ class ServerPrivateInfo {
return data; return data;
} }
} }
List<ServerPrivateInfo> getServerInfoList(dynamic data) {
List<ServerPrivateInfo> ss = [];
if (data is String) {
data = json.decode(data);
}
for (var t in data) {
ss.add(ServerPrivateInfo.fromJson(t));
}
return ss;
}

View File

@@ -1,5 +1,3 @@
import 'dart:convert';
import 'package:hive_flutter/hive_flutter.dart'; import 'package:hive_flutter/hive_flutter.dart';
part 'snippet.g.dart'; part 'snippet.g.dart';
@@ -23,15 +21,3 @@ class Snippet {
return data; return data;
} }
} }
List<Snippet> getSnippetList(dynamic data) {
List<Snippet> ss = [];
if (data is String) {
data = json.decode(data);
}
for (var t in data) {
ss.add(Snippet.fromJson(t));
}
return ss;
}

View File

@@ -9,7 +9,7 @@ class VirtualKey {
final VirtualKeyFunc? func; final VirtualKeyFunc? func;
VirtualKey(this.text, VirtualKey(this.text,
{this.key, this.toggleable = false, this.icon, this.func}); {this.key, this.toggleable = false, this.icon, this.func,});
} }
enum VirtualKeyFunc { toggleIME, backspace, copy, paste, snippet } enum VirtualKeyFunc { toggleIME, backspace, copy, paste, snippet }

View File

@@ -9,7 +9,7 @@ import 'package:toolbox/core/extension/uint8list.dart';
import 'package:toolbox/core/provider_base.dart'; import 'package:toolbox/core/provider_base.dart';
import 'package:toolbox/data/model/docker/image.dart'; import 'package:toolbox/data/model/docker/image.dart';
import 'package:toolbox/data/model/docker/ps.dart'; import 'package:toolbox/data/model/docker/ps.dart';
import 'package:toolbox/data/res/error.dart'; import 'package:toolbox/data/model/app/error.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';

View File

@@ -2,8 +2,8 @@
class BuildData { class BuildData {
static const String name = "ServerBox"; static const String name = "ServerBox";
static const int build = 314; static const int build = 318;
static const String engine = "3.10.0"; static const String engine = "3.10.2";
static const String buildAt = "2023-05-18 22:09:44.404990"; static const String buildAt = "2023-05-26 13:49:02.698178";
static const int modifications = 2; static const int modifications = 6;
} }

View File

@@ -47,8 +47,17 @@ ServerStatus get initStatus => ServerStatus(
mem: _initMemory, mem: _initMemory,
sysVer: 'Loading...', sysVer: 'Loading...',
uptime: '', uptime: '',
disk: [DiskInfo('/', '/', 0, '0', '0', '0')], disk: [
tcp: ConnStatus(0, 0, 0, 0), DiskInfo(
path: '/',
loc: '/',
usedPercent: 0,
used: '0',
size: '0',
avail: '0',
)
],
tcp: ConnStatus(maxConn: 0, active: 0, passive: 0, fail: 0),
netSpeed: initNetSpeed, netSpeed: initNetSpeed,
swap: _initSwap, swap: _initSwap,
temps: Temperatures(), temps: Temperatures(),

View File

@@ -84,12 +84,12 @@ class BackupPage extends StatelessWidget {
final result = _diyEncrtpt( final result = _diyEncrtpt(
json.encode( json.encode(
Backup( Backup(
backupFormatVersion, version: backupFormatVersion,
DateTime.now().toString().split('.').first, date: DateTime.now().toString().split('.').first,
_server.fetch(), spis: _server.fetch(),
_snippet.fetch(), snippets: _snippet.fetch(),
_privateKey.fetch(), keys: _privateKey.fetch(),
_dockerHosts.fetch(), dockerHosts: _dockerHosts.fetch(),
), ),
), ),
); );

View File

@@ -10,8 +10,8 @@ import '../../data/model/docker/ps.dart';
import '../../data/model/server/server_private_info.dart'; import '../../data/model/server/server_private_info.dart';
import '../../data/provider/docker.dart'; import '../../data/provider/docker.dart';
import '../../data/provider/server.dart'; import '../../data/provider/server.dart';
import '../../data/res/error.dart'; import '../../data/model/app/error.dart';
import '../../data/res/menu.dart'; import '../../data/model/app/menu.dart';
import '../../data/res/ui.dart'; import '../../data/res/ui.dart';
import '../../data/res/url.dart'; import '../../data/res/url.dart';
import '../../data/store/docker.dart'; import '../../data/store/docker.dart';

View File

@@ -389,7 +389,7 @@ class _ServerDetailPageState extends State<ServerDetailPage>
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
Icon(Icons.device_hub, size: 17), Icon(Icons.device_hub, size: 17),
Icon(Icons.arrow_downward, size: 17), Icon(Icons.ac_unit, size: 17),
], ],
), ),
const Padding( const Padding(

View File

@@ -14,7 +14,7 @@ import '../../../data/model/server/server_private_info.dart';
import '../../../data/model/server/server_status.dart'; import '../../../data/model/server/server_status.dart';
import '../../../data/provider/server.dart'; import '../../../data/provider/server.dart';
import '../../../data/res/color.dart'; import '../../../data/res/color.dart';
import '../../../data/res/menu.dart'; import '../../../data/model/app/menu.dart';
import '../../../data/res/ui.dart'; import '../../../data/res/ui.dart';
import '../../../data/res/url.dart'; import '../../../data/res/url.dart';
import '../../../data/store/setting.dart'; import '../../../data/store/setting.dart';

View File

@@ -263,12 +263,12 @@ class _SSHPageState extends State<SSHPage> {
} }
final selected = terminalSelected; final selected = terminalSelected;
final children = <Widget>[ final children = <Widget>[
TextButton( // TextButton(
onPressed: () { // onPressed: () {
_paste(); // _paste();
}, // },
child: Text(_s.paste), // child: Text(_s.paste),
), // ),
]; ];
if (selected?.trim().isNotEmpty ?? false) { if (selected?.trim().isNotEmpty ?? false) {
children.add( children.add(

View File

@@ -1,4 +1,5 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:toolbox/data/res/ui.dart';
class TwoLineText extends StatelessWidget { class TwoLineText extends StatelessWidget {
const TwoLineText({Key? key, required this.up, required this.down}) const TwoLineText({Key? key, required this.up, required this.down})
@@ -12,11 +13,11 @@ class TwoLineText extends StatelessWidget {
children: [ children: [
Text( Text(
up, up,
style: const TextStyle(fontSize: 15), style: textSize15,
), ),
Text( Text(
down, down,
style: const TextStyle(fontSize: 11), style: textSize11,
) )
], ],
); );

View File

@@ -475,9 +475,9 @@
baseConfigurationReference = C1C758C41C4E208965A68933 /* Pods-RunnerTests.debug.xcconfig */; baseConfigurationReference = C1C758C41C4E208965A68933 /* Pods-RunnerTests.debug.xcconfig */;
buildSettings = { buildSettings = {
BUNDLE_LOADER = "$(TEST_HOST)"; BUNDLE_LOADER = "$(TEST_HOST)";
CURRENT_PROJECT_VERSION = 314; CURRENT_PROJECT_VERSION = 318;
GENERATE_INFOPLIST_FILE = YES; GENERATE_INFOPLIST_FILE = YES;
MARKETING_VERSION = 1.0.314; MARKETING_VERSION = 1.0.318;
PRODUCT_BUNDLE_IDENTIFIER = tech.lolli.serverBox.RunnerTests; PRODUCT_BUNDLE_IDENTIFIER = tech.lolli.serverBox.RunnerTests;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 5.0; SWIFT_VERSION = 5.0;
@@ -490,9 +490,9 @@
baseConfigurationReference = 15AF97DF993E8968098D6EBE /* Pods-RunnerTests.release.xcconfig */; baseConfigurationReference = 15AF97DF993E8968098D6EBE /* Pods-RunnerTests.release.xcconfig */;
buildSettings = { buildSettings = {
BUNDLE_LOADER = "$(TEST_HOST)"; BUNDLE_LOADER = "$(TEST_HOST)";
CURRENT_PROJECT_VERSION = 314; CURRENT_PROJECT_VERSION = 318;
GENERATE_INFOPLIST_FILE = YES; GENERATE_INFOPLIST_FILE = YES;
MARKETING_VERSION = 1.0.314; MARKETING_VERSION = 1.0.318;
PRODUCT_BUNDLE_IDENTIFIER = tech.lolli.serverBox.RunnerTests; PRODUCT_BUNDLE_IDENTIFIER = tech.lolli.serverBox.RunnerTests;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 5.0; SWIFT_VERSION = 5.0;
@@ -505,9 +505,9 @@
baseConfigurationReference = 7CFA7DE7FABA75685DFB6948 /* Pods-RunnerTests.profile.xcconfig */; baseConfigurationReference = 7CFA7DE7FABA75685DFB6948 /* Pods-RunnerTests.profile.xcconfig */;
buildSettings = { buildSettings = {
BUNDLE_LOADER = "$(TEST_HOST)"; BUNDLE_LOADER = "$(TEST_HOST)";
CURRENT_PROJECT_VERSION = 314; CURRENT_PROJECT_VERSION = 318;
GENERATE_INFOPLIST_FILE = YES; GENERATE_INFOPLIST_FILE = YES;
MARKETING_VERSION = 1.0.314; MARKETING_VERSION = 1.0.318;
PRODUCT_BUNDLE_IDENTIFIER = tech.lolli.serverBox.RunnerTests; PRODUCT_BUNDLE_IDENTIFIER = tech.lolli.serverBox.RunnerTests;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 5.0; SWIFT_VERSION = 5.0;