mirror of
https://github.com/lollipopkit/flutter_server_box.git
synced 2025-12-17 07:14:28 +01:00
#43 new: bsd base support
This commit is contained in:
@@ -470,7 +470,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 = 491;
|
CURRENT_PROJECT_VERSION = 493;
|
||||||
DEVELOPMENT_TEAM = BA88US33G6;
|
DEVELOPMENT_TEAM = BA88US33G6;
|
||||||
ENABLE_BITCODE = NO;
|
ENABLE_BITCODE = NO;
|
||||||
INFOPLIST_FILE = "Runner/Info-$(CONFIGURATION).plist";
|
INFOPLIST_FILE = "Runner/Info-$(CONFIGURATION).plist";
|
||||||
@@ -478,7 +478,7 @@
|
|||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
);
|
);
|
||||||
MARKETING_VERSION = 1.0.491;
|
MARKETING_VERSION = 1.0.493;
|
||||||
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";
|
||||||
@@ -602,7 +602,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 = 491;
|
CURRENT_PROJECT_VERSION = 493;
|
||||||
DEVELOPMENT_TEAM = BA88US33G6;
|
DEVELOPMENT_TEAM = BA88US33G6;
|
||||||
ENABLE_BITCODE = NO;
|
ENABLE_BITCODE = NO;
|
||||||
INFOPLIST_FILE = "Runner/Info-$(CONFIGURATION).plist";
|
INFOPLIST_FILE = "Runner/Info-$(CONFIGURATION).plist";
|
||||||
@@ -610,7 +610,7 @@
|
|||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
);
|
);
|
||||||
MARKETING_VERSION = 1.0.491;
|
MARKETING_VERSION = 1.0.493;
|
||||||
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";
|
||||||
@@ -628,7 +628,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 = 491;
|
CURRENT_PROJECT_VERSION = 493;
|
||||||
DEVELOPMENT_TEAM = BA88US33G6;
|
DEVELOPMENT_TEAM = BA88US33G6;
|
||||||
ENABLE_BITCODE = NO;
|
ENABLE_BITCODE = NO;
|
||||||
INFOPLIST_FILE = "Runner/Info-$(CONFIGURATION).plist";
|
INFOPLIST_FILE = "Runner/Info-$(CONFIGURATION).plist";
|
||||||
@@ -636,7 +636,7 @@
|
|||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
);
|
);
|
||||||
MARKETING_VERSION = 1.0.491;
|
MARKETING_VERSION = 1.0.493;
|
||||||
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";
|
||||||
@@ -657,7 +657,7 @@
|
|||||||
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
|
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
|
||||||
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 491;
|
CURRENT_PROJECT_VERSION = 493;
|
||||||
DEVELOPMENT_TEAM = BA88US33G6;
|
DEVELOPMENT_TEAM = BA88US33G6;
|
||||||
GCC_C_LANGUAGE_STANDARD = gnu11;
|
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||||
GENERATE_INFOPLIST_FILE = YES;
|
GENERATE_INFOPLIST_FILE = YES;
|
||||||
@@ -670,7 +670,7 @@
|
|||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
"@executable_path/../../Frameworks",
|
"@executable_path/../../Frameworks",
|
||||||
);
|
);
|
||||||
MARKETING_VERSION = 1.0.491;
|
MARKETING_VERSION = 1.0.493;
|
||||||
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
|
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
|
||||||
MTL_FAST_MATH = YES;
|
MTL_FAST_MATH = YES;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.StatusWidget;
|
PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.StatusWidget;
|
||||||
@@ -696,7 +696,7 @@
|
|||||||
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
|
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
|
||||||
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 491;
|
CURRENT_PROJECT_VERSION = 493;
|
||||||
DEVELOPMENT_TEAM = BA88US33G6;
|
DEVELOPMENT_TEAM = BA88US33G6;
|
||||||
GCC_C_LANGUAGE_STANDARD = gnu11;
|
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||||
GENERATE_INFOPLIST_FILE = YES;
|
GENERATE_INFOPLIST_FILE = YES;
|
||||||
@@ -709,7 +709,7 @@
|
|||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
"@executable_path/../../Frameworks",
|
"@executable_path/../../Frameworks",
|
||||||
);
|
);
|
||||||
MARKETING_VERSION = 1.0.491;
|
MARKETING_VERSION = 1.0.493;
|
||||||
MTL_FAST_MATH = YES;
|
MTL_FAST_MATH = YES;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.StatusWidget;
|
PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.StatusWidget;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
@@ -732,7 +732,7 @@
|
|||||||
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
|
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
|
||||||
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 491;
|
CURRENT_PROJECT_VERSION = 493;
|
||||||
DEVELOPMENT_TEAM = BA88US33G6;
|
DEVELOPMENT_TEAM = BA88US33G6;
|
||||||
GCC_C_LANGUAGE_STANDARD = gnu11;
|
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||||
GENERATE_INFOPLIST_FILE = YES;
|
GENERATE_INFOPLIST_FILE = YES;
|
||||||
@@ -745,7 +745,7 @@
|
|||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
"@executable_path/../../Frameworks",
|
"@executable_path/../../Frameworks",
|
||||||
);
|
);
|
||||||
MARKETING_VERSION = 1.0.491;
|
MARKETING_VERSION = 1.0.493;
|
||||||
MTL_FAST_MATH = YES;
|
MTL_FAST_MATH = YES;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.StatusWidget;
|
PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.StatusWidget;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
|
|||||||
@@ -35,11 +35,19 @@ enum DockerMenuType {
|
|||||||
rm,
|
rm,
|
||||||
logs,
|
logs,
|
||||||
terminal,
|
terminal,
|
||||||
stats;
|
//stats,
|
||||||
|
;
|
||||||
|
|
||||||
static List<DockerMenuType> items(bool running) {
|
static List<DockerMenuType> items(bool running) {
|
||||||
if (running) {
|
if (running) {
|
||||||
return [stop, restart, rm, logs, terminal, stats];
|
return [
|
||||||
|
stop,
|
||||||
|
restart,
|
||||||
|
rm,
|
||||||
|
logs,
|
||||||
|
terminal,
|
||||||
|
//stats,
|
||||||
|
];
|
||||||
} else {
|
} else {
|
||||||
return [start, rm, logs];
|
return [start, rm, logs];
|
||||||
}
|
}
|
||||||
@@ -59,8 +67,8 @@ enum DockerMenuType {
|
|||||||
return Icons.logo_dev;
|
return Icons.logo_dev;
|
||||||
case DockerMenuType.terminal:
|
case DockerMenuType.terminal:
|
||||||
return Icons.terminal;
|
return Icons.terminal;
|
||||||
case DockerMenuType.stats:
|
// case DockerMenuType.stats:
|
||||||
return Icons.bar_chart;
|
// return Icons.bar_chart;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -78,8 +86,8 @@ enum DockerMenuType {
|
|||||||
return s.log;
|
return s.log;
|
||||||
case DockerMenuType.terminal:
|
case DockerMenuType.terminal:
|
||||||
return s.terminal;
|
return s.terminal;
|
||||||
case DockerMenuType.stats:
|
// case DockerMenuType.stats:
|
||||||
return s.stats;
|
// return s.stats;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,12 @@
|
|||||||
|
import '../../res/build_data.dart';
|
||||||
import '../../res/server_cmd.dart';
|
import '../../res/server_cmd.dart';
|
||||||
|
import '../server/system.dart';
|
||||||
|
|
||||||
const _cmdDivider = '\necho $seperator\n';
|
const _cmdDivider = '\necho $seperator\n';
|
||||||
|
|
||||||
|
const _serverBoxDir = r'$HOME/.config/server_box';
|
||||||
|
const _shellPath = '$_serverBoxDir/mobile_app.sh';
|
||||||
|
|
||||||
enum AppShellFuncType {
|
enum AppShellFuncType {
|
||||||
status,
|
status,
|
||||||
docker;
|
docker;
|
||||||
@@ -15,7 +20,7 @@ enum AppShellFuncType {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
String get exec => 'sh $shellPath -$flag';
|
String get exec => 'sh $_shellPath -$flag';
|
||||||
|
|
||||||
String get name {
|
String get name {
|
||||||
switch (this) {
|
switch (this) {
|
||||||
@@ -31,16 +36,20 @@ enum AppShellFuncType {
|
|||||||
String get cmd {
|
String get cmd {
|
||||||
switch (this) {
|
switch (this) {
|
||||||
case AppShellFuncType.status:
|
case AppShellFuncType.status:
|
||||||
return statusCmds.join(_cmdDivider);
|
return '''
|
||||||
|
result=\$(uname 2>&1 | grep "Linux")
|
||||||
|
if [ "\$result" != "" ]; then
|
||||||
|
${_statusCmds.join(_cmdDivider)}
|
||||||
|
else
|
||||||
|
${_bsdStatusCmd.join(_cmdDivider)}
|
||||||
|
fi''';
|
||||||
case AppShellFuncType.docker:
|
case AppShellFuncType.docker:
|
||||||
return '''
|
return '''
|
||||||
result=\$(docker version 2>&1)
|
result=\$(docker version 2>&1 | grep "permission denied")
|
||||||
deniedStr="permission denied"
|
if [ "\$result" != "" ]; then
|
||||||
containStr=\$(echo \$result | grep "\${deniedStr}")
|
${_dockerCmds.join(_cmdDivider)}
|
||||||
if [[ \$containStr != "" ]]; then
|
|
||||||
${dockerCmds.join(_cmdDivider)}
|
|
||||||
else
|
else
|
||||||
${dockerCmds.map((e) => "sudo -S $e").join(_cmdDivider)}
|
${_dockerCmds.map((e) => "sudo -S $e").join(_cmdDivider)}
|
||||||
fi''';
|
fi''';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -83,6 +92,7 @@ extension EnumX on Enum {
|
|||||||
}
|
}
|
||||||
|
|
||||||
enum StatusCmdType {
|
enum StatusCmdType {
|
||||||
|
echo,
|
||||||
time,
|
time,
|
||||||
net,
|
net,
|
||||||
sys,
|
sys,
|
||||||
@@ -94,12 +104,81 @@ enum StatusCmdType {
|
|||||||
tempType,
|
tempType,
|
||||||
tempVal,
|
tempVal,
|
||||||
host,
|
host,
|
||||||
sysRhel;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Cmds for linux server
|
||||||
|
const _statusCmds = [
|
||||||
|
'echo $linuxSign',
|
||||||
|
'date +%s',
|
||||||
|
'cat /proc/net/dev',
|
||||||
|
'cat /etc/*-release | grep PRETTY_NAME',
|
||||||
|
'cat /proc/stat | grep cpu',
|
||||||
|
'uptime',
|
||||||
|
'cat /proc/net/snmp',
|
||||||
|
'df -h',
|
||||||
|
'cat /proc/meminfo',
|
||||||
|
'cat /sys/class/thermal/thermal_zone*/type',
|
||||||
|
'cat /sys/class/thermal/thermal_zone*/temp',
|
||||||
|
'hostname',
|
||||||
|
];
|
||||||
|
|
||||||
enum DockerCmdType {
|
enum DockerCmdType {
|
||||||
version,
|
version,
|
||||||
ps,
|
ps,
|
||||||
stats,
|
//stats,
|
||||||
images;
|
images,
|
||||||
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const _dockerCmds = [
|
||||||
|
'docker version',
|
||||||
|
'docker ps -a',
|
||||||
|
//'docker stats --no-stream',
|
||||||
|
'docker image ls',
|
||||||
|
];
|
||||||
|
|
||||||
|
enum BSDStatusCmdType {
|
||||||
|
echo,
|
||||||
|
time,
|
||||||
|
net,
|
||||||
|
sys,
|
||||||
|
cpu,
|
||||||
|
uptime,
|
||||||
|
disk,
|
||||||
|
mem,
|
||||||
|
//temp,
|
||||||
|
host,
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Cmds for BSD server
|
||||||
|
const _bsdStatusCmd = [
|
||||||
|
'echo $bsdSign',
|
||||||
|
'date +%s',
|
||||||
|
'netstat -ibn',
|
||||||
|
'uname -or',
|
||||||
|
'top -l 1 | grep "CPU usage"',
|
||||||
|
'uptime',
|
||||||
|
'df -h',
|
||||||
|
'top -l 1 | grep PhysMem',
|
||||||
|
//'sysctl -a | grep temperature',
|
||||||
|
'hostname',
|
||||||
|
];
|
||||||
|
|
||||||
|
final _shellCmd = """
|
||||||
|
#!/bin/sh
|
||||||
|
#
|
||||||
|
# Script for ServerBox app v1.0.${BuildData.build}
|
||||||
|
#
|
||||||
|
# DO NOT delete this file while app is running
|
||||||
|
# DO NOT run multi ServerBox apps with different version at the same time
|
||||||
|
|
||||||
|
export LANG=en_US.UTF-8
|
||||||
|
|
||||||
|
${AppShellFuncType.shellScript}
|
||||||
|
""";
|
||||||
|
|
||||||
|
final installShellCmd = "mkdir -p $_serverBoxDir && "
|
||||||
|
"echo '$_shellCmd' > $_shellPath && "
|
||||||
|
"chmod +x $_shellPath";
|
||||||
|
|||||||
@@ -8,10 +8,10 @@ class DockerPsItem {
|
|||||||
late String status;
|
late String status;
|
||||||
late String ports;
|
late String ports;
|
||||||
late String name;
|
late String name;
|
||||||
String? cpu;
|
// String? cpu;
|
||||||
String? mem;
|
// String? mem;
|
||||||
String? net;
|
// String? net;
|
||||||
String? disk;
|
// String? disk;
|
||||||
|
|
||||||
DockerPsItem(
|
DockerPsItem(
|
||||||
this.containerId,
|
this.containerId,
|
||||||
@@ -41,19 +41,19 @@ class DockerPsItem {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void parseStats(String rawString) {
|
// void parseStats(String rawString) {
|
||||||
if (rawString.isEmpty) {
|
// if (rawString.isEmpty) {
|
||||||
return;
|
// return;
|
||||||
}
|
// }
|
||||||
final parts = rawString.split(_seperator);
|
// final parts = rawString.split(_seperator);
|
||||||
if (parts.length != 8) {
|
// if (parts.length != 8) {
|
||||||
return;
|
// return;
|
||||||
}
|
// }
|
||||||
cpu = parts[2];
|
// cpu = parts[2];
|
||||||
mem = parts[3];
|
// mem = parts[3];
|
||||||
net = parts[5];
|
// net = parts[5];
|
||||||
disk = parts[6];
|
// disk = parts[6];
|
||||||
}
|
// }
|
||||||
|
|
||||||
bool get running => status.contains('Up ');
|
bool get running => status.contains('Up ');
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
import 'package:toolbox/data/res/status.dart';
|
||||||
|
|
||||||
import 'time_seq.dart';
|
import 'time_seq.dart';
|
||||||
|
|
||||||
class Cpus extends TimeSeq<OneTimeCpuStatus> {
|
class Cpus extends TimeSeq<OneTimeCpuStatus> {
|
||||||
@@ -95,3 +97,22 @@ List<OneTimeCpuStatus> parseCPU(String raw) {
|
|||||||
}
|
}
|
||||||
return cpus;
|
return cpus;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final _bsdCpuPercentReg = RegExp(r'(\d+\.\d+)%');
|
||||||
|
|
||||||
|
/// TODO: Change this implementation to parse cpu status on BSD system
|
||||||
|
///
|
||||||
|
/// [raw]:
|
||||||
|
/// CPU usage: 14.70% user, 12.76% sys, 72.52% idle
|
||||||
|
Cpus parseBsdCpu(String raw) {
|
||||||
|
final percents = _bsdCpuPercentReg
|
||||||
|
.allMatches(raw)
|
||||||
|
.map((e) => double.parse(e.group(1) ?? '0') * 100)
|
||||||
|
.toList();
|
||||||
|
if (percents.length != 3) return initCpuStatus;
|
||||||
|
return initCpuStatus
|
||||||
|
..now = [
|
||||||
|
OneTimeCpuStatus('cpu', percents[0].toInt(), percents[1].toInt(), 0,
|
||||||
|
percents[2].toInt(), 0, 0, 0)
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|||||||
@@ -115,3 +115,51 @@ List<NetSpeedPart> parseNetSpeed(String raw, int time) {
|
|||||||
}
|
}
|
||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// [raw] example:
|
||||||
|
/// Name Mtu Network Address Ipkts Ierrs Ibytes Opkts Oerrs Obytes Coll
|
||||||
|
/// lo0 16384 <Link#1> 17296531 0 2524959720 17296531 0 2524959720 0
|
||||||
|
/// lo0 16384 127 127.0.0.1 17296531 - 2524959720 17296531 - 2524959720 -
|
||||||
|
/// lo0 16384 ::1/128 ::1 17296531 - 2524959720 17296531 - 2524959720 -
|
||||||
|
/// lo0 16384 fe80::1%lo0 fe80:1::1 17296531 - 2524959720 17296531 - 2524959720 -
|
||||||
|
/// gif0* 1280 <Link#2> 0 0 0 0 0 0 0
|
||||||
|
/// stf0* 1280 <Link#3> 0 0 0 0 0 0 0
|
||||||
|
/// en0 1500 <Link#4> 22:20:xx:xx:xx:e6 739447 0 693997876 535600 0 79008877 0
|
||||||
|
/// en0 1500 fe80::f1:xx fe80:4::f1:xxxx:9 739447 - 693997876 535600 - 79008877 -
|
||||||
|
/// en0 1500 192.168.2 192.168.2.111 739447 - 693997876 535600 - 79008877 -
|
||||||
|
/// en0 1500 fd6b:xxxx:3 fd6b:xxxx:xxxx:0: 739447 - 693997876 535600 - 79008877 -
|
||||||
|
/// en1 1500 <Link#5> 88:d8:xx:xx:xx:1d 0 0 0 0 0 0 0
|
||||||
|
/// utun0 1380 <Link#6> 0 0 0 3 0 280 0
|
||||||
|
/// utun0 1380 fe80::xxxx: fe80:6::xxxx:xxxx 0 - 0 3 - 280 -
|
||||||
|
/// utun1 2000 <Link#7> 0 0 0 3 0 280 0
|
||||||
|
/// utun1 2000 fe80::xxxx: fe80:7::xxxx:xxxx 0 - 0 3 - 280 -
|
||||||
|
/// utun2 1000 <Link#8> 0 0 0 3 0 280 0
|
||||||
|
/// utun2 1000 fe80::xxxx: fe80:8::xxxx:xxx: 0 - 0 3 - 280 -
|
||||||
|
/// utun4 9000 <Link#10> 746744 0 845373390 386111 0 424400998 0
|
||||||
|
/// utun4 9000 198.18.0/16 198.18.0.1 746744 - 845373390 386111 - 424400998 -
|
||||||
|
/// en2* 1500 <Link#11> 36:7c:xx:xx:xx:xx 0 0 0 0 0 0 0
|
||||||
|
List<NetSpeedPart> parseBsdNetSpeed(String raw, int time) {
|
||||||
|
final split = raw.split('\n');
|
||||||
|
if (split.length < 2) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
final results = <NetSpeedPart>[];
|
||||||
|
for (final item in split.sublist(1)) {
|
||||||
|
final data = item.trim().split(RegExp(r'\s+'));
|
||||||
|
final device = data[0];
|
||||||
|
if (device.endsWith('*')) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (results.any((element) => element.device == device)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (data.length != 11) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
final bytesIn = BigInt.parse(data[6]);
|
||||||
|
final bytesOut = BigInt.parse(data[9]);
|
||||||
|
results.add(NetSpeedPart(device, bytesIn, bytesOut, time));
|
||||||
|
}
|
||||||
|
return results;
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import 'package:toolbox/data/model/server/system.dart';
|
||||||
import 'package:toolbox/data/model/server/temp.dart';
|
import 'package:toolbox/data/model/server/temp.dart';
|
||||||
|
|
||||||
import 'cpu.dart';
|
import 'cpu.dart';
|
||||||
@@ -16,6 +17,7 @@ class ServerStatus {
|
|||||||
Conn tcp;
|
Conn tcp;
|
||||||
NetSpeed netSpeed;
|
NetSpeed netSpeed;
|
||||||
Temperatures temps;
|
Temperatures temps;
|
||||||
|
SystemType system;
|
||||||
String? failedInfo;
|
String? failedInfo;
|
||||||
|
|
||||||
ServerStatus({
|
ServerStatus({
|
||||||
@@ -28,6 +30,7 @@ class ServerStatus {
|
|||||||
required this.netSpeed,
|
required this.netSpeed,
|
||||||
required this.swap,
|
required this.swap,
|
||||||
required this.temps,
|
required this.temps,
|
||||||
|
required this.system,
|
||||||
this.failedInfo,
|
this.failedInfo,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
import 'package:toolbox/data/model/server/system.dart';
|
||||||
|
|
||||||
import '../app/shell_func.dart';
|
import '../app/shell_func.dart';
|
||||||
import 'cpu.dart';
|
import 'cpu.dart';
|
||||||
import 'disk.dart';
|
import 'disk.dart';
|
||||||
@@ -9,11 +11,25 @@ import 'conn.dart';
|
|||||||
class ServerStatusUpdateReq {
|
class ServerStatusUpdateReq {
|
||||||
final ServerStatus ss;
|
final ServerStatus ss;
|
||||||
final List<String> segments;
|
final List<String> segments;
|
||||||
|
final SystemType system;
|
||||||
|
|
||||||
const ServerStatusUpdateReq(this.ss, this.segments);
|
const ServerStatusUpdateReq({
|
||||||
|
required this.system,
|
||||||
|
required this.ss,
|
||||||
|
required this.segments,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<ServerStatus> getStatus(ServerStatusUpdateReq req) async {
|
Future<ServerStatus> getStatus(ServerStatusUpdateReq req) async {
|
||||||
|
switch (req.system) {
|
||||||
|
case SystemType.linux:
|
||||||
|
return _getLinuxStatus(req);
|
||||||
|
case SystemType.bsd:
|
||||||
|
return _getBsdStatus(req);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<ServerStatus> _getLinuxStatus(ServerStatusUpdateReq req) async {
|
||||||
final segments = req.segments;
|
final segments = req.segments;
|
||||||
|
|
||||||
final time = int.parse(StatusCmdType.time.find(segments));
|
final time = int.parse(StatusCmdType.time.find(segments));
|
||||||
@@ -24,7 +40,6 @@ Future<ServerStatus> getStatus(ServerStatusUpdateReq req) async {
|
|||||||
final sys = _parseSysVer(
|
final sys = _parseSysVer(
|
||||||
StatusCmdType.sys.find(segments),
|
StatusCmdType.sys.find(segments),
|
||||||
StatusCmdType.host.find(segments),
|
StatusCmdType.host.find(segments),
|
||||||
StatusCmdType.sysRhel.find(segments),
|
|
||||||
);
|
);
|
||||||
if (sys != null) {
|
if (sys != null) {
|
||||||
req.ss.sysVer = sys;
|
req.ss.sysVer = sys;
|
||||||
@@ -56,6 +71,30 @@ Future<ServerStatus> getStatus(ServerStatusUpdateReq req) async {
|
|||||||
return req.ss;
|
return req.ss;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<ServerStatus> _getBsdStatus(ServerStatusUpdateReq req) async {
|
||||||
|
final segments = req.segments;
|
||||||
|
|
||||||
|
final time = int.parse(BSDStatusCmdType.time.find(segments));
|
||||||
|
|
||||||
|
final net = parseBsdNetSpeed(BSDStatusCmdType.net.find(segments), time);
|
||||||
|
req.ss.netSpeed.update(net);
|
||||||
|
|
||||||
|
req.ss.sysVer = BSDStatusCmdType.sys.find(segments);
|
||||||
|
|
||||||
|
req.ss.cpu = parseBsdCpu(BSDStatusCmdType.cpu.find(segments));
|
||||||
|
|
||||||
|
//req.ss.mem = parseBsdMem(BSDStatusCmdType.mem.find(segments));
|
||||||
|
|
||||||
|
final uptime = _parseUpTime(BSDStatusCmdType.uptime.find(segments));
|
||||||
|
if (uptime != null) {
|
||||||
|
req.ss.uptime = uptime;
|
||||||
|
}
|
||||||
|
|
||||||
|
req.ss.disk = parseDisk(BSDStatusCmdType.disk.find(segments));
|
||||||
|
|
||||||
|
return req.ss;
|
||||||
|
}
|
||||||
|
|
||||||
// raw:
|
// raw:
|
||||||
// 19:39:15 up 61 days, 18:16, 1 user, load average: 0.00, 0.00, 0.00
|
// 19:39:15 up 61 days, 18:16, 1 user, load average: 0.00, 0.00, 0.00
|
||||||
String? _parseUpTime(String raw) {
|
String? _parseUpTime(String raw) {
|
||||||
@@ -69,17 +108,14 @@ String? _parseUpTime(String raw) {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
String? _parseSysVer(String raw, String hostname, String rawRhel) {
|
String? _parseSysVer(String raw, String hostname) {
|
||||||
try {
|
try {
|
||||||
final s = raw.split('=');
|
final s = raw.split('=');
|
||||||
if (s.length == 2) {
|
if (s.length == 2) {
|
||||||
return s[1].replaceAll('"', '').replaceFirst('\n', '');
|
return s[1].replaceAll('"', '').replaceFirst('\n', '');
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} finally {
|
||||||
if (!rawRhel.contains('cat: /etc/redhat-release:')) {
|
// ignore: control_flow_in_finally
|
||||||
return rawRhel;
|
return hostname.isEmpty ? null : hostname;
|
||||||
}
|
|
||||||
if (hostname.isNotEmpty) return hostname;
|
|
||||||
}
|
}
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|||||||
34
lib/data/model/server/system.dart
Normal file
34
lib/data/model/server/system.dart
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
import 'package:toolbox/data/model/app/shell_func.dart';
|
||||||
|
|
||||||
|
enum SystemType {
|
||||||
|
linux._(linuxSign),
|
||||||
|
bsd._(bsdSign),
|
||||||
|
;
|
||||||
|
|
||||||
|
final String value;
|
||||||
|
|
||||||
|
const SystemType._(this.value);
|
||||||
|
|
||||||
|
static SystemType? parse(String? value) {
|
||||||
|
if (value == null) return null;
|
||||||
|
switch (value) {
|
||||||
|
case linuxSign:
|
||||||
|
return SystemType.linux;
|
||||||
|
case bsdSign:
|
||||||
|
return SystemType.bsd;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isSegmentsLenMatch(int len) {
|
||||||
|
switch (this) {
|
||||||
|
case SystemType.linux:
|
||||||
|
return len == StatusCmdType.values.length;
|
||||||
|
case SystemType.bsd:
|
||||||
|
return len == BSDStatusCmdType.values.length;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const linuxSign = 'linux';
|
||||||
|
const bsdSign = 'bsd';
|
||||||
@@ -1,5 +1,3 @@
|
|||||||
// ignore_for_file: prefer_final_fields
|
|
||||||
|
|
||||||
abstract class TimeSeq<T extends TimeSeqIface> {
|
abstract class TimeSeq<T extends TimeSeqIface> {
|
||||||
List<T> pre;
|
List<T> pre;
|
||||||
List<T> now;
|
List<T> now;
|
||||||
|
|||||||
@@ -10,10 +10,11 @@ import 'package:toolbox/data/model/app/shell_func.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/model/app/error.dart';
|
import 'package:toolbox/data/model/app/error.dart';
|
||||||
import 'package:toolbox/data/res/server_cmd.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`
|
||||||
@@ -72,7 +73,7 @@ class DockerProvider extends ChangeNotifier {
|
|||||||
|
|
||||||
// Check result segments count
|
// Check result segments count
|
||||||
final segments = raw.split(seperator);
|
final segments = raw.split(seperator);
|
||||||
if (segments.length != dockerCmds.length) {
|
if (segments.length != DockerCmdType.values.length) {
|
||||||
error = DockerErr(type: DockerErrType.segmentsNotMatch);
|
error = DockerErr(type: DockerErrType.segmentsNotMatch);
|
||||||
_logger.warning('Docker segments not match: ${segments.length}');
|
_logger.warning('Docker segments not match: ${segments.length}');
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
@@ -119,28 +120,28 @@ class DockerProvider extends ChangeNotifier {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Parse docker stats
|
// Parse docker stats
|
||||||
final statsRaw = DockerCmdType.stats.find(segments);
|
// final statsRaw = DockerCmdType.stats.find(segments);
|
||||||
try {
|
// try {
|
||||||
final statsLines = statsRaw.split('\n');
|
// final statsLines = statsRaw.split('\n');
|
||||||
statsLines.removeWhere((element) => element.isEmpty);
|
// statsLines.removeWhere((element) => element.isEmpty);
|
||||||
if (statsLines.isNotEmpty) statsLines.removeAt(0);
|
// if (statsLines.isNotEmpty) statsLines.removeAt(0);
|
||||||
for (var item in items!) {
|
// for (var item in items!) {
|
||||||
final statsLine = statsLines.firstWhere(
|
// final statsLine = statsLines.firstWhere(
|
||||||
(element) => element.contains(item.containerId),
|
// (element) => element.contains(item.containerId),
|
||||||
orElse: () => '',
|
// orElse: () => '',
|
||||||
);
|
// );
|
||||||
if (statsLine.isEmpty) continue;
|
// if (statsLine.isEmpty) continue;
|
||||||
item.parseStats(statsLine);
|
// item.parseStats(statsLine);
|
||||||
}
|
// }
|
||||||
} catch (e, trace) {
|
// } catch (e, trace) {
|
||||||
error = DockerErr(
|
// error = DockerErr(
|
||||||
type: DockerErrType.parseStats,
|
// type: DockerErrType.parseStats,
|
||||||
message: '$statsRaw\n-\n$e',
|
// message: '$statsRaw\n-\n$e',
|
||||||
);
|
// );
|
||||||
_logger.warning('Parse docker stats: $statsRaw', e, trace);
|
// _logger.warning('Parse docker stats: $statsRaw', e, trace);
|
||||||
} finally {
|
// } finally {
|
||||||
notifyListeners();
|
// notifyListeners();
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _onPwd(String event, StreamSink<Uint8List> stdin) async {
|
Future<void> _onPwd(String event, StreamSink<Uint8List> stdin) async {
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import 'dart:async';
|
|||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:logging/logging.dart';
|
import 'package:logging/logging.dart';
|
||||||
import 'package:toolbox/data/model/app/shell_func.dart';
|
import 'package:toolbox/data/model/app/shell_func.dart';
|
||||||
|
import 'package:toolbox/data/model/server/system.dart';
|
||||||
|
|
||||||
import '../../core/extension/order.dart';
|
import '../../core/extension/order.dart';
|
||||||
import '../../core/extension/uint8list.dart';
|
import '../../core/extension/uint8list.dart';
|
||||||
@@ -265,18 +266,28 @@ class ServerProvider extends ChangeNotifier {
|
|||||||
|
|
||||||
final raw = await s.client?.run(AppShellFuncType.status.exec).string;
|
final raw = await s.client?.run(AppShellFuncType.status.exec).string;
|
||||||
final segments = raw?.split(seperator).map((e) => e.trim()).toList();
|
final segments = raw?.split(seperator).map((e) => e.trim()).toList();
|
||||||
if (raw == null ||
|
if (raw == null || raw.isEmpty || segments == null || segments.isEmpty) {
|
||||||
raw.isEmpty ||
|
|
||||||
segments == null ||
|
|
||||||
segments.length != StatusCmdType.values.length) {
|
|
||||||
_limiter.inc(sid);
|
_limiter.inc(sid);
|
||||||
s.status.failedInfo = 'Seperate segments failed, raw:\n$raw';
|
s.status.failedInfo = 'Seperate segments failed, raw:\n$raw';
|
||||||
_setServerState(s, ServerState.failed);
|
_setServerState(s, ServerState.failed);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final systemType = SystemType.parse(segments[0]);
|
||||||
|
if (systemType == null || !systemType.isSegmentsLenMatch(segments.length)) {
|
||||||
|
_limiter.inc(sid);
|
||||||
|
s.status.failedInfo = 'Segments not match: ${segments.length}';
|
||||||
|
_setServerState(s, ServerState.failed);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
s.status.system = systemType;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
final req = ServerStatusUpdateReq(s.status, segments);
|
final req = ServerStatusUpdateReq(
|
||||||
|
ss: s.status,
|
||||||
|
segments: segments,
|
||||||
|
system: systemType,
|
||||||
|
);
|
||||||
s.status = await compute(getStatus, req);
|
s.status = await compute(getStatus, req);
|
||||||
} catch (e, trace) {
|
} catch (e, trace) {
|
||||||
_limiter.inc(sid);
|
_limiter.inc(sid);
|
||||||
|
|||||||
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
class BuildData {
|
class BuildData {
|
||||||
static const String name = "ServerBox";
|
static const String name = "ServerBox";
|
||||||
static const int build = 491;
|
static const int build = 493;
|
||||||
static const String engine = "3.10.6";
|
static const String engine = "3.13.0";
|
||||||
static const String buildAt = "2023-08-20 23:32:07.343451";
|
static const String buildAt = "2023-08-22 16:14:41.022063";
|
||||||
static const int modifications = 4;
|
static const int modifications = 8;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,41 +1 @@
|
|||||||
import '../model/app/shell_func.dart';
|
|
||||||
import 'build_data.dart';
|
|
||||||
|
|
||||||
const seperator = 'SrvBoxSep';
|
const seperator = 'SrvBoxSep';
|
||||||
const serverBoxDir = r'$HOME/.config/server_box';
|
|
||||||
const shellPath = '$serverBoxDir/mobile_app.sh';
|
|
||||||
|
|
||||||
const statusCmds = [
|
|
||||||
'date +%s',
|
|
||||||
'cat /proc/net/dev',
|
|
||||||
'cat /etc/os-release | grep PRETTY_NAME',
|
|
||||||
'cat /proc/stat | grep cpu',
|
|
||||||
'uptime',
|
|
||||||
'cat /proc/net/snmp',
|
|
||||||
'df -h',
|
|
||||||
'cat /proc/meminfo',
|
|
||||||
'cat /sys/class/thermal/thermal_zone*/type',
|
|
||||||
'cat /sys/class/thermal/thermal_zone*/temp',
|
|
||||||
'hostname',
|
|
||||||
'cat /etc/redhat-release',
|
|
||||||
];
|
|
||||||
|
|
||||||
const dockerCmds = [
|
|
||||||
'docker version',
|
|
||||||
'docker ps -a',
|
|
||||||
'docker stats --no-stream',
|
|
||||||
'docker image ls',
|
|
||||||
];
|
|
||||||
|
|
||||||
final shellCmd = """
|
|
||||||
# Script for app `${BuildData.name} v1.0.${BuildData.build}`
|
|
||||||
# Delete this file while app is running will cause app crash
|
|
||||||
|
|
||||||
export LANG=en_US.UTF-8
|
|
||||||
|
|
||||||
${AppShellFuncType.shellScript}
|
|
||||||
""";
|
|
||||||
|
|
||||||
final installShellCmd = "mkdir -p $serverBoxDir && "
|
|
||||||
"echo '$shellCmd' > $shellPath && "
|
|
||||||
"chmod +x $shellPath";
|
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import '../model/server/memory.dart';
|
|||||||
import '../model/server/net_speed.dart';
|
import '../model/server/net_speed.dart';
|
||||||
import '../model/server/server_status.dart';
|
import '../model/server/server_status.dart';
|
||||||
import '../model/server/conn.dart';
|
import '../model/server/conn.dart';
|
||||||
|
import '../model/server/system.dart';
|
||||||
|
|
||||||
Memory get _initMemory => Memory(
|
Memory get _initMemory => Memory(
|
||||||
total: 1,
|
total: 1,
|
||||||
@@ -38,8 +39,8 @@ NetSpeed get initNetSpeed => NetSpeed(
|
|||||||
[_initNetSpeedPart],
|
[_initNetSpeedPart],
|
||||||
);
|
);
|
||||||
Swap get _initSwap => Swap(
|
Swap get _initSwap => Swap(
|
||||||
total: 1,
|
total: 0,
|
||||||
free: 1,
|
free: 0,
|
||||||
cached: 0,
|
cached: 0,
|
||||||
);
|
);
|
||||||
ServerStatus get initStatus => ServerStatus(
|
ServerStatus get initStatus => ServerStatus(
|
||||||
@@ -60,5 +61,6 @@ ServerStatus get initStatus => ServerStatus(
|
|||||||
tcp: Conn(maxConn: 0, active: 0, passive: 0, fail: 0),
|
tcp: Conn(maxConn: 0, active: 0, passive: 0, fail: 0),
|
||||||
netSpeed: initNetSpeed,
|
netSpeed: initNetSpeed,
|
||||||
swap: _initSwap,
|
swap: _initSwap,
|
||||||
|
system: SystemType.linux,
|
||||||
temps: Temperatures(),
|
temps: Temperatures(),
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -474,24 +474,24 @@ class _DockerManagePageState extends State<DockerManagePage> {
|
|||||||
'Docker terminal',
|
'Docker terminal',
|
||||||
).go(context);
|
).go(context);
|
||||||
break;
|
break;
|
||||||
case DockerMenuType.stats:
|
// case DockerMenuType.stats:
|
||||||
showRoundDialog(
|
// showRoundDialog(
|
||||||
context: context,
|
// context: context,
|
||||||
title: Text(_s.stats),
|
// title: Text(_s.stats),
|
||||||
child: Text(
|
// child: Text(
|
||||||
'CPU: ${dItem.cpu}\n'
|
// 'CPU: ${dItem.cpu}\n'
|
||||||
'Mem: ${dItem.mem}\n'
|
// 'Mem: ${dItem.mem}\n'
|
||||||
'Net: ${dItem.net}\n'
|
// 'Net: ${dItem.net}\n'
|
||||||
'Block: ${dItem.disk}',
|
// 'Block: ${dItem.disk}',
|
||||||
),
|
// ),
|
||||||
actions: [
|
// actions: [
|
||||||
TextButton(
|
// TextButton(
|
||||||
onPressed: () => context.pop(),
|
// onPressed: () => context.pop(),
|
||||||
child: Text(_s.ok),
|
// child: Text(_s.ok),
|
||||||
),
|
// ),
|
||||||
],
|
// ],
|
||||||
);
|
// );
|
||||||
break;
|
// break;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -108,12 +108,6 @@ class _ServerPageState extends State<ServerPage>
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
List<String> _filterServers(ServerProvider pro) => pro.serverOrder
|
|
||||||
.where((e) => pro.servers.containsKey(e))
|
|
||||||
.where((e) =>
|
|
||||||
_tag == null || (pro.servers[e]?.spi.tags?.contains(_tag) ?? false))
|
|
||||||
.toList();
|
|
||||||
|
|
||||||
Widget _buildTagsSwitcher(ServerProvider provider) {
|
Widget _buildTagsSwitcher(ServerProvider provider) {
|
||||||
return TagSwitcher(
|
return TagSwitcher(
|
||||||
tags: provider.tags,
|
tags: provider.tags,
|
||||||
@@ -224,14 +218,11 @@ class _ServerPageState extends State<ServerPage>
|
|||||||
) {
|
) {
|
||||||
final rootDisk = findRootDisk(ss.disk);
|
final rootDisk = findRootDisk(ss.disk);
|
||||||
late final List<Widget> children;
|
late final List<Widget> children;
|
||||||
double? height;
|
|
||||||
if (cs != ServerState.finished) {
|
if (cs != ServerState.finished) {
|
||||||
height = 23.0;
|
|
||||||
children = [
|
children = [
|
||||||
_buildServerCardTitle(ss, cs, spi),
|
_buildServerCardTitle(ss, cs, spi),
|
||||||
];
|
];
|
||||||
} else {
|
} else {
|
||||||
height = 107;
|
|
||||||
children = [
|
children = [
|
||||||
_buildServerCardTitle(ss, cs, spi),
|
_buildServerCardTitle(ss, cs, spi),
|
||||||
height13,
|
height13,
|
||||||
@@ -262,7 +253,7 @@ class _ServerPageState extends State<ServerPage>
|
|||||||
return AnimatedContainer(
|
return AnimatedContainer(
|
||||||
duration: const Duration(milliseconds: 377),
|
duration: const Duration(milliseconds: 377),
|
||||||
curve: Curves.fastEaseInToSlowEaseOut,
|
curve: Curves.fastEaseInToSlowEaseOut,
|
||||||
height: height,
|
height: _calcCardHeight(cs),
|
||||||
child: Column(
|
child: Column(
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
mainAxisAlignment: MainAxisAlignment.start,
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
@@ -355,38 +346,6 @@ class _ServerPageState extends State<ServerPage>
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
String _getTopRightStr(
|
|
||||||
ServerState cs,
|
|
||||||
double? temp,
|
|
||||||
String upTime,
|
|
||||||
String? failedInfo,
|
|
||||||
) {
|
|
||||||
switch (cs) {
|
|
||||||
case ServerState.disconnected:
|
|
||||||
return _s.disconnected;
|
|
||||||
case ServerState.finished:
|
|
||||||
final tempStr = temp == null ? '' : '${temp.toStringAsFixed(1)}°C';
|
|
||||||
final items = [tempStr, upTime];
|
|
||||||
final str = items.where((element) => element.isNotEmpty).join(' | ');
|
|
||||||
if (str.isEmpty) return _s.noResult;
|
|
||||||
return str;
|
|
||||||
case ServerState.loading:
|
|
||||||
return _s.serverTabLoading;
|
|
||||||
case ServerState.connected:
|
|
||||||
return _s.connected;
|
|
||||||
case ServerState.connecting:
|
|
||||||
return _s.serverTabConnecting;
|
|
||||||
case ServerState.failed:
|
|
||||||
if (failedInfo == null) {
|
|
||||||
return _s.serverTabFailed;
|
|
||||||
}
|
|
||||||
if (failedInfo.contains('encypted')) {
|
|
||||||
return _s.serverTabPlzSave;
|
|
||||||
}
|
|
||||||
return failedInfo;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget _buildIOData(String up, String down) {
|
Widget _buildIOData(String up, String down) {
|
||||||
return Column(
|
return Column(
|
||||||
children: [
|
children: [
|
||||||
@@ -448,4 +407,52 @@ class _ServerPageState extends State<ServerPage>
|
|||||||
}
|
}
|
||||||
_serverProvider.startAutoRefresh();
|
_serverProvider.startAutoRefresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
List<String> _filterServers(ServerProvider pro) => pro.serverOrder
|
||||||
|
.where((e) => pro.servers.containsKey(e))
|
||||||
|
.where((e) =>
|
||||||
|
_tag == null || (pro.servers[e]?.spi.tags?.contains(_tag) ?? false))
|
||||||
|
.toList();
|
||||||
|
|
||||||
|
String _getTopRightStr(
|
||||||
|
ServerState cs,
|
||||||
|
double? temp,
|
||||||
|
String upTime,
|
||||||
|
String? failedInfo,
|
||||||
|
) {
|
||||||
|
switch (cs) {
|
||||||
|
case ServerState.disconnected:
|
||||||
|
return _s.disconnected;
|
||||||
|
case ServerState.finished:
|
||||||
|
final tempStr = temp == null ? '' : '${temp.toStringAsFixed(1)}°C';
|
||||||
|
final items = [tempStr, upTime];
|
||||||
|
final str = items.where((element) => element.isNotEmpty).join(' | ');
|
||||||
|
if (str.isEmpty) return _s.noResult;
|
||||||
|
return str;
|
||||||
|
case ServerState.loading:
|
||||||
|
return _s.serverTabLoading;
|
||||||
|
case ServerState.connected:
|
||||||
|
return _s.connected;
|
||||||
|
case ServerState.connecting:
|
||||||
|
return _s.serverTabConnecting;
|
||||||
|
case ServerState.failed:
|
||||||
|
if (failedInfo == null) {
|
||||||
|
return _s.serverTabFailed;
|
||||||
|
}
|
||||||
|
if (failedInfo.contains('encypted')) {
|
||||||
|
return _s.serverTabPlzSave;
|
||||||
|
}
|
||||||
|
return failedInfo;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
double _calcCardHeight(ServerState cs) {
|
||||||
|
if (cs != ServerState.finished) {
|
||||||
|
return 23.0;
|
||||||
|
}
|
||||||
|
if (_settingStore.moveOutServerTabFuncBtns.fetch()!) {
|
||||||
|
return 132;
|
||||||
|
}
|
||||||
|
return 107;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -130,7 +130,7 @@ class _SSHPageState extends State<SSHPage> {
|
|||||||
deleteDetection: isIOS,
|
deleteDetection: isIOS,
|
||||||
autofocus: true,
|
autofocus: true,
|
||||||
keyboardAppearance: _isDark ? Brightness.dark : Brightness.light,
|
keyboardAppearance: _isDark ? Brightness.dark : Brightness.light,
|
||||||
hideScrollBar: isMobile,
|
hideScrollBar: false,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -55,12 +55,13 @@ class Input extends StatelessWidget {
|
|||||||
autocorrect: autoCorrect,
|
autocorrect: autoCorrect,
|
||||||
enableSuggestions: suggestiion,
|
enableSuggestions: suggestiion,
|
||||||
decoration: InputDecoration(
|
decoration: InputDecoration(
|
||||||
label: label != null ? Text(label!) : null,
|
label: label != null ? Text(label!) : null,
|
||||||
hintText: hint,
|
hintText: hint,
|
||||||
icon: icon != null ? Icon(icon) : null,
|
icon: icon != null ? Icon(icon) : null,
|
||||||
border: InputBorder.none,
|
border: InputBorder.none,
|
||||||
errorText: errorText,
|
errorText: errorText,
|
||||||
prefix: prefix,),
|
prefix: prefix,
|
||||||
|
),
|
||||||
controller: controller,
|
controller: controller,
|
||||||
obscureText: obscureText,
|
obscureText: obscureText,
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -258,7 +258,7 @@
|
|||||||
isa = PBXProject;
|
isa = PBXProject;
|
||||||
attributes = {
|
attributes = {
|
||||||
LastSwiftUpdateCheck = 0920;
|
LastSwiftUpdateCheck = 0920;
|
||||||
LastUpgradeCheck = 1300;
|
LastUpgradeCheck = 1430;
|
||||||
ORGANIZATIONNAME = "";
|
ORGANIZATIONNAME = "";
|
||||||
TargetAttributes = {
|
TargetAttributes = {
|
||||||
331C80D4294CF70F00263BE5 = {
|
331C80D4294CF70F00263BE5 = {
|
||||||
@@ -474,9 +474,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 = 491;
|
CURRENT_PROJECT_VERSION = 493;
|
||||||
GENERATE_INFOPLIST_FILE = YES;
|
GENERATE_INFOPLIST_FILE = YES;
|
||||||
MARKETING_VERSION = 1.0.491;
|
MARKETING_VERSION = 1.0.493;
|
||||||
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;
|
||||||
@@ -489,9 +489,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 = 491;
|
CURRENT_PROJECT_VERSION = 493;
|
||||||
GENERATE_INFOPLIST_FILE = YES;
|
GENERATE_INFOPLIST_FILE = YES;
|
||||||
MARKETING_VERSION = 1.0.491;
|
MARKETING_VERSION = 1.0.493;
|
||||||
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;
|
||||||
@@ -504,9 +504,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 = 491;
|
CURRENT_PROJECT_VERSION = 493;
|
||||||
GENERATE_INFOPLIST_FILE = YES;
|
GENERATE_INFOPLIST_FILE = YES;
|
||||||
MARKETING_VERSION = 1.0.491;
|
MARKETING_VERSION = 1.0.493;
|
||||||
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;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<Scheme
|
<Scheme
|
||||||
LastUpgradeVersion = "1300"
|
LastUpgradeVersion = "1430"
|
||||||
version = "1.3">
|
version = "1.3">
|
||||||
<BuildAction
|
<BuildAction
|
||||||
parallelizeBuildables = "YES"
|
parallelizeBuildables = "YES"
|
||||||
|
|||||||
76
make.dart
76
make.dart
@@ -17,6 +17,7 @@ const buildFuncs = {
|
|||||||
'ios': flutterBuildIOS,
|
'ios': flutterBuildIOS,
|
||||||
'android': flutterBuildAndroid,
|
'android': flutterBuildAndroid,
|
||||||
'macos': flutterBuildMacOS,
|
'macos': flutterBuildMacOS,
|
||||||
|
'linux': flutterBuildLinux,
|
||||||
};
|
};
|
||||||
|
|
||||||
int? build;
|
int? build;
|
||||||
@@ -133,15 +134,21 @@ Future<void> flutterBuildIOS() async {
|
|||||||
|
|
||||||
Future<void> flutterBuildMacOS() async {
|
Future<void> flutterBuildMacOS() async {
|
||||||
await flutterBuild('macos');
|
await flutterBuild('macos');
|
||||||
|
await scpMacOS2CDN();
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> flutterBuildAndroid() async {
|
Future<void> flutterBuildAndroid() async {
|
||||||
await flutterBuild('apk');
|
await flutterBuild('apk');
|
||||||
await killJava();
|
await killJava();
|
||||||
await scp2CDN();
|
await scpApk2CDN();
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> scp2CDN() async {
|
Future<void> flutterBuildLinux() async {
|
||||||
|
await flutterBuild('linux');
|
||||||
|
await scpLinux2CDN();
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> scpApk2CDN() async {
|
||||||
final sha256 = await getFileSha256(apkPath);
|
final sha256 = await getFileSha256(apkPath);
|
||||||
print('SHA256: $sha256');
|
print('SHA256: $sha256');
|
||||||
final result = await Process.run(
|
final result = await Process.run(
|
||||||
@@ -155,6 +162,45 @@ Future<void> scp2CDN() async {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<void> scpMacOS2CDN() async {
|
||||||
|
final zipName = '$build.app.zip';
|
||||||
|
// Zip the .app
|
||||||
|
await Process.run('zip', [
|
||||||
|
'-r',
|
||||||
|
'./release/$zipName',
|
||||||
|
'./build/macos/Build/Products/Release/server_box.app',
|
||||||
|
]);
|
||||||
|
final result = await Process.run(
|
||||||
|
'scp',
|
||||||
|
[
|
||||||
|
'./release/$zipName',
|
||||||
|
'hk:/var/www/res/serverbox/$build.app.zip',
|
||||||
|
],
|
||||||
|
runInShell: true,
|
||||||
|
);
|
||||||
|
if (result.exitCode != 0) {
|
||||||
|
print(result.stderr);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
print('Upload macOS $zipName finished.');
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> scpLinux2CDN() async {
|
||||||
|
final result = await Process.run(
|
||||||
|
'scp',
|
||||||
|
[
|
||||||
|
'./build/linux/x64/release/bundle/server_box.tar.gz',
|
||||||
|
'hk:/var/www/res/serverbox/$build.tar.gz',
|
||||||
|
],
|
||||||
|
runInShell: true,
|
||||||
|
);
|
||||||
|
if (result.exitCode != 0) {
|
||||||
|
print(result.stderr);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
print('Upload Linux $build.tar.gz finished.');
|
||||||
|
}
|
||||||
|
|
||||||
Future<void> changeAppleVersion() async {
|
Future<void> changeAppleVersion() async {
|
||||||
for (final path in ['ios', 'macos']) {
|
for (final path in ['ios', 'macos']) {
|
||||||
final file = File('$path/$appleXCConfigPath');
|
final file = File('$path/$appleXCConfigPath');
|
||||||
@@ -185,38 +231,40 @@ void main(List<String> args) async {
|
|||||||
}
|
}
|
||||||
|
|
||||||
final command = args[0];
|
final command = args[0];
|
||||||
|
|
||||||
switch (command) {
|
switch (command) {
|
||||||
case 'build':
|
case 'build':
|
||||||
final stopwatch = Stopwatch()..start();
|
|
||||||
await dartFormat();
|
await dartFormat();
|
||||||
await getGitCommitCount();
|
await getGitCommitCount();
|
||||||
// always change version to avoid dismatch version between different
|
// always change version to avoid dismatch version between different
|
||||||
// platforms
|
// platforms
|
||||||
await changeAppleVersion();
|
await changeAppleVersion();
|
||||||
await updateBuildData();
|
await updateBuildData();
|
||||||
|
|
||||||
|
final funcs = <Future<void> Function()>[];
|
||||||
|
|
||||||
if (args.length > 1) {
|
if (args.length > 1) {
|
||||||
final platforms = args[1];
|
final platforms = args[1];
|
||||||
for (final platform in platforms.split(',')) {
|
for (final platform in platforms.split(',')) {
|
||||||
if (buildFuncs.keys.contains(platform)) {
|
if (buildFuncs.keys.contains(platform)) {
|
||||||
await buildFuncs[platform]!();
|
funcs.add(buildFuncs[platform]!);
|
||||||
print('Build finished in [${stopwatch.elapsed}]');
|
|
||||||
stopwatch.reset();
|
|
||||||
stopwatch.start();
|
|
||||||
} else {
|
} else {
|
||||||
print('Unknown platform: $platform');
|
print('Unknown platform: $platform');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
funcs.addAll(buildFuncs.values);
|
||||||
|
}
|
||||||
|
|
||||||
return;
|
final stopwatch = Stopwatch();
|
||||||
}
|
for (final func in funcs) {
|
||||||
for (final func in buildFuncs.values) {
|
stopwatch.start();
|
||||||
await func();
|
await func();
|
||||||
|
print('Build finished in ${stopwatch.elapsed}\n');
|
||||||
|
stopwatch.reset();
|
||||||
}
|
}
|
||||||
print('Build finished in ${stopwatch.elapsed}\n');
|
break;
|
||||||
return;
|
|
||||||
default:
|
default:
|
||||||
print('Unsupported command: $command');
|
print('Unsupported command: $command');
|
||||||
return;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
34
pubspec.lock
34
pubspec.lock
@@ -182,10 +182,10 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: collection
|
name: collection
|
||||||
sha256: "4a07be6cb69c84d677a6c3096fcf960cc3285a8330b4603e0d463d15d9bd934c"
|
sha256: f092b211a4319e98e5ff58223576de6c2803db36221657b46c82574721240687
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.17.1"
|
version: "1.17.2"
|
||||||
convert:
|
convert:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -458,10 +458,10 @@ packages:
|
|||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: intl
|
name: intl
|
||||||
sha256: a3715e3bc90294e971cb7dc063fbf3cd9ee0ebf8604ffeafabd9e6f16abbdbe6
|
sha256: "3bc132a9dbce73a7e4a21a17d06e1878839ffbf975568bc875c60537824b0c4d"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.18.0"
|
version: "0.18.1"
|
||||||
io:
|
io:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -522,18 +522,18 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: matcher
|
name: matcher
|
||||||
sha256: "6501fbd55da300384b768785b83e5ce66991266cec21af89ab9ae7f5ce1c4cbb"
|
sha256: "1803e76e6653768d64ed8ff2e1e67bea3ad4b923eb5c56a295c3e634bad5960e"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.12.15"
|
version: "0.12.16"
|
||||||
material_color_utilities:
|
material_color_utilities:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: material_color_utilities
|
name: material_color_utilities
|
||||||
sha256: d92141dc6fe1dad30722f9aa826c7fbc896d021d792f80678280601aff8cf724
|
sha256: "9528f2f296073ff54cb9fee677df673ace1218163c3bc7628093e7eed5203d41"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.2.0"
|
version: "0.5.0"
|
||||||
meta:
|
meta:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -839,10 +839,10 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: source_span
|
name: source_span
|
||||||
sha256: dd904f795d4b4f3b870833847c461801f6750a9fa8e61ea5ac53f9422b31f250
|
sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.9.1"
|
version: "1.10.0"
|
||||||
stack_trace:
|
stack_trace:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -887,10 +887,10 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: test_api
|
name: test_api
|
||||||
sha256: eb6ac1540b26de412b3403a163d919ba86f6a973fe6cc50ae3541b80092fdcfb
|
sha256: "75760ffd7786fffdfb9597c35c5b27eaeec82be8edfb6d71d32651128ed7aab8"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.5.1"
|
version: "0.6.0"
|
||||||
timing:
|
timing:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -1003,6 +1003,14 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.1.0"
|
version: "1.1.0"
|
||||||
|
web:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: web
|
||||||
|
sha256: dc8ccd225a2005c1be616fe02951e2e342092edf968cf0844220383757ef8f10
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "0.1.4-beta"
|
||||||
web_socket_channel:
|
web_socket_channel:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -1061,5 +1069,5 @@ packages:
|
|||||||
source: hosted
|
source: hosted
|
||||||
version: "0.0.6"
|
version: "0.0.6"
|
||||||
sdks:
|
sdks:
|
||||||
dart: ">=3.0.0 <4.0.0"
|
dart: ">=3.1.0-185.0.dev <4.0.0"
|
||||||
flutter: ">=3.10.0"
|
flutter: ">=3.10.0"
|
||||||
|
|||||||
Reference in New Issue
Block a user