From 4a93b326db5cd8c84fa68e3b8413e7d37b081313 Mon Sep 17 00:00:00 2001 From: lollipopkit Date: Wed, 20 Dec 2023 17:26:04 +0800 Subject: [PATCH] new: more battery data & fix: auto reload --- ios/Runner.xcodeproj/project.pbxproj | 36 +++---- lib/data/model/app/shell_func.dart | 2 +- lib/data/model/server/battery.dart | 93 +++++++++++++++++++ lib/data/model/server/server.dart | 9 +- .../server/server_status_update_req.dart | 7 +- lib/data/provider/server.dart | 24 ----- lib/data/res/build_data.dart | 6 +- lib/data/res/default.dart | 5 +- lib/data/res/ui.dart | 19 ++-- lib/view/page/backup.dart | 2 +- lib/view/page/docker.dart | 2 +- lib/view/page/full_screen.dart | 2 +- lib/view/page/home.dart | 2 +- lib/view/page/ping.dart | 2 +- lib/view/page/private_key/edit.dart | 2 +- lib/view/page/private_key/list.dart | 2 +- lib/view/page/server/detail.dart | 67 ++++++++++--- lib/view/page/server/edit.dart | 2 +- lib/view/page/server/tab.dart | 35 +++---- lib/view/page/setting/entry.dart | 31 ++++--- lib/view/page/setting/platform_pub.dart | 2 +- lib/view/page/snippet/edit.dart | 2 +- lib/view/page/storage/sftp.dart | 30 +++--- lib/view/page/storage/sftp_mission.dart | 2 +- lib/view/widget/tag.dart | 4 +- lib/view/widget/two_line_text.dart | 4 +- 26 files changed, 247 insertions(+), 147 deletions(-) create mode 100644 lib/data/model/server/battery.dart diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index a0b5204a..16aff68c 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -586,7 +586,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; - CURRENT_PROJECT_VERSION = 683; + CURRENT_PROJECT_VERSION = 685; DEVELOPMENT_TEAM = BA88US33G6; ENABLE_BITCODE = NO; INFOPLIST_FILE = "Runner/Info-$(CONFIGURATION).plist"; @@ -596,7 +596,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.0.683; + MARKETING_VERSION = 1.0.685; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; @@ -720,7 +720,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; - CURRENT_PROJECT_VERSION = 683; + CURRENT_PROJECT_VERSION = 685; DEVELOPMENT_TEAM = BA88US33G6; ENABLE_BITCODE = NO; INFOPLIST_FILE = "Runner/Info-$(CONFIGURATION).plist"; @@ -730,7 +730,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.0.683; + MARKETING_VERSION = 1.0.685; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; @@ -748,7 +748,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; - CURRENT_PROJECT_VERSION = 683; + CURRENT_PROJECT_VERSION = 685; DEVELOPMENT_TEAM = BA88US33G6; ENABLE_BITCODE = NO; INFOPLIST_FILE = "Runner/Info-$(CONFIGURATION).plist"; @@ -758,7 +758,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.0.683; + MARKETING_VERSION = 1.0.685; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; @@ -779,7 +779,7 @@ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 683; + CURRENT_PROJECT_VERSION = 685; DEVELOPMENT_TEAM = BA88US33G6; GCC_C_LANGUAGE_STANDARD = gnu11; GENERATE_INFOPLIST_FILE = YES; @@ -792,7 +792,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 1.0.683; + MARKETING_VERSION = 1.0.685; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.StatusWidget; @@ -818,7 +818,7 @@ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 683; + CURRENT_PROJECT_VERSION = 685; DEVELOPMENT_TEAM = BA88US33G6; GCC_C_LANGUAGE_STANDARD = gnu11; GENERATE_INFOPLIST_FILE = YES; @@ -831,7 +831,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 1.0.683; + MARKETING_VERSION = 1.0.685; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.StatusWidget; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -854,7 +854,7 @@ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 683; + CURRENT_PROJECT_VERSION = 685; DEVELOPMENT_TEAM = BA88US33G6; GCC_C_LANGUAGE_STANDARD = gnu11; GENERATE_INFOPLIST_FILE = YES; @@ -867,7 +867,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 1.0.683; + MARKETING_VERSION = 1.0.685; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.StatusWidget; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -890,7 +890,7 @@ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 683; + CURRENT_PROJECT_VERSION = 685; DEVELOPMENT_ASSET_PATHS = ""; DEVELOPMENT_TEAM = BA88US33G6; ENABLE_PREVIEWS = YES; @@ -902,7 +902,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.0.683; + MARKETING_VERSION = 1.0.685; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.WatchEnd; @@ -931,7 +931,7 @@ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 683; + CURRENT_PROJECT_VERSION = 685; DEVELOPMENT_ASSET_PATHS = ""; DEVELOPMENT_TEAM = BA88US33G6; ENABLE_PREVIEWS = YES; @@ -943,7 +943,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.0.683; + MARKETING_VERSION = 1.0.685; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.WatchEnd; PRODUCT_NAME = ServerBox; @@ -969,7 +969,7 @@ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 683; + CURRENT_PROJECT_VERSION = 685; DEVELOPMENT_ASSET_PATHS = ""; DEVELOPMENT_TEAM = BA88US33G6; ENABLE_PREVIEWS = YES; @@ -981,7 +981,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.0.683; + MARKETING_VERSION = 1.0.685; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.WatchEnd; PRODUCT_NAME = ServerBox; diff --git a/lib/data/model/app/shell_func.dart b/lib/data/model/app/shell_func.dart index 4ab1f816..b9bb8099 100644 --- a/lib/data/model/app/shell_func.dart +++ b/lib/data/model/app/shell_func.dart @@ -220,7 +220,7 @@ const _statusCmds = [ 'cat /sys/class/thermal/thermal_zone*/temp', 'hostname', 'cat /proc/diskstats', - 'cat /sys/class/power_supply/*/capacity', + 'cat /sys/class/power_supply/*/uevent', 'nvidia-smi -q -x', ]; diff --git a/lib/data/model/server/battery.dart b/lib/data/model/server/battery.dart new file mode 100644 index 00000000..630f0828 --- /dev/null +++ b/lib/data/model/server/battery.dart @@ -0,0 +1,93 @@ +import 'package:toolbox/data/res/logger.dart'; + +/// raw dat from server: +/// ```text +/// POWER_SUPPLY_NAME=hidpp_battery_0 +/// POWER_SUPPLY_TYPE=Battery +/// POWER_SUPPLY_ONLINE=1 +/// POWER_SUPPLY_STATUS=Discharging +/// POWER_SUPPLY_SCOPE=Device +/// POWER_SUPPLY_MODEL_NAME=MX Anywhere 3 +/// POWER_SUPPLY_MANUFACTURER=Logitech +/// POWER_SUPPLY_SERIAL_NUMBER=0f-fc-43-f8 +/// POWER_SUPPLY_CAPACITY=35 +/// ``` +class Battery { + final int? percent; + final BatteryStatus status; + final String? name; + final int? cycle; + final int? powerNow; + + const Battery({ + required this.status, + this.percent, + this.name, + this.cycle, + this.powerNow, + }); + + factory Battery.fromRaw(String raw) { + final lines = raw.split('\n'); + final map = {}; + for (final line in lines) { + final parts = line.split('='); + if (parts.length != 2) continue; + map[parts[0]] = parts[1]; + } + + final capacity = map['POWER_SUPPLY_CAPACITY']; // 30% + final cycle = map['POWER_SUPPLY_CYCLE_COUNT']; // 30 + final powerNow = map['POWER_SUPPLY_POWER_NOW']; // 30W + + return Battery( + percent: capacity == null ? null : int.tryParse(capacity), + status: BatteryStatus.parse(map['POWER_SUPPLY_STATUS']), + name: map['POWER_SUPPLY_MODEL_NAME'], + cycle: cycle == null ? null : int.tryParse(cycle), + powerNow: powerNow == null ? null : int.tryParse(powerNow), + ); + } +} + +enum BatteryStatus { + charging, + discharging, + full, + unknown, + ; + + static BatteryStatus parse(String? status) { + switch (status) { + case 'Charging': + return BatteryStatus.charging; + case 'Discharging': + return BatteryStatus.discharging; + case 'Full': + return BatteryStatus.full; + default: + return BatteryStatus.unknown; + } + } +} + +abstract final class Batteries { + static List parse(String raw) { + final lines = raw.split('\n'); + final batteries = []; + final oneBatLines = []; + for (final line in lines) { + if (line.isEmpty) { + try { + batteries.add(Battery.fromRaw(oneBatLines.join('\n'))); + } catch (e, s) { + Loggers.parse.warning(e, s); + } + oneBatLines.clear(); + } else { + oneBatLines.add(line); + } + } + return batteries; + } +} diff --git a/lib/data/model/server/server.dart b/lib/data/model/server/server.dart index 10bac765..80ac636f 100644 --- a/lib/data/model/server/server.dart +++ b/lib/data/model/server/server.dart @@ -1,5 +1,6 @@ import 'package:dartssh2/dartssh2.dart'; import 'package:toolbox/data/model/app/shell_func.dart'; +import 'package:toolbox/data/model/server/battery.dart'; import 'package:toolbox/data/model/server/conn.dart'; import 'package:toolbox/data/model/server/cpu.dart'; import 'package:toolbox/data/model/server/disk.dart'; @@ -38,10 +39,6 @@ class Server implements TagPickable { bool get canViewDetails => state == ServerState.finished; String get id => spi.id; - - bool get isBusy => status._isBusy; - - set isBusy(bool value) => status._isBusy = value; } class ServerStatus { @@ -56,11 +53,9 @@ class ServerStatus { String? err; DiskIO diskIO; List? nvidia; + final List batteries = []; final Map more = {}; - /// Whether is connectting, parsing and etc. - bool _isBusy = false; - ServerStatus({ required this.cpu, required this.mem, diff --git a/lib/data/model/server/server_status_update_req.dart b/lib/data/model/server/server_status_update_req.dart index 0ec45281..9e71eeeb 100644 --- a/lib/data/model/server/server_status_update_req.dart +++ b/lib/data/model/server/server_status_update_req.dart @@ -1,3 +1,4 @@ +import 'package:toolbox/data/model/server/battery.dart'; import 'package:toolbox/data/model/server/nvdia.dart'; import 'package:toolbox/data/model/server/server.dart'; import 'package:toolbox/data/model/server/system.dart'; @@ -129,8 +130,10 @@ Future _getLinuxStatus(ServerStatusUpdateReq req) async { try { final battery = StatusCmdType.battery.find(segments); - if (battery.isNotEmpty && !battery.contains('/sys/class/power_supply')) { - req.ss.more[StatusCmdType.battery] = battery; + final batteries = Batteries.parse(battery); + req.ss.batteries.clear(); + if (batteries.isNotEmpty) { + req.ss.batteries.addAll(batteries); } } catch (e, s) { Loggers.parse.warning(e, s); diff --git a/lib/data/provider/server.dart b/lib/data/provider/server.dart index d01b238b..040b4d75 100644 --- a/lib/data/provider/server.dart +++ b/lib/data/provider/server.dart @@ -155,16 +155,6 @@ class ServerProvider extends ChangeNotifier { } } - void setNotBusy([String? id]) { - if (id == null) { - for (final s in _servers.values) { - s.isBusy = false; - } - return; - } - _servers[id]?.isBusy = false; - } - bool get isAutoRefreshOn => _timer != null; void setDisconnected() { @@ -248,15 +238,6 @@ class ServerProvider extends ChangeNotifier { void _setServerState(Server s, ServerState ss) { s.state = ss; - - /// Only set [Sever.isBusy] to false when err occurs or finished. - switch (ss) { - case ServerState.failed || ServerState.finished: - s.isBusy = false; - break; - default: - break; - } notifyListeners(); } @@ -275,11 +256,6 @@ class ServerProvider extends ChangeNotifier { s.status.err = null; - /// If busy, it may be because of network reasons that the last request - /// has not been completed, and the request should not be made again at this time. - if (s.isBusy) return; - s.isBusy = true; - if (s.needGenClient || (s.client?.isClosed ?? true)) { _setServerState(s, ServerState.connecting); diff --git a/lib/data/res/build_data.dart b/lib/data/res/build_data.dart index 03a26791..032f4b37 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 = 683; + static const int build = 685; static const String engine = "3.16.4"; - static const String buildAt = "2023-12-19 15:25:07"; - static const int modifications = 1; + static const String buildAt = "2023-12-20 14:09:17"; + static const int modifications = 4; static const int script = 32; } diff --git a/lib/data/res/default.dart b/lib/data/res/default.dart index 8ef79d17..7ad73ad4 100644 --- a/lib/data/res/default.dart +++ b/lib/data/res/default.dart @@ -5,14 +5,15 @@ import 'package:toolbox/data/model/ssh/virtual_key.dart'; abstract final class Defaults { // default server details page cards order static const detailCardOrder = [ - 'uptime', + 'sys', 'cpu', 'mem', 'swap', 'gpu', 'disk', 'net', - 'temp' + 'temp', + 'battery' ]; static const diskIgnorePath = [ diff --git a/lib/data/res/ui.dart b/lib/data/res/ui.dart index c542ee53..ecb54a68 100644 --- a/lib/data/res/ui.dart +++ b/lib/data/res/ui.dart @@ -3,28 +3,27 @@ import 'package:flutter/material.dart'; abstract final class UIs { /// Font style - static const textSize9Grey = TextStyle(color: Colors.grey, fontSize: 9); - static const textSize11 = TextStyle(fontSize: 11); - static const textSize11Bold = TextStyle( + static const text11 = TextStyle(fontSize: 11); + static const text11Bold = TextStyle( fontSize: 11, fontWeight: FontWeight.w500, ); - static const textSize11Grey = TextStyle(color: Colors.grey, fontSize: 11); + static const text11Grey = TextStyle(color: Colors.grey, fontSize: 11); static const text12 = TextStyle(fontSize: 12); static const text12Bold = TextStyle( fontSize: 12, fontWeight: FontWeight.bold, ); static const text12Grey = TextStyle(color: Colors.grey, fontSize: 12); - static const textSize13 = TextStyle(fontSize: 13); - static const textSize13Bold = TextStyle( + static const text13 = TextStyle(fontSize: 13); + static const text13Bold = TextStyle( fontSize: 13, fontWeight: FontWeight.bold, ); - static const textSize13Grey = TextStyle(color: Colors.grey, fontSize: 13); - static const textSize15 = TextStyle(fontSize: 15); - static const textSize18 = TextStyle(fontSize: 18); - static const textSize27 = TextStyle(fontSize: 27); + static const text13Grey = TextStyle(color: Colors.grey, fontSize: 13); + static const text15 = TextStyle(fontSize: 15); + static const text18 = TextStyle(fontSize: 18); + static const text27 = TextStyle(fontSize: 27); static const textGrey = TextStyle(color: Colors.grey); static const textRed = TextStyle(color: Colors.red); diff --git a/lib/view/page/backup.dart b/lib/view/page/backup.dart index 2086550e..028a873d 100644 --- a/lib/view/page/backup.dart +++ b/lib/view/page/backup.dart @@ -33,7 +33,7 @@ class BackupPage extends StatelessWidget { Widget build(BuildContext context) { return Scaffold( appBar: CustomAppBar( - title: Text(l10n.backupAndRestore, style: UIs.textSize18), + title: Text(l10n.backupAndRestore, style: UIs.text18), ), body: _buildBody(context), ); diff --git a/lib/view/page/docker.dart b/lib/view/page/docker.dart index 35e9a931..ff48640c 100644 --- a/lib/view/page/docker.dart +++ b/lib/view/page/docker.dart @@ -349,7 +349,7 @@ class _DockerManagePageState extends State { title: Text(item.image), subtitle: Text( '${item.name} - ${item.status}', - style: UIs.textSize13Grey, + style: UIs.text13Grey, ), trailing: _buildMoreBtn(item), ); diff --git a/lib/view/page/full_screen.dart b/lib/view/page/full_screen.dart index f9f582df..72c485d1 100644 --- a/lib/view/page/full_screen.dart +++ b/lib/view/page/full_screen.dart @@ -245,7 +245,7 @@ class _FullScreenPageState extends State with AfterLayoutMixin { ); return Text( topRightStr, - style: UIs.textSize11Grey, + style: UIs.text11Grey, ); } diff --git a/lib/view/page/home.dart b/lib/view/page/home.dart index 490edcc3..53aeceb5 100644 --- a/lib/view/page/home.dart +++ b/lib/view/page/home.dart @@ -200,7 +200,7 @@ class _HomePageState extends State child: Text( '${BuildData.name}\n$_versionStr', textAlign: TextAlign.center, - style: UIs.textSize15, + style: UIs.text15, ), ), const SizedBox(height: 37), diff --git a/lib/view/page/ping.dart b/lib/view/page/ping.dart index 59f3c3fb..a7f95aca 100644 --- a/lib/view/page/ping.dart +++ b/lib/view/page/ping.dart @@ -131,7 +131,7 @@ class _PingPageState extends State ), subtitle: Text( _buildPingSummary(result, unknown, ms), - style: UIs.textSize11, + style: UIs.text11, ), trailing: Text( '${l10n.pingAvg}${result.statistic?.avg?.toStringAsFixed(2) ?? l10n.unknown} $ms', diff --git a/lib/view/page/private_key/edit.dart b/lib/view/page/private_key/edit.dart index da0df174..ac20e9bb 100644 --- a/lib/view/page/private_key/edit.dart +++ b/lib/view/page/private_key/edit.dart @@ -113,7 +113,7 @@ class _PrivateKeyEditPageState extends State { ) ]; return CustomAppBar( - title: Text(l10n.edit, style: UIs.textSize18), + title: Text(l10n.edit, style: UIs.text18), actions: widget.pki == null ? null : actions, ); } diff --git a/lib/view/page/private_key/list.dart b/lib/view/page/private_key/list.dart index 0a072afd..8abbbeb2 100644 --- a/lib/view/page/private_key/list.dart +++ b/lib/view/page/private_key/list.dart @@ -30,7 +30,7 @@ class _PrivateKeyListState extends State Widget build(BuildContext context) { return Scaffold( appBar: CustomAppBar( - title: Text(l10n.privateKey, style: UIs.textSize18), + title: Text(l10n.privateKey, style: UIs.text18), ), body: _buildBody(), floatingActionButton: FloatingActionButton( diff --git a/lib/view/page/server/detail.dart b/lib/view/page/server/detail.dart index 583150e5..5a35bafa 100644 --- a/lib/view/page/server/detail.dart +++ b/lib/view/page/server/detail.dart @@ -6,6 +6,7 @@ import 'package:toolbox/core/extension/context/locale.dart'; import 'package:toolbox/core/extension/order.dart'; import 'package:toolbox/core/extension/status_cmd_type.dart'; import 'package:toolbox/core/extension/widget.dart'; +import 'package:toolbox/data/model/server/battery.dart'; import 'package:toolbox/data/model/server/cpu.dart'; import 'package:toolbox/data/model/server/disk.dart'; import 'package:toolbox/data/model/server/net_speed.dart'; @@ -53,6 +54,7 @@ class _ServerDetailPageState extends State _buildDiskView, _buildNetView, _buildTemperature, + _buildBatteries, ], ); @@ -89,7 +91,7 @@ class _ServerDetailPageState extends State final buildFuncs = !Stores.setting.moveOutServerTabFuncBtns.fetch(); return Scaffold( appBar: CustomAppBar( - title: Text(si.spi.name, style: UIs.textSize18), + title: Text(si.spi.name, style: UIs.text18), actions: [ IconButton( icon: const Icon(Icons.edit), @@ -135,8 +137,8 @@ class _ServerDetailPageState extends State (e) => Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - Text(e.key.i18n, style: UIs.textSize13), - Text(e.value, style: UIs.textSize13Grey) + Text(e.key.i18n, style: UIs.text13), + Text(e.value, style: UIs.text13Grey) ], ).padding(const EdgeInsets.symmetric(vertical: 2)), ) @@ -168,7 +170,7 @@ class _ServerDetailPageState extends State child: _buildAnimatedText( ValueKey(percent), '$percent%', - UIs.textSize27, + UIs.text27, ), ), childrenPadding: const EdgeInsets.symmetric(vertical: 13), @@ -248,12 +250,12 @@ class _ServerDetailPageState extends State _buildAnimatedText( ValueKey(usedStr), '$usedStr%', - UIs.textSize27, + UIs.text27, ), UIs.width7, Text( 'of ${(ss.mem.total * 1024).convertBytes}', - style: UIs.textSize13Grey, + style: UIs.text13Grey, ) ], ), @@ -290,11 +292,11 @@ class _ServerDetailPageState extends State children: [ Row( children: [ - Text('${used.toStringAsFixed(0)}%', style: UIs.textSize27), + Text('${used.toStringAsFixed(0)}%', style: UIs.text27), UIs.width7, Text( 'of ${(ss.swap.total * 1024).convertBytes} ', - style: UIs.textSize13Grey, + style: UIs.text13Grey, ) ], ), @@ -330,7 +332,7 @@ class _ServerDetailPageState extends State children.addAll(processes.map((e) => _buildGpuProcessItem(e))); } return ListTile( - title: Text(item.name, style: UIs.textSize13), + title: Text(item.name, style: UIs.text13), subtitle: Text( '${item.power} - ${item.temp} °C\n${mem.used} / ${mem.total} ${mem.unit} - ${item.fanSpeed} RPM', style: UIs.text12Grey, @@ -483,7 +485,7 @@ class _ServerDetailPageState extends State backgroundColor: DynamicColors.progress.resolve(context), color: primaryColor, ), - Text('${disk.usedPercent}%', style: UIs.textSize13Grey) + Text('${disk.usedPercent}%', style: UIs.text13Grey) ], ), ) @@ -498,7 +500,7 @@ class _ServerDetailPageState extends State children.add(Center( child: Text( l10n.noInterface, - style: UIs.textSize13Grey, + style: UIs.text13Grey, ), )); } else { @@ -531,7 +533,7 @@ class _ServerDetailPageState extends State UIs.width7, Text( _netSortType.name, - style: UIs.textSize13Grey, + style: UIs.text13Grey, ), ], ), @@ -576,7 +578,7 @@ class _ServerDetailPageState extends State child: Text( '↑ ${ns.speedOut(device: device)}\n↓ ${ns.speedIn(device: device)}', textAlign: TextAlign.end, - style: UIs.textSize13Grey, + style: UIs.text13Grey, ), ) ], @@ -607,8 +609,43 @@ class _ServerDetailPageState extends State child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - Text(key, style: UIs.textSize15), - Text('${val?.toStringAsFixed(1)}°C', style: UIs.textSize13Grey), + Text(key, style: UIs.text15), + Text('${val?.toStringAsFixed(1)}°C', style: UIs.text13Grey), + ], + ), + ); + } + + Widget _buildBatteries(ServerStatus ss) { + if (ss.batteries.isEmpty) { + return UIs.placeholder; + } + return CardX( + child: ExpandTile( + title: Text(l10n.battery), + leading: const Icon(Icons.battery_charging_full, size: 17), + childrenPadding: const EdgeInsets.only(bottom: 7), + children: ss.batteries.map(_buildBatteryItem).toList(), + ), + ); + } + + Widget _buildBatteryItem(Battery battery) { + return Padding( + padding: const EdgeInsets.symmetric(horizontal: 17, vertical: 5), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text('${battery.name}', style: UIs.text15), + Text('${battery.status.name} - ${battery.cycle} - ${battery.powerNow}', style: UIs.text13Grey), + ], + ), + Text('${battery.percent?.toStringAsFixed(0)}%', + style: UIs.text13Grey), ], ), ); diff --git a/lib/view/page/server/edit.dart b/lib/view/page/server/edit.dart index df7d0729..770a5997 100644 --- a/lib/view/page/server/edit.dart +++ b/lib/view/page/server/edit.dart @@ -109,7 +109,7 @@ class _ServerEditPageState extends State { PreferredSizeWidget _buildAppBar() { return CustomAppBar( - title: Text(l10n.edit, style: UIs.textSize18), + title: Text(l10n.edit, style: UIs.text18), actions: widget.spi != null ? [ IconButton( diff --git a/lib/view/page/server/tab.dart b/lib/view/page/server/tab.dart index bc6705e0..5d1c68b8 100644 --- a/lib/view/page/server/tab.dart +++ b/lib/view/page/server/tab.dart @@ -358,7 +358,7 @@ class _ServerPageState extends State children: [ Text( spi.name, - style: UIs.textSize13Bold, + style: UIs.text13Bold, ), const Icon( Icons.keyboard_arrow_right, @@ -390,13 +390,13 @@ class _ServerPageState extends State onTap: () => _showFailReason(ss), child: Text( l10n.viewErr, - style: UIs.textSize13Grey, + style: UIs.text13Grey, ), ); } return Text( topRightStr, - style: UIs.textSize13Grey, + style: UIs.text13Grey, ); } @@ -500,25 +500,20 @@ class _ServerPageState extends State if (percent <= 0) percent = 0.01; if (percent >= 100) percent = 99.9; return Stack( + alignment: Alignment.center, children: [ - Center( - child: CircleChart( - progressColor: primaryColor, - progressNumber: percent, - maxNumber: 100, - width: 57, - height: 57, - animationDuration: const Duration(milliseconds: 777), - ), + CircleChart( + progressColor: primaryColor, + progressNumber: percent, + maxNumber: 100, + width: 57, + height: 57, + animationDuration: const Duration(milliseconds: 777), ), - Positioned.fill( - child: Center( - child: Text( - '${percent.toStringAsFixed(1)}%', - textAlign: TextAlign.center, - style: UIs.textSize13, - ), - ), + Text( + '${percent.toStringAsFixed(1)}%', + textAlign: TextAlign.center, + style: const TextStyle(fontSize: 12.7), ), ], ); diff --git a/lib/view/page/setting/entry.dart b/lib/view/page/setting/entry.dart index df5a598a..020c6b83 100644 --- a/lib/view/page/setting/entry.dart +++ b/lib/view/page/setting/entry.dart @@ -151,7 +151,8 @@ class _SettingPageState extends State { _buildSFTP(), _buildTitle(l10n.editor), _buildEditor(), - /// Fullscreen Mode is designed for old mobile phone which can be + + /// Fullscreen Mode is designed for old mobile phone which can be /// used as a status screen, so it's only available on mobile phone. if (!isDesktop) _buildTitle(l10n.fullScreen), if (!isDesktop) _buildFullScreen(), @@ -301,7 +302,7 @@ class _SettingPageState extends State { }, child: Text( '${_updateInterval.value} ${l10n.second}', - style: UIs.textSize15, + style: UIs.text15, ), ), ), @@ -455,7 +456,7 @@ class _SettingPageState extends State { }, child: Text( '${_maxRetryCount.value} ${l10n.times}', - style: UIs.textSize15, + style: UIs.text15, ), ), listenable: _maxRetryCount, @@ -504,7 +505,7 @@ class _SettingPageState extends State { }, child: Text( _buildThemeModeStr(_nightMode.value), - style: UIs.textSize15, + style: UIs.text15, ), ), ), @@ -532,7 +533,7 @@ class _SettingPageState extends State { title: Text(l10n.font), trailing: Text( fontName ?? l10n.notSelected, - style: UIs.textSize15, + style: UIs.text15, ), onTap: () { context.showRoundDialog( @@ -583,7 +584,7 @@ class _SettingPageState extends State { title: Text(l10n.fontSize), trailing: Text( _termFontSize.value.toString(), - style: UIs.textSize15, + style: UIs.text15, ), onTap: () => _showFontSizeDialog(_termFontSize, _setting.termFontSize), ), @@ -655,7 +656,7 @@ class _SettingPageState extends State { }, child: Text( l10n.languageName, - style: UIs.textSize15, + style: UIs.text15, ), ), ), @@ -693,7 +694,7 @@ class _SettingPageState extends State { }, child: Text( _editorTheme.value, - style: UIs.textSize15, + style: UIs.text15, ), ), ), @@ -726,7 +727,7 @@ class _SettingPageState extends State { }, child: Text( _editorDarkTheme.value, - style: UIs.textSize15, + style: UIs.text15, ), ), ), @@ -780,7 +781,7 @@ class _SettingPageState extends State { }, child: Text( degrees[_rotateQuarter.value], - style: UIs.textSize15, + style: UIs.text15, ), ), ), @@ -828,7 +829,7 @@ class _SettingPageState extends State { }, child: Text( names[_keyboardType.value], - style: UIs.textSize15, + style: UIs.text15, ), ), ), @@ -884,7 +885,7 @@ class _SettingPageState extends State { }, child: Text( _netViewType.value.toStr, - style: UIs.textSize15, + style: UIs.text15, ), ), ), @@ -946,7 +947,7 @@ class _SettingPageState extends State { listenable: _textScaler, build: () => Text( _textScaler.value.toString(), - style: UIs.textSize15, + style: UIs.text15, ), ), onTap: () => context.showRoundDialog( @@ -984,7 +985,7 @@ class _SettingPageState extends State { Widget _buildServerFuncBtns() { return ListTile( title: Text(l10n.location), - subtitle: Text(l10n.moveOutServerFuncBtnsHelp, style: UIs.textSize13Grey), + subtitle: Text(l10n.moveOutServerFuncBtnsHelp, style: UIs.text13Grey), trailing: StoreSwitch(prop: _setting.moveOutServerTabFuncBtns), ); } @@ -1018,7 +1019,7 @@ class _SettingPageState extends State { title: Text(l10n.fontSize), trailing: Text( _editorFontSize.value.toString(), - style: UIs.textSize15, + style: UIs.text15, ), onTap: () => _showFontSizeDialog(_editorFontSize, _setting.editorFontSize), diff --git a/lib/view/page/setting/platform_pub.dart b/lib/view/page/setting/platform_pub.dart index 109a0979..302ee297 100644 --- a/lib/view/page/setting/platform_pub.dart +++ b/lib/view/page/setting/platform_pub.dart @@ -6,7 +6,7 @@ import 'package:toolbox/data/res/ui.dart'; import 'package:toolbox/view/widget/future_widget.dart'; import 'package:toolbox/view/widget/store_switch.dart'; -class PlatformPublicSettings { +abstract final class PlatformPublicSettings { static Widget buildBioAuth() { return FutureWidget( future: BioAuth.isAvail, diff --git a/lib/view/page/snippet/edit.dart b/lib/view/page/snippet/edit.dart index 36f494df..898ffe33 100644 --- a/lib/view/page/snippet/edit.dart +++ b/lib/view/page/snippet/edit.dart @@ -42,7 +42,7 @@ class _SnippetEditPageState extends State Widget build(BuildContext context) { return Scaffold( appBar: CustomAppBar( - title: Text(l10n.edit, style: UIs.textSize18), + title: Text(l10n.edit, style: UIs.text18), actions: _buildAppBarActions(), ), body: _buildBody(), diff --git a/lib/view/page/storage/sftp.dart b/lib/view/page/storage/sftp.dart index e8102f21..8f6c7ed7 100644 --- a/lib/view/page/storage/sftp.dart +++ b/lib/view/page/storage/sftp.dart @@ -161,22 +161,22 @@ class _SftpPageState extends State with AfterLayoutMixin { Widget _buildAddBtn() { return IconButton( onPressed: () => context.showRoundDialog( - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - ListTile( - leading: const Icon(Icons.folder), - title: Text(l10n.createFolder), - onTap: _mkdir, - ), - ListTile( - leading: const Icon(Icons.insert_drive_file), - title: Text(l10n.createFile), - onTap: _newFile, - ), - ], + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + ListTile( + leading: const Icon(Icons.folder), + title: Text(l10n.createFolder), + onTap: _mkdir, ), - ), + ListTile( + leading: const Icon(Icons.insert_drive_file), + title: Text(l10n.createFile), + onTap: _newFile, + ), + ], + ), + ), icon: const Icon(Icons.add), ); } diff --git a/lib/view/page/storage/sftp_mission.dart b/lib/view/page/storage/sftp_mission.dart index c0676edf..ce47ee3c 100644 --- a/lib/view/page/storage/sftp_mission.dart +++ b/lib/view/page/storage/sftp_mission.dart @@ -27,7 +27,7 @@ class _SftpMissionPageState extends State { Widget build(BuildContext context) { return Scaffold( appBar: CustomAppBar( - title: Text(l10n.mission, style: UIs.textSize18), + title: Text(l10n.mission, style: UIs.text18), ), body: _buildBody(), ); diff --git a/lib/view/widget/tag.dart b/lib/view/widget/tag.dart index d6f7c111..220cb782 100644 --- a/lib/view/widget/tag.dart +++ b/lib/view/widget/tag.dart @@ -29,7 +29,7 @@ class TagBtn extends StatelessWidget { Text( content, textAlign: TextAlign.center, - style: isEnable ? UIs.textSize13 : UIs.textSize13Grey, + style: isEnable ? UIs.text13 : UIs.text13Grey, ), onTap: onTap, ); @@ -106,7 +106,7 @@ class _TagEditorState extends State { Text( '#$tag', textAlign: TextAlign.center, - style: isAdd ? UIs.textSize13Grey : UIs.textSize13, + style: isAdd ? UIs.text13Grey : UIs.text13, ), const SizedBox(width: 4.0), Icon( diff --git a/lib/view/widget/two_line_text.dart b/lib/view/widget/two_line_text.dart index b0e963fb..91400c57 100644 --- a/lib/view/widget/two_line_text.dart +++ b/lib/view/widget/two_line_text.dart @@ -14,12 +14,12 @@ class TwoLineText extends StatelessWidget { children: [ Text( up, - style: UIs.textSize15, + style: UIs.text15, overflow: TextOverflow.ellipsis, ), Text( down, - style: UIs.textSize11, + style: UIs.text11, overflow: TextOverflow.ellipsis, ) ],