opt.: use json_serializable

This commit is contained in:
lollipopkit🏳️‍⚧️
2024-08-15 16:44:13 +08:00
parent 195ddd2bcc
commit 7ce3854392
18 changed files with 221 additions and 196 deletions

View File

@@ -38,7 +38,7 @@ Please only download pkgs from the source that **you trust**!
## 🔖 Feature
- `Status chart` (CPU, Sensors, GPU...), `SSH` Term, `SFTP`, `Docker & Process`...
- `Status chart` (CPU, Sensors, GPU...), `SSH` Term, `SFTP`, `Docker & Process & Systemd`...
- Platform specific: `Bio auth``Msg push``Home widget``watchOS App`...
- English, 简体中文; Deutsch [@its-tom](https://github.com/its-tom), 繁體中文 [@kalashnikov](https://github.com/kalashnikov), Indonesian [@azkadev](https://github.com/azkadev), Français [@FrancXPT](https://github.com/FrancXPT), Dutch [@QazCetelic](https://github.com/QazCetelic), Türkçe [@mikropsoft](https://github.com/mikropsoft); Español, Русский язык, Português, 日本語 (Generated by GPT)

View File

@@ -38,7 +38,7 @@ Linux / Windows | [GitHub](https://github.com/lollipopkit/flutter_server_box/rel
## 🔖 特点
- `状态图表`CPU、传感器、GPU 等), `SSH` 终端, `SFTP`, `Docker & 进程` 管理...
- `状态图表`CPU、传感器、GPU 等), `SSH` 终端, `SFTP`, `Docker & 进程 & Systemd` 管理...
- 特殊支持:`生物认证``推送``桌面小部件``watchOS App``跟随系统颜色`...
- 本地化
- English, 简体中文

View File

@@ -2,6 +2,7 @@ import 'dart:convert';
import 'dart:io';
import 'package:fl_lib/fl_lib.dart';
import 'package:json_annotation/json_annotation.dart';
import 'package:logging/logging.dart';
import 'package:server_box/data/model/server/private_key_info.dart';
import 'package:server_box/data/model/server/server_private_info.dart';
@@ -11,10 +12,13 @@ import 'package:server_box/data/res/provider.dart';
import 'package:server_box/data/res/rebuild.dart';
import 'package:server_box/data/res/store.dart';
part 'backup.g.dart';
const backupFormatVersion = 1;
final _logger = Logger('Backup');
@JsonSerializable()
class Backup {
// backup format version
final int version;
@@ -37,31 +41,9 @@ class Backup {
this.lastModTime,
});
Backup.fromJson(Map<String, dynamic> json)
: version = json['version'] as int,
date = json['date'],
spis = (json['spis'] as List)
.map((e) => ServerPrivateInfo.fromJson(e))
.toList(),
snippets =
(json['snippets'] as List).map((e) => Snippet.fromJson(e)).toList(),
keys = (json['keys'] as List)
.map((e) => PrivateKeyInfo.fromJson(e))
.toList(),
container = json['container'] ?? {},
lastModTime = json['lastModTime'],
history = json['history'] ?? {};
factory Backup.fromJson(Map<String, dynamic> json) => _$BackupFromJson(json);
Map<String, dynamic> toJson() => {
'version': version,
'date': date,
'spis': spis,
'snippets': snippets,
'keys': keys,
'container': container,
'lastModTime': lastModTime,
'history': history,
};
Map<String, dynamic> toJson() => _$BackupToJson(this);
Backup.loadFromStore()
: version = backupFormatVersion,
@@ -201,8 +183,8 @@ class Backup {
_logger.info('Restore success');
}
Backup.fromJsonString(String raw)
: this.fromJson(json.decode(_diyDecrypt(raw)));
factory Backup.fromJsonString(String raw) =>
Backup.fromJson(json.decode(_diyDecrypt(raw)));
}
String _diyEncrypt(String raw) => json.encode(

View File

@@ -0,0 +1,35 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'backup.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
Backup _$BackupFromJson(Map<String, dynamic> json) => Backup(
version: (json['version'] as num).toInt(),
date: json['date'] as String,
spis: (json['spis'] as List<dynamic>)
.map((e) => ServerPrivateInfo.fromJson(e as Map<String, dynamic>))
.toList(),
snippets: (json['snippets'] as List<dynamic>)
.map((e) => Snippet.fromJson(e as Map<String, dynamic>))
.toList(),
keys: (json['keys'] as List<dynamic>)
.map((e) => PrivateKeyInfo.fromJson(e as Map<String, dynamic>))
.toList(),
container: json['container'] as Map<String, dynamic>,
history: json['history'] as Map<String, dynamic>,
lastModTime: (json['lastModTime'] as num?)?.toInt(),
);
Map<String, dynamic> _$BackupToJson(Backup instance) => <String, dynamic>{
'version': instance.version,
'date': instance.date,
'spis': instance.spis,
'snippets': instance.snippets,
'keys': instance.keys,
'container': instance.container,
'history': instance.history,
'lastModTime': instance.lastModTime,
};

View File

@@ -1,7 +1,9 @@
import 'package:hive_flutter/adapters.dart';
import 'package:json_annotation/json_annotation.dart';
part 'custom.g.dart';
@JsonSerializable()
@HiveType(typeId: 7)
final class ServerCustom {
// @HiveField(0)
@@ -28,44 +30,11 @@ final class ServerCustom {
this.logoUrl,
});
static ServerCustom fromJson(Map<String, dynamic> json) {
//final temperature = json["temperature"] as String?;
final pveAddr = json['pveAddr'] as String?;
final pveIgnoreCert = json['pveIgnoreCert'] as bool;
final cmds = json['cmds'] as Map<String, dynamic>?;
final preferTempDev = json['preferTempDev'] as String?;
final logoUrl = json['logoUrl'] as String?;
return ServerCustom(
//temperature: temperature,
pveAddr: pveAddr,
pveIgnoreCert: pveIgnoreCert,
cmds: cmds?.cast<String, String>(),
preferTempDev: preferTempDev,
logoUrl: logoUrl,
);
}
factory ServerCustom.fromJson(Map<String, dynamic> json) =>
_$ServerCustomFromJson(json);
Map<String, dynamic> toJson() {
final json = <String, dynamic>{};
// if (temperature != null) {
// json["temperature"] = temperature;
// }
if (pveAddr != null) {
json['pveAddr'] = pveAddr;
}
json['pveIgnoreCert'] = pveIgnoreCert;
Map<String, dynamic> toJson() => _$ServerCustomToJson(this);
if (cmds != null) {
json['cmds'] = cmds;
}
if (preferTempDev != null) {
json['preferTempDev'] = preferTempDev;
}
if (logoUrl != null) {
json['logoUrl'] = logoUrl;
}
return json;
}
@override
String toString() {

View File

@@ -51,3 +51,26 @@ class ServerCustomAdapter extends TypeAdapter<ServerCustom> {
runtimeType == other.runtimeType &&
typeId == other.typeId;
}
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
ServerCustom _$ServerCustomFromJson(Map<String, dynamic> json) => ServerCustom(
pveAddr: json['pveAddr'] as String?,
pveIgnoreCert: json['pveIgnoreCert'] as bool? ?? false,
cmds: (json['cmds'] as Map<String, dynamic>?)?.map(
(k, e) => MapEntry(k, e as String),
),
preferTempDev: json['preferTempDev'] as String?,
logoUrl: json['logoUrl'] as String?,
);
Map<String, dynamic> _$ServerCustomToJson(ServerCustom instance) =>
<String, dynamic>{
'pveAddr': instance.pveAddr,
'pveIgnoreCert': instance.pveIgnoreCert,
'cmds': instance.cmds,
'preferTempDev': instance.preferTempDev,
'logoUrl': instance.logoUrl,
};

View File

@@ -1,11 +1,14 @@
import 'package:hive_flutter/hive_flutter.dart';
import 'package:json_annotation/json_annotation.dart';
part 'private_key_info.g.dart';
@JsonSerializable()
@HiveType(typeId: 1)
class PrivateKeyInfo {
@HiveField(0)
final String id;
@JsonKey(name: 'private_key')
@HiveField(1)
final String key;
@@ -14,6 +17,11 @@ class PrivateKeyInfo {
required this.key,
});
factory PrivateKeyInfo.fromJson(Map<String, dynamic> json) =>
_$PrivateKeyInfoFromJson(json);
Map<String, dynamic> toJson() => _$PrivateKeyInfoToJson(this);
String? get type {
final lines = key.split('\n');
if (lines.length < 2) {
@@ -26,15 +34,4 @@ class PrivateKeyInfo {
}
return splited[1];
}
PrivateKeyInfo.fromJson(Map<String, dynamic> json)
: id = json['id'].toString(),
key = json['private_key'].toString();
Map<String, dynamic> toJson() {
final data = <String, String>{};
data['id'] = id;
data['private_key'] = key;
return data;
}
}

View File

@@ -42,3 +42,19 @@ class PrivateKeyInfoAdapter extends TypeAdapter<PrivateKeyInfo> {
runtimeType == other.runtimeType &&
typeId == other.typeId;
}
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
PrivateKeyInfo _$PrivateKeyInfoFromJson(Map<String, dynamic> json) =>
PrivateKeyInfo(
id: json['id'] as String,
key: json['private_key'] as String,
);
Map<String, dynamic> _$PrivateKeyInfoToJson(PrivateKeyInfo instance) =>
<String, dynamic>{
'id': instance.id,
'private_key': instance.key,
};

View File

@@ -1,6 +1,7 @@
import 'dart:convert';
import 'package:hive_flutter/hive_flutter.dart';
import 'package:json_annotation/json_annotation.dart';
import 'package:server_box/data/model/server/custom.dart';
import 'package:server_box/data/model/server/server.dart';
import 'package:server_box/data/model/server/wol_cfg.dart';
@@ -11,6 +12,7 @@ import 'package:server_box/data/model/app/error.dart';
part 'server_private_info.g.dart';
/// In former version, it's called `ServerPrivateInfo`.
@JsonSerializable()
@HiveType(typeId: 3)
class ServerPrivateInfo {
@HiveField(0)
@@ -25,6 +27,7 @@ class ServerPrivateInfo {
final String? pwd;
/// [id] of private key
@JsonKey(name: 'pubKeyId')
@HiveField(5)
final String? keyId;
@HiveField(6)
@@ -66,83 +69,10 @@ class ServerPrivateInfo {
this.envs,
}) : id = '$user@$ip:$port';
static ServerPrivateInfo fromJson(Map<String, dynamic> json) {
final ip = json['ip'] as String? ?? '';
final port = json['port'] as int? ?? 22;
final user = json['user'] as String? ?? 'root';
final name = json['name'] as String? ?? '';
final pwd = json['pwd'] as String? ?? json['authorization'] as String?;
final keyId = json['pubKeyId'] as String?;
final tags = (json['tags'] as List?)?.cast<String>();
final alterUrl = json['alterUrl'] as String?;
final autoConnect = json['autoConnect'] as bool? ?? true;
final jumpId = json['jumpId'] as String?;
final custom = json['customCmd'] == null
? null
: ServerCustom.fromJson(json['custom'].cast<String, dynamic>());
final wolCfg = json['wolCfg'] == null
? null
: WakeOnLanCfg.fromJson(json['wolCfg'].cast<String, dynamic>());
final envs_ = json['envs'] as Map<String, dynamic>?;
final envs = <String, String>{};
if (envs_ != null) {
envs_.forEach((key, value) {
if (value is String) {
envs[key] = value;
}
});
}
return ServerPrivateInfo(
name: name,
ip: ip,
port: port,
user: user,
pwd: pwd,
keyId: keyId,
tags: tags,
alterUrl: alterUrl,
autoConnect: autoConnect,
jumpId: jumpId,
custom: custom,
wolCfg: wolCfg,
envs: envs.isEmpty ? null : envs,
);
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
data['name'] = name;
data['ip'] = ip;
data['port'] = port;
data['user'] = user;
if (pwd != null) {
data['pwd'] = pwd;
}
if (keyId != null) {
data['pubKeyId'] = keyId;
}
if (tags != null) {
data['tags'] = tags;
}
if (alterUrl != null) {
data['alterUrl'] = alterUrl;
}
data['autoConnect'] = autoConnect;
if (jumpId != null) {
data['jumpId'] = jumpId;
}
if (custom != null) {
data['custom'] = custom?.toJson();
}
if (wolCfg != null) {
data['wolCfg'] = wolCfg?.toJson();
}
if (envs != null) {
data['envs'] = envs;
}
return data;
}
factory ServerPrivateInfo.fromJson(Map<String, dynamic> json) =>
_$ServerPrivateInfoFromJson(json);
Map<String, dynamic> toJson() => _$ServerPrivateInfoToJson(this);
String toJsonString() => json.encode(toJson());

View File

@@ -75,3 +75,47 @@ class ServerPrivateInfoAdapter extends TypeAdapter<ServerPrivateInfo> {
runtimeType == other.runtimeType &&
typeId == other.typeId;
}
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
ServerPrivateInfo _$ServerPrivateInfoFromJson(Map<String, dynamic> json) =>
ServerPrivateInfo(
name: json['name'] as String,
ip: json['ip'] as String,
port: (json['port'] as num).toInt(),
user: json['user'] as String,
pwd: json['pwd'] as String?,
keyId: json['pubKeyId'] as String?,
tags: (json['tags'] as List<dynamic>?)?.map((e) => e as String).toList(),
alterUrl: json['alterUrl'] as String?,
autoConnect: json['autoConnect'] as bool? ?? true,
jumpId: json['jumpId'] as String?,
custom: json['custom'] == null
? null
: ServerCustom.fromJson(json['custom'] as Map<String, dynamic>),
wolCfg: json['wolCfg'] == null
? null
: WakeOnLanCfg.fromJson(json['wolCfg'] as Map<String, dynamic>),
envs: (json['envs'] as Map<String, dynamic>?)?.map(
(k, e) => MapEntry(k, e as String),
),
);
Map<String, dynamic> _$ServerPrivateInfoToJson(ServerPrivateInfo instance) =>
<String, dynamic>{
'name': instance.name,
'ip': instance.ip,
'port': instance.port,
'user': instance.user,
'pwd': instance.pwd,
'pubKeyId': instance.keyId,
'tags': instance.tags,
'alterUrl': instance.alterUrl,
'autoConnect': instance.autoConnect,
'jumpId': instance.jumpId,
'custom': instance.custom,
'wolCfg': instance.wolCfg,
'envs': instance.envs,
};

View File

@@ -2,6 +2,7 @@ import 'dart:async';
import 'package:fl_lib/fl_lib.dart';
import 'package:hive_flutter/hive_flutter.dart';
import 'package:json_annotation/json_annotation.dart';
import 'package:server_box/data/model/server/server_private_info.dart';
import 'package:xterm/core.dart';
@@ -9,6 +10,7 @@ import 'package:server_box/data/model/app/tag_pickable.dart';
part 'snippet.g.dart';
@JsonSerializable()
@HiveType(typeId: 2)
class Snippet implements TagPickable {
@HiveField(0)
@@ -32,22 +34,9 @@ class Snippet implements TagPickable {
this.autoRunOn,
});
Snippet.fromJson(Map<String, dynamic> json)
: name = json['name'].toString(),
script = json['script'].toString(),
tags = json['tags']?.cast<String>(),
note = json['note']?.toString(),
autoRunOn = json['autoRunOn']?.cast<String>();
factory Snippet.fromJson(Map<String, dynamic> json) => _$SnippetFromJson(json);
Map<String, dynamic> toJson() {
final data = <String, dynamic>{};
data['name'] = name;
data['script'] = script;
data['tags'] = tags;
data['note'] = note;
data['autoRunOn'] = autoRunOn;
return data;
}
Map<String, dynamic> toJson() => _$SnippetToJson(this);
@override
bool containsTag(String tag) {

View File

@@ -51,3 +51,25 @@ class SnippetAdapter extends TypeAdapter<Snippet> {
runtimeType == other.runtimeType &&
typeId == other.typeId;
}
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
Snippet _$SnippetFromJson(Map<String, dynamic> json) => Snippet(
name: json['name'] as String,
script: json['script'] as String,
tags: (json['tags'] as List<dynamic>?)?.map((e) => e as String).toList(),
note: json['note'] as String?,
autoRunOn: (json['autoRunOn'] as List<dynamic>?)
?.map((e) => e as String)
.toList(),
);
Map<String, dynamic> _$SnippetToJson(Snippet instance) => <String, dynamic>{
'name': instance.name,
'script': instance.script,
'tags': instance.tags,
'note': instance.note,
'autoRunOn': instance.autoRunOn,
};

View File

@@ -1,10 +1,12 @@
import 'dart:io';
import 'package:hive_flutter/hive_flutter.dart';
import 'package:json_annotation/json_annotation.dart';
import 'package:wake_on_lan/wake_on_lan.dart';
part 'wol_cfg.g.dart';
@JsonSerializable()
@HiveType(typeId: 8)
final class WakeOnLanCfg {
@HiveField(0)
@@ -54,22 +56,8 @@ final class WakeOnLanCfg {
);
}
static WakeOnLanCfg fromJson(Map<String, dynamic> json) {
return WakeOnLanCfg(
mac: json['mac'] as String,
ip: json['ip'] as String,
pwd: json['pwd'] as String?,
);
}
factory WakeOnLanCfg.fromJson(Map<String, dynamic> json) =>
_$WakeOnLanCfgFromJson(json);
Map<String, dynamic> toJson() {
final map = <String, dynamic>{
'mac': mac,
'ip': ip,
};
if (pwd != null) {
map['pwd'] = pwd;
}
return map;
}
Map<String, dynamic> toJson() => _$WakeOnLanCfgToJson(this);
}

View File

@@ -45,3 +45,20 @@ class WakeOnLanCfgAdapter extends TypeAdapter<WakeOnLanCfg> {
runtimeType == other.runtimeType &&
typeId == other.typeId;
}
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
WakeOnLanCfg _$WakeOnLanCfgFromJson(Map<String, dynamic> json) => WakeOnLanCfg(
mac: json['mac'] as String,
ip: json['ip'] as String,
pwd: json['pwd'] as String?,
);
Map<String, dynamic> _$WakeOnLanCfgToJson(WakeOnLanCfg instance) =>
<String, dynamic>{
'mac': instance.mac,
'ip': instance.ip,
'pwd': instance.pwd,
};

View File

@@ -711,7 +711,12 @@ class _ServerDetailPageState extends State<ServerDetailPage>
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(key, style: UIs.text15),
Text(key, style: UIs.text15).paddingSymmetric(horizontal: 5).tap(
onTap: () {
Pfs.copy(key);
context.showSnackBar('${libL10n.copy} ${libL10n.success}');
},
),
Text('${val?.toStringAsFixed(1)}°C', style: UIs.text13Grey),
],
),

View File

@@ -38,11 +38,11 @@ final class _SystemdPageState extends State<SystemdPage> {
return Scaffold(
appBar: CustomAppBar(
title: const Text('Systemd'),
actions: [
Btn.icon(icon: const Icon(Icons.refresh), onTap: _pro.getUnits),
],
actions: isDesktop
? [Btn.icon(icon: const Icon(Icons.refresh), onTap: _pro.getUnits)]
: null,
),
body: _buildBody(),
body: RefreshIndicator(onRefresh: _pro.getUnits, child: _buildBody()),
);
}
@@ -71,8 +71,8 @@ final class _SystemdPageState extends State<SystemdPage> {
(units) {
if (units.isEmpty) {
return SliverToBoxAdapter(
child: CenterGreyTitle(libL10n.empty)
.paddingSymmetric(horizontal: 13),
child:
CenterGreyTitle(libL10n.empty).paddingSymmetric(horizontal: 13),
);
}
return SliverList(
@@ -155,10 +155,8 @@ final class _SystemdPageState extends State<SystemdPage> {
color: color?.withOpacity(0.7) ?? UIs.halfAlpha,
borderRadius: BorderRadius.circular(5),
),
child: Text(
tag,
style: UIs.text11Grey,
).paddingSymmetric(horizontal: 5, vertical: 1),
child: Text(tag, style: UIs.text11)
.paddingSymmetric(horizontal: 5, vertical: 1),
).paddingOnly(right: noPad ? 0 : 5);
}
}

View File

@@ -672,13 +672,21 @@ packages:
source: hosted
version: "0.7.1"
json_annotation:
dependency: transitive
dependency: "direct main"
description:
name: json_annotation
sha256: "1ce844379ca14835a50d2f019a3099f419082cfdd231cd86a142af94dd5c6bb1"
url: "https://pub.dev"
source: hosted
version: "4.9.0"
json_serializable:
dependency: "direct dev"
description:
name: json_serializable
sha256: ea1432d167339ea9b5bb153f0571d0039607a873d6e04e0117af043f14a1fd4b
url: "https://pub.dev"
source: hosted
version: "6.8.0"
leak_tracker:
dependency: transitive
description:

View File

@@ -29,6 +29,7 @@ dependencies:
wake_on_lan: ^4.1.1+3
flutter_adaptive_scaffold: ^0.1.10+2
extended_image: ^8.2.1
json_annotation: ^4.9.0
dartssh2:
git:
url: https://github.com/lollipopkit/dartssh2
@@ -77,6 +78,7 @@ dev_dependencies:
hive_generator: ^2.0.0
build_runner: ^2.3.2
flutter_lints: ^3.0.0
json_serializable: ^6.8.0
flutter_test:
sdk: flutter
fl_build: