diff --git a/lib/data/model/server/cpu_status.dart b/lib/data/model/server/cpu_status.dart index 1fdf1b69..297923c6 100644 --- a/lib/data/model/server/cpu_status.dart +++ b/lib/data/model/server/cpu_status.dart @@ -102,13 +102,11 @@ final cpuTempReg = RegExp(r'(x86_pkg_temp|cpu_thermal)'); String parseCPUTemp(String type, String value) { const noMatch = "/sys/class/thermal/thermal_zone*/type"; // Not support to get CPU temperature - if (value.contains(noMatch) || - type.contains(noMatch) || - value.isEmpty || - type.isEmpty) { + if (type.contains(noMatch) || value.isEmpty || type.isEmpty) { return ''; } final split = type.split('\n'); + // if no match, use idx 0 int idx = 0; for (var item in split) { if (item.contains(cpuTempReg)) { diff --git a/lib/data/model/server/memory.dart b/lib/data/model/server/memory.dart index b6000760..9f8b4aaf 100644 --- a/lib/data/model/server/memory.dart +++ b/lib/data/model/server/memory.dart @@ -1,16 +1,24 @@ class Memory { int total; - int used; int free; int cache; int avail; + Memory({ required this.total, - required this.used, required this.free, required this.cache, required this.avail, }); + + double get availPercent { + if (avail == 0) { + return free / total; + } + return avail / total; + } + + double get usedPercent => 1 - availPercent; } final memItemReg = RegExp(r'([A-Z].+:)\s+([0-9]+) kB'); @@ -18,22 +26,49 @@ 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', - ); - final free = int.parse( - items.firstWhere((e) => e?.group(1) == 'MemFree:')?.group(2) ?? '0', - ); - final cached = int.parse( - items.firstWhere((e) => e?.group(1) == 'Cached:')?.group(2) ?? '0', - ); - final available = int.parse( - items.firstWhere((e) => e?.group(1) == 'MemAvailable:')?.group(2) ?? '0', - ); + final total = int.tryParse( + items + .firstWhere( + (e) => e?.group(1) == 'MemTotal:', + orElse: () => null, + ) + ?.group(2) ?? + '1', + ) ?? + 1; + final free = int.tryParse( + items + .firstWhere( + (e) => e?.group(1) == 'MemFree:', + orElse: () => null, + ) + ?.group(2) ?? + '0', + ) ?? + 0; + final cached = int.tryParse( + items + .firstWhere( + (e) => e?.group(1) == 'Cached:', + orElse: () => null, + ) + ?.group(2) ?? + '0', + ) ?? + 0; + final available = int.tryParse( + items + .firstWhere( + (e) => e?.group(1) == 'MemAvailable:', + orElse: () => null, + ) + ?.group(2) ?? + '0', + ) ?? + 0; return Memory( total: total, - used: total - available, free: free, cache: cached, avail: available, @@ -42,39 +77,61 @@ Memory parseMem(String raw) { 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, }); + double get usedPercent => 1 - free / total; + + double get freePercent => free / total; + @override String toString() { - return 'Swap{total: $total, used: $used, free: $free, cached: $cached}'; + return 'Swap{total: $total, 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', - ); + final total = int.tryParse( + items + .firstWhere( + (e) => e?.group(1) == 'SwapTotal:', + orElse: () => null, + ) + ?.group(2) ?? + '1', + ) ?? + 1; + final free = int.tryParse( + items + .firstWhere( + (e) => e?.group(1) == 'SwapFree:', + orElse: () => null, + ) + ?.group(2) ?? + '1', + ) ?? + 1; + final cached = int.tryParse( + items + .firstWhere( + (e) => e?.group(1) == 'SwapCached:', + orElse: () => null, + ) + ?.group(2) ?? + '0', + ) ?? + 0; return Swap( total: total, - used: total - free, free: free, cached: cached, ); diff --git a/lib/data/provider/pkg.dart b/lib/data/provider/pkg.dart index facb08ec..c48d08c8 100644 --- a/lib/data/provider/pkg.dart +++ b/lib/data/provider/pkg.dart @@ -59,9 +59,11 @@ class PkgProvider extends BusyProvider { Future refresh() async { final result = await _update(); - _parse(result); - try {} catch (e) { + try { + _parse(result); + } catch (e) { error = '[Server Raw]:\n$result\n[App Error]:\n$e'; + rethrow; } finally { notifyListeners(); } diff --git a/lib/data/res/build_data.dart b/lib/data/res/build_data.dart index f813e0b2..a639f436 100644 --- a/lib/data/res/build_data.dart +++ b/lib/data/res/build_data.dart @@ -4,6 +4,6 @@ class BuildData { static const String name = "ServerBox"; static const int build = 293; static const String engine = "3.7.11"; - static const String buildAt = "2023-05-09 19:48:09.523377"; - static const int modifications = 4; + static const String buildAt = "2023-05-10 12:26:52.686"; + static const int modifications = 11; } diff --git a/lib/data/res/status.dart b/lib/data/res/status.dart index 8cd934b0..2fffcf39 100644 --- a/lib/data/res/status.dart +++ b/lib/data/res/status.dart @@ -7,7 +7,6 @@ import '../model/server/conn_status.dart'; Memory get _initMemory => Memory( total: 1, - used: 0, free: 1, cache: 0, avail: 1, @@ -39,7 +38,6 @@ NetSpeed get initNetSpeed => NetSpeed( ); Swap get _initSwap => Swap( total: 1, - used: 0, free: 1, cached: 0, ); diff --git a/lib/data/store/setting.dart b/lib/data/store/setting.dart index 8bc321ce..fb69649f 100644 --- a/lib/data/store/setting.dart +++ b/lib/data/store/setting.dart @@ -1,9 +1,10 @@ import 'package:flutter/material.dart'; import 'package:toolbox/core/persistant_store.dart'; +import 'package:toolbox/core/utils/platform.dart'; class SettingStore extends PersistentStore { StoreProperty get primaryColor => - property('primaryColor', defaultValue: Colors.deepPurpleAccent.value); + property('primaryColor', defaultValue: Colors.pink.value); StoreProperty get serverStatusUpdateInterval => property('serverStatusUpdateInterval', defaultValue: 3); @@ -37,5 +38,5 @@ class SettingStore extends PersistentStore { StoreProperty get fontPath => property('fontPath'); /// Backgroud running (Android) - StoreProperty get bgRun => property('bgRun', defaultValue: true); + StoreProperty get bgRun => property('bgRun', defaultValue: isAndroid); } diff --git a/lib/view/page/backup.dart b/lib/view/page/backup.dart index e0d69e6f..570a620f 100644 --- a/lib/view/page/backup.dart +++ b/lib/view/page/backup.dart @@ -191,7 +191,7 @@ class BackupPage extends StatelessWidget { ); } catch (e) { showSnackBar(context, Text(e.toString())); - return; + rethrow; } } } diff --git a/lib/view/page/ping.dart b/lib/view/page/ping.dart index 1ba754ba..6b3b1106 100644 --- a/lib/view/page/ping.dart +++ b/lib/view/page/ping.dart @@ -85,6 +85,7 @@ class _PingPageState extends State doPing(); } catch (e) { showSnackBar(context, Text('Error: \n$e')); + rethrow; } }, child: const Icon(Icons.play_arrow), @@ -154,18 +155,14 @@ class _PingPageState extends State return; } - try { - await Future.wait(_serverProvider.servers.values.map((e) async { - if (e.client == null) { - return; - } - final result = await e.client!.run('ping -c 3 $target').string; - _results.add(PingResult.parse(e.spi.name, result)); - setState(() {}); - })); - } catch (e) { - showSnackBar(context, Text(e.toString())); - } + await Future.wait(_serverProvider.servers.values.map((e) async { + if (e.client == null) { + return; + } + final result = await e.client!.run('ping -c 3 $target').string; + _results.add(PingResult.parse(e.spi.name, result)); + setState(() {}); + })); } @override diff --git a/lib/view/page/private_key/edit.dart b/lib/view/page/private_key/edit.dart index 88c61333..a38abca7 100644 --- a/lib/view/page/private_key/edit.dart +++ b/lib/view/page/private_key/edit.dart @@ -105,18 +105,16 @@ class _PrivateKeyEditPageState extends State ); }); final info = PrivateKeyInfo(name, key, ''); - bool haveErr = false; try { info.privateKey = await compute(decyptPem, [key, pwd]); } catch (e) { showSnackBar(context, Text(e.toString())); - haveErr = true; + rethrow; } finally { setState(() { _loading = const SizedBox(); }); } - if (haveErr) return; if (widget.info != null) { _provider.updateInfo(widget.info!, info); } else { diff --git a/lib/view/page/server/detail.dart b/lib/view/page/server/detail.dart index 20da05fd..5a6e5813 100644 --- a/lib/view/page/server/detail.dart +++ b/lib/view/page/server/detail.dart @@ -204,9 +204,9 @@ class _ServerDetailPageState extends State } Widget _buildMemView(ServerStatus ss) { - final used = ss.mem.used / ss.mem.total * 100; final free = ss.mem.free / ss.mem.total * 100; - final avail = ss.mem.avail / ss.mem.total * 100; + final avail = ss.mem.availPercent * 100; + final used = ss.mem.usedPercent * 100; return RoundRectCard( Padding( @@ -245,7 +245,7 @@ class _ServerDetailPageState extends State Widget _buildSwapView(ServerStatus ss) { if (ss.swap.total == 0) return const SizedBox(); - final used = ss.swap.used / ss.swap.total * 100; + final used = ss.swap.usedPercent * 100; final cached = ss.swap.cached / ss.swap.total * 100; return RoundRectCard( Padding( diff --git a/lib/view/page/server/tab.dart b/lib/view/page/server/tab.dart index 1b6d6fe0..753eed9a 100644 --- a/lib/view/page/server/tab.dart +++ b/lib/view/page/server/tab.dart @@ -205,7 +205,7 @@ class _ServerPageState extends State mainAxisAlignment: MainAxisAlignment.spaceAround, children: [ _buildPercentCircle(ss.cpu.usedPercent()), - _buildPercentCircle(ss.mem.used / ss.mem.total * 100), + _buildPercentCircle(ss.mem.usedPercent * 100), _buildIOData('Conn:\n${ss.tcp.maxConn}', 'Fail:\n${ss.tcp.fail}'), _buildIOData( 'Total:\n${rootDisk.size}', 'Used:\n${rootDisk.usedPercent}%')