fix & opt.: prefer temperature dev

This commit is contained in:
lollipopkit
2024-04-21 01:04:43 +08:00
parent 23764f8c93
commit a0ea95b1c3
22 changed files with 152 additions and 206 deletions

View File

@@ -10,6 +10,8 @@ final class ServerCustom {
final String? pveAddr; final String? pveAddr;
@HiveField(2, defaultValue: false) @HiveField(2, defaultValue: false)
final bool pveIgnoreCert; final bool pveIgnoreCert;
@HiveField(3)
final String? preferTempDev;
/// {"title": "cmd"} /// {"title": "cmd"}
@HiveField(3) @HiveField(3)
@@ -20,6 +22,7 @@ final class ServerCustom {
this.pveAddr, this.pveAddr,
this.pveIgnoreCert = false, this.pveIgnoreCert = false,
this.cmds, this.cmds,
this.preferTempDev,
}); });
static ServerCustom fromJson(Map<String, dynamic> json) { static ServerCustom fromJson(Map<String, dynamic> json) {
@@ -27,11 +30,13 @@ final class ServerCustom {
final pveAddr = json["pveAddr"] as String?; final pveAddr = json["pveAddr"] as String?;
final pveIgnoreCert = json["pveIgnoreCert"] as bool; final pveIgnoreCert = json["pveIgnoreCert"] as bool;
final cmds = json["cmds"] as Map<String, dynamic>?; final cmds = json["cmds"] as Map<String, dynamic>?;
final preferTempDev = json["preferTempDev"] as String?;
return ServerCustom( return ServerCustom(
//temperature: temperature, //temperature: temperature,
pveAddr: pveAddr, pveAddr: pveAddr,
pveIgnoreCert: pveIgnoreCert, pveIgnoreCert: pveIgnoreCert,
cmds: cmds?.cast<String, String>(), cmds: cmds?.cast<String, String>(),
preferTempDev: preferTempDev,
); );
} }
@@ -48,6 +53,9 @@ final class ServerCustom {
if (cmds != null) { if (cmds != null) {
json["cmds"] = cmds; json["cmds"] = cmds;
} }
if (preferTempDev != null) {
json["preferTempDev"] = preferTempDev;
}
return json; return json;
} }
} }

View File

@@ -2,7 +2,6 @@ import 'dart:convert';
import 'package:toolbox/core/extension/listx.dart'; import 'package:toolbox/core/extension/listx.dart';
import 'package:toolbox/data/res/logger.dart'; import 'package:toolbox/data/res/logger.dart';
import 'package:toolbox/data/res/store.dart';
final class SensorAdaptor { final class SensorAdaptor {
final String raw; final String raw;
@@ -101,92 +100,4 @@ final class SensorItem {
} }
return items; return items;
} }
static double? findPreferTempVal(List<SensorItem> items) {
if (items.isEmpty) {
return null;
}
final preferTemperatureDevs = Stores.setting.preferTemperatureDevs.fetch();
if (preferTemperatureDevs.isNotEmpty) {
for (final key in preferTemperatureDevs) {
final item = items.firstWhereOrNull((e) => e.device == key);
if (item != null) {
return item.props.values.firstOrNull?.current;
}
}
}
return items.first.props.values.firstOrNull?.current;
}
static const sensorsRaw = '''
{
"coretemp-isa-0000":{
"Adapter": "ISA adapter",
"Package id 0":{
"temp1_input": 51.000,
"temp1_max": 105.000,
"temp1_crit": 105.000,
"temp1_crit_alarm": 0.000
},
"Core 0":{
"temp2_input": 40.000,
"temp2_max": 105.000,
"temp2_crit": 105.000,
"temp2_crit_alarm": 0.000
},
"Core 1":{
"temp3_input": 40.000,
"temp3_max": 105.000,
"temp3_crit": 105.000,
"temp3_crit_alarm": 0.000
},
"Core 2":{
"temp4_input": 40.000,
"temp4_max": 105.000,
"temp4_crit": 105.000,
"temp4_crit_alarm": 0.000
},
"Core 3":{
"temp5_input": 40.000,
"temp5_max": 105.000,
"temp5_crit": 105.000,
"temp5_crit_alarm": 0.000
}
},
"acpitz-acpi-0":{
"Adapter": "ACPI interface",
"temp1":{
"temp1_input": 27.800,
"temp1_crit": 119.000
}
},
"iwlwifi_1-virtual-0":{
"Adapter": "Virtual device",
"temp1":{
ERROR: Can't get value of subfeature temp1_input: Can't read
}
},
"nvme-pci-0400":{
"Adapter": "PCI adapter",
"Composite":{
"temp1_input": 35.850,
"temp1_max": 83.850,
"temp1_min": -273.150,
"temp1_crit": 84.850,
"temp1_alarm": 0.000
},
"Sensor 1":{
"temp2_input": 35.850,
"temp2_max": 65261.850,
"temp2_min": -273.150
},
"Sensor 2":{
"temp3_input": 37.850,
"temp3_max": 65261.850,
"temp3_min": -273.150
}
}
}
''';
} }

View File

@@ -1,5 +1,6 @@
import 'package:dartssh2/dartssh2.dart'; import 'package:dartssh2/dartssh2.dart';
import 'package:toolbox/core/extension/context/locale.dart'; import 'package:toolbox/core/extension/context/locale.dart';
import 'package:toolbox/core/extension/listx.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/battery.dart';
import 'package:toolbox/data/model/server/conn.dart'; import 'package:toolbox/data/model/server/conn.dart';

View File

@@ -1,28 +1,42 @@
part of 'server.dart'; part of 'server.dart';
extension ServerX on Server { extension ServerX on Server {
String get topRightStr { String getTopRightStr(ServerPrivateInfo spi) {
switch (state) { switch (state) {
case ServerState.disconnected: case ServerState.disconnected:
return l10n.disconnected; return l10n.disconnected;
case ServerState.finished: case ServerState.finished:
// Highest priority of temperature display
final cmdTemp = status.customCmds['server_card_top_right']; final cmdTemp = status.customCmds['server_card_top_right'];
final temp = status.temps.first;
final sensorTemp = SensorItem.findPreferTempVal(status.sensors);
final temperatureVal = () { final temperatureVal = () {
// Second priority
final preferTempDev = spi.custom?.preferTempDev;
if (preferTempDev != null) {
final preferTemp = status.sensors
.firstWhereOrNull(
(e) => e.device == preferTempDev,
)
?.props
.values
.firstOrNull
?.current;
if (preferTemp != null) return preferTemp;
}
// Last priority
final temp = status.temps.first;
if (temp != null) { if (temp != null) {
return temp; return temp;
} }
if (sensorTemp != null) {
return sensorTemp;
}
return null; return null;
}(); }();
final tempVal = temperatureVal != null
? '${temperatureVal.toStringAsFixed(1)}°C'
: null;
final upTime = status.more[StatusCmdType.uptime]; final upTime = status.more[StatusCmdType.uptime];
final items = [tempVal ?? cmdTemp, upTime]; final items = [
cmdTemp ??
(temperatureVal != null
? '${temperatureVal.toStringAsFixed(1)}°C'
: null),
upTime
];
final str = items.where((e) => e != null && e.isNotEmpty).join(' | '); final str = items.where((e) => e != null && e.isNotEmpty).join(' | ');
if (str.isEmpty) return l10n.noResult; if (str.isEmpty) return l10n.noResult;
return str; return str;

View File

@@ -1,5 +1,3 @@
import 'package:toolbox/data/res/store.dart';
class Temperatures { class Temperatures {
final Map<String, double> _map = {}; final Map<String, double> _map = {};
@@ -37,14 +35,6 @@ class Temperatures {
if (_map.isEmpty) { if (_map.isEmpty) {
return null; return null;
} }
final preferTemperatureDevs = Stores.setting.preferTemperatureDevs.fetch();
if (preferTemperatureDevs.isNotEmpty) {
for (final key in preferTemperatureDevs) {
if (_map.containsKey(key)) {
return _map[key];
}
}
}
for (final key in _cpuTemp) { for (final key in _cpuTemp) {
if (_map.containsKey(key)) { if (_map.containsKey(key)) {
return _map[key]; return _map[key];

View File

@@ -225,13 +225,6 @@ class SettingStore extends PersistentStore {
/// Auto refresh container status /// Auto refresh container status
late final contaienrAutoRefresh = property('contaienrAutoRefresh', true); late final contaienrAutoRefresh = property('contaienrAutoRefresh', true);
/// eg:
/// Available devices: ['iwlwifi','x86pkg_temp']
/// Prefer list: ['x86pkg_temp','example']
/// Result: use x86pkg_temp's temperature as the temperature
late final preferTemperatureDevs =
listProperty('preferTemperatureDevs', <String>[]);
/// Use double column servers page on Desktop /// Use double column servers page on Desktop
late final doubleColumnServersPage = property( late final doubleColumnServersPage = property(
'doubleColumnServersPage', 'doubleColumnServersPage',

View File

@@ -68,6 +68,7 @@
"delete": "Löschen", "delete": "Löschen",
"deleteScripts": "Gleichzeitiges Löschen von Server-Skripten", "deleteScripts": "Gleichzeitiges Löschen von Server-Skripten",
"deleteServers": "Batch-Löschung von Servern", "deleteServers": "Batch-Löschung von Servern",
"deviceName": "Gerätename",
"dirEmpty": "Stelle sicher, dass der Ordner leer ist.", "dirEmpty": "Stelle sicher, dass der Ordner leer ist.",
"disabled": "Behinderte", "disabled": "Behinderte",
"disconnected": "Disconnected", "disconnected": "Disconnected",
@@ -206,8 +207,6 @@
"plzEnterHost": "Bitte Host eingeben.", "plzEnterHost": "Bitte Host eingeben.",
"plzSelectKey": "Wähle einen Key.", "plzSelectKey": "Wähle einen Key.",
"port": "Port", "port": "Port",
"preferTemperatureDeviceList": "Liste mit Priorität für die Anzeige der Temperatur",
"preferTemperatureDeviceListTip": "Zum Beispiel: Geräte, die die Anzeige der Temperatur unterstützen, sind ['a', 'b'], diese Einstellung ist ['b', 'c'], daher wird die Temperatur des Geräts b angezeigt",
"preview": "Vorschau", "preview": "Vorschau",
"primaryColorSeed": "Farbschema", "primaryColorSeed": "Farbschema",
"privateKey": "Private Key", "privateKey": "Private Key",

View File

@@ -68,6 +68,7 @@
"delete": "Delete", "delete": "Delete",
"deleteScripts": "Delete server scripts at the same time", "deleteScripts": "Delete server scripts at the same time",
"deleteServers": "Batch delete servers", "deleteServers": "Batch delete servers",
"deviceName": "Device name",
"dirEmpty": "Make sure dir is empty.", "dirEmpty": "Make sure dir is empty.",
"disabled": "Disabled", "disabled": "Disabled",
"disconnected": "Disconnected", "disconnected": "Disconnected",
@@ -206,8 +207,6 @@
"plzEnterHost": "Please enter host.", "plzEnterHost": "Please enter host.",
"plzSelectKey": "Please select a key.", "plzSelectKey": "Please select a key.",
"port": "Port", "port": "Port",
"preferTemperatureDeviceList": "List prioritizing the display of temperature",
"preferTemperatureDeviceListTip": "For example: Devices supporting temperature display include ['a', 'b'], this configuration is ['b', 'c'], so display the temperature of device b",
"preview": "Preview", "preview": "Preview",
"primaryColorSeed": "Primary color seed", "primaryColorSeed": "Primary color seed",
"privateKey": "Private Key", "privateKey": "Private Key",

View File

@@ -68,6 +68,7 @@
"delete": "Eliminar", "delete": "Eliminar",
"deleteScripts": "Eliminar scripts del servidor simultáneamente", "deleteScripts": "Eliminar scripts del servidor simultáneamente",
"deleteServers": "Eliminar servidores en lote", "deleteServers": "Eliminar servidores en lote",
"deviceName": "Nombre del dispositivo",
"dirEmpty": "Asegúrate de que el directorio esté vacío", "dirEmpty": "Asegúrate de que el directorio esté vacío",
"disabled": "Deshabilitado", "disabled": "Deshabilitado",
"disconnected": "Desconectado", "disconnected": "Desconectado",
@@ -206,8 +207,6 @@
"plzEnterHost": "Por favor, introduce el host", "plzEnterHost": "Por favor, introduce el host",
"plzSelectKey": "Por favor, selecciona una llave privada", "plzSelectKey": "Por favor, selecciona una llave privada",
"port": "Puerto", "port": "Puerto",
"preferTemperatureDeviceList": "Lista de dispositivos con preferencia de temperatura",
"preferTemperatureDeviceListTip": "Por ejemplo: si los dispositivos que soportan mostrar temperatura son ['a', 'b'], y esta configuración es ['b', 'c'], entonces se mostrará la temperatura del dispositivo 'b'",
"preview": "Vista previa", "preview": "Vista previa",
"primaryColorSeed": "Semilla de color primario", "primaryColorSeed": "Semilla de color primario",
"privateKey": "Llave privada", "privateKey": "Llave privada",

View File

@@ -68,6 +68,7 @@
"delete": "Supprimer", "delete": "Supprimer",
"deleteScripts": "Supprimer également les scripts du serveur", "deleteScripts": "Supprimer également les scripts du serveur",
"deleteServers": "Suppression par lot de serveurs", "deleteServers": "Suppression par lot de serveurs",
"deviceName": "Nom de l'appareil",
"dirEmpty": "Assurez-vous que le répertoire est vide.", "dirEmpty": "Assurez-vous que le répertoire est vide.",
"disabled": "Désactivé", "disabled": "Désactivé",
"disconnected": "Déconnecté", "disconnected": "Déconnecté",
@@ -206,8 +207,6 @@
"plzEnterHost": "Veuillez saisir l'hôte.", "plzEnterHost": "Veuillez saisir l'hôte.",
"plzSelectKey": "Veuillez sélectionner une clé.", "plzSelectKey": "Veuillez sélectionner une clé.",
"port": "Port", "port": "Port",
"preferTemperatureDeviceList": "Liste d'affichage prioritaire de la température",
"preferTemperatureDeviceListTip": "Par exemple : Les appareils prenant en charge l'affichage de la température sont ['a', 'b'], cette configuration est ['b', 'c'], donc afficher la température de l'appareil b",
"preview": "Aperçu", "preview": "Aperçu",
"primaryColorSeed": "Graine de couleur primaire", "primaryColorSeed": "Graine de couleur primaire",
"privateKey": "Clé privée", "privateKey": "Clé privée",

View File

@@ -68,6 +68,7 @@
"delete": "Menghapus", "delete": "Menghapus",
"deleteScripts": "Menghapus skrip server secara bersamaan", "deleteScripts": "Menghapus skrip server secara bersamaan",
"deleteServers": "Penghapusan server secara batch", "deleteServers": "Penghapusan server secara batch",
"deviceName": "Nama perangkat",
"dirEmpty": "Pastikan dir kosong.", "dirEmpty": "Pastikan dir kosong.",
"disabled": "Dengan disabilitas", "disabled": "Dengan disabilitas",
"disconnected": "Terputus", "disconnected": "Terputus",
@@ -206,8 +207,6 @@
"plzEnterHost": "Harap masukkan host.", "plzEnterHost": "Harap masukkan host.",
"plzSelectKey": "Pilih kunci.", "plzSelectKey": "Pilih kunci.",
"port": "Port", "port": "Port",
"preferTemperatureDeviceList": "Daftar prioritas tampilan suhu",
"preferTemperatureDeviceListTip": "Contohnya: Perangkat yang mendukung tampilan suhu adalah ['a', 'b'], pengaturan ini adalah ['b', 'c'], maka tampilkan suhu perangkat b",
"preview": "Pratinjau", "preview": "Pratinjau",
"primaryColorSeed": "Warna utama", "primaryColorSeed": "Warna utama",
"privateKey": "Kunci Pribadi", "privateKey": "Kunci Pribadi",

View File

@@ -68,6 +68,7 @@
"delete": "削除", "delete": "削除",
"deleteScripts": "サーバースクリプトも削除", "deleteScripts": "サーバースクリプトも削除",
"deleteServers": "サーバーを一括削除", "deleteServers": "サーバーを一括削除",
"deviceName": "デバイス名",
"dirEmpty": "フォルダーが空であることを確認してください", "dirEmpty": "フォルダーが空であることを確認してください",
"disabled": "無効", "disabled": "無効",
"disconnected": "接続が切断されました", "disconnected": "接続が切断されました",
@@ -206,8 +207,6 @@
"plzEnterHost": "ホストを入力してください", "plzEnterHost": "ホストを入力してください",
"plzSelectKey": "プライベートキーを選択してください", "plzSelectKey": "プライベートキーを選択してください",
"port": "ポート", "port": "ポート",
"preferTemperatureDeviceList": "温度表示を優先するデバイスリスト",
"preferTemperatureDeviceListTip": "例:温度表示をサポートするデバイスが['a','b']である場合、この設定が['b','c']であれば、デバイスbの温度を表示します",
"preview": "プレビュー", "preview": "プレビュー",
"primaryColorSeed": "プライマリーカラーシード", "primaryColorSeed": "プライマリーカラーシード",
"privateKey": "プライベートキー", "privateKey": "プライベートキー",

View File

@@ -68,6 +68,7 @@
"delete": "Verwijderen", "delete": "Verwijderen",
"deleteScripts": "Verwijder tegelijkertijd serverscripts", "deleteScripts": "Verwijder tegelijkertijd serverscripts",
"deleteServers": "Servers batchgewijs verwijderen", "deleteServers": "Servers batchgewijs verwijderen",
"deviceName": "Apparaatnaam",
"dirEmpty": "Zorg ervoor dat de map leeg is.", "dirEmpty": "Zorg ervoor dat de map leeg is.",
"disabled": "Uitgeschakeld", "disabled": "Uitgeschakeld",
"disconnected": "Verbroken", "disconnected": "Verbroken",
@@ -205,8 +206,6 @@
"plzEnterHost": "Voer host in a.u.b.", "plzEnterHost": "Voer host in a.u.b.",
"plzSelectKey": "Selecteer a.u.b. een sleutel.", "plzSelectKey": "Selecteer a.u.b. een sleutel.",
"port": "Poort", "port": "Poort",
"preferTemperatureDeviceList": "Lijst met voorkeursweergave van temperatuur",
"preferTemperatureDeviceListTip": "Bijvoorbeeld: Apparaten die temperatuurweergave ondersteunen zijn ['a', 'b'], deze configuratie is ['b', 'c'], dus de temperatuur van apparaat b weergeven",
"preview": "Voorbeeld", "preview": "Voorbeeld",
"primaryColorSeed": "Basis kleurzaad", "primaryColorSeed": "Basis kleurzaad",
"privateKey": "Privésleutel", "privateKey": "Privésleutel",

View File

@@ -68,6 +68,7 @@
"delete": "Excluir", "delete": "Excluir",
"deleteScripts": "Excluir scripts do servidor simultaneamente", "deleteScripts": "Excluir scripts do servidor simultaneamente",
"deleteServers": "Excluir servidores em lote", "deleteServers": "Excluir servidores em lote",
"deviceName": "Nome do dispositivo",
"dirEmpty": "Certifique-se de que a pasta está vazia", "dirEmpty": "Certifique-se de que a pasta está vazia",
"disabled": "Desativado", "disabled": "Desativado",
"disconnected": "Desconectado", "disconnected": "Desconectado",
@@ -206,8 +207,6 @@
"plzEnterHost": "Por favor, insira o host", "plzEnterHost": "Por favor, insira o host",
"plzSelectKey": "Por favor, selecione uma chave privada", "plzSelectKey": "Por favor, selecione uma chave privada",
"port": "Porta", "port": "Porta",
"preferTemperatureDeviceList": "Dispositivos preferenciais para exibir temperatura",
"preferTemperatureDeviceListTip": "Por exemplo: dispositivos que suportam exibição de temperatura são ['a','b'], esta configuração é ['b','c'], então mostrará a temperatura do dispositivo b",
"preview": "Pré-visualização", "preview": "Pré-visualização",
"primaryColorSeed": "Semente da cor primária", "primaryColorSeed": "Semente da cor primária",
"privateKey": "Chave privada", "privateKey": "Chave privada",

View File

@@ -68,6 +68,7 @@
"delete": "удалить", "delete": "удалить",
"deleteScripts": "удалить скрипты с сервера", "deleteScripts": "удалить скрипты с сервера",
"deleteServers": "удалить серверы пакетно", "deleteServers": "удалить серверы пакетно",
"deviceName": "Название устройства",
"dirEmpty": "Пожалуйста, убедитесь, что папка пуста", "dirEmpty": "Пожалуйста, убедитесь, что папка пуста",
"disabled": "отключено", "disabled": "отключено",
"disconnected": "отключено", "disconnected": "отключено",
@@ -206,8 +207,6 @@
"plzEnterHost": "Пожалуйста, введите хост", "plzEnterHost": "Пожалуйста, введите хост",
"plzSelectKey": "Пожалуйста, выберите ключ", "plzSelectKey": "Пожалуйста, выберите ключ",
"port": "порт", "port": "порт",
"preferTemperatureDeviceList": "список устройств с приоритетным отображением температуры",
"preferTemperatureDeviceListTip": "Например: если устройства, поддерживающие отображение температуры, включают ['a', 'b'], а этот параметр установлен на ['b', 'c'], то будет отображаться температура устройства b",
"preview": "предпросмотр", "preview": "предпросмотр",
"primaryColorSeed": "основной цветовой тон", "primaryColorSeed": "основной цветовой тон",
"privateKey": "приватный ключ", "privateKey": "приватный ключ",

View File

@@ -68,6 +68,7 @@
"delete": "删除", "delete": "删除",
"deleteScripts": "同时删除服务器脚本", "deleteScripts": "同时删除服务器脚本",
"deleteServers": "批量删除服务器", "deleteServers": "批量删除服务器",
"deviceName": "设备名",
"dirEmpty": "请确保文件夹为空", "dirEmpty": "请确保文件夹为空",
"disabled": "已禁用", "disabled": "已禁用",
"disconnected": "连接断开", "disconnected": "连接断开",
@@ -206,8 +207,6 @@
"plzEnterHost": "请输入主机", "plzEnterHost": "请输入主机",
"plzSelectKey": "请选择私钥", "plzSelectKey": "请选择私钥",
"port": "端口", "port": "端口",
"preferTemperatureDeviceList": "优先显示温度的列表",
"preferTemperatureDeviceListTip": "例如:设备支持显示温度的设备有['a','b'],此设置为['b','c']则显示设备b的温度",
"preview": "预览", "preview": "预览",
"primaryColorSeed": "主题色种子", "primaryColorSeed": "主题色种子",
"privateKey": "私钥", "privateKey": "私钥",

View File

@@ -68,6 +68,7 @@
"delete": "刪除", "delete": "刪除",
"deleteScripts": "同時刪除服務器腳本", "deleteScripts": "同時刪除服務器腳本",
"deleteServers": "批量刪除服務器", "deleteServers": "批量刪除服務器",
"deviceName": "設備名",
"dirEmpty": "請確保文件夾為空", "dirEmpty": "請確保文件夾為空",
"disabled": "已禁用", "disabled": "已禁用",
"disconnected": "連接斷開", "disconnected": "連接斷開",
@@ -206,8 +207,6 @@
"plzEnterHost": "請輸入主機", "plzEnterHost": "請輸入主機",
"plzSelectKey": "請選擇私鑰", "plzSelectKey": "請選擇私鑰",
"port": "端口", "port": "端口",
"preferTemperatureDeviceList": "優先顯示溫度的列表",
"preferTemperatureDeviceListTip": "例如:支持顯示溫度的設備有['a', 'b'],此設置為['b', 'c']則顯示設備b的溫度",
"preview": "預覽", "preview": "預覽",
"primaryColorSeed": "主要色調種子", "primaryColorSeed": "主要色調種子",
"privateKey": "私鑰", "privateKey": "私鑰",

View File

@@ -16,7 +16,6 @@ import 'package:toolbox/data/res/provider.dart';
import 'package:toolbox/view/widget/expand_tile.dart'; import 'package:toolbox/view/widget/expand_tile.dart';
import '../../../core/route.dart'; import '../../../core/route.dart';
import '../../../data/model/server/private_key_info.dart';
import '../../../data/model/server/server_private_info.dart'; import '../../../data/model/server/server_private_info.dart';
import '../../../data/provider/private_key.dart'; import '../../../data/provider/private_key.dart';
import '../../../data/res/ui.dart'; import '../../../data/res/ui.dart';
@@ -43,6 +42,7 @@ class _ServerEditPageState extends State<ServerEditPage> {
final _passwordController = TextEditingController(); final _passwordController = TextEditingController();
final _pveAddrCtrl = TextEditingController(); final _pveAddrCtrl = TextEditingController();
final _customCmdCtrl = TextEditingController(); final _customCmdCtrl = TextEditingController();
final _preferTempDevCtrl = TextEditingController();
final _nameFocus = FocusNode(); final _nameFocus = FocusNode();
final _ipFocus = FocusNode(); final _ipFocus = FocusNode();
@@ -95,6 +95,7 @@ class _ServerEditPageState extends State<ServerEditPage> {
_customCmdCtrl.text = encoded; _customCmdCtrl.text = encoded;
} }
} catch (_) {} } catch (_) {}
_preferTempDevCtrl.text = custom.preferTempDev ?? '';
} }
} }
} }
@@ -113,6 +114,9 @@ class _ServerEditPageState extends State<ServerEditPage> {
_alterUrlFocus.dispose(); _alterUrlFocus.dispose();
_portFocus.dispose(); _portFocus.dispose();
_usernameFocus.dispose(); _usernameFocus.dispose();
_pveAddrCtrl.dispose();
_customCmdCtrl.dispose();
_preferTempDevCtrl.dispose();
} }
@override @override
@@ -319,7 +323,7 @@ class _ServerEditPageState extends State<ServerEditPage> {
final tiles = List<Widget>.generate(key.pkis.length, (index) { final tiles = List<Widget>.generate(key.pkis.length, (index) {
final e = key.pkis[index]; final e = key.pkis[index];
return ListTile( return ListTile(
contentPadding: EdgeInsets.zero, contentPadding: const EdgeInsets.symmetric(horizontal: 17),
leading: Text( leading: Text(
'#${index + 1}', '#${index + 1}',
style: const TextStyle(fontWeight: FontWeight.bold, fontSize: 15), style: const TextStyle(fontWeight: FontWeight.bold, fontSize: 15),
@@ -330,25 +334,29 @@ class _ServerEditPageState extends State<ServerEditPage> {
textAlign: TextAlign.start, textAlign: TextAlign.start,
style: UIs.textGrey, style: UIs.textGrey,
), ),
trailing: _buildRadio(index, e), trailing: Radio<int>(
value: index,
groupValue: _keyIdx.value,
onChanged: (value) => _keyIdx.value = value,
),
onTap: () => _keyIdx.value = index,
); );
}); });
tiles.add( tiles.add(
ListTile( ListTile(
title: Text(l10n.addPrivateKey), title: Text(l10n.addPrivateKey),
contentPadding: EdgeInsets.zero, contentPadding: const EdgeInsets.symmetric(horizontal: 17),
trailing: IconButton( trailing: IconButton(
icon: const Icon(Icons.add), icon: const Icon(Icons.add),
onPressed: () => AppRoute.keyEdit().go(context), onPressed: () {},
), ),
onTap: () => AppRoute.keyEdit().go(context),
), ),
); );
return CardX( return CardX(
child: Padding( child: ListenableBuilder(
padding: const EdgeInsets.symmetric(horizontal: 17), listenable: _keyIdx,
child: Column( builder: (_, __) => Column(children: tiles),
children: tiles,
),
), ),
); );
}, },
@@ -359,7 +367,6 @@ class _ServerEditPageState extends State<ServerEditPage> {
return ExpandTile( return ExpandTile(
title: Text(l10n.more), title: Text(l10n.more),
children: [ children: [
UIs.height7,
const Text('PVE', style: UIs.text13Grey), const Text('PVE', style: UIs.text13Grey),
UIs.height7, UIs.height7,
Input( Input(
@@ -406,6 +413,16 @@ class _ServerEditPageState extends State<ServerEditPage> {
trailing: const Icon(Icons.open_in_new, size: 17), trailing: const Icon(Icons.open_in_new, size: 17),
onTap: () => openUrl(l10n.customCmdDocUrl), onTap: () => openUrl(l10n.customCmdDocUrl),
).card, ).card,
UIs.height7,
Text(l10n.temperature, style: UIs.text13Grey),
UIs.height7,
Input(
controller: _preferTempDevCtrl,
type: TextInputType.text,
label: l10n.deviceName,
icon: MingCute.low_temperature_line,
hint: 'nvme-pci-0400',
),
], ],
); );
} }
@@ -417,19 +434,6 @@ class _ServerEditPageState extends State<ServerEditPage> {
); );
} }
Widget _buildRadio(int index, PrivateKeyInfo pki) {
return ListenableBuilder(
listenable: _keyIdx,
builder: (_, __) => Radio<int>(
value: index,
groupValue: _keyIdx.value,
onChanged: (value) {
_keyIdx.value = value;
},
),
);
}
Widget _buildJumpServer() { Widget _buildJumpServer() {
return ListenableBuilder( return ListenableBuilder(
listenable: _jumpServer, listenable: _jumpServer,
@@ -446,16 +450,16 @@ class _ServerEditPageState extends State<ServerEditPage> {
value: e.spi.id, value: e.spi.id,
onChanged: (val) => _jumpServer.value = val, onChanged: (val) => _jumpServer.value = val,
), ),
onTap: () { onTap: () => _jumpServer.value = e.spi.id,
_jumpServer.value = e.spi.id; contentPadding: const EdgeInsets.symmetric(horizontal: 17),
},
), ),
) )
.toList(); .toList();
children.add(ListTile( children.add(ListTile(
title: Text(l10n.clear), title: Text(l10n.clear),
trailing: const Icon(Icons.clear), trailing: IconButton(onPressed: () {}, icon: const Icon(Icons.clear)),
onTap: () => _jumpServer.value = null, onTap: () => _jumpServer.value = null,
contentPadding: const EdgeInsets.symmetric(horizontal: 17),
)); ));
return CardX( return CardX(
child: ExpandTile( child: ExpandTile(
@@ -513,11 +517,11 @@ class _ServerEditPageState extends State<ServerEditPage> {
return null; return null;
} }
}(); }();
final pveAddr = _pveAddrCtrl.text.selfIfNotNullEmpty;
final custom = ServerCustom( final custom = ServerCustom(
pveAddr: pveAddr, pveAddr: _pveAddrCtrl.text.selfIfNotNullEmpty,
pveIgnoreCert: _pveIgnoreCert.value, pveIgnoreCert: _pveIgnoreCert.value,
cmds: customCmds, cmds: customCmds,
preferTempDev: _preferTempDevCtrl.text.selfIfNotNullEmpty,
); );
final spi = ServerPrivateInfo( final spi = ServerPrivateInfo(

View File

@@ -501,7 +501,7 @@ class _ServerPageState extends State<ServerPage>
); );
} }
return Text( return Text(
s.topRightStr, s.getTopRightStr(s.spi),
style: UIs.text13Grey, style: UIs.text13Grey,
); );
} }

View File

@@ -981,47 +981,12 @@ class _SettingPageState extends State<SettingPage> {
); );
} }
Widget _buildPreferTemperatureDeviceList() {
void onSubmitted(String s) {
final list = s.split('\n');
_setting.preferTemperatureDevs.put(list);
context.pop();
}
return ListTile(
title: Text(l10n.preferTemperatureDeviceList),
subtitle: Text(l10n.preferTemperatureDeviceListTip, style: UIs.textGrey),
trailing: const Icon(Icons.keyboard_arrow_right),
onTap: () {
final list = _setting.preferTemperatureDevs.fetch();
final listStr = list.join('\n');
final ctrl = TextEditingController(text: listStr);
context.showRoundDialog(
title: Text(l10n.preferTemperatureDeviceList),
child: Input(
autoFocus: true,
controller: ctrl,
maxLines: 3,
onSubmitted: onSubmitted,
),
actions: [
TextButton(
onPressed: () => onSubmitted(ctrl.text),
child: Text(l10n.ok),
),
],
);
},
);
}
Widget _buildServerMore() { Widget _buildServerMore() {
return ExpandTile( return ExpandTile(
title: Text(l10n.more), title: Text(l10n.more),
children: [ children: [
_buildRememberPwdInMem(), _buildRememberPwdInMem(),
_buildTextScaler(), _buildTextScaler(),
_buildPreferTemperatureDeviceList(),
_buildKeepStatusWhenErr(), _buildKeepStatusWhenErr(),
_buildDoubleColumnServersPage(), _buildDoubleColumnServersPage(),
_buildUpdateInterval(), _buildUpdateInterval(),

View File

@@ -60,7 +60,7 @@ class _TagEditorState extends State<TagEditor> {
child: ListTile( child: ListTile(
// Align the place of TextField.prefixIcon // Align the place of TextField.prefixIcon
leading: const Padding( leading: const Padding(
padding: EdgeInsets.only(left: 6), padding: EdgeInsets.only(left: 10),
child: Icon(Icons.tag), child: Icon(Icons.tag),
), ),
title: _buildTags(widget.tags), title: _buildTags(widget.tags),

View File

@@ -3,7 +3,78 @@ import 'package:toolbox/data/model/server/sensors.dart';
void main() { void main() {
test('parse sensors', () { test('parse sensors', () {
final sensors = SensorItem.parse(SensorItem.sensorsRaw); const sensorsRaw = '''
{
"coretemp-isa-0000":{
"Adapter": "ISA adapter",
"Package id 0":{
"temp1_input": 51.000,
"temp1_max": 105.000,
"temp1_crit": 105.000,
"temp1_crit_alarm": 0.000
},
"Core 0":{
"temp2_input": 40.000,
"temp2_max": 105.000,
"temp2_crit": 105.000,
"temp2_crit_alarm": 0.000
},
"Core 1":{
"temp3_input": 40.000,
"temp3_max": 105.000,
"temp3_crit": 105.000,
"temp3_crit_alarm": 0.000
},
"Core 2":{
"temp4_input": 40.000,
"temp4_max": 105.000,
"temp4_crit": 105.000,
"temp4_crit_alarm": 0.000
},
"Core 3":{
"temp5_input": 40.000,
"temp5_max": 105.000,
"temp5_crit": 105.000,
"temp5_crit_alarm": 0.000
}
},
"acpitz-acpi-0":{
"Adapter": "ACPI interface",
"temp1":{
"temp1_input": 27.800,
"temp1_crit": 119.000
}
},
"iwlwifi_1-virtual-0":{
"Adapter": "Virtual device",
"temp1":{
ERROR: Can't get value of subfeature temp1_input: Can't read
}
},
"nvme-pci-0400":{
"Adapter": "PCI adapter",
"Composite":{
"temp1_input": 35.850,
"temp1_max": 83.850,
"temp1_min": -273.150,
"temp1_crit": 84.850,
"temp1_alarm": 0.000
},
"Sensor 1":{
"temp2_input": 35.850,
"temp2_max": 65261.850,
"temp2_min": -273.150
},
"Sensor 2":{
"temp3_input": 37.850,
"temp3_max": 65261.850,
"temp3_min": -273.150
}
}
}
''';
final sensors = SensorItem.parse(sensorsRaw);
expect(sensors.map((e) => e.device), [ expect(sensors.map((e) => e.device), [
'coretemp-isa-0000', 'coretemp-isa-0000',
'acpitz-acpi-0', 'acpitz-acpi-0',