diff --git a/lib/data/model/server/disk_info.dart b/lib/data/model/server/disk_info.dart index e7ce45fe..b4b3200c 100644 --- a/lib/data/model/server/disk_info.dart +++ b/lib/data/model/server/disk_info.dart @@ -1,3 +1,5 @@ +import '../../res/misc.dart'; + class DiskInfo { /* { @@ -26,3 +28,24 @@ class DiskInfo { this.avail, ); } + +List parseDisk(String raw) { + final list = []; + final items = raw.split('\n'); + items.removeAt(0); + for (var item in items) { + if (item.isEmpty) { + continue; + } + final vals = item.split(numReg); + list.add(DiskInfo( + vals[0], + vals[5], + int.parse(vals[4].replaceFirst('%', '')), + vals[2], + vals[1], + vals[3], + )); + } + return list; +} diff --git a/lib/data/model/server/net_speed.dart b/lib/data/model/server/net_speed.dart index b0706e68..148b85a5 100644 --- a/lib/data/model/server/net_speed.dart +++ b/lib/data/model/server/net_speed.dart @@ -36,6 +36,13 @@ class NetSpeed { return buildStandardOutput(speedInBytesPerSecond); } + String totalIn({String? device}) { + if (_old[0].device == '' || _now[0].device == '') return '0kb'; + final idx = deviceIdx(device); + final totalInBytes = _now[idx].bytesIn; + return totalInBytes.toInt().convertBytes; + } + String speedOut({String? device}) { if (_old[0].device == '' || _now[0].device == '') return '0kb/s'; final idx = deviceIdx(device); @@ -44,6 +51,13 @@ class NetSpeed { return buildStandardOutput(speedOutBytesPerSecond); } + String totalOut({String? device}) { + if (_old[0].device == '' || _now[0].device == '') return '0kb'; + final idx = deviceIdx(device); + final totalOutBytes = _now[idx].bytesOut; + return totalOutBytes.toInt().convertBytes; + } + int deviceIdx(String? device) { if (device != null) { for (var item in _now) { @@ -55,10 +69,15 @@ class NetSpeed { return 0; } - String buildStandardOutput(double speed) => - '${speed.convertBytes.toLowerCase()}/s'; + String buildStandardOutput(double speed) => '${speed.convertBytes}/s'; } +/// [raw] example: +/// Inter-| Receive | Transmit +/// face |bytes packets errs drop fifo frame compressed multicast|bytes packets errs drop fifo colls carrier compressed +/// lo: 45929941 269112 0 0 0 0 0 0 45929941 269112 0 0 0 0 0 0 +/// eth0: 48481023 505772 0 0 0 0 0 0 36002262 202307 0 0 0 0 0 0 +/// 1635752901 List parseNetSpeed(String raw) { final split = raw.split('\n'); if (split.length < 4) { diff --git a/lib/data/model/server/tcp_status.dart b/lib/data/model/server/tcp_status.dart index 19cfd39b..d5305814 100644 --- a/lib/data/model/server/tcp_status.dart +++ b/lib/data/model/server/tcp_status.dart @@ -1,4 +1,5 @@ import '../../../core/extension/stringx.dart'; +import '../../res/misc.dart'; /// /// Code generated by jsonToDartModel https://ashamp.github.io/jsonToDartModel/ @@ -42,8 +43,6 @@ class TcpStatus { } } -final numReg = RegExp(r'\s{1,}'); - TcpStatus? parseTcp(String raw) { final lines = raw.split('\n'); final idx = lines.lastWhere((element) => element.startsWith('Tcp:'), diff --git a/lib/data/provider/server.dart b/lib/data/provider/server.dart index cd56cc2b..40e70be4 100644 --- a/lib/data/provider/server.dart +++ b/lib/data/provider/server.dart @@ -186,12 +186,6 @@ class ServerProvider extends BusyProvider { } } - /// [raw] example: - /// Inter-| Receive | Transmit - /// face |bytes packets errs drop fifo frame compressed multicast|bytes packets errs drop fifo colls carrier compressed - /// lo: 45929941 269112 0 0 0 0 0 0 45929941 269112 0 0 0 0 0 0 - /// eth0: 48481023 505772 0 0 0 0 0 0 36002262 202307 0 0 0 0 0 0 - /// 1635752901 Future _getNetSpeed(ServerPrivateInfo spi, String raw) async { final info = _servers.firstWhere((e) => e.spi == spi); info.status.netSpeed.update(await compute(parseNetSpeed, raw)); @@ -211,8 +205,10 @@ class ServerProvider extends BusyProvider { final cpus = await compute(parseCPU, raw); if (cpus.isNotEmpty) { - info.status.cpu - .update(cpus, await compute(parseCPUTemp, [tempType, tempValue])); + info.status.cpu.update( + cpus, + await compute(parseCPUTemp, [tempType, tempValue]), + ); } } @@ -229,25 +225,14 @@ class ServerProvider extends BusyProvider { } } - void _getDisk(ServerPrivateInfo spi, String raw) { + Future _getDisk(ServerPrivateInfo spi, String raw) async { final info = _servers.firstWhere((e) => e.spi == spi); - final list = []; - final items = raw.split('\n'); - for (var item in items) { - if (items.indexOf(item) == 0 || item.isEmpty) { - continue; - } - final vals = item.split(numReg); - list.add(DiskInfo(vals[0], vals[5], - int.parse(vals[4].replaceFirst('%', '')), vals[2], vals[1], vals[3])); - } - info.status.disk = list; + info.status.disk = await compute(parseDisk, raw); } Future _getMem(ServerPrivateInfo spi, String raw) async { final info = _servers.firstWhere((e) => e.spi == spi); - final mem = await compute(parseMem, raw); - info.status.mem = mem; + info.status.mem = await compute(parseMem, raw); } Future runSnippet(String id, Snippet snippet) async { diff --git a/lib/data/res/build_data.dart b/lib/data/res/build_data.dart index aa3fc9bc..093449df 100644 --- a/lib/data/res/build_data.dart +++ b/lib/data/res/build_data.dart @@ -2,9 +2,9 @@ class BuildData { static const String name = "ServerBox"; - static const int build = 210; + static const int build = 211; static const String engine = "Flutter 3.7.0 • channel stable • https://github.com/flutter/flutter.git\nFramework • revision b06b8b2710 (9 days ago) • 2023-01-23 16:55:55 -0800\nEngine • revision b24591ed32\nTools • Dart 2.19.0 • DevTools 2.20.1\n"; - static const String buildAt = "2023-02-01 23:36:32.789406"; - static const int modifications = 0; + static const String buildAt = "2023-02-02 12:40:53.962160"; + static const int modifications = 5; } diff --git a/lib/data/res/misc.dart b/lib/data/res/misc.dart index 8b37b09e..76dc418b 100644 --- a/lib/data/res/misc.dart +++ b/lib/data/res/misc.dart @@ -1 +1,3 @@ const serverMaxTryTimes = 7; + +final numReg = RegExp(r'\s{1,}'); diff --git a/lib/generated/intl/messages_zh.dart b/lib/generated/intl/messages_zh.dart index 89021667..4c573cae 100644 --- a/lib/generated/intl/messages_zh.dart +++ b/lib/generated/intl/messages_zh.dart @@ -89,7 +89,7 @@ class MessageLookup extends MessageLookupByLibrary { "cmd": MessageLookupByLibrary.simpleMessage("命令"), "containerStatus": MessageLookupByLibrary.simpleMessage("容器状态"), "convert": MessageLookupByLibrary.simpleMessage("转换"), - "copy": MessageLookupByLibrary.simpleMessage("复制到剪切板"), + "copy": MessageLookupByLibrary.simpleMessage("复制"), "copyPath": MessageLookupByLibrary.simpleMessage("复制路径"), "createFile": MessageLookupByLibrary.simpleMessage("创建文件"), "createFolder": MessageLookupByLibrary.simpleMessage("创建文件夹"), diff --git a/lib/l10n/intl_zh.arb b/lib/l10n/intl_zh.arb index 19832ab2..cc032b3c 100644 --- a/lib/l10n/intl_zh.arb +++ b/lib/l10n/intl_zh.arb @@ -20,7 +20,7 @@ "cmd": "命令", "containerStatus": "容器状态", "convert": "转换", - "copy": "复制到剪切板", + "copy": "复制", "copyPath": "复制路径", "createFile": "创建文件", "createFolder": "创建文件夹", diff --git a/lib/view/page/server/detail.dart b/lib/view/page/server/detail.dart index fb6b2382..29620019 100644 --- a/lib/view/page/server/detail.dart +++ b/lib/view/page/server/detail.dart @@ -245,7 +245,7 @@ class _ServerDetailPageState extends State Widget _buildDiskView(ServerStatus ss) { final clone = ss.disk.toList(); for (var item in ss.disk) { - if (ignorePath.any((ele) => item.loc.contains(ele))) { + if (_ignorePath.any((ele) => item.path.startsWith(ele))) { clone.remove(item); } } @@ -316,10 +316,7 @@ class _ServerDetailPageState extends State child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: const [ - Icon( - Icons.device_hub, - size: 17, - ), + Icon(Icons.device_hub, size: 17), Icon(Icons.arrow_downward, size: 17), Icon(Icons.arrow_upward, size: 17), ], @@ -328,39 +325,42 @@ class _ServerDetailPageState extends State } Widget _buildNetSpeedItem(NetSpeed ns, String device) { + final width = (_media.size.width - 34 - 34) / 3; return Padding( padding: const EdgeInsets.symmetric(vertical: 3), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ SizedBox( - width: _media.size.width / 4, - child: Text(device, style: textSize11, textScaleFactor: 1.0)), - SizedBox( - width: _media.size.width / 4, - child: Text(ns.speedIn(device: device), - style: textSize11, - textAlign: TextAlign.center, - textScaleFactor: 1.0), + width: width, + child: Text( + device, + style: textSize11, + textScaleFactor: 1.0, + ), ), SizedBox( - width: _media.size.width / 4, - child: Text(ns.speedOut(device: device), - style: textSize11, - textAlign: TextAlign.right, - textScaleFactor: 1.0), + width: width, + child: Text( + '${ns.speedIn(device: device)}\n${ns.totalIn(device: device)}', + style: textSize11, + textAlign: TextAlign.center, + textScaleFactor: 0.87, + ), + ), + SizedBox( + width: width, + child: Text( + '${ns.speedOut(device: device)}\n${ns.totalOut(device: device)}', + style: textSize11, + textAlign: TextAlign.right, + textScaleFactor: 0.87, + ), ) ], ), ); } - static const ignorePath = [ - '/run', - '/sys', - '/dev/shm', - '/snap', - '/var/lib/docker', - '/dev/tty' - ]; + static const _ignorePath = ['udev', 'tmpfs', 'devtmpfs']; } diff --git a/lib/view/page/ssh.dart b/lib/view/page/ssh.dart index a03c8dd5..7126f6e0 100644 --- a/lib/view/page/ssh.dart +++ b/lib/view/page/ssh.dart @@ -6,6 +6,7 @@ import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:provider/provider.dart'; +import 'package:toolbox/generated/l10n.dart'; import 'package:xterm/xterm.dart'; import '../../core/utils/ui.dart'; @@ -35,8 +36,9 @@ class _SSHPageState extends State { final TerminalController _terminalController = TerminalController(); final ContextMenuController _menuController = ContextMenuController(); late TextStyle _menuTextStyle; + late S _s; - var isDark = false; + var _isDark = false; @override void initState() { @@ -47,9 +49,10 @@ class _SSHPageState extends State { @override void didChangeDependencies() { super.didChangeDependencies(); - isDark = isDarkMode(context); + _isDark = isDarkMode(context); _media = MediaQuery.of(context); _menuTextStyle = TextStyle(color: contentColor.resolve(context)); + _s = S.of(context); } @override @@ -78,15 +81,8 @@ class _SSHPageState extends State { session.write(utf8.encode(data) as Uint8List); }; - session.stdout - .cast>() - .transform(const Utf8Decoder()) - .listen(_terminal.write); - - session.stderr - .cast>() - .transform(const Utf8Decoder()) - .listen(_terminal.write); + _listen(session.stdout); + _listen(session.stderr); await session.done; if (mounted) { @@ -94,9 +90,16 @@ class _SSHPageState extends State { } } + void _listen(Stream stream) { + stream + .cast>() + .transform(const Utf8Decoder()) + .listen(_terminal.write); + } + @override Widget build(BuildContext context) { - final termTheme = isDark ? termDarkTheme : termLightTheme; + final termTheme = _isDark ? termDarkTheme : termLightTheme; return Scaffold( backgroundColor: termTheme.background, body: _buildBody(termTheme), @@ -118,7 +121,7 @@ class _SSHPageState extends State { deleteDetection: Platform.isIOS, onTapUp: _onTapUp, autofocus: true, - keyboardAppearance: isDark ? Brightness.dark : Brightness.light, + keyboardAppearance: _isDark ? Brightness.dark : Brightness.light, ), ); } @@ -170,7 +173,7 @@ class _SSHPageState extends State { final child = item.icon != null ? Icon( item.icon, - color: isDark ? Colors.white : Colors.black, + color: _isDark ? Colors.white : Colors.black, size: 17, ) : Text( @@ -296,7 +299,7 @@ class _SSHPageState extends State { children: [ TextButton( child: Text( - 'Copy', + _s.copy, style: _menuTextStyle, ), onPressed: () {