new: more battery data & fix: auto reload

This commit is contained in:
lollipopkit
2023-12-20 17:26:04 +08:00
parent 7283c968ae
commit 4a93b326db
26 changed files with 247 additions and 147 deletions

View File

@@ -586,7 +586,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 = 683; CURRENT_PROJECT_VERSION = 685;
DEVELOPMENT_TEAM = BA88US33G6; DEVELOPMENT_TEAM = BA88US33G6;
ENABLE_BITCODE = NO; ENABLE_BITCODE = NO;
INFOPLIST_FILE = "Runner/Info-$(CONFIGURATION).plist"; INFOPLIST_FILE = "Runner/Info-$(CONFIGURATION).plist";
@@ -596,7 +596,7 @@
"$(inherited)", "$(inherited)",
"@executable_path/Frameworks", "@executable_path/Frameworks",
); );
MARKETING_VERSION = 1.0.683; MARKETING_VERSION = 1.0.685;
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";
@@ -720,7 +720,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 = 683; CURRENT_PROJECT_VERSION = 685;
DEVELOPMENT_TEAM = BA88US33G6; DEVELOPMENT_TEAM = BA88US33G6;
ENABLE_BITCODE = NO; ENABLE_BITCODE = NO;
INFOPLIST_FILE = "Runner/Info-$(CONFIGURATION).plist"; INFOPLIST_FILE = "Runner/Info-$(CONFIGURATION).plist";
@@ -730,7 +730,7 @@
"$(inherited)", "$(inherited)",
"@executable_path/Frameworks", "@executable_path/Frameworks",
); );
MARKETING_VERSION = 1.0.683; MARKETING_VERSION = 1.0.685;
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";
@@ -748,7 +748,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 = 683; CURRENT_PROJECT_VERSION = 685;
DEVELOPMENT_TEAM = BA88US33G6; DEVELOPMENT_TEAM = BA88US33G6;
ENABLE_BITCODE = NO; ENABLE_BITCODE = NO;
INFOPLIST_FILE = "Runner/Info-$(CONFIGURATION).plist"; INFOPLIST_FILE = "Runner/Info-$(CONFIGURATION).plist";
@@ -758,7 +758,7 @@
"$(inherited)", "$(inherited)",
"@executable_path/Frameworks", "@executable_path/Frameworks",
); );
MARKETING_VERSION = 1.0.683; MARKETING_VERSION = 1.0.685;
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";
@@ -779,7 +779,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 = 683; CURRENT_PROJECT_VERSION = 685;
DEVELOPMENT_TEAM = BA88US33G6; DEVELOPMENT_TEAM = BA88US33G6;
GCC_C_LANGUAGE_STANDARD = gnu11; GCC_C_LANGUAGE_STANDARD = gnu11;
GENERATE_INFOPLIST_FILE = YES; GENERATE_INFOPLIST_FILE = YES;
@@ -792,7 +792,7 @@
"@executable_path/Frameworks", "@executable_path/Frameworks",
"@executable_path/../../Frameworks", "@executable_path/../../Frameworks",
); );
MARKETING_VERSION = 1.0.683; MARKETING_VERSION = 1.0.685;
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;
@@ -818,7 +818,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 = 683; CURRENT_PROJECT_VERSION = 685;
DEVELOPMENT_TEAM = BA88US33G6; DEVELOPMENT_TEAM = BA88US33G6;
GCC_C_LANGUAGE_STANDARD = gnu11; GCC_C_LANGUAGE_STANDARD = gnu11;
GENERATE_INFOPLIST_FILE = YES; GENERATE_INFOPLIST_FILE = YES;
@@ -831,7 +831,7 @@
"@executable_path/Frameworks", "@executable_path/Frameworks",
"@executable_path/../../Frameworks", "@executable_path/../../Frameworks",
); );
MARKETING_VERSION = 1.0.683; MARKETING_VERSION = 1.0.685;
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)";
@@ -854,7 +854,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 = 683; CURRENT_PROJECT_VERSION = 685;
DEVELOPMENT_TEAM = BA88US33G6; DEVELOPMENT_TEAM = BA88US33G6;
GCC_C_LANGUAGE_STANDARD = gnu11; GCC_C_LANGUAGE_STANDARD = gnu11;
GENERATE_INFOPLIST_FILE = YES; GENERATE_INFOPLIST_FILE = YES;
@@ -867,7 +867,7 @@
"@executable_path/Frameworks", "@executable_path/Frameworks",
"@executable_path/../../Frameworks", "@executable_path/../../Frameworks",
); );
MARKETING_VERSION = 1.0.683; MARKETING_VERSION = 1.0.685;
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)";
@@ -890,7 +890,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 = 683; CURRENT_PROJECT_VERSION = 685;
DEVELOPMENT_ASSET_PATHS = ""; DEVELOPMENT_ASSET_PATHS = "";
DEVELOPMENT_TEAM = BA88US33G6; DEVELOPMENT_TEAM = BA88US33G6;
ENABLE_PREVIEWS = YES; ENABLE_PREVIEWS = YES;
@@ -902,7 +902,7 @@
"$(inherited)", "$(inherited)",
"@executable_path/Frameworks", "@executable_path/Frameworks",
); );
MARKETING_VERSION = 1.0.683; MARKETING_VERSION = 1.0.685;
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.WatchEnd; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.WatchEnd;
@@ -931,7 +931,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 = 683; CURRENT_PROJECT_VERSION = 685;
DEVELOPMENT_ASSET_PATHS = ""; DEVELOPMENT_ASSET_PATHS = "";
DEVELOPMENT_TEAM = BA88US33G6; DEVELOPMENT_TEAM = BA88US33G6;
ENABLE_PREVIEWS = YES; ENABLE_PREVIEWS = YES;
@@ -943,7 +943,7 @@
"$(inherited)", "$(inherited)",
"@executable_path/Frameworks", "@executable_path/Frameworks",
); );
MARKETING_VERSION = 1.0.683; MARKETING_VERSION = 1.0.685;
MTL_FAST_MATH = YES; MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.WatchEnd; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.WatchEnd;
PRODUCT_NAME = ServerBox; PRODUCT_NAME = ServerBox;
@@ -969,7 +969,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 = 683; CURRENT_PROJECT_VERSION = 685;
DEVELOPMENT_ASSET_PATHS = ""; DEVELOPMENT_ASSET_PATHS = "";
DEVELOPMENT_TEAM = BA88US33G6; DEVELOPMENT_TEAM = BA88US33G6;
ENABLE_PREVIEWS = YES; ENABLE_PREVIEWS = YES;
@@ -981,7 +981,7 @@
"$(inherited)", "$(inherited)",
"@executable_path/Frameworks", "@executable_path/Frameworks",
); );
MARKETING_VERSION = 1.0.683; MARKETING_VERSION = 1.0.685;
MTL_FAST_MATH = YES; MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.WatchEnd; PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.WatchEnd;
PRODUCT_NAME = ServerBox; PRODUCT_NAME = ServerBox;

View File

@@ -220,7 +220,7 @@ const _statusCmds = [
'cat /sys/class/thermal/thermal_zone*/temp', 'cat /sys/class/thermal/thermal_zone*/temp',
'hostname', 'hostname',
'cat /proc/diskstats', 'cat /proc/diskstats',
'cat /sys/class/power_supply/*/capacity', 'cat /sys/class/power_supply/*/uevent',
'nvidia-smi -q -x', 'nvidia-smi -q -x',
]; ];

View File

@@ -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 = <String, String>{};
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<Battery> parse(String raw) {
final lines = raw.split('\n');
final batteries = <Battery>[];
final oneBatLines = <String>[];
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;
}
}

View File

@@ -1,5 +1,6 @@
import 'package:dartssh2/dartssh2.dart'; import 'package:dartssh2/dartssh2.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/battery.dart';
import 'package:toolbox/data/model/server/conn.dart'; import 'package:toolbox/data/model/server/conn.dart';
import 'package:toolbox/data/model/server/cpu.dart'; import 'package:toolbox/data/model/server/cpu.dart';
import 'package:toolbox/data/model/server/disk.dart'; import 'package:toolbox/data/model/server/disk.dart';
@@ -38,10 +39,6 @@ class Server implements TagPickable {
bool get canViewDetails => state == ServerState.finished; bool get canViewDetails => state == ServerState.finished;
String get id => spi.id; String get id => spi.id;
bool get isBusy => status._isBusy;
set isBusy(bool value) => status._isBusy = value;
} }
class ServerStatus { class ServerStatus {
@@ -56,11 +53,9 @@ class ServerStatus {
String? err; String? err;
DiskIO diskIO; DiskIO diskIO;
List<NvidiaSmiItem>? nvidia; List<NvidiaSmiItem>? nvidia;
final List<Battery> batteries = [];
final Map<StatusCmdType, String> more = {}; final Map<StatusCmdType, String> more = {};
/// Whether is connectting, parsing and etc.
bool _isBusy = false;
ServerStatus({ ServerStatus({
required this.cpu, required this.cpu,
required this.mem, required this.mem,

View File

@@ -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/nvdia.dart';
import 'package:toolbox/data/model/server/server.dart'; import 'package:toolbox/data/model/server/server.dart';
import 'package:toolbox/data/model/server/system.dart'; import 'package:toolbox/data/model/server/system.dart';
@@ -129,8 +130,10 @@ Future<ServerStatus> _getLinuxStatus(ServerStatusUpdateReq req) async {
try { try {
final battery = StatusCmdType.battery.find(segments); final battery = StatusCmdType.battery.find(segments);
if (battery.isNotEmpty && !battery.contains('/sys/class/power_supply')) { final batteries = Batteries.parse(battery);
req.ss.more[StatusCmdType.battery] = battery; req.ss.batteries.clear();
if (batteries.isNotEmpty) {
req.ss.batteries.addAll(batteries);
} }
} catch (e, s) { } catch (e, s) {
Loggers.parse.warning(e, s); Loggers.parse.warning(e, s);

View File

@@ -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; bool get isAutoRefreshOn => _timer != null;
void setDisconnected() { void setDisconnected() {
@@ -248,15 +238,6 @@ class ServerProvider extends ChangeNotifier {
void _setServerState(Server s, ServerState ss) { void _setServerState(Server s, ServerState ss) {
s.state = 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(); notifyListeners();
} }
@@ -275,11 +256,6 @@ class ServerProvider extends ChangeNotifier {
s.status.err = null; 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)) { if (s.needGenClient || (s.client?.isClosed ?? true)) {
_setServerState(s, ServerState.connecting); _setServerState(s, ServerState.connecting);

View File

@@ -2,9 +2,9 @@
class BuildData { class BuildData {
static const String name = "ServerBox"; 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 engine = "3.16.4";
static const String buildAt = "2023-12-19 15:25:07"; static const String buildAt = "2023-12-20 14:09:17";
static const int modifications = 1; static const int modifications = 4;
static const int script = 32; static const int script = 32;
} }

View File

@@ -5,14 +5,15 @@ import 'package:toolbox/data/model/ssh/virtual_key.dart';
abstract final class Defaults { abstract final class Defaults {
// default server details page cards order // default server details page cards order
static const detailCardOrder = [ static const detailCardOrder = [
'uptime', 'sys',
'cpu', 'cpu',
'mem', 'mem',
'swap', 'swap',
'gpu', 'gpu',
'disk', 'disk',
'net', 'net',
'temp' 'temp',
'battery'
]; ];
static const diskIgnorePath = [ static const diskIgnorePath = [

View File

@@ -3,28 +3,27 @@ import 'package:flutter/material.dart';
abstract final class UIs { abstract final class UIs {
/// Font style /// Font style
static const textSize9Grey = TextStyle(color: Colors.grey, fontSize: 9); static const text11 = TextStyle(fontSize: 11);
static const textSize11 = TextStyle(fontSize: 11); static const text11Bold = TextStyle(
static const textSize11Bold = TextStyle(
fontSize: 11, fontSize: 11,
fontWeight: FontWeight.w500, 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 text12 = TextStyle(fontSize: 12);
static const text12Bold = TextStyle( static const text12Bold = TextStyle(
fontSize: 12, fontSize: 12,
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
); );
static const text12Grey = TextStyle(color: Colors.grey, fontSize: 12); static const text12Grey = TextStyle(color: Colors.grey, fontSize: 12);
static const textSize13 = TextStyle(fontSize: 13); static const text13 = TextStyle(fontSize: 13);
static const textSize13Bold = TextStyle( static const text13Bold = TextStyle(
fontSize: 13, fontSize: 13,
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
); );
static const textSize13Grey = TextStyle(color: Colors.grey, fontSize: 13); static const text13Grey = TextStyle(color: Colors.grey, fontSize: 13);
static const textSize15 = TextStyle(fontSize: 15); static const text15 = TextStyle(fontSize: 15);
static const textSize18 = TextStyle(fontSize: 18); static const text18 = TextStyle(fontSize: 18);
static const textSize27 = TextStyle(fontSize: 27); static const text27 = TextStyle(fontSize: 27);
static const textGrey = TextStyle(color: Colors.grey); static const textGrey = TextStyle(color: Colors.grey);
static const textRed = TextStyle(color: Colors.red); static const textRed = TextStyle(color: Colors.red);

View File

@@ -33,7 +33,7 @@ class BackupPage extends StatelessWidget {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
appBar: CustomAppBar( appBar: CustomAppBar(
title: Text(l10n.backupAndRestore, style: UIs.textSize18), title: Text(l10n.backupAndRestore, style: UIs.text18),
), ),
body: _buildBody(context), body: _buildBody(context),
); );

View File

@@ -349,7 +349,7 @@ class _DockerManagePageState extends State<DockerManagePage> {
title: Text(item.image), title: Text(item.image),
subtitle: Text( subtitle: Text(
'${item.name} - ${item.status}', '${item.name} - ${item.status}',
style: UIs.textSize13Grey, style: UIs.text13Grey,
), ),
trailing: _buildMoreBtn(item), trailing: _buildMoreBtn(item),
); );

View File

@@ -245,7 +245,7 @@ class _FullScreenPageState extends State<FullScreenPage> with AfterLayoutMixin {
); );
return Text( return Text(
topRightStr, topRightStr,
style: UIs.textSize11Grey, style: UIs.text11Grey,
); );
} }

View File

@@ -200,7 +200,7 @@ class _HomePageState extends State<HomePage>
child: Text( child: Text(
'${BuildData.name}\n$_versionStr', '${BuildData.name}\n$_versionStr',
textAlign: TextAlign.center, textAlign: TextAlign.center,
style: UIs.textSize15, style: UIs.text15,
), ),
), ),
const SizedBox(height: 37), const SizedBox(height: 37),

View File

@@ -131,7 +131,7 @@ class _PingPageState extends State<PingPage>
), ),
subtitle: Text( subtitle: Text(
_buildPingSummary(result, unknown, ms), _buildPingSummary(result, unknown, ms),
style: UIs.textSize11, style: UIs.text11,
), ),
trailing: Text( trailing: Text(
'${l10n.pingAvg}${result.statistic?.avg?.toStringAsFixed(2) ?? l10n.unknown} $ms', '${l10n.pingAvg}${result.statistic?.avg?.toStringAsFixed(2) ?? l10n.unknown} $ms',

View File

@@ -113,7 +113,7 @@ class _PrivateKeyEditPageState extends State<PrivateKeyEditPage> {
) )
]; ];
return CustomAppBar( return CustomAppBar(
title: Text(l10n.edit, style: UIs.textSize18), title: Text(l10n.edit, style: UIs.text18),
actions: widget.pki == null ? null : actions, actions: widget.pki == null ? null : actions,
); );
} }

View File

@@ -30,7 +30,7 @@ class _PrivateKeyListState extends State<PrivateKeysListPage>
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
appBar: CustomAppBar( appBar: CustomAppBar(
title: Text(l10n.privateKey, style: UIs.textSize18), title: Text(l10n.privateKey, style: UIs.text18),
), ),
body: _buildBody(), body: _buildBody(),
floatingActionButton: FloatingActionButton( floatingActionButton: FloatingActionButton(

View File

@@ -6,6 +6,7 @@ import 'package:toolbox/core/extension/context/locale.dart';
import 'package:toolbox/core/extension/order.dart'; import 'package:toolbox/core/extension/order.dart';
import 'package:toolbox/core/extension/status_cmd_type.dart'; import 'package:toolbox/core/extension/status_cmd_type.dart';
import 'package:toolbox/core/extension/widget.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/cpu.dart';
import 'package:toolbox/data/model/server/disk.dart'; import 'package:toolbox/data/model/server/disk.dart';
import 'package:toolbox/data/model/server/net_speed.dart'; import 'package:toolbox/data/model/server/net_speed.dart';
@@ -53,6 +54,7 @@ class _ServerDetailPageState extends State<ServerDetailPage>
_buildDiskView, _buildDiskView,
_buildNetView, _buildNetView,
_buildTemperature, _buildTemperature,
_buildBatteries,
], ],
); );
@@ -89,7 +91,7 @@ class _ServerDetailPageState extends State<ServerDetailPage>
final buildFuncs = !Stores.setting.moveOutServerTabFuncBtns.fetch(); final buildFuncs = !Stores.setting.moveOutServerTabFuncBtns.fetch();
return Scaffold( return Scaffold(
appBar: CustomAppBar( appBar: CustomAppBar(
title: Text(si.spi.name, style: UIs.textSize18), title: Text(si.spi.name, style: UIs.text18),
actions: [ actions: [
IconButton( IconButton(
icon: const Icon(Icons.edit), icon: const Icon(Icons.edit),
@@ -135,8 +137,8 @@ class _ServerDetailPageState extends State<ServerDetailPage>
(e) => Row( (e) => Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
Text(e.key.i18n, style: UIs.textSize13), Text(e.key.i18n, style: UIs.text13),
Text(e.value, style: UIs.textSize13Grey) Text(e.value, style: UIs.text13Grey)
], ],
).padding(const EdgeInsets.symmetric(vertical: 2)), ).padding(const EdgeInsets.symmetric(vertical: 2)),
) )
@@ -168,7 +170,7 @@ class _ServerDetailPageState extends State<ServerDetailPage>
child: _buildAnimatedText( child: _buildAnimatedText(
ValueKey(percent), ValueKey(percent),
'$percent%', '$percent%',
UIs.textSize27, UIs.text27,
), ),
), ),
childrenPadding: const EdgeInsets.symmetric(vertical: 13), childrenPadding: const EdgeInsets.symmetric(vertical: 13),
@@ -248,12 +250,12 @@ class _ServerDetailPageState extends State<ServerDetailPage>
_buildAnimatedText( _buildAnimatedText(
ValueKey(usedStr), ValueKey(usedStr),
'$usedStr%', '$usedStr%',
UIs.textSize27, UIs.text27,
), ),
UIs.width7, UIs.width7,
Text( Text(
'of ${(ss.mem.total * 1024).convertBytes}', 'of ${(ss.mem.total * 1024).convertBytes}',
style: UIs.textSize13Grey, style: UIs.text13Grey,
) )
], ],
), ),
@@ -290,11 +292,11 @@ class _ServerDetailPageState extends State<ServerDetailPage>
children: [ children: [
Row( Row(
children: [ children: [
Text('${used.toStringAsFixed(0)}%', style: UIs.textSize27), Text('${used.toStringAsFixed(0)}%', style: UIs.text27),
UIs.width7, UIs.width7,
Text( Text(
'of ${(ss.swap.total * 1024).convertBytes} ', 'of ${(ss.swap.total * 1024).convertBytes} ',
style: UIs.textSize13Grey, style: UIs.text13Grey,
) )
], ],
), ),
@@ -330,7 +332,7 @@ class _ServerDetailPageState extends State<ServerDetailPage>
children.addAll(processes.map((e) => _buildGpuProcessItem(e))); children.addAll(processes.map((e) => _buildGpuProcessItem(e)));
} }
return ListTile( return ListTile(
title: Text(item.name, style: UIs.textSize13), title: Text(item.name, style: UIs.text13),
subtitle: Text( subtitle: Text(
'${item.power} - ${item.temp} °C\n${mem.used} / ${mem.total} ${mem.unit} - ${item.fanSpeed} RPM', '${item.power} - ${item.temp} °C\n${mem.used} / ${mem.total} ${mem.unit} - ${item.fanSpeed} RPM',
style: UIs.text12Grey, style: UIs.text12Grey,
@@ -483,7 +485,7 @@ class _ServerDetailPageState extends State<ServerDetailPage>
backgroundColor: DynamicColors.progress.resolve(context), backgroundColor: DynamicColors.progress.resolve(context),
color: primaryColor, color: primaryColor,
), ),
Text('${disk.usedPercent}%', style: UIs.textSize13Grey) Text('${disk.usedPercent}%', style: UIs.text13Grey)
], ],
), ),
) )
@@ -498,7 +500,7 @@ class _ServerDetailPageState extends State<ServerDetailPage>
children.add(Center( children.add(Center(
child: Text( child: Text(
l10n.noInterface, l10n.noInterface,
style: UIs.textSize13Grey, style: UIs.text13Grey,
), ),
)); ));
} else { } else {
@@ -531,7 +533,7 @@ class _ServerDetailPageState extends State<ServerDetailPage>
UIs.width7, UIs.width7,
Text( Text(
_netSortType.name, _netSortType.name,
style: UIs.textSize13Grey, style: UIs.text13Grey,
), ),
], ],
), ),
@@ -576,7 +578,7 @@ class _ServerDetailPageState extends State<ServerDetailPage>
child: Text( child: Text(
'${ns.speedOut(device: device)}\n${ns.speedIn(device: device)}', '${ns.speedOut(device: device)}\n${ns.speedIn(device: device)}',
textAlign: TextAlign.end, textAlign: TextAlign.end,
style: UIs.textSize13Grey, style: UIs.text13Grey,
), ),
) )
], ],
@@ -607,8 +609,43 @@ class _ServerDetailPageState extends State<ServerDetailPage>
child: Row( child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
Text(key, style: UIs.textSize15), Text(key, style: UIs.text15),
Text('${val?.toStringAsFixed(1)}°C', style: UIs.textSize13Grey), 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),
], ],
), ),
); );

View File

@@ -109,7 +109,7 @@ class _ServerEditPageState extends State<ServerEditPage> {
PreferredSizeWidget _buildAppBar() { PreferredSizeWidget _buildAppBar() {
return CustomAppBar( return CustomAppBar(
title: Text(l10n.edit, style: UIs.textSize18), title: Text(l10n.edit, style: UIs.text18),
actions: widget.spi != null actions: widget.spi != null
? [ ? [
IconButton( IconButton(

View File

@@ -358,7 +358,7 @@ class _ServerPageState extends State<ServerPage>
children: [ children: [
Text( Text(
spi.name, spi.name,
style: UIs.textSize13Bold, style: UIs.text13Bold,
), ),
const Icon( const Icon(
Icons.keyboard_arrow_right, Icons.keyboard_arrow_right,
@@ -390,13 +390,13 @@ class _ServerPageState extends State<ServerPage>
onTap: () => _showFailReason(ss), onTap: () => _showFailReason(ss),
child: Text( child: Text(
l10n.viewErr, l10n.viewErr,
style: UIs.textSize13Grey, style: UIs.text13Grey,
), ),
); );
} }
return Text( return Text(
topRightStr, topRightStr,
style: UIs.textSize13Grey, style: UIs.text13Grey,
); );
} }
@@ -500,25 +500,20 @@ class _ServerPageState extends State<ServerPage>
if (percent <= 0) percent = 0.01; if (percent <= 0) percent = 0.01;
if (percent >= 100) percent = 99.9; if (percent >= 100) percent = 99.9;
return Stack( return Stack(
alignment: Alignment.center,
children: [ children: [
Center( CircleChart(
child: CircleChart( progressColor: primaryColor,
progressColor: primaryColor, progressNumber: percent,
progressNumber: percent, maxNumber: 100,
maxNumber: 100, width: 57,
width: 57, height: 57,
height: 57, animationDuration: const Duration(milliseconds: 777),
animationDuration: const Duration(milliseconds: 777),
),
), ),
Positioned.fill( Text(
child: Center( '${percent.toStringAsFixed(1)}%',
child: Text( textAlign: TextAlign.center,
'${percent.toStringAsFixed(1)}%', style: const TextStyle(fontSize: 12.7),
textAlign: TextAlign.center,
style: UIs.textSize13,
),
),
), ),
], ],
); );

View File

@@ -151,7 +151,8 @@ class _SettingPageState extends State<SettingPage> {
_buildSFTP(), _buildSFTP(),
_buildTitle(l10n.editor), _buildTitle(l10n.editor),
_buildEditor(), _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. /// used as a status screen, so it's only available on mobile phone.
if (!isDesktop) _buildTitle(l10n.fullScreen), if (!isDesktop) _buildTitle(l10n.fullScreen),
if (!isDesktop) _buildFullScreen(), if (!isDesktop) _buildFullScreen(),
@@ -301,7 +302,7 @@ class _SettingPageState extends State<SettingPage> {
}, },
child: Text( child: Text(
'${_updateInterval.value} ${l10n.second}', '${_updateInterval.value} ${l10n.second}',
style: UIs.textSize15, style: UIs.text15,
), ),
), ),
), ),
@@ -455,7 +456,7 @@ class _SettingPageState extends State<SettingPage> {
}, },
child: Text( child: Text(
'${_maxRetryCount.value} ${l10n.times}', '${_maxRetryCount.value} ${l10n.times}',
style: UIs.textSize15, style: UIs.text15,
), ),
), ),
listenable: _maxRetryCount, listenable: _maxRetryCount,
@@ -504,7 +505,7 @@ class _SettingPageState extends State<SettingPage> {
}, },
child: Text( child: Text(
_buildThemeModeStr(_nightMode.value), _buildThemeModeStr(_nightMode.value),
style: UIs.textSize15, style: UIs.text15,
), ),
), ),
), ),
@@ -532,7 +533,7 @@ class _SettingPageState extends State<SettingPage> {
title: Text(l10n.font), title: Text(l10n.font),
trailing: Text( trailing: Text(
fontName ?? l10n.notSelected, fontName ?? l10n.notSelected,
style: UIs.textSize15, style: UIs.text15,
), ),
onTap: () { onTap: () {
context.showRoundDialog( context.showRoundDialog(
@@ -583,7 +584,7 @@ class _SettingPageState extends State<SettingPage> {
title: Text(l10n.fontSize), title: Text(l10n.fontSize),
trailing: Text( trailing: Text(
_termFontSize.value.toString(), _termFontSize.value.toString(),
style: UIs.textSize15, style: UIs.text15,
), ),
onTap: () => _showFontSizeDialog(_termFontSize, _setting.termFontSize), onTap: () => _showFontSizeDialog(_termFontSize, _setting.termFontSize),
), ),
@@ -655,7 +656,7 @@ class _SettingPageState extends State<SettingPage> {
}, },
child: Text( child: Text(
l10n.languageName, l10n.languageName,
style: UIs.textSize15, style: UIs.text15,
), ),
), ),
), ),
@@ -693,7 +694,7 @@ class _SettingPageState extends State<SettingPage> {
}, },
child: Text( child: Text(
_editorTheme.value, _editorTheme.value,
style: UIs.textSize15, style: UIs.text15,
), ),
), ),
), ),
@@ -726,7 +727,7 @@ class _SettingPageState extends State<SettingPage> {
}, },
child: Text( child: Text(
_editorDarkTheme.value, _editorDarkTheme.value,
style: UIs.textSize15, style: UIs.text15,
), ),
), ),
), ),
@@ -780,7 +781,7 @@ class _SettingPageState extends State<SettingPage> {
}, },
child: Text( child: Text(
degrees[_rotateQuarter.value], degrees[_rotateQuarter.value],
style: UIs.textSize15, style: UIs.text15,
), ),
), ),
), ),
@@ -828,7 +829,7 @@ class _SettingPageState extends State<SettingPage> {
}, },
child: Text( child: Text(
names[_keyboardType.value], names[_keyboardType.value],
style: UIs.textSize15, style: UIs.text15,
), ),
), ),
), ),
@@ -884,7 +885,7 @@ class _SettingPageState extends State<SettingPage> {
}, },
child: Text( child: Text(
_netViewType.value.toStr, _netViewType.value.toStr,
style: UIs.textSize15, style: UIs.text15,
), ),
), ),
), ),
@@ -946,7 +947,7 @@ class _SettingPageState extends State<SettingPage> {
listenable: _textScaler, listenable: _textScaler,
build: () => Text( build: () => Text(
_textScaler.value.toString(), _textScaler.value.toString(),
style: UIs.textSize15, style: UIs.text15,
), ),
), ),
onTap: () => context.showRoundDialog( onTap: () => context.showRoundDialog(
@@ -984,7 +985,7 @@ class _SettingPageState extends State<SettingPage> {
Widget _buildServerFuncBtns() { Widget _buildServerFuncBtns() {
return ListTile( return ListTile(
title: Text(l10n.location), title: Text(l10n.location),
subtitle: Text(l10n.moveOutServerFuncBtnsHelp, style: UIs.textSize13Grey), subtitle: Text(l10n.moveOutServerFuncBtnsHelp, style: UIs.text13Grey),
trailing: StoreSwitch(prop: _setting.moveOutServerTabFuncBtns), trailing: StoreSwitch(prop: _setting.moveOutServerTabFuncBtns),
); );
} }
@@ -1018,7 +1019,7 @@ class _SettingPageState extends State<SettingPage> {
title: Text(l10n.fontSize), title: Text(l10n.fontSize),
trailing: Text( trailing: Text(
_editorFontSize.value.toString(), _editorFontSize.value.toString(),
style: UIs.textSize15, style: UIs.text15,
), ),
onTap: () => onTap: () =>
_showFontSizeDialog(_editorFontSize, _setting.editorFontSize), _showFontSizeDialog(_editorFontSize, _setting.editorFontSize),

View File

@@ -6,7 +6,7 @@ import 'package:toolbox/data/res/ui.dart';
import 'package:toolbox/view/widget/future_widget.dart'; import 'package:toolbox/view/widget/future_widget.dart';
import 'package:toolbox/view/widget/store_switch.dart'; import 'package:toolbox/view/widget/store_switch.dart';
class PlatformPublicSettings { abstract final class PlatformPublicSettings {
static Widget buildBioAuth() { static Widget buildBioAuth() {
return FutureWidget<bool>( return FutureWidget<bool>(
future: BioAuth.isAvail, future: BioAuth.isAvail,

View File

@@ -42,7 +42,7 @@ class _SnippetEditPageState extends State<SnippetEditPage>
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
appBar: CustomAppBar( appBar: CustomAppBar(
title: Text(l10n.edit, style: UIs.textSize18), title: Text(l10n.edit, style: UIs.text18),
actions: _buildAppBarActions(), actions: _buildAppBarActions(),
), ),
body: _buildBody(), body: _buildBody(),

View File

@@ -161,22 +161,22 @@ class _SftpPageState extends State<SftpPage> with AfterLayoutMixin {
Widget _buildAddBtn() { Widget _buildAddBtn() {
return IconButton( return IconButton(
onPressed: () => context.showRoundDialog( onPressed: () => context.showRoundDialog(
child: Column( child: Column(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: [ children: [
ListTile( ListTile(
leading: const Icon(Icons.folder), leading: const Icon(Icons.folder),
title: Text(l10n.createFolder), title: Text(l10n.createFolder),
onTap: _mkdir, onTap: _mkdir,
),
ListTile(
leading: const Icon(Icons.insert_drive_file),
title: Text(l10n.createFile),
onTap: _newFile,
),
],
), ),
), ListTile(
leading: const Icon(Icons.insert_drive_file),
title: Text(l10n.createFile),
onTap: _newFile,
),
],
),
),
icon: const Icon(Icons.add), icon: const Icon(Icons.add),
); );
} }

View File

@@ -27,7 +27,7 @@ class _SftpMissionPageState extends State<SftpMissionPage> {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
appBar: CustomAppBar( appBar: CustomAppBar(
title: Text(l10n.mission, style: UIs.textSize18), title: Text(l10n.mission, style: UIs.text18),
), ),
body: _buildBody(), body: _buildBody(),
); );

View File

@@ -29,7 +29,7 @@ class TagBtn extends StatelessWidget {
Text( Text(
content, content,
textAlign: TextAlign.center, textAlign: TextAlign.center,
style: isEnable ? UIs.textSize13 : UIs.textSize13Grey, style: isEnable ? UIs.text13 : UIs.text13Grey,
), ),
onTap: onTap, onTap: onTap,
); );
@@ -106,7 +106,7 @@ class _TagEditorState extends State<TagEditor> {
Text( Text(
'#$tag', '#$tag',
textAlign: TextAlign.center, textAlign: TextAlign.center,
style: isAdd ? UIs.textSize13Grey : UIs.textSize13, style: isAdd ? UIs.text13Grey : UIs.text13,
), ),
const SizedBox(width: 4.0), const SizedBox(width: 4.0),
Icon( Icon(

View File

@@ -14,12 +14,12 @@ class TwoLineText extends StatelessWidget {
children: [ children: [
Text( Text(
up, up,
style: UIs.textSize15, style: UIs.text15,
overflow: TextOverflow.ellipsis, overflow: TextOverflow.ellipsis,
), ),
Text( Text(
down, down,
style: UIs.textSize11, style: UIs.text11,
overflow: TextOverflow.ellipsis, overflow: TextOverflow.ellipsis,
) )
], ],