mirror of
https://github.com/lollipopkit/flutter_server_box.git
synced 2025-12-17 07:14:28 +01:00
new: swap view for #10
This commit is contained in:
11
README.md
11
README.md
@@ -35,7 +35,9 @@ Especially thanks to <a href="https://github.com/TerminalStudio/dartssh2">dartss
|
||||
- [x] `Ping`
|
||||
- [x] Status charts
|
||||
- [x] etc.
|
||||
- [x] i18n (English, Chinese), **welcome contribution** :)
|
||||
- [x] i18n (English, Chinese)
|
||||
- **Welcome contribution** :)
|
||||
- [How to contribute?](#i18n-guide)
|
||||
- [x] Desktop support
|
||||
|
||||
## 📱 ScreenShots
|
||||
@@ -78,6 +80,13 @@ Status|Platform
|
||||
Full Support|Android/iOS
|
||||
Support, but not tested|macOS/Windows/Linux
|
||||
|
||||
## i18n guide
|
||||
1. Fork this repo and clone it to your local machine.
|
||||
2. Create `arb` file in `lib/l10n/` directory
|
||||
- File name should be `intl_XX.arb`, where `XX` is the language code. Such as `intl_en.arb` for English and `intl_zh.arb` for Chinese.
|
||||
3. Add content to the file. You can refer to `intl_en.arb` and `intl_zh.arb` for the format.
|
||||
4. Pull commit to your forked repo.
|
||||
5. Request a pull request on my repo.
|
||||
|
||||
## 📝 License
|
||||
`GPL v3. lollipopkit 2023`
|
||||
|
||||
@@ -1,6 +1,40 @@
|
||||
PODS:
|
||||
- countly_flutter (22.09.0):
|
||||
- Flutter
|
||||
- DKImagePickerController/Core (4.3.4):
|
||||
- DKImagePickerController/ImageDataManager
|
||||
- DKImagePickerController/Resource
|
||||
- DKImagePickerController/ImageDataManager (4.3.4)
|
||||
- DKImagePickerController/PhotoGallery (4.3.4):
|
||||
- DKImagePickerController/Core
|
||||
- DKPhotoGallery
|
||||
- DKImagePickerController/Resource (4.3.4)
|
||||
- DKPhotoGallery (0.0.17):
|
||||
- DKPhotoGallery/Core (= 0.0.17)
|
||||
- DKPhotoGallery/Model (= 0.0.17)
|
||||
- DKPhotoGallery/Preview (= 0.0.17)
|
||||
- DKPhotoGallery/Resource (= 0.0.17)
|
||||
- SDWebImage
|
||||
- SwiftyGif
|
||||
- DKPhotoGallery/Core (0.0.17):
|
||||
- DKPhotoGallery/Model
|
||||
- DKPhotoGallery/Preview
|
||||
- SDWebImage
|
||||
- SwiftyGif
|
||||
- DKPhotoGallery/Model (0.0.17):
|
||||
- SDWebImage
|
||||
- SwiftyGif
|
||||
- DKPhotoGallery/Preview (0.0.17):
|
||||
- DKPhotoGallery/Model
|
||||
- DKPhotoGallery/Resource
|
||||
- SDWebImage
|
||||
- SwiftyGif
|
||||
- DKPhotoGallery/Resource (0.0.17):
|
||||
- SDWebImage
|
||||
- SwiftyGif
|
||||
- file_picker (0.0.1):
|
||||
- DKImagePickerController/PhotoGallery
|
||||
- Flutter
|
||||
- Flutter (1.0.0)
|
||||
- flutter_native_splash (0.0.1):
|
||||
- Flutter
|
||||
@@ -9,13 +43,18 @@ PODS:
|
||||
- FlutterMacOS
|
||||
- r_upgrade (0.0.1):
|
||||
- Flutter
|
||||
- SDWebImage (5.15.2):
|
||||
- SDWebImage/Core (= 5.15.2)
|
||||
- SDWebImage/Core (5.15.2)
|
||||
- share_plus (0.0.1):
|
||||
- Flutter
|
||||
- SwiftyGif (5.4.4)
|
||||
- url_launcher_ios (0.0.1):
|
||||
- Flutter
|
||||
|
||||
DEPENDENCIES:
|
||||
- countly_flutter (from `.symlinks/plugins/countly_flutter/ios`)
|
||||
- file_picker (from `.symlinks/plugins/file_picker/ios`)
|
||||
- Flutter (from `Flutter`)
|
||||
- flutter_native_splash (from `.symlinks/plugins/flutter_native_splash/ios`)
|
||||
- path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/ios`)
|
||||
@@ -23,9 +62,18 @@ DEPENDENCIES:
|
||||
- share_plus (from `.symlinks/plugins/share_plus/ios`)
|
||||
- url_launcher_ios (from `.symlinks/plugins/url_launcher_ios/ios`)
|
||||
|
||||
SPEC REPOS:
|
||||
trunk:
|
||||
- DKImagePickerController
|
||||
- DKPhotoGallery
|
||||
- SDWebImage
|
||||
- SwiftyGif
|
||||
|
||||
EXTERNAL SOURCES:
|
||||
countly_flutter:
|
||||
:path: ".symlinks/plugins/countly_flutter/ios"
|
||||
file_picker:
|
||||
:path: ".symlinks/plugins/file_picker/ios"
|
||||
Flutter:
|
||||
:path: Flutter
|
||||
flutter_native_splash:
|
||||
@@ -41,11 +89,16 @@ EXTERNAL SOURCES:
|
||||
|
||||
SPEC CHECKSUMS:
|
||||
countly_flutter: 135f1a4930f8e26ba223a14201d3f265ea7b4c83
|
||||
DKImagePickerController: b512c28220a2b8ac7419f21c491fc8534b7601ac
|
||||
DKPhotoGallery: fdfad5125a9fdda9cc57df834d49df790dbb4179
|
||||
file_picker: ce3938a0df3cc1ef404671531facef740d03f920
|
||||
Flutter: f04841e97a9d0b0a8025694d0796dd46242b2854
|
||||
flutter_native_splash: 52501b97d1c0a5f898d687f1646226c1f93c56ef
|
||||
path_provider_foundation: 37748e03f12783f9de2cb2c4eadfaa25fe6d4852
|
||||
r_upgrade: 44d715c61914cce3d01ea225abffe894fd51c114
|
||||
SDWebImage: 8ab87d4b3e5cc4927bd47f78db6ceb0b94442577
|
||||
share_plus: 056a1e8ac890df3e33cb503afffaf1e9b4fbae68
|
||||
SwiftyGif: 93a1cc87bf3a51916001cf8f3d63835fb64c819f
|
||||
url_launcher_ios: ae1517e5e344f5544fb090b079e11f399dfbe4d2
|
||||
|
||||
PODFILE CHECKSUM: ef19549a9bc3046e7bb7d2fab4d021637c0c58a3
|
||||
|
||||
@@ -356,7 +356,7 @@
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CURRENT_PROJECT_VERSION = 217;
|
||||
CURRENT_PROJECT_VERSION = 218;
|
||||
DEVELOPMENT_TEAM = BA88US33G6;
|
||||
ENABLE_BITCODE = NO;
|
||||
INFOPLIST_FILE = Runner/Info.plist;
|
||||
@@ -364,7 +364,7 @@
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 1.0.217;
|
||||
MARKETING_VERSION = 1.0.218;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
||||
@@ -486,7 +486,7 @@
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CURRENT_PROJECT_VERSION = 217;
|
||||
CURRENT_PROJECT_VERSION = 218;
|
||||
DEVELOPMENT_TEAM = BA88US33G6;
|
||||
ENABLE_BITCODE = NO;
|
||||
INFOPLIST_FILE = Runner/Info.plist;
|
||||
@@ -494,7 +494,7 @@
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 1.0.217;
|
||||
MARKETING_VERSION = 1.0.218;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
||||
@@ -510,7 +510,7 @@
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CURRENT_PROJECT_VERSION = 217;
|
||||
CURRENT_PROJECT_VERSION = 218;
|
||||
DEVELOPMENT_TEAM = BA88US33G6;
|
||||
ENABLE_BITCODE = NO;
|
||||
INFOPLIST_FILE = Runner/Info.plist;
|
||||
@@ -518,7 +518,7 @@
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 1.0.217;
|
||||
MARKETING_VERSION = 1.0.218;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
||||
|
||||
@@ -16,18 +16,65 @@ final memItemReg = RegExp(r'([A-Z].+:)\s+([0-9]+) kB');
|
||||
|
||||
Memory parseMem(String raw) {
|
||||
final items = raw.split('\n').map((e) => memItemReg.firstMatch(e)).toList();
|
||||
|
||||
final total = int.parse(
|
||||
items.firstWhere((e) => e?.group(1) == 'MemTotal:')?.group(2) ?? '1');
|
||||
items.firstWhere((e) => e?.group(1) == 'MemTotal:')?.group(2) ?? '1',
|
||||
);
|
||||
final free = int.parse(
|
||||
items.firstWhere((e) => e?.group(1) == 'MemFree:')?.group(2) ?? '0');
|
||||
items.firstWhere((e) => e?.group(1) == 'MemFree:')?.group(2) ?? '0',
|
||||
);
|
||||
final cached = int.parse(
|
||||
items.firstWhere((e) => e?.group(1) == 'Cached:')?.group(2) ?? '0');
|
||||
items.firstWhere((e) => e?.group(1) == 'Cached:')?.group(2) ?? '0',
|
||||
);
|
||||
final available = int.parse(
|
||||
items.firstWhere((e) => e?.group(1) == 'MemAvailable:')?.group(2) ?? '0');
|
||||
items.firstWhere((e) => e?.group(1) == 'MemAvailable:')?.group(2) ?? '0',
|
||||
);
|
||||
|
||||
return Memory(
|
||||
total: total,
|
||||
used: total - available,
|
||||
free: free,
|
||||
cache: cached,
|
||||
avail: available);
|
||||
total: total,
|
||||
used: total - available,
|
||||
free: free,
|
||||
cache: cached,
|
||||
avail: available,
|
||||
);
|
||||
}
|
||||
|
||||
class Swap {
|
||||
final int total;
|
||||
final int used;
|
||||
final int free;
|
||||
final int cached;
|
||||
|
||||
Swap({
|
||||
required this.total,
|
||||
required this.used,
|
||||
required this.free,
|
||||
required this.cached,
|
||||
});
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'Swap{total: $total, used: $used, free: $free, cached: $cached}';
|
||||
}
|
||||
}
|
||||
|
||||
Swap parseSwap(String raw) {
|
||||
final items = raw.split('\n').map((e) => memItemReg.firstMatch(e)).toList();
|
||||
|
||||
final total = int.parse(
|
||||
items.firstWhere((e) => e?.group(1) == 'SwapTotal:')?.group(2) ?? '1',
|
||||
);
|
||||
final free = int.parse(
|
||||
items.firstWhere((e) => e?.group(1) == 'SwapFree:')?.group(2) ?? '0',
|
||||
);
|
||||
final cached = int.parse(
|
||||
items.firstWhere((e) => e?.group(1) == 'SwapCached:')?.group(2) ?? '0',
|
||||
);
|
||||
|
||||
return Swap(
|
||||
total: total,
|
||||
used: total - free,
|
||||
free: free,
|
||||
cached: cached,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -32,6 +32,7 @@ class ServerStatus {
|
||||
|
||||
CpuStatus cpu;
|
||||
Memory mem;
|
||||
Swap swap;
|
||||
String sysVer;
|
||||
String uptime;
|
||||
List<DiskInfo> disk;
|
||||
@@ -39,7 +40,15 @@ class ServerStatus {
|
||||
NetSpeed netSpeed;
|
||||
String? failedInfo;
|
||||
|
||||
ServerStatus(this.cpu, this.mem, this.sysVer, this.uptime, this.disk,
|
||||
this.tcp, this.netSpeed,
|
||||
{this.failedInfo});
|
||||
ServerStatus({
|
||||
required this.cpu,
|
||||
required this.mem,
|
||||
required this.sysVer,
|
||||
required this.uptime,
|
||||
required this.disk,
|
||||
required this.tcp,
|
||||
required this.netSpeed,
|
||||
required this.swap,
|
||||
this.failedInfo,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -241,7 +241,9 @@ class ServerProvider extends BusyProvider {
|
||||
}
|
||||
|
||||
Future<void> _getMem(String id, String raw) async {
|
||||
getServer(id).status.mem = await compute(parseMem, raw);
|
||||
final s = getServer(id);
|
||||
s.status.mem = await compute(parseMem, raw);
|
||||
s.status.swap = await compute(parseSwap, raw);
|
||||
}
|
||||
|
||||
Future<String?> runSnippet(String id, Snippet snippet) async {
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
|
||||
class BuildData {
|
||||
static const String name = "ServerBox";
|
||||
static const int build = 217;
|
||||
static const int build = 218;
|
||||
static const String engine =
|
||||
"Flutter 3.7.2 • channel stable • https://github.com/flutter/flutter.git\nFramework • revision 32fb2f948e (5 days ago) • 2023-02-08 07:30:10 -0800\nEngine • revision f40b73f8a4\nTools • Dart 2.19.2 • DevTools 2.20.1\n";
|
||||
static const String buildAt = "2023-02-13 14:53:15.900258";
|
||||
static const int modifications = 2;
|
||||
"Flutter 3.7.3 • channel stable • https://github.com/flutter/flutter.git\nFramework • revision 9944297138 (5 days ago) • 2023-02-08 15:46:04 -0800\nEngine • revision 248290d6d5\nTools • Dart 2.19.2 • DevTools 2.20.1\n";
|
||||
static const String buildAt = "2023-02-14 18:46:55.180156";
|
||||
static const int modifications = 5;
|
||||
}
|
||||
|
||||
@@ -37,12 +37,19 @@ get initNetSpeed => NetSpeed(
|
||||
[_initNetSpeedPart],
|
||||
[_initNetSpeedPart],
|
||||
);
|
||||
get initStatus => ServerStatus(
|
||||
initCpuStatus,
|
||||
_initMemory,
|
||||
'Loading...',
|
||||
'',
|
||||
[DiskInfo('/', '/', 0, '0', '0', '0')],
|
||||
TcpStatus(0, 0, 0, 0),
|
||||
initNetSpeed,
|
||||
get _initSwap => Swap(
|
||||
total: 1,
|
||||
used: 0,
|
||||
free: 1,
|
||||
cached: 0,
|
||||
);
|
||||
get initStatus => ServerStatus(
|
||||
cpu: initCpuStatus,
|
||||
mem: _initMemory,
|
||||
sysVer: 'Loading...',
|
||||
uptime: '',
|
||||
disk: [DiskInfo('/', '/', 0, '0', '0', '0')],
|
||||
tcp: TcpStatus(0, 0, 0, 0),
|
||||
netSpeed: initNetSpeed,
|
||||
swap: _initSwap,
|
||||
);
|
||||
|
||||
@@ -185,6 +185,7 @@ class _MyHomePageState extends State<MyHomePage>
|
||||
child: Text(
|
||||
'${BuildData.name}\n$_versionStr',
|
||||
textAlign: TextAlign.center,
|
||||
style: textSize13,
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
|
||||
@@ -62,6 +62,7 @@ class _ServerDetailPageState extends State<ServerDetailPage>
|
||||
_buildUpTimeAndSys(si.status),
|
||||
_buildCPUView(si.status),
|
||||
_buildMemView(si.status),
|
||||
_buildSwapView(si.status),
|
||||
_buildDiskView(si.status),
|
||||
_buildNetView(si.status.netSpeed),
|
||||
// avoid the hieght of navigation bar
|
||||
@@ -219,7 +220,7 @@ class _ServerDetailPageState extends State<ServerDetailPage>
|
||||
children: [
|
||||
Text('${used.toStringAsFixed(0)}%', style: textSize27),
|
||||
width7,
|
||||
Text('of ${(ss.mem.total * 1024).convertBytes}',
|
||||
Text('of ${(ss.mem.total * 1024).convertBytes} Mem',
|
||||
style: textSize13Grey)
|
||||
],
|
||||
),
|
||||
@@ -242,6 +243,48 @@ class _ServerDetailPageState extends State<ServerDetailPage>
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildSwapView(ServerStatus ss) {
|
||||
if (ss.swap.total == 0) return const SizedBox();
|
||||
final used = ss.swap.used / ss.swap.total * 100;
|
||||
final free = ss.swap.free / ss.swap.total * 100;
|
||||
final cached = ss.swap.cached / ss.swap.total * 100;
|
||||
return RoundRectCard(
|
||||
Padding(
|
||||
padding: roundRectCardPadding,
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Text('${used.toStringAsFixed(0)}%', style: textSize27),
|
||||
width7,
|
||||
Text('of ${(ss.swap.total * 1024).convertBytes} Swap',
|
||||
style: textSize13Grey)
|
||||
],
|
||||
),
|
||||
Row(
|
||||
children: [
|
||||
_buildDetailPercent(free, 'free'),
|
||||
width13,
|
||||
_buildDetailPercent(cached, 'cached')
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(
|
||||
height: 11,
|
||||
),
|
||||
_buildProgress(used)
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildDiskView(ServerStatus ss) {
|
||||
final clone = ss.disk.toList();
|
||||
for (var item in ss.disk) {
|
||||
|
||||
@@ -79,7 +79,7 @@ class _SettingPageState extends State<SettingPage> {
|
||||
child: Center(
|
||||
child: Text(
|
||||
text,
|
||||
style: TextStyle(color: primaryColor),
|
||||
style: textSize13,
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
27
make.dart
27
make.dart
@@ -123,7 +123,7 @@ Future<void> flutterBuild(
|
||||
'--build-name=1.0.$build',
|
||||
]);
|
||||
}
|
||||
print('[$buildType]\nBuilding with args: ${args.join(' ')}');
|
||||
print('\n[$buildType]\nBuilding with args: ${args.join(' ')}');
|
||||
final buildResult = await fvmRun(['flutter', ...args]);
|
||||
final exitCode = buildResult.exitCode;
|
||||
|
||||
@@ -139,8 +139,6 @@ Future<void> flutterBuild(
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
print('Done.\n');
|
||||
} else {
|
||||
print(buildResult.stdout);
|
||||
print(buildResult.stderr);
|
||||
@@ -186,25 +184,28 @@ void main(List<String> args) async {
|
||||
case 'build':
|
||||
final stopwatch = Stopwatch()..start();
|
||||
build = await getGitCommitCount();
|
||||
await updateBuildData();
|
||||
await dartFormat();
|
||||
await updateBuildData();
|
||||
await changeAppleVersion();
|
||||
if (args.length > 1) {
|
||||
final platform = args[1];
|
||||
if (buildFuncs.keys.contains(platform)) {
|
||||
await buildFuncs[platform]!();
|
||||
print('Build finished in ${stopwatch.elapsed}');
|
||||
stopwatch.reset();
|
||||
stopwatch.start();
|
||||
} else {
|
||||
print('Unknown platform: $platform');
|
||||
final platforms = args[1];
|
||||
for (final platform in platforms.split(',')) {
|
||||
if (buildFuncs.keys.contains(platform)) {
|
||||
await buildFuncs[platform]!();
|
||||
print('Build finished in ${stopwatch.elapsed}');
|
||||
stopwatch.reset();
|
||||
stopwatch.start();
|
||||
} else {
|
||||
print('Unknown platform: $platform');
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
for (final func in buildFuncs.values) {
|
||||
await func();
|
||||
}
|
||||
print('Build finished in ${stopwatch.elapsed}');
|
||||
print('Build finished in ${stopwatch.elapsed}\n');
|
||||
return;
|
||||
default:
|
||||
print('Unsupported command: $command');
|
||||
|
||||
@@ -298,6 +298,14 @@ packages:
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "6.1.4"
|
||||
file_picker:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: file_picker
|
||||
sha256: d090ae03df98b0247b82e5928f44d1b959867049d18d73635e2e0bc3f49542b9
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "5.2.5"
|
||||
fixnum:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
||||
@@ -56,6 +56,7 @@ dependencies:
|
||||
# xterm: ^3.4.1
|
||||
xterm:
|
||||
path: ../xterm.dart
|
||||
file_picker: ^5.2.5
|
||||
|
||||
dev_dependencies:
|
||||
flutter_native_splash: ^2.1.6
|
||||
|
||||
Reference in New Issue
Block a user