fix: cloud sync (#769)

This commit is contained in:
lollipopkit🏳️‍⚧️
2025-06-04 00:11:31 +08:00
committed by GitHub
parent 9547d92ac5
commit 0c1ada0067
70 changed files with 2348 additions and 1906 deletions

View File

@@ -20,7 +20,7 @@ jobs:
uses: subosito/flutter-action@v2
with:
channel: "stable"
flutter-version: "3.27.3"
flutter-version: "3.32.1"
- uses: actions/setup-java@v4
with:
distribution: "zulu"
@@ -108,7 +108,7 @@ jobs:
# uses: subosito/flutter-action@v2
# with:
# channel: 'stable'
# flutter-version: '3.22.2'
# flutter-version: '3.32.1'
# - name: Build
# run: dart run fl_build -p ios,mac
# - name: Create Release

View File

@@ -12,17 +12,17 @@ extension SftpFileX on SftpFileMode {
UnixPerm toUnixPerm() {
return UnixPerm(
user: RWX(
user: UnixPermOp(
r: userRead,
w: userWrite,
x: userExecute,
),
group: RWX(
group: UnixPermOp(
r: groupRead,
w: groupWrite,
x: groupExecute,
),
other: RWX(
other: UnixPermOp(
r: otherRead,
w: otherWrite,
x: otherExecute,

View File

@@ -1,7 +1,8 @@
import 'dart:io';
import 'package:fl_lib/fl_lib.dart';
import 'package:server_box/data/model/app/backup.dart';
import 'package:server_box/data/model/app/bak/backup2.dart';
import 'package:server_box/data/model/app/bak/utils.dart';
const bakSync = BakSyncer._();
@@ -11,12 +12,12 @@ final class BakSyncer extends SyncIface {
const BakSyncer._() : super();
@override
Future<void> saveToFile() => Backup.backup();
Future<void> saveToFile() => BackupV2.backup();
@override
Future<Backup> fromFile(String path) async {
Future<Mergeable> fromFile(String path) async {
final content = await File(path).readAsString();
return Backup.fromJsonString(content);
return MergeableUtils.fromJsonString(content).$1;
}
@override

View File

@@ -1,37 +0,0 @@
// 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) => Spi.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>,
settings: json['settings'] 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,
'settings': instance.settings,
};

View File

@@ -46,7 +46,7 @@ class Backup implements Mergeable {
Map<String, dynamic> toJson() => _$BackupToJson(this);
static Future<Backup> loadFromStore() async {
final lastModTime = Stores.lastModTime?.millisecondsSinceEpoch;
final lastModTime = Stores.lastModTime;
return Backup(
version: backupFormatVersion,
date: DateTime.now().toString().split('.').firstOrNull ?? '',
@@ -70,7 +70,7 @@ class Backup implements Mergeable {
@override
Future<void> merge({bool force = false}) async {
final curTime = Stores.lastModTime?.millisecondsSinceEpoch ?? 0;
final curTime = Stores.lastModTime;
final bakTime = lastModTime ?? 0;
final shouldRestore = force || curTime < bakTime;
if (!shouldRestore) {
@@ -234,3 +234,4 @@ String _diyDecrypt(String raw) {
rethrow;
}
}

View File

@@ -0,0 +1,37 @@
// 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) => Spi.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>,
settings: json['settings'] 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,
'settings': instance.settings,
};

View File

@@ -0,0 +1,89 @@
import 'dart:convert';
import 'dart:io';
import 'package:fl_lib/fl_lib.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:logging/logging.dart';
import 'package:server_box/data/res/misc.dart';
import 'package:server_box/data/res/store.dart';
part 'backup2.freezed.dart';
part 'backup2.g.dart';
final _loggerV2 = Logger('BackupV2');
@freezed
abstract class BackupV2 with _$BackupV2 implements Mergeable {
const BackupV2._();
/// Construct a backup with the latest format (v2).
///
/// All `Map<String, dynamic>` are:
/// ```json
/// {
/// "key1": Model{},
/// "_lastModTime": {
/// "key1": 1234567890,
/// },
/// }
/// ```
const factory BackupV2({
required int version,
required int date,
required Map<String, Object?> spis,
required Map<String, Object?> snippets,
required Map<String, Object?> keys,
required Map<String, Object?> container,
required Map<String, Object?> history,
required Map<String, Object?> settings,
}) = _BackupV2;
factory BackupV2.fromJson(Map<String, dynamic> json) => _$BackupV2FromJson(json);
@override
Future<void> merge({bool force = false}) async {
_loggerV2.info('Merging...');
// Merge each store
await Mergeable.mergeStore(backupData: spis, store: Stores.server, force: force);
await Mergeable.mergeStore(backupData: snippets, store: Stores.snippet, force: force);
await Mergeable.mergeStore(backupData: keys, store: Stores.key, force: force);
await Mergeable.mergeStore(backupData: container, store: Stores.container, force: force);
await Mergeable.mergeStore(backupData: history, store: Stores.history, force: force);
await Mergeable.mergeStore(backupData: settings, store: Stores.setting, force: force);
// Reload providers and notify listeners
Provider.reload();
RNodes.app.notify();
_loggerV2.info('Merge completed');
}
static const formatVer = 2;
static Future<BackupV2> loadFromStore() async {
return BackupV2(
version: formatVer,
date: DateTimeX.timestamp,
spis: Stores.server.getAllMap(includeInternalKeys: true),
snippets: Stores.snippet.getAllMap(includeInternalKeys: true),
keys: Stores.key.getAllMap(includeInternalKeys: true),
container: Stores.container.getAllMap(includeInternalKeys: true),
history: Stores.history.getAllMap(includeInternalKeys: true),
settings: Stores.setting.getAllMap(includeInternalKeys: true),
);
}
static Future<String> backup([String? name]) async {
final bak = await BackupV2.loadFromStore();
final result = json.encode(bak.toJson());
final path = Paths.doc.joinPath(name ?? Miscs.bakFileName);
await File(path).writeAsString(result);
return path;
}
factory BackupV2.fromJsonString(String jsonString) {
final map = json.decode(jsonString) as Map<String, dynamic>;
return BackupV2.fromJson(map);
}
}

View File

@@ -0,0 +1,372 @@
// coverage:ignore-file
// GENERATED CODE - DO NOT MODIFY BY HAND
// ignore_for_file: type=lint
// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark
part of 'backup2.dart';
// **************************************************************************
// FreezedGenerator
// **************************************************************************
T _$identity<T>(T value) => value;
final _privateConstructorUsedError = UnsupportedError(
'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#adding-getters-and-methods-to-our-models',
);
BackupV2 _$BackupV2FromJson(Map<String, dynamic> json) {
return _BackupV2.fromJson(json);
}
/// @nodoc
mixin _$BackupV2 {
int get version => throw _privateConstructorUsedError;
int get date => throw _privateConstructorUsedError;
Map<String, Object?> get spis => throw _privateConstructorUsedError;
Map<String, Object?> get snippets => throw _privateConstructorUsedError;
Map<String, Object?> get keys => throw _privateConstructorUsedError;
Map<String, Object?> get container => throw _privateConstructorUsedError;
Map<String, Object?> get history => throw _privateConstructorUsedError;
Map<String, Object?> get settings => throw _privateConstructorUsedError;
/// Serializes this BackupV2 to a JSON map.
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
/// Create a copy of BackupV2
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
$BackupV2CopyWith<BackupV2> get copyWith =>
throw _privateConstructorUsedError;
}
/// @nodoc
abstract class $BackupV2CopyWith<$Res> {
factory $BackupV2CopyWith(BackupV2 value, $Res Function(BackupV2) then) =
_$BackupV2CopyWithImpl<$Res, BackupV2>;
@useResult
$Res call({
int version,
int date,
Map<String, Object?> spis,
Map<String, Object?> snippets,
Map<String, Object?> keys,
Map<String, Object?> container,
Map<String, Object?> history,
Map<String, Object?> settings,
});
}
/// @nodoc
class _$BackupV2CopyWithImpl<$Res, $Val extends BackupV2>
implements $BackupV2CopyWith<$Res> {
_$BackupV2CopyWithImpl(this._value, this._then);
// ignore: unused_field
final $Val _value;
// ignore: unused_field
final $Res Function($Val) _then;
/// Create a copy of BackupV2
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline')
@override
$Res call({
Object? version = null,
Object? date = null,
Object? spis = null,
Object? snippets = null,
Object? keys = null,
Object? container = null,
Object? history = null,
Object? settings = null,
}) {
return _then(
_value.copyWith(
version: null == version
? _value.version
: version // ignore: cast_nullable_to_non_nullable
as int,
date: null == date
? _value.date
: date // ignore: cast_nullable_to_non_nullable
as int,
spis: null == spis
? _value.spis
: spis // ignore: cast_nullable_to_non_nullable
as Map<String, Object?>,
snippets: null == snippets
? _value.snippets
: snippets // ignore: cast_nullable_to_non_nullable
as Map<String, Object?>,
keys: null == keys
? _value.keys
: keys // ignore: cast_nullable_to_non_nullable
as Map<String, Object?>,
container: null == container
? _value.container
: container // ignore: cast_nullable_to_non_nullable
as Map<String, Object?>,
history: null == history
? _value.history
: history // ignore: cast_nullable_to_non_nullable
as Map<String, Object?>,
settings: null == settings
? _value.settings
: settings // ignore: cast_nullable_to_non_nullable
as Map<String, Object?>,
)
as $Val,
);
}
}
/// @nodoc
abstract class _$$BackupV2ImplCopyWith<$Res>
implements $BackupV2CopyWith<$Res> {
factory _$$BackupV2ImplCopyWith(
_$BackupV2Impl value,
$Res Function(_$BackupV2Impl) then,
) = __$$BackupV2ImplCopyWithImpl<$Res>;
@override
@useResult
$Res call({
int version,
int date,
Map<String, Object?> spis,
Map<String, Object?> snippets,
Map<String, Object?> keys,
Map<String, Object?> container,
Map<String, Object?> history,
Map<String, Object?> settings,
});
}
/// @nodoc
class __$$BackupV2ImplCopyWithImpl<$Res>
extends _$BackupV2CopyWithImpl<$Res, _$BackupV2Impl>
implements _$$BackupV2ImplCopyWith<$Res> {
__$$BackupV2ImplCopyWithImpl(
_$BackupV2Impl _value,
$Res Function(_$BackupV2Impl) _then,
) : super(_value, _then);
/// Create a copy of BackupV2
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline')
@override
$Res call({
Object? version = null,
Object? date = null,
Object? spis = null,
Object? snippets = null,
Object? keys = null,
Object? container = null,
Object? history = null,
Object? settings = null,
}) {
return _then(
_$BackupV2Impl(
version: null == version
? _value.version
: version // ignore: cast_nullable_to_non_nullable
as int,
date: null == date
? _value.date
: date // ignore: cast_nullable_to_non_nullable
as int,
spis: null == spis
? _value._spis
: spis // ignore: cast_nullable_to_non_nullable
as Map<String, Object?>,
snippets: null == snippets
? _value._snippets
: snippets // ignore: cast_nullable_to_non_nullable
as Map<String, Object?>,
keys: null == keys
? _value._keys
: keys // ignore: cast_nullable_to_non_nullable
as Map<String, Object?>,
container: null == container
? _value._container
: container // ignore: cast_nullable_to_non_nullable
as Map<String, Object?>,
history: null == history
? _value._history
: history // ignore: cast_nullable_to_non_nullable
as Map<String, Object?>,
settings: null == settings
? _value._settings
: settings // ignore: cast_nullable_to_non_nullable
as Map<String, Object?>,
),
);
}
}
/// @nodoc
@JsonSerializable()
class _$BackupV2Impl extends _BackupV2 {
const _$BackupV2Impl({
required this.version,
required this.date,
required final Map<String, Object?> spis,
required final Map<String, Object?> snippets,
required final Map<String, Object?> keys,
required final Map<String, Object?> container,
required final Map<String, Object?> history,
required final Map<String, Object?> settings,
}) : _spis = spis,
_snippets = snippets,
_keys = keys,
_container = container,
_history = history,
_settings = settings,
super._();
factory _$BackupV2Impl.fromJson(Map<String, dynamic> json) =>
_$$BackupV2ImplFromJson(json);
@override
final int version;
@override
final int date;
final Map<String, Object?> _spis;
@override
Map<String, Object?> get spis {
if (_spis is EqualUnmodifiableMapView) return _spis;
// ignore: implicit_dynamic_type
return EqualUnmodifiableMapView(_spis);
}
final Map<String, Object?> _snippets;
@override
Map<String, Object?> get snippets {
if (_snippets is EqualUnmodifiableMapView) return _snippets;
// ignore: implicit_dynamic_type
return EqualUnmodifiableMapView(_snippets);
}
final Map<String, Object?> _keys;
@override
Map<String, Object?> get keys {
if (_keys is EqualUnmodifiableMapView) return _keys;
// ignore: implicit_dynamic_type
return EqualUnmodifiableMapView(_keys);
}
final Map<String, Object?> _container;
@override
Map<String, Object?> get container {
if (_container is EqualUnmodifiableMapView) return _container;
// ignore: implicit_dynamic_type
return EqualUnmodifiableMapView(_container);
}
final Map<String, Object?> _history;
@override
Map<String, Object?> get history {
if (_history is EqualUnmodifiableMapView) return _history;
// ignore: implicit_dynamic_type
return EqualUnmodifiableMapView(_history);
}
final Map<String, Object?> _settings;
@override
Map<String, Object?> get settings {
if (_settings is EqualUnmodifiableMapView) return _settings;
// ignore: implicit_dynamic_type
return EqualUnmodifiableMapView(_settings);
}
@override
String toString() {
return 'BackupV2(version: $version, date: $date, spis: $spis, snippets: $snippets, keys: $keys, container: $container, history: $history, settings: $settings)';
}
@override
bool operator ==(Object other) {
return identical(this, other) ||
(other.runtimeType == runtimeType &&
other is _$BackupV2Impl &&
(identical(other.version, version) || other.version == version) &&
(identical(other.date, date) || other.date == date) &&
const DeepCollectionEquality().equals(other._spis, _spis) &&
const DeepCollectionEquality().equals(other._snippets, _snippets) &&
const DeepCollectionEquality().equals(other._keys, _keys) &&
const DeepCollectionEquality().equals(
other._container,
_container,
) &&
const DeepCollectionEquality().equals(other._history, _history) &&
const DeepCollectionEquality().equals(other._settings, _settings));
}
@JsonKey(includeFromJson: false, includeToJson: false)
@override
int get hashCode => Object.hash(
runtimeType,
version,
date,
const DeepCollectionEquality().hash(_spis),
const DeepCollectionEquality().hash(_snippets),
const DeepCollectionEquality().hash(_keys),
const DeepCollectionEquality().hash(_container),
const DeepCollectionEquality().hash(_history),
const DeepCollectionEquality().hash(_settings),
);
/// Create a copy of BackupV2
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@override
@pragma('vm:prefer-inline')
_$$BackupV2ImplCopyWith<_$BackupV2Impl> get copyWith =>
__$$BackupV2ImplCopyWithImpl<_$BackupV2Impl>(this, _$identity);
@override
Map<String, dynamic> toJson() {
return _$$BackupV2ImplToJson(this);
}
}
abstract class _BackupV2 extends BackupV2 {
const factory _BackupV2({
required final int version,
required final int date,
required final Map<String, Object?> spis,
required final Map<String, Object?> snippets,
required final Map<String, Object?> keys,
required final Map<String, Object?> container,
required final Map<String, Object?> history,
required final Map<String, Object?> settings,
}) = _$BackupV2Impl;
const _BackupV2._() : super._();
factory _BackupV2.fromJson(Map<String, dynamic> json) =
_$BackupV2Impl.fromJson;
@override
int get version;
@override
int get date;
@override
Map<String, Object?> get spis;
@override
Map<String, Object?> get snippets;
@override
Map<String, Object?> get keys;
@override
Map<String, Object?> get container;
@override
Map<String, Object?> get history;
@override
Map<String, Object?> get settings;
/// Create a copy of BackupV2
/// with the given fields replaced by the non-null parameter values.
@override
@JsonKey(includeFromJson: false, includeToJson: false)
_$$BackupV2ImplCopyWith<_$BackupV2Impl> get copyWith =>
throw _privateConstructorUsedError;
}

View File

@@ -0,0 +1,31 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'backup2.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
_$BackupV2Impl _$$BackupV2ImplFromJson(Map<String, dynamic> json) =>
_$BackupV2Impl(
version: (json['version'] as num).toInt(),
date: (json['date'] as num).toInt(),
spis: json['spis'] as Map<String, dynamic>,
snippets: json['snippets'] as Map<String, dynamic>,
keys: json['keys'] as Map<String, dynamic>,
container: json['container'] as Map<String, dynamic>,
history: json['history'] as Map<String, dynamic>,
settings: json['settings'] as Map<String, dynamic>,
);
Map<String, dynamic> _$$BackupV2ImplToJson(_$BackupV2Impl instance) =>
<String, dynamic>{
'version': instance.version,
'date': instance.date,
'spis': instance.spis,
'snippets': instance.snippets,
'keys': instance.keys,
'container': instance.container,
'history': instance.history,
'settings': instance.settings,
};

View File

@@ -0,0 +1,15 @@
import 'package:fl_lib/fl_lib.dart';
import 'package:server_box/data/model/app/bak/backup.dart';
import 'package:server_box/data/model/app/bak/backup2.dart';
abstract final class MergeableUtils {
static (Mergeable, String) fromJsonString(String json) {
try {
final bak = BackupV2.fromJsonString(json);
return (bak, DateTime.fromMillisecondsSinceEpoch(bak.date).hms());
} catch (e) {
final bak = Backup.fromJsonString(json);
return (bak, bak.date);
}
}
}

View File

@@ -1,26 +1,5 @@
import 'package:server_box/core/extension/context/locale.dart';
enum ErrFrom {
unknown,
apt,
docker,
sftp,
ssh,
status,
icloud,
webdav,
;
}
abstract class Err<T> {
final ErrFrom from;
final T type;
final String? message;
String? get solution;
Err({required this.from, required this.type, this.message});
}
import 'package:fl_lib/fl_lib.dart';
enum SSHErrType {
unknown,
@@ -35,7 +14,7 @@ enum SSHErrType {
}
class SSHErr extends Err<SSHErrType> {
SSHErr({required super.type, super.message}) : super(from: ErrFrom.ssh);
SSHErr({required super.type, super.message});
@override
String? get solution => switch (type) {
@@ -45,11 +24,6 @@ class SSHErr extends Err<SSHErrType> {
SSHErrType.noPrivateKey => l10n.noPrivateKeyTip,
_ => null,
};
@override
String toString() {
return 'SSHErr<$type>: $message';
}
}
enum ContainerErrType {
@@ -65,16 +39,10 @@ enum ContainerErrType {
}
class ContainerErr extends Err<ContainerErrType> {
ContainerErr({required super.type, super.message})
: super(from: ErrFrom.docker);
ContainerErr({required super.type, super.message});
@override
String? get solution => null;
@override
String toString() {
return 'ContainerErr<$type>: $message';
}
}
enum ICloudErrType {
@@ -84,15 +52,10 @@ enum ICloudErrType {
}
class ICloudErr extends Err<ICloudErrType> {
ICloudErr({required super.type, super.message}) : super(from: ErrFrom.icloud);
ICloudErr({required super.type, super.message});
@override
String? get solution => null;
@override
String toString() {
return 'ICloudErr<$type>: $message';
}
}
enum WebdavErrType {
@@ -102,15 +65,10 @@ enum WebdavErrType {
}
class WebdavErr extends Err<WebdavErrType> {
WebdavErr({required super.type, super.message}) : super(from: ErrFrom.webdav);
WebdavErr({required super.type, super.message});
@override
String? get solution => null;
@override
String toString() {
return 'WebdavErr<$type>: $message';
}
}
enum PveErrType {
@@ -121,13 +79,8 @@ enum PveErrType {
}
class PveErr extends Err<PveErrType> {
PveErr({required super.type, super.message}) : super(from: ErrFrom.status);
PveErr({required super.type, super.message});
@override
String? get solution => null;
@override
String toString() {
return 'PveErr<$type>: $message';
}
}

View File

@@ -1,36 +1,23 @@
import 'package:flutter/material.dart';
import 'package:hive_flutter/hive_flutter.dart';
import 'package:icons_plus/icons_plus.dart';
import 'package:server_box/core/extension/context/locale.dart';
import 'package:server_box/data/res/store.dart';
part 'server_func.g.dart';
@HiveType(typeId: 6)
enum ServerFuncBtn {
@HiveField(0)
terminal._(),
@HiveField(1)
sftp._(),
@HiveField(2)
container._(),
@HiveField(3)
process._(),
//@HiveField(4)
//pkg,
@HiveField(5)
snippet._(),
@HiveField(6)
iperf._(),
// @HiveField(7)
// pve,
@HiveField(8)
systemd._(1058),
terminal(),
sftp(),
container(),
process(),
//pkg(),
snippet(),
iperf(),
// pve(),
systemd(1058),
;
final int? addedVersion;
const ServerFuncBtn._([this.addedVersion]);
const ServerFuncBtn([this.addedVersion]);
static void autoAddNewFuncs(int cur) {
if (cur >= systemd.addedVersion!) {

View File

@@ -1,71 +0,0 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'server_func.dart';
// **************************************************************************
// TypeAdapterGenerator
// **************************************************************************
class ServerFuncBtnAdapter extends TypeAdapter<ServerFuncBtn> {
@override
final int typeId = 6;
@override
ServerFuncBtn read(BinaryReader reader) {
switch (reader.readByte()) {
case 0:
return ServerFuncBtn.terminal;
case 1:
return ServerFuncBtn.sftp;
case 2:
return ServerFuncBtn.container;
case 3:
return ServerFuncBtn.process;
case 5:
return ServerFuncBtn.snippet;
case 6:
return ServerFuncBtn.iperf;
case 8:
return ServerFuncBtn.systemd;
default:
return ServerFuncBtn.terminal;
}
}
@override
void write(BinaryWriter writer, ServerFuncBtn obj) {
switch (obj) {
case ServerFuncBtn.terminal:
writer.writeByte(0);
break;
case ServerFuncBtn.sftp:
writer.writeByte(1);
break;
case ServerFuncBtn.container:
writer.writeByte(2);
break;
case ServerFuncBtn.process:
writer.writeByte(3);
break;
case ServerFuncBtn.snippet:
writer.writeByte(5);
break;
case ServerFuncBtn.iperf:
writer.writeByte(6);
break;
case ServerFuncBtn.systemd:
writer.writeByte(8);
break;
}
}
@override
int get hashCode => typeId.hashCode;
@override
bool operator ==(Object other) =>
identical(this, other) ||
other is ServerFuncBtnAdapter &&
runtimeType == other.runtimeType &&
typeId == other.typeId;
}

View File

@@ -1,17 +1,10 @@
import 'package:fl_lib/fl_lib.dart';
import 'package:hive_flutter/hive_flutter.dart';
import 'package:server_box/core/extension/context/locale.dart';
import 'package:server_box/data/model/server/server.dart';
part 'net_view.g.dart';
@HiveType(typeId: 5)
enum NetViewType {
@HiveField(0)
conn,
@HiveField(1)
speed,
@HiveField(2)
traffic;
NetViewType get next => switch (this) {

View File

@@ -1,51 +0,0 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'net_view.dart';
// **************************************************************************
// TypeAdapterGenerator
// **************************************************************************
class NetViewTypeAdapter extends TypeAdapter<NetViewType> {
@override
final int typeId = 5;
@override
NetViewType read(BinaryReader reader) {
switch (reader.readByte()) {
case 0:
return NetViewType.conn;
case 1:
return NetViewType.speed;
case 2:
return NetViewType.traffic;
default:
return NetViewType.conn;
}
}
@override
void write(BinaryWriter writer, NetViewType obj) {
switch (obj) {
case NetViewType.conn:
writer.writeByte(0);
break;
case NetViewType.speed:
writer.writeByte(1);
break;
case NetViewType.traffic:
writer.writeByte(2);
break;
}
}
@override
int get hashCode => typeId.hashCode;
@override
bool operator ==(Object other) =>
identical(this, other) ||
other is NetViewTypeAdapter &&
runtimeType == other.runtimeType &&
typeId == other.typeId;
}

View File

@@ -1,24 +0,0 @@
import 'dart:async';
class SyncResult<T, E> {
final List<T> up;
final List<T> down;
final Map<T, E> err;
const SyncResult({
required this.up,
required this.down,
required this.err,
});
@override
String toString() {
return 'SyncResult{up: $up, down: $down, err: $err}';
}
}
abstract class SyncIface<T> {
/// Merge [other] into [this], return [this] after merge.
/// Data in [other] has higher priority than [this].
FutureOr<void> sync(T other);
}

View File

@@ -1,32 +1,27 @@
import 'package:hive_flutter/adapters.dart';
import 'package:json_annotation/json_annotation.dart';
part 'custom.g.dart';
@JsonSerializable()
@HiveType(typeId: 7)
@JsonSerializable(includeIfNull: false)
final class ServerCustom {
// @HiveField(0)
// final String? temperature;
@HiveField(1)
final String? pveAddr;
@HiveField(2, defaultValue: false)
final bool pveIgnoreCert;
/// {"title": "cmd"}
@HiveField(3)
final Map<String, String>? cmds;
@HiveField(4)
final String? preferTempDev;
@HiveField(5)
final String? logoUrl;
/// The device name of the network interface displayed in the home server card.
@HiveField(6)
final String? netDev;
/// The directory where the script is stored.
@HiveField(7)
final String? scriptDir;
const ServerCustom({
@@ -40,8 +35,7 @@ final class ServerCustom {
this.scriptDir,
});
factory ServerCustom.fromJson(Map<String, dynamic> json) =>
_$ServerCustomFromJson(json);
factory ServerCustom.fromJson(Map<String, dynamic> json) => _$ServerCustomFromJson(json);
Map<String, dynamic> toJson() => _$ServerCustomToJson(this);

View File

@@ -2,62 +2,6 @@
part of 'custom.dart';
// **************************************************************************
// TypeAdapterGenerator
// **************************************************************************
class ServerCustomAdapter extends TypeAdapter<ServerCustom> {
@override
final int typeId = 7;
@override
ServerCustom read(BinaryReader reader) {
final numOfFields = reader.readByte();
final fields = <int, dynamic>{
for (int i = 0; i < numOfFields; i++) reader.readByte(): reader.read(),
};
return ServerCustom(
pveAddr: fields[1] as String?,
pveIgnoreCert: fields[2] == null ? false : fields[2] as bool,
cmds: (fields[3] as Map?)?.cast<String, String>(),
preferTempDev: fields[4] as String?,
logoUrl: fields[5] as String?,
netDev: fields[6] as String?,
scriptDir: fields[7] as String?,
);
}
@override
void write(BinaryWriter writer, ServerCustom obj) {
writer
..writeByte(7)
..writeByte(1)
..write(obj.pveAddr)
..writeByte(2)
..write(obj.pveIgnoreCert)
..writeByte(3)
..write(obj.cmds)
..writeByte(4)
..write(obj.preferTempDev)
..writeByte(5)
..write(obj.logoUrl)
..writeByte(6)
..write(obj.netDev)
..writeByte(7)
..write(obj.scriptDir);
}
@override
int get hashCode => typeId.hashCode;
@override
bool operator ==(Object other) =>
identical(this, other) ||
other is ServerCustomAdapter &&
runtimeType == other.runtimeType &&
typeId == other.typeId;
}
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
@@ -72,15 +16,15 @@ ServerCustom _$ServerCustomFromJson(Map<String, dynamic> json) => ServerCustom(
logoUrl: json['logoUrl'] as String?,
netDev: json['netDev'] as String?,
scriptDir: json['scriptDir'] as String?,
);
);
Map<String, dynamic> _$ServerCustomToJson(ServerCustom instance) =>
<String, dynamic>{
'pveAddr': instance.pveAddr,
if (instance.pveAddr case final value?) 'pveAddr': value,
'pveIgnoreCert': instance.pveIgnoreCert,
'cmds': instance.cmds,
'preferTempDev': instance.preferTempDev,
'logoUrl': instance.logoUrl,
'netDev': instance.netDev,
'scriptDir': instance.scriptDir,
if (instance.cmds case final value?) 'cmds': value,
if (instance.preferTempDev case final value?) 'preferTempDev': value,
if (instance.logoUrl case final value?) 'logoUrl': value,
if (instance.netDev case final value?) 'netDev': value,
if (instance.scriptDir case final value?) 'scriptDir': value,
};

View File

@@ -1,15 +1,11 @@
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;
const PrivateKeyInfo({
@@ -17,8 +13,7 @@ class PrivateKeyInfo {
required this.key,
});
factory PrivateKeyInfo.fromJson(Map<String, dynamic> json) =>
_$PrivateKeyInfoFromJson(json);
factory PrivateKeyInfo.fromJson(Map<String, dynamic> json) => _$PrivateKeyInfoFromJson(json);
Map<String, dynamic> toJson() => _$PrivateKeyInfoToJson(this);

View File

@@ -2,47 +2,6 @@
part of 'private_key_info.dart';
// **************************************************************************
// TypeAdapterGenerator
// **************************************************************************
class PrivateKeyInfoAdapter extends TypeAdapter<PrivateKeyInfo> {
@override
final int typeId = 1;
@override
PrivateKeyInfo read(BinaryReader reader) {
final numOfFields = reader.readByte();
final fields = <int, dynamic>{
for (int i = 0; i < numOfFields; i++) reader.readByte(): reader.read(),
};
return PrivateKeyInfo(
id: fields[0] as String,
key: fields[1] as String,
);
}
@override
void write(BinaryWriter writer, PrivateKeyInfo obj) {
writer
..writeByte(2)
..writeByte(0)
..write(obj.id)
..writeByte(1)
..write(obj.key);
}
@override
int get hashCode => typeId.hashCode;
@override
bool operator ==(Object other) =>
identical(this, other) ||
other is PrivateKeyInfoAdapter &&
runtimeType == other.runtimeType &&
typeId == other.typeId;
}
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
@@ -54,7 +13,4 @@ PrivateKeyInfo _$PrivateKeyInfoFromJson(Map<String, dynamic> json) =>
);
Map<String, dynamic> _$PrivateKeyInfoToJson(PrivateKeyInfo instance) =>
<String, dynamic>{
'id': instance.id,
'private_key': instance.key,
};
<String, dynamic>{'id': instance.id, 'private_key': instance.key};

View File

@@ -1,5 +1,5 @@
import 'package:dartssh2/dartssh2.dart';
import 'package:server_box/data/model/app/error.dart';
import 'package:fl_lib/fl_lib.dart';
import 'package:server_box/data/model/app/shell_func.dart';
import 'package:server_box/data/model/server/battery.dart';
import 'package:server_box/data/model/server/conn.dart';

View File

@@ -2,7 +2,7 @@ import 'dart:convert';
import 'package:fl_lib/fl_lib.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:hive_flutter/hive_flutter.dart';
import 'package:hive_ce_flutter/hive_flutter.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';
@@ -20,31 +20,31 @@ part 'server_private_info.freezed.dart';
/// Some params named as `spi` in the codebase which is the abbreviation of `ServerPrivateInfo`.
///
/// Nowaday, more fields are added to this class, and it's renamed to `Spi`.
@freezed
@HiveType(typeId: 3)
@Freezed(fromJson: false)
@JsonSerializable(includeIfNull: false)
class Spi with _$Spi {
const Spi._();
const factory Spi({
@HiveField(0) required String name,
@HiveField(1) required String ip,
@HiveField(2) required int port,
@HiveField(3) required String user,
@HiveField(4) String? pwd,
required String name,
required String ip,
required int port,
required String user,
String? pwd,
/// [id] of private key
@JsonKey(name: 'pubKeyId') @HiveField(5) String? keyId,
@HiveField(6) List<String>? tags,
@HiveField(7) String? alterUrl,
@HiveField(8, defaultValue: true) @Default(true) bool autoConnect,
@JsonKey(name: 'pubKeyId') String? keyId,
List<String>? tags,
String? alterUrl,
@Default(true) @JsonKey(defaultValue: true) bool autoConnect,
/// [id] of the jump server
@HiveField(9) String? jumpId,
@HiveField(10) ServerCustom? custom,
@HiveField(11) WakeOnLanCfg? wolCfg,
String? jumpId,
ServerCustom? custom,
WakeOnLanCfg? wolCfg,
/// It only applies to SSH terminal.
@HiveField(12) Map<String, String>? envs,
Map<String, String>? envs,
@JsonKey(fromJson: Spi.parseId) @HiveField(13, defaultValue: '') required String id,
}) = _Spi;

View File

@@ -12,46 +12,31 @@ part of 'server_private_info.dart';
T _$identity<T>(T value) => value;
final _privateConstructorUsedError = UnsupportedError(
'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#adding-getters-and-methods-to-our-models');
Spi _$SpiFromJson(Map<String, dynamic> json) {
return _Spi.fromJson(json);
}
'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#adding-getters-and-methods-to-our-models',
);
/// @nodoc
mixin _$Spi {
@HiveField(0)
String get name => throw _privateConstructorUsedError;
@HiveField(1)
String get ip => throw _privateConstructorUsedError;
@HiveField(2)
int get port => throw _privateConstructorUsedError;
@HiveField(3)
String get user => throw _privateConstructorUsedError;
@HiveField(4)
String? get pwd => throw _privateConstructorUsedError;
/// [id] of private key
@JsonKey(name: 'pubKeyId')
@HiveField(5)
String? get keyId => throw _privateConstructorUsedError;
@HiveField(6)
List<String>? get tags => throw _privateConstructorUsedError;
@HiveField(7)
String? get alterUrl => throw _privateConstructorUsedError;
@HiveField(8, defaultValue: true)
@JsonKey(defaultValue: true)
bool get autoConnect => throw _privateConstructorUsedError;
/// [id] of the jump server
@HiveField(9)
String? get jumpId => throw _privateConstructorUsedError;
@HiveField(10)
ServerCustom? get custom => throw _privateConstructorUsedError;
@HiveField(11)
WakeOnLanCfg? get wolCfg => throw _privateConstructorUsedError;
/// It only applies to SSH terminal.
@HiveField(12)
Map<String, String>? get envs => throw _privateConstructorUsedError;
@JsonKey(fromJson: Spi.parseId)
@HiveField(13, defaultValue: '')
@@ -71,23 +56,22 @@ abstract class $SpiCopyWith<$Res> {
factory $SpiCopyWith(Spi value, $Res Function(Spi) then) =
_$SpiCopyWithImpl<$Res, Spi>;
@useResult
$Res call(
{@HiveField(0) String name,
@HiveField(1) String ip,
@HiveField(2) int port,
@HiveField(3) String user,
@HiveField(4) String? pwd,
@JsonKey(name: 'pubKeyId') @HiveField(5) String? keyId,
@HiveField(6) List<String>? tags,
@HiveField(7) String? alterUrl,
@HiveField(8, defaultValue: true) bool autoConnect,
@HiveField(9) String? jumpId,
@HiveField(10) ServerCustom? custom,
@HiveField(11) WakeOnLanCfg? wolCfg,
@HiveField(12) Map<String, String>? envs,
@JsonKey(fromJson: Spi.parseId)
@HiveField(13, defaultValue: '')
String id});
$Res call({
String name,
String ip,
int port,
String user,
String? pwd,
@JsonKey(name: 'pubKeyId') String? keyId,
List<String>? tags,
String? alterUrl,
@JsonKey(defaultValue: true) bool autoConnect,
String? jumpId,
ServerCustom? custom,
WakeOnLanCfg? wolCfg,
Map<String, String>? envs,
@JsonKey(fromJson: Spi.parseId) @HiveField(13, defaultValue: '') String id,
});
}
/// @nodoc
@@ -119,7 +103,8 @@ class _$SpiCopyWithImpl<$Res, $Val extends Spi> implements $SpiCopyWith<$Res> {
Object? envs = freezed,
Object? id = null,
}) {
return _then(_value.copyWith(
return _then(
_value.copyWith(
name: null == name
? _value.name
: name // ignore: cast_nullable_to_non_nullable
@@ -176,7 +161,9 @@ class _$SpiCopyWithImpl<$Res, $Val extends Spi> implements $SpiCopyWith<$Res> {
? _value.id
: id // ignore: cast_nullable_to_non_nullable
as String,
) as $Val);
)
as $Val,
);
}
}
@@ -186,23 +173,22 @@ abstract class _$$SpiImplCopyWith<$Res> implements $SpiCopyWith<$Res> {
__$$SpiImplCopyWithImpl<$Res>;
@override
@useResult
$Res call(
{@HiveField(0) String name,
@HiveField(1) String ip,
@HiveField(2) int port,
@HiveField(3) String user,
@HiveField(4) String? pwd,
@JsonKey(name: 'pubKeyId') @HiveField(5) String? keyId,
@HiveField(6) List<String>? tags,
@HiveField(7) String? alterUrl,
@HiveField(8, defaultValue: true) bool autoConnect,
@HiveField(9) String? jumpId,
@HiveField(10) ServerCustom? custom,
@HiveField(11) WakeOnLanCfg? wolCfg,
@HiveField(12) Map<String, String>? envs,
@JsonKey(fromJson: Spi.parseId)
@HiveField(13, defaultValue: '')
String id});
$Res call({
String name,
String ip,
int port,
String user,
String? pwd,
@JsonKey(name: 'pubKeyId') String? keyId,
List<String>? tags,
String? alterUrl,
@JsonKey(defaultValue: true) bool autoConnect,
String? jumpId,
ServerCustom? custom,
WakeOnLanCfg? wolCfg,
Map<String, String>? envs,
@JsonKey(fromJson: Spi.parseId) @HiveField(13, defaultValue: '') String id,
});
}
/// @nodoc
@@ -231,7 +217,8 @@ class __$$SpiImplCopyWithImpl<$Res> extends _$SpiCopyWithImpl<$Res, _$SpiImpl>
Object? envs = freezed,
Object? id = null,
}) {
return _then(_$SpiImpl(
return _then(
_$SpiImpl(
name: null == name
? _value.name
: name // ignore: cast_nullable_to_non_nullable
@@ -288,61 +275,52 @@ class __$$SpiImplCopyWithImpl<$Res> extends _$SpiCopyWithImpl<$Res, _$SpiImpl>
? _value.id
: id // ignore: cast_nullable_to_non_nullable
as String,
));
),
);
}
}
/// @nodoc
@JsonSerializable()
@JsonSerializable(createFactory: false)
class _$SpiImpl extends _Spi {
const _$SpiImpl(
{@HiveField(0) required this.name,
@HiveField(1) required this.ip,
@HiveField(2) required this.port,
@HiveField(3) required this.user,
@HiveField(4) this.pwd,
@JsonKey(name: 'pubKeyId') @HiveField(5) this.keyId,
@HiveField(6) final List<String>? tags,
@HiveField(7) this.alterUrl,
@HiveField(8, defaultValue: true) this.autoConnect = true,
@HiveField(9) this.jumpId,
@HiveField(10) this.custom,
@HiveField(11) this.wolCfg,
@HiveField(12) final Map<String, String>? envs,
const _$SpiImpl({
required this.name,
required this.ip,
required this.port,
required this.user,
this.pwd,
@JsonKey(name: 'pubKeyId') this.keyId,
final List<String>? tags,
this.alterUrl,
@JsonKey(defaultValue: true) this.autoConnect = true,
this.jumpId,
this.custom,
this.wolCfg,
final Map<String, String>? envs,
@JsonKey(fromJson: Spi.parseId)
@HiveField(13, defaultValue: '')
required this.id})
: _tags = tags,
required this.id,
}) : _tags = tags,
_envs = envs,
super._();
factory _$SpiImpl.fromJson(Map<String, dynamic> json) =>
_$$SpiImplFromJson(json);
@override
@HiveField(0)
final String name;
@override
@HiveField(1)
final String ip;
@override
@HiveField(2)
final int port;
@override
@HiveField(3)
final String user;
@override
@HiveField(4)
final String? pwd;
/// [id] of private key
@override
@JsonKey(name: 'pubKeyId')
@HiveField(5)
final String? keyId;
final List<String>? _tags;
@override
@HiveField(6)
List<String>? get tags {
final value = _tags;
if (value == null) return null;
@@ -352,22 +330,17 @@ class _$SpiImpl extends _Spi {
}
@override
@HiveField(7)
final String? alterUrl;
@override
@JsonKey()
@HiveField(8, defaultValue: true)
@JsonKey(defaultValue: true)
final bool autoConnect;
/// [id] of the jump server
@override
@HiveField(9)
final String? jumpId;
@override
@HiveField(10)
final ServerCustom? custom;
@override
@HiveField(11)
final WakeOnLanCfg? wolCfg;
/// It only applies to SSH terminal.
@@ -375,7 +348,6 @@ class _$SpiImpl extends _Spi {
/// It only applies to SSH terminal.
@override
@HiveField(12)
Map<String, String>? get envs {
final value = _envs;
if (value == null) return null;
@@ -429,7 +401,8 @@ class _$SpiImpl extends _Spi {
custom,
wolCfg,
const DeepCollectionEquality().hash(_envs),
id);
id,
);
/// Create a copy of Spi
/// with the given fields replaced by the non-null parameter values.
@@ -441,79 +414,64 @@ class _$SpiImpl extends _Spi {
@override
Map<String, dynamic> toJson() {
return _$$SpiImplToJson(
this,
);
return _$$SpiImplToJson(this);
}
}
abstract class _Spi extends Spi {
const factory _Spi(
{@HiveField(0) required final String name,
@HiveField(1) required final String ip,
@HiveField(2) required final int port,
@HiveField(3) required final String user,
@HiveField(4) final String? pwd,
@JsonKey(name: 'pubKeyId') @HiveField(5) final String? keyId,
@HiveField(6) final List<String>? tags,
@HiveField(7) final String? alterUrl,
@HiveField(8, defaultValue: true) final bool autoConnect,
@HiveField(9) final String? jumpId,
@HiveField(10) final ServerCustom? custom,
@HiveField(11) final WakeOnLanCfg? wolCfg,
@HiveField(12) final Map<String, String>? envs,
const factory _Spi({
required final String name,
required final String ip,
required final int port,
required final String user,
final String? pwd,
@JsonKey(name: 'pubKeyId') final String? keyId,
final List<String>? tags,
final String? alterUrl,
@JsonKey(defaultValue: true) final bool autoConnect,
final String? jumpId,
final ServerCustom? custom,
final WakeOnLanCfg? wolCfg,
final Map<String, String>? envs,
@JsonKey(fromJson: Spi.parseId)
@HiveField(13, defaultValue: '')
required final String id}) = _$SpiImpl;
required final String id,
}) = _$SpiImpl;
const _Spi._() : super._();
factory _Spi.fromJson(Map<String, dynamic> json) = _$SpiImpl.fromJson;
@override
@HiveField(0)
String get name;
@override
@HiveField(1)
String get ip;
@override
@HiveField(2)
int get port;
@override
@HiveField(3)
String get user;
@override
@HiveField(4)
String? get pwd;
/// [id] of private key
@override
@JsonKey(name: 'pubKeyId')
@HiveField(5)
String? get keyId;
@override
@HiveField(6)
List<String>? get tags;
@override
@HiveField(7)
String? get alterUrl;
@override
@HiveField(8, defaultValue: true)
@JsonKey(defaultValue: true)
bool get autoConnect;
/// [id] of the jump server
@override
@HiveField(9)
String? get jumpId;
@override
@HiveField(10)
ServerCustom? get custom;
@override
@HiveField(11)
WakeOnLanCfg? get wolCfg;
/// It only applies to SSH terminal.
@override
@HiveField(12)
Map<String, String>? get envs;
@override
@JsonKey(fromJson: Spi.parseId)

View File

@@ -2,88 +2,11 @@
part of 'server_private_info.dart';
// **************************************************************************
// TypeAdapterGenerator
// **************************************************************************
class SpiAdapter extends TypeAdapter<Spi> {
@override
final int typeId = 3;
@override
Spi read(BinaryReader reader) {
final numOfFields = reader.readByte();
final fields = <int, dynamic>{
for (int i = 0; i < numOfFields; i++) reader.readByte(): reader.read(),
};
return Spi(
name: fields[0] as String,
ip: fields[1] as String,
port: fields[2] as int,
user: fields[3] as String,
pwd: fields[4] as String?,
keyId: fields[5] as String?,
tags: (fields[6] as List?)?.cast<String>(),
alterUrl: fields[7] as String?,
autoConnect: fields[8] == null ? true : fields[8] as bool,
jumpId: fields[9] as String?,
custom: fields[10] as ServerCustom?,
wolCfg: fields[11] as WakeOnLanCfg?,
envs: (fields[12] as Map?)?.cast<String, String>(),
id: fields[13] == null ? '' : fields[13] as String,
);
}
@override
void write(BinaryWriter writer, Spi obj) {
writer
..writeByte(14)
..writeByte(0)
..write(obj.name)
..writeByte(1)
..write(obj.ip)
..writeByte(2)
..write(obj.port)
..writeByte(3)
..write(obj.user)
..writeByte(4)
..write(obj.pwd)
..writeByte(5)
..write(obj.keyId)
..writeByte(6)
..write(obj.tags)
..writeByte(7)
..write(obj.alterUrl)
..writeByte(8)
..write(obj.autoConnect)
..writeByte(9)
..write(obj.jumpId)
..writeByte(10)
..write(obj.custom)
..writeByte(11)
..write(obj.wolCfg)
..writeByte(12)
..write(obj.envs)
..writeByte(13)
..write(obj.id);
}
@override
int get hashCode => typeId.hashCode;
@override
bool operator ==(Object other) =>
identical(this, other) ||
other is SpiAdapter &&
runtimeType == other.runtimeType &&
typeId == other.typeId;
}
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
_$SpiImpl _$$SpiImplFromJson(Map<String, dynamic> json) => _$SpiImpl(
Spi _$SpiFromJson(Map<String, dynamic> json) => Spi(
name: json['name'] as String,
ip: json['ip'] as String,
port: (json['port'] as num).toInt(),
@@ -104,7 +27,24 @@ _$SpiImpl _$$SpiImplFromJson(Map<String, dynamic> json) => _$SpiImpl(
(k, e) => MapEntry(k, e as String),
),
id: Spi.parseId(json['id']),
);
);
Map<String, dynamic> _$SpiToJson(Spi instance) => <String, dynamic>{
'name': instance.name,
'ip': instance.ip,
'port': instance.port,
'user': instance.user,
if (instance.pwd case final value?) 'pwd': value,
if (instance.keyId case final value?) 'pubKeyId': value,
if (instance.tags case final value?) 'tags': value,
if (instance.alterUrl case final value?) 'alterUrl': value,
'autoConnect': instance.autoConnect,
if (instance.jumpId case final value?) 'jumpId': value,
if (instance.custom case final value?) 'custom': value,
if (instance.wolCfg case final value?) 'wolCfg': value,
if (instance.envs case final value?) 'envs': value,
'id': instance.id,
};
Map<String, dynamic> _$$SpiImplToJson(_$SpiImpl instance) => <String, dynamic>{
'name': instance.name,
@@ -121,4 +61,4 @@ Map<String, dynamic> _$$SpiImplToJson(_$SpiImpl instance) => <String, dynamic>{
'wolCfg': instance.wolCfg,
'envs': instance.envs,
'id': instance.id,
};
};

View File

@@ -2,7 +2,6 @@ import 'dart:async';
import 'package:fl_lib/fl_lib.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:hive_flutter/hive_flutter.dart';
import 'package:server_box/data/model/server/server_private_info.dart';
import 'package:xterm/core.dart';
@@ -10,16 +9,15 @@ part 'snippet.g.dart';
part 'snippet.freezed.dart';
@freezed
@HiveType(typeId: 2)
class Snippet with _$Snippet {
const factory Snippet({
@HiveField(0) required String name,
@HiveField(1) required String script,
@HiveField(2) List<String>? tags,
@HiveField(3) String? note,
required String name,
required String script,
List<String>? tags,
String? note,
/// List of server id that this snippet should be auto run on
@HiveField(4) List<String>? autoRunOn,
List<String>? autoRunOn,
}) = _Snippet;
factory Snippet.fromJson(Map<String, dynamic> json) => _$SnippetFromJson(json);

View File

@@ -12,7 +12,8 @@ part of 'snippet.dart';
T _$identity<T>(T value) => value;
final _privateConstructorUsedError = UnsupportedError(
'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#adding-getters-and-methods-to-our-models');
'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#adding-getters-and-methods-to-our-models',
);
Snippet _$SnippetFromJson(Map<String, dynamic> json) {
return _Snippet.fromJson(json);
@@ -20,17 +21,12 @@ Snippet _$SnippetFromJson(Map<String, dynamic> json) {
/// @nodoc
mixin _$Snippet {
@HiveField(0)
String get name => throw _privateConstructorUsedError;
@HiveField(1)
String get script => throw _privateConstructorUsedError;
@HiveField(2)
List<String>? get tags => throw _privateConstructorUsedError;
@HiveField(3)
String? get note => throw _privateConstructorUsedError;
/// List of server id that this snippet should be auto run on
@HiveField(4)
List<String>? get autoRunOn => throw _privateConstructorUsedError;
/// Serializes this Snippet to a JSON map.
@@ -47,12 +43,13 @@ abstract class $SnippetCopyWith<$Res> {
factory $SnippetCopyWith(Snippet value, $Res Function(Snippet) then) =
_$SnippetCopyWithImpl<$Res, Snippet>;
@useResult
$Res call(
{@HiveField(0) String name,
@HiveField(1) String script,
@HiveField(2) List<String>? tags,
@HiveField(3) String? note,
@HiveField(4) List<String>? autoRunOn});
$Res call({
String name,
String script,
List<String>? tags,
String? note,
List<String>? autoRunOn,
});
}
/// @nodoc
@@ -76,7 +73,8 @@ class _$SnippetCopyWithImpl<$Res, $Val extends Snippet>
Object? note = freezed,
Object? autoRunOn = freezed,
}) {
return _then(_value.copyWith(
return _then(
_value.copyWith(
name: null == name
? _value.name
: name // ignore: cast_nullable_to_non_nullable
@@ -97,23 +95,27 @@ class _$SnippetCopyWithImpl<$Res, $Val extends Snippet>
? _value.autoRunOn
: autoRunOn // ignore: cast_nullable_to_non_nullable
as List<String>?,
) as $Val);
)
as $Val,
);
}
}
/// @nodoc
abstract class _$$SnippetImplCopyWith<$Res> implements $SnippetCopyWith<$Res> {
factory _$$SnippetImplCopyWith(
_$SnippetImpl value, $Res Function(_$SnippetImpl) then) =
__$$SnippetImplCopyWithImpl<$Res>;
_$SnippetImpl value,
$Res Function(_$SnippetImpl) then,
) = __$$SnippetImplCopyWithImpl<$Res>;
@override
@useResult
$Res call(
{@HiveField(0) String name,
@HiveField(1) String script,
@HiveField(2) List<String>? tags,
@HiveField(3) String? note,
@HiveField(4) List<String>? autoRunOn});
$Res call({
String name,
String script,
List<String>? tags,
String? note,
List<String>? autoRunOn,
});
}
/// @nodoc
@@ -121,8 +123,9 @@ class __$$SnippetImplCopyWithImpl<$Res>
extends _$SnippetCopyWithImpl<$Res, _$SnippetImpl>
implements _$$SnippetImplCopyWith<$Res> {
__$$SnippetImplCopyWithImpl(
_$SnippetImpl _value, $Res Function(_$SnippetImpl) _then)
: super(_value, _then);
_$SnippetImpl _value,
$Res Function(_$SnippetImpl) _then,
) : super(_value, _then);
/// Create a copy of Snippet
/// with the given fields replaced by the non-null parameter values.
@@ -135,7 +138,8 @@ class __$$SnippetImplCopyWithImpl<$Res>
Object? note = freezed,
Object? autoRunOn = freezed,
}) {
return _then(_$SnippetImpl(
return _then(
_$SnippetImpl(
name: null == name
? _value.name
: name // ignore: cast_nullable_to_non_nullable
@@ -156,34 +160,32 @@ class __$$SnippetImplCopyWithImpl<$Res>
? _value._autoRunOn
: autoRunOn // ignore: cast_nullable_to_non_nullable
as List<String>?,
));
),
);
}
}
/// @nodoc
@JsonSerializable()
class _$SnippetImpl implements _Snippet {
const _$SnippetImpl(
{@HiveField(0) required this.name,
@HiveField(1) required this.script,
@HiveField(2) final List<String>? tags,
@HiveField(3) this.note,
@HiveField(4) final List<String>? autoRunOn})
: _tags = tags,
const _$SnippetImpl({
required this.name,
required this.script,
final List<String>? tags,
this.note,
final List<String>? autoRunOn,
}) : _tags = tags,
_autoRunOn = autoRunOn;
factory _$SnippetImpl.fromJson(Map<String, dynamic> json) =>
_$$SnippetImplFromJson(json);
@override
@HiveField(0)
final String name;
@override
@HiveField(1)
final String script;
final List<String>? _tags;
@override
@HiveField(2)
List<String>? get tags {
final value = _tags;
if (value == null) return null;
@@ -193,7 +195,6 @@ class _$SnippetImpl implements _Snippet {
}
@override
@HiveField(3)
final String? note;
/// List of server id that this snippet should be auto run on
@@ -201,7 +202,6 @@ class _$SnippetImpl implements _Snippet {
/// List of server id that this snippet should be auto run on
@override
@HiveField(4)
List<String>? get autoRunOn {
final value = _autoRunOn;
if (value == null) return null;
@@ -224,8 +224,10 @@ class _$SnippetImpl implements _Snippet {
(identical(other.script, script) || other.script == script) &&
const DeepCollectionEquality().equals(other._tags, _tags) &&
(identical(other.note, note) || other.note == note) &&
const DeepCollectionEquality()
.equals(other._autoRunOn, _autoRunOn));
const DeepCollectionEquality().equals(
other._autoRunOn,
_autoRunOn,
));
}
@JsonKey(includeFromJson: false, includeToJson: false)
@@ -236,7 +238,8 @@ class _$SnippetImpl implements _Snippet {
script,
const DeepCollectionEquality().hash(_tags),
note,
const DeepCollectionEquality().hash(_autoRunOn));
const DeepCollectionEquality().hash(_autoRunOn),
);
/// Create a copy of Snippet
/// with the given fields replaced by the non-null parameter values.
@@ -248,38 +251,32 @@ class _$SnippetImpl implements _Snippet {
@override
Map<String, dynamic> toJson() {
return _$$SnippetImplToJson(
this,
);
return _$$SnippetImplToJson(this);
}
}
abstract class _Snippet implements Snippet {
const factory _Snippet(
{@HiveField(0) required final String name,
@HiveField(1) required final String script,
@HiveField(2) final List<String>? tags,
@HiveField(3) final String? note,
@HiveField(4) final List<String>? autoRunOn}) = _$SnippetImpl;
const factory _Snippet({
required final String name,
required final String script,
final List<String>? tags,
final String? note,
final List<String>? autoRunOn,
}) = _$SnippetImpl;
factory _Snippet.fromJson(Map<String, dynamic> json) = _$SnippetImpl.fromJson;
@override
@HiveField(0)
String get name;
@override
@HiveField(1)
String get script;
@override
@HiveField(2)
List<String>? get tags;
@override
@HiveField(3)
String? get note;
/// List of server id that this snippet should be auto run on
@override
@HiveField(4)
List<String>? get autoRunOn;
/// Create a copy of Snippet

View File

@@ -2,56 +2,6 @@
part of 'snippet.dart';
// **************************************************************************
// TypeAdapterGenerator
// **************************************************************************
class SnippetAdapter extends TypeAdapter<Snippet> {
@override
final int typeId = 2;
@override
Snippet read(BinaryReader reader) {
final numOfFields = reader.readByte();
final fields = <int, dynamic>{
for (int i = 0; i < numOfFields; i++) reader.readByte(): reader.read(),
};
return Snippet(
name: fields[0] as String,
script: fields[1] as String,
tags: (fields[2] as List?)?.cast<String>(),
note: fields[3] as String?,
autoRunOn: (fields[4] as List?)?.cast<String>(),
);
}
@override
void write(BinaryWriter writer, Snippet obj) {
writer
..writeByte(5)
..writeByte(0)
..write(obj.name)
..writeByte(1)
..write(obj.script)
..writeByte(2)
..write(obj.tags)
..writeByte(3)
..write(obj.note)
..writeByte(4)
..write(obj.autoRunOn);
}
@override
int get hashCode => typeId.hashCode;
@override
bool operator ==(Object other) =>
identical(this, other) ||
other is SnippetAdapter &&
runtimeType == other.runtimeType &&
typeId == other.typeId;
}
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************

View File

@@ -1,19 +1,14 @@
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)
@JsonSerializable(includeIfNull: false)
final class WakeOnLanCfg {
@HiveField(0)
final String mac;
@HiveField(1)
final String ip;
@HiveField(2)
final String? pwd;
const WakeOnLanCfg({
@@ -26,18 +21,12 @@ final class WakeOnLanCfg {
final macValidation = MACAddress.validate(mac);
final ipValidation = IPAddress.validate(
ip,
type: ip.contains(':')
? InternetAddressType.IPv6
: InternetAddressType.IPv4,
type: ip.contains(':') ? InternetAddressType.IPv6 : InternetAddressType.IPv4,
);
final pwdValidation = pwd != null
? SecureONPassword.validate(pwd)
: (state: true, error: null);
final pwdValidation = pwd != null ? SecureONPassword.validate(pwd) : (state: true, error: null);
final valid =
macValidation.state && ipValidation.state && pwdValidation.state;
final err =
macValidation.error ?? ipValidation.error ?? pwdValidation.error;
final valid = macValidation.state && ipValidation.state && pwdValidation.state;
final err = macValidation.error ?? ipValidation.error ?? pwdValidation.error;
return (err, valid);
}
@@ -56,8 +45,7 @@ final class WakeOnLanCfg {
);
}
factory WakeOnLanCfg.fromJson(Map<String, dynamic> json) =>
_$WakeOnLanCfgFromJson(json);
factory WakeOnLanCfg.fromJson(Map<String, dynamic> json) => _$WakeOnLanCfgFromJson(json);
Map<String, dynamic> toJson() => _$WakeOnLanCfgToJson(this);
}

View File

@@ -2,50 +2,6 @@
part of 'wol_cfg.dart';
// **************************************************************************
// TypeAdapterGenerator
// **************************************************************************
class WakeOnLanCfgAdapter extends TypeAdapter<WakeOnLanCfg> {
@override
final int typeId = 8;
@override
WakeOnLanCfg read(BinaryReader reader) {
final numOfFields = reader.readByte();
final fields = <int, dynamic>{
for (int i = 0; i < numOfFields; i++) reader.readByte(): reader.read(),
};
return WakeOnLanCfg(
mac: fields[0] as String,
ip: fields[1] as String,
pwd: fields[2] as String?,
);
}
@override
void write(BinaryWriter writer, WakeOnLanCfg obj) {
writer
..writeByte(3)
..writeByte(0)
..write(obj.mac)
..writeByte(1)
..write(obj.ip)
..writeByte(2)
..write(obj.pwd);
}
@override
int get hashCode => typeId.hashCode;
@override
bool operator ==(Object other) =>
identical(this, other) ||
other is WakeOnLanCfgAdapter &&
runtimeType == other.runtimeType &&
typeId == other.typeId;
}
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
@@ -54,11 +10,11 @@ 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,
if (instance.pwd case final value?) 'pwd': value,
};

View File

@@ -1,103 +1,55 @@
import 'package:fl_lib/fl_lib.dart';
import 'package:flutter/material.dart';
import 'package:hive_flutter/hive_flutter.dart';
import 'package:server_box/core/extension/context/locale.dart';
import 'package:server_box/data/res/store.dart';
import 'package:xterm/core.dart';
part 'virtual_key.g.dart';
enum VirtualKeyFunc { toggleIME, backspace, clipboard, snippet, file }
@HiveType(typeId: 4)
enum VirtKey {
@HiveField(0)
esc,
@HiveField(1)
alt,
@HiveField(2)
home,
@HiveField(3)
up,
@HiveField(4)
end,
@HiveField(5)
sftp,
@HiveField(6)
snippet,
@HiveField(7)
tab,
@HiveField(8)
ctrl,
@HiveField(9)
left,
@HiveField(10)
down,
@HiveField(11)
right,
@HiveField(12)
clipboard,
@HiveField(13)
ime,
@HiveField(14)
pgup,
@HiveField(15)
pgdn,
@HiveField(16)
slash,
@HiveField(17)
backSlash,
@HiveField(18)
underscore,
@HiveField(19)
plus,
@HiveField(20)
equal,
@HiveField(21)
minus,
@HiveField(22)
parenLeft,
@HiveField(23)
parenRight,
@HiveField(24)
bracketLeft,
@HiveField(25)
bracketRight,
@HiveField(26)
braceLeft,
@HiveField(27)
braceRight,
@HiveField(28)
chevronLeft,
@HiveField(29)
chevronRight,
@HiveField(30)
colon,
@HiveField(31)
semicolon,
@HiveField(32)
f1,
@HiveField(33)
f2,
@HiveField(34)
f3,
@HiveField(35)
f4,
@HiveField(36)
f5,
@HiveField(37)
f6,
@HiveField(38)
f7,
@HiveField(39)
f8,
@HiveField(40)
f9,
@HiveField(41)
f10,
@HiveField(42)
f11,
@HiveField(43)
f12;
}

View File

@@ -1,256 +0,0 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'virtual_key.dart';
// **************************************************************************
// TypeAdapterGenerator
// **************************************************************************
class VirtKeyAdapter extends TypeAdapter<VirtKey> {
@override
final int typeId = 4;
@override
VirtKey read(BinaryReader reader) {
switch (reader.readByte()) {
case 0:
return VirtKey.esc;
case 1:
return VirtKey.alt;
case 2:
return VirtKey.home;
case 3:
return VirtKey.up;
case 4:
return VirtKey.end;
case 5:
return VirtKey.sftp;
case 6:
return VirtKey.snippet;
case 7:
return VirtKey.tab;
case 8:
return VirtKey.ctrl;
case 9:
return VirtKey.left;
case 10:
return VirtKey.down;
case 11:
return VirtKey.right;
case 12:
return VirtKey.clipboard;
case 13:
return VirtKey.ime;
case 14:
return VirtKey.pgup;
case 15:
return VirtKey.pgdn;
case 16:
return VirtKey.slash;
case 17:
return VirtKey.backSlash;
case 18:
return VirtKey.underscore;
case 19:
return VirtKey.plus;
case 20:
return VirtKey.equal;
case 21:
return VirtKey.minus;
case 22:
return VirtKey.parenLeft;
case 23:
return VirtKey.parenRight;
case 24:
return VirtKey.bracketLeft;
case 25:
return VirtKey.bracketRight;
case 26:
return VirtKey.braceLeft;
case 27:
return VirtKey.braceRight;
case 28:
return VirtKey.chevronLeft;
case 29:
return VirtKey.chevronRight;
case 30:
return VirtKey.colon;
case 31:
return VirtKey.semicolon;
case 32:
return VirtKey.f1;
case 33:
return VirtKey.f2;
case 34:
return VirtKey.f3;
case 35:
return VirtKey.f4;
case 36:
return VirtKey.f5;
case 37:
return VirtKey.f6;
case 38:
return VirtKey.f7;
case 39:
return VirtKey.f8;
case 40:
return VirtKey.f9;
case 41:
return VirtKey.f10;
case 42:
return VirtKey.f11;
case 43:
return VirtKey.f12;
default:
return VirtKey.esc;
}
}
@override
void write(BinaryWriter writer, VirtKey obj) {
switch (obj) {
case VirtKey.esc:
writer.writeByte(0);
break;
case VirtKey.alt:
writer.writeByte(1);
break;
case VirtKey.home:
writer.writeByte(2);
break;
case VirtKey.up:
writer.writeByte(3);
break;
case VirtKey.end:
writer.writeByte(4);
break;
case VirtKey.sftp:
writer.writeByte(5);
break;
case VirtKey.snippet:
writer.writeByte(6);
break;
case VirtKey.tab:
writer.writeByte(7);
break;
case VirtKey.ctrl:
writer.writeByte(8);
break;
case VirtKey.left:
writer.writeByte(9);
break;
case VirtKey.down:
writer.writeByte(10);
break;
case VirtKey.right:
writer.writeByte(11);
break;
case VirtKey.clipboard:
writer.writeByte(12);
break;
case VirtKey.ime:
writer.writeByte(13);
break;
case VirtKey.pgup:
writer.writeByte(14);
break;
case VirtKey.pgdn:
writer.writeByte(15);
break;
case VirtKey.slash:
writer.writeByte(16);
break;
case VirtKey.backSlash:
writer.writeByte(17);
break;
case VirtKey.underscore:
writer.writeByte(18);
break;
case VirtKey.plus:
writer.writeByte(19);
break;
case VirtKey.equal:
writer.writeByte(20);
break;
case VirtKey.minus:
writer.writeByte(21);
break;
case VirtKey.parenLeft:
writer.writeByte(22);
break;
case VirtKey.parenRight:
writer.writeByte(23);
break;
case VirtKey.bracketLeft:
writer.writeByte(24);
break;
case VirtKey.bracketRight:
writer.writeByte(25);
break;
case VirtKey.braceLeft:
writer.writeByte(26);
break;
case VirtKey.braceRight:
writer.writeByte(27);
break;
case VirtKey.chevronLeft:
writer.writeByte(28);
break;
case VirtKey.chevronRight:
writer.writeByte(29);
break;
case VirtKey.colon:
writer.writeByte(30);
break;
case VirtKey.semicolon:
writer.writeByte(31);
break;
case VirtKey.f1:
writer.writeByte(32);
break;
case VirtKey.f2:
writer.writeByte(33);
break;
case VirtKey.f3:
writer.writeByte(34);
break;
case VirtKey.f4:
writer.writeByte(35);
break;
case VirtKey.f5:
writer.writeByte(36);
break;
case VirtKey.f6:
writer.writeByte(37);
break;
case VirtKey.f7:
writer.writeByte(38);
break;
case VirtKey.f8:
writer.writeByte(39);
break;
case VirtKey.f9:
writer.writeByte(40);
break;
case VirtKey.f10:
writer.writeByte(41);
break;
case VirtKey.f11:
writer.writeByte(42);
break;
case VirtKey.f12:
writer.writeByte(43);
break;
}
}
@override
int get hashCode => typeId.hashCode;
@override
bool operator ==(Object other) =>
identical(this, other) ||
other is VirtKeyAdapter &&
runtimeType == other.runtimeType &&
typeId == other.typeId;
}

View File

@@ -12,7 +12,8 @@ part of 'app.dart';
T _$identity<T>(T value) => value;
final _privateConstructorUsedError = UnsupportedError(
'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#adding-getters-and-methods-to-our-models');
'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#adding-getters-and-methods-to-our-models',
);
/// @nodoc
mixin _$AppState {
@@ -47,15 +48,16 @@ class _$AppStateCopyWithImpl<$Res, $Val extends AppState>
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline')
@override
$Res call({
Object? desktopMode = null,
}) {
return _then(_value.copyWith(
$Res call({Object? desktopMode = null}) {
return _then(
_value.copyWith(
desktopMode: null == desktopMode
? _value.desktopMode
: desktopMode // ignore: cast_nullable_to_non_nullable
as bool,
) as $Val);
)
as $Val,
);
}
}
@@ -63,8 +65,9 @@ class _$AppStateCopyWithImpl<$Res, $Val extends AppState>
abstract class _$$AppStateImplCopyWith<$Res>
implements $AppStateCopyWith<$Res> {
factory _$$AppStateImplCopyWith(
_$AppStateImpl value, $Res Function(_$AppStateImpl) then) =
__$$AppStateImplCopyWithImpl<$Res>;
_$AppStateImpl value,
$Res Function(_$AppStateImpl) then,
) = __$$AppStateImplCopyWithImpl<$Res>;
@override
@useResult
$Res call({bool desktopMode});
@@ -75,22 +78,23 @@ class __$$AppStateImplCopyWithImpl<$Res>
extends _$AppStateCopyWithImpl<$Res, _$AppStateImpl>
implements _$$AppStateImplCopyWith<$Res> {
__$$AppStateImplCopyWithImpl(
_$AppStateImpl _value, $Res Function(_$AppStateImpl) _then)
: super(_value, _then);
_$AppStateImpl _value,
$Res Function(_$AppStateImpl) _then,
) : super(_value, _then);
/// Create a copy of AppState
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline')
@override
$Res call({
Object? desktopMode = null,
}) {
return _then(_$AppStateImpl(
$Res call({Object? desktopMode = null}) {
return _then(
_$AppStateImpl(
desktopMode: null == desktopMode
? _value.desktopMode
: desktopMode // ignore: cast_nullable_to_non_nullable
as bool,
));
),
);
}
}

View File

@@ -13,8 +13,9 @@ String _$appProviderHash() => r'8378ec9d0a9c8d99cc05805047cd2d52ac4dbb56';
final appProviderProvider = NotifierProvider<AppProvider, AppState>.internal(
AppProvider.new,
name: r'appProviderProvider',
debugGetCreateSourceHash:
const bool.fromEnvironment('dart.vm.product') ? null : _$appProviderHash,
debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product')
? null
: _$appProviderHash,
dependencies: null,
allTransitiveDependencies: null,
);

View File

@@ -49,8 +49,7 @@ class ServerProvider extends Provider {
/// #258
/// If not [shouldReconnect], then keep the old state.
if (originServer != null &&
!originServer.value.spi.shouldReconnect(spi)) {
if (originServer != null && !originServer.value.spi.shouldReconnect(spi)) {
newServer.conn = originServer.value.conn;
}
servers[spi.id] = newServer.vn;
@@ -174,12 +173,16 @@ class ServerProvider extends Provider {
static void _closeOneServer(String id) {
final s = servers[id];
final item = s?.value;
item?.client?.close();
item?.client = null;
item?.conn = ServerConn.disconnected;
if (s == null) {
Loggers.app.warning('Server with id $id not found');
return;
}
final item = s.value;
item.client?.close();
item.client = null;
item.conn = ServerConn.disconnected;
_manualDisconnectedIds.add(id);
s?.notify();
s.notify();
}
static void addServer(Spi spi) {

View File

@@ -28,17 +28,22 @@ abstract final class Stores {
await Future.wait(_allBackup.map((store) => store.init()));
}
static DateTime? get lastModTime {
DateTime? lastModTime;
static int get lastModTime {
var lastModTime = 0;
for (final store in _allBackup) {
final last = store.lastUpdateTs;
if (last == null) {
continue;
}
if (lastModTime == null) {
lastModTime = last;
} else if (last.isAfter(lastModTime)) {
lastModTime = last;
var lastModTimeTs = 0;
for (final item in last.entries) {
final ts = item.value;
if (ts > lastModTimeTs) {
lastModTimeTs = ts;
}
}
if (lastModTimeTs > lastModTime) {
lastModTime = lastModTimeTs;
}
}
return lastModTime;

View File

@@ -14,8 +14,7 @@ class ContainerStore extends HiveStore {
}
void put(String id, String host) {
box.put(id, host);
updateLastUpdateTs();
set(id, host);
}
ContainerType getType([String id = '']) {
@@ -36,10 +35,11 @@ class ContainerStore extends HiveStore {
void setType(ContainerType type, [String id = '']) {
if (type == defaultType) {
box.delete(_keyConfig + id);
// box.delete(_keyConfig + id);
remove(_keyConfig + id);
} else {
box.put(_keyConfig + id, type.toString());
// box.put(_keyConfig + id, type.toString());
set(_keyConfig + id, type.toString());
}
updateLastUpdateTs();
}
}

View File

@@ -1,5 +1,5 @@
import 'package:fl_lib/fl_lib.dart';
import 'package:hive_flutter/hive_flutter.dart';
import 'package:hive_ce_flutter/hive_flutter.dart';
/// index from 0 -> n : latest -> oldest
class _ListHistory {

View File

@@ -12,11 +12,27 @@ class PrivateKeyStore extends HiveStore {
}
List<PrivateKeyInfo> fetch() {
final keys = box.keys;
final ps = <PrivateKeyInfo>[];
for (final key in keys) {
final s = box.get(key);
if (s != null && s is PrivateKeyInfo) {
for (final key in keys()) {
final s = get<PrivateKeyInfo>(
key,
fromObj: (val) {
if (val is PrivateKeyInfo) return val;
if (val is Map<dynamic, dynamic>) {
final map = val.toStrDynMap;
if (map == null) return null;
try {
final pki = PrivateKeyInfo.fromJson(map as Map<String, dynamic>);
put(pki);
return pki;
} catch (e) {
dprint('Parsing PrivateKeyInfo from JSON', e);
}
}
return null;
},
);
if (s != null) {
ps.add(s);
}
}

View File

@@ -17,8 +17,25 @@ class ServerStore extends HiveStore {
List<Spi> fetch() {
final List<Spi> ss = [];
for (final id in keys()) {
final s = box.get(id);
if (s != null && s is Spi) {
final s = get<Spi>(
id,
fromObj: (val) {
if (val is Spi) return val;
if (val is Map<dynamic, dynamic>) {
final map = val.toStrDynMap;
if (map == null) return null;
try {
final spi = Spi.fromJson(map as Map<String, dynamic>);
put(spi);
return spi;
} catch (e) {
dprint('Parsing Spi from JSON', e);
}
}
return null;
},
);
if (s != null) {
ss.add(s);
}
}

View File

@@ -13,12 +13,6 @@ class SettingStore extends HiveStore {
static final instance = SettingStore._();
// ------BEGIN------
//
// These settings are not displayed in the settings page
// You can edit them in the settings json editor (by long press the settings
// item in the drawer of the home page)
/// Discussion #146
late final serverTabUseOldUI = propertyDefault('serverTabUseOldUI', false);
@@ -37,8 +31,6 @@ class SettingStore extends HiveStore {
false,
);
// ------END------
/// Bigger for bigger font size
/// 1.0 means 100%
/// Warning: This may cause some UI issues
@@ -65,14 +57,14 @@ class SettingStore extends HiveStore {
late final bgRun = propertyDefault('bgRun', isAndroid);
// Server order
late final serverOrder = propertyDefault<List<String>>('serverOrder', []);
late final serverOrder = listProperty<String>('serverOrder');
late final snippetOrder = propertyDefault<List<String>>('snippetOrder', []);
late final snippetOrder = listProperty<String>('snippetOrder');
// Server details page cards order
late final detailCardOrder = propertyDefault(
late final detailCardOrder = listProperty(
'detailCardOrder',
ServerDetailCards.values.map((e) => e.name).toList(),
defaultValue: ServerDetailCards.values.map((e) => e.name).toList(),
);
// SSH term font size
@@ -82,16 +74,14 @@ class SettingStore extends HiveStore {
late final locale = propertyDefault('locale', '');
// SSH virtual key (ctrl | alt) auto turn off
late final sshVirtualKeyAutoOff =
propertyDefault('sshVirtualKeyAutoOff', true);
late final sshVirtualKeyAutoOff = propertyDefault('sshVirtualKeyAutoOff', true);
late final editorFontSize = propertyDefault('editorFontSize', 12.5);
// Editor theme
late final editorTheme = propertyDefault('editorTheme', Defaults.editorTheme);
late final editorDarkTheme =
propertyDefault('editorDarkTheme', Defaults.editorDarkTheme);
late final editorDarkTheme = propertyDefault('editorDarkTheme', Defaults.editorDarkTheme);
late final fullScreen = propertyDefault('fullScreen', false);
@@ -107,31 +97,34 @@ class SettingStore extends HiveStore {
// TextInputType.text.index,
// );
late final sshVirtKeys = propertyDefault(
late final sshVirtKeys = listProperty<int>(
'sshVirtKeys',
VirtKeyX.defaultOrder.map((e) => e.index).toList(),
defaultValue: VirtKeyX.defaultOrder.map((e) => e.index).toList(),
fromObj: (val) => List<int>.from(val as List),
);
late final netViewType = propertyDefault('netViewType', NetViewType.speed);
late final netViewType = propertyDefault(
'netViewType',
NetViewType.speed,
fromObj: (val) => NetViewType.values.firstWhereOrNull((e) => e.name == val),
toObj: (type) => type?.name,
);
// Only valid on iOS
late final autoUpdateHomeWidget =
propertyDefault('autoUpdateHomeWidget', isIOS);
late final autoUpdateHomeWidget = propertyDefault('autoUpdateHomeWidget', isIOS);
late final autoCheckAppUpdate = propertyDefault('autoCheckAppUpdate', true);
/// Display server tab function buttons on the bottom of each server card if [true]
///
/// Otherwise, display them on the top of server detail page
late final moveServerFuncs =
propertyDefault('moveOutServerTabFuncBtns', false);
late final moveServerFuncs = propertyDefault('moveOutServerTabFuncBtns', false);
/// Whether use `rm -r` to delete directory on SFTP
late final sftpRmrDir = propertyDefault('sftpRmrDir', false);
/// Whether use system's primary color as the app's primary color
late final useSystemPrimaryColor =
propertyDefault('useSystemPrimaryColor', false);
late final useSystemPrimaryColor = propertyDefault('useSystemPrimaryColor', false);
/// Only valid on iOS / Android / Windows
late final useBioAuth = propertyDefault('useBioAuth', false);
@@ -143,8 +136,7 @@ class SettingStore extends HiveStore {
late final sftpOpenLastPath = propertyDefault('sftpOpenLastPath', true);
/// Show folders first in SFTP file browser
late final sftpShowFoldersFirst =
propertyDefault('sftpShowFoldersFirst', true);
late final sftpShowFoldersFirst = propertyDefault('sftpShowFoldersFirst', true);
/// Show tip of suspend
late final showSuspendTip = propertyDefault('showSuspendTip', true);
@@ -152,9 +144,9 @@ class SettingStore extends HiveStore {
/// Whether collapse UI items by default
late final collapseUIDefault = propertyDefault('collapseUIDefault', true);
late final serverFuncBtns = propertyDefault(
late final serverFuncBtns = listProperty(
'serverBtns',
ServerFuncBtn.defaultIdxs,
defaultValue: ServerFuncBtn.defaultIdxs,
);
/// Docker is more popular than podman, set to `false` to use docker
@@ -170,8 +162,7 @@ class SettingStore extends HiveStore {
late final containerParseStat = propertyDefault('containerParseStat', true);
/// Auto refresh container status
late final contaienrAutoRefresh =
propertyDefault('contaienrAutoRefresh', true);
late final contaienrAutoRefresh = propertyDefault('contaienrAutoRefresh', true);
/// Use double column servers page on Desktop
late final doubleColumnServersPage = propertyDefault(
@@ -229,9 +220,8 @@ class SettingStore extends HiveStore {
/// Record the position and size of the window.
late final windowState = property<WindowState>(
'windowState',
fromStr: (jsonStr) =>
WindowState.fromJson(jsonDecode(jsonStr) as Map<String, dynamic>),
toStr: (state) => state == null ? null : jsonEncode(state.toJson()),
fromObj: (raw) => WindowState.fromJson(jsonDecode(raw as String) as Map<String, dynamic>),
toObj: (state) => state == null ? null : jsonEncode(state.toJson()),
);
late final introVer = propertyDefault('introVer', 0);
@@ -248,15 +238,9 @@ class SettingStore extends HiveStore {
/// Close the editor after saving
late final closeAfterSave = propertyDefault('closeAfterSave', false);
// Never show these settings for users
//
// ------BEGIN------
/// Version of store db
late final storeVersion = propertyDefault('storeVersion', 0);
/// Have notified user for notificaiton permission or not
late final noNotiPerm = propertyDefault('noNotiPerm', false);
// ------END------
}

View File

@@ -14,8 +14,25 @@ class SnippetStore extends HiveStore {
List<Snippet> fetch() {
final ss = <Snippet>{};
for (final key in keys()) {
final s = box.get(key);
if (s != null && s is Snippet) {
final s = get<Snippet>(
key,
fromObj: (val) {
if (val is Snippet) return val;
if (val is Map<dynamic, dynamic>) {
final map = val.toStrDynMap;
if (map == null) return null;
try {
final snippet = Snippet.fromJson(map as Map<String, dynamic>);
put(snippet);
return snippet;
} catch (e) {
dprint('Parsing Snippet from JSON', e);
}
}
return null;
},
);
if (s != null) {
ss.add(s);
}
}

View File

@@ -116,7 +116,7 @@ abstract class AppLocalizations {
Locale('tr'),
Locale('uk'),
Locale('zh'),
Locale('zh', 'TW')
Locale('zh', 'TW'),
];
/// No description provided for @aboutThanks.
@@ -370,7 +370,9 @@ abstract class AppLocalizations {
/// In en, this message translates to:
/// **'{runningCount} running, {stoppedCount} container stopped.'**
String dockerStatusRunningAndStoppedFmt(
Object runningCount, Object stoppedCount);
Object runningCount,
Object stoppedCount,
);
/// No description provided for @dockerStatusRunningFmt.
///
@@ -1499,7 +1501,7 @@ class _AppLocalizationsDelegate
'ru',
'tr',
'uk',
'zh'
'zh',
].contains(locale.languageCode);
@override
@@ -1551,5 +1553,6 @@ AppLocalizations lookupAppLocalizations(Locale locale) {
'AppLocalizations.delegate failed to load unsupported locale "$locale". This is likely '
'an issue with the localizations generation tool. Please file an issue '
'on GitHub with a reproducible sample app and the gen-l10n configuration '
'that was used.');
'that was used.',
);
}

View File

@@ -149,7 +149,9 @@ class AppLocalizationsDe extends AppLocalizations {
@override
String dockerStatusRunningAndStoppedFmt(
Object runningCount, Object stoppedCount) {
Object runningCount,
Object stoppedCount,
) {
return '$runningCount aktiv, $stoppedCount container gestoppt.';
}

View File

@@ -148,7 +148,9 @@ class AppLocalizationsEn extends AppLocalizations {
@override
String dockerStatusRunningAndStoppedFmt(
Object runningCount, Object stoppedCount) {
Object runningCount,
Object stoppedCount,
) {
return '$runningCount running, $stoppedCount container stopped.';
}

View File

@@ -149,7 +149,9 @@ class AppLocalizationsEs extends AppLocalizations {
@override
String dockerStatusRunningAndStoppedFmt(
Object runningCount, Object stoppedCount) {
Object runningCount,
Object stoppedCount,
) {
return '$runningCount en ejecución, $stoppedCount detenidos';
}

View File

@@ -149,7 +149,9 @@ class AppLocalizationsFr extends AppLocalizations {
@override
String dockerStatusRunningAndStoppedFmt(
Object runningCount, Object stoppedCount) {
Object runningCount,
Object stoppedCount,
) {
return '$runningCount en cours d\'exécution, $stoppedCount conteneur arrêté.';
}

View File

@@ -148,7 +148,9 @@ class AppLocalizationsId extends AppLocalizations {
@override
String dockerStatusRunningAndStoppedFmt(
Object runningCount, Object stoppedCount) {
Object runningCount,
Object stoppedCount,
) {
return '$runningCount running, $stoppedCount container stopped.';
}

View File

@@ -142,7 +142,9 @@ class AppLocalizationsJa extends AppLocalizations {
@override
String dockerStatusRunningAndStoppedFmt(
Object runningCount, Object stoppedCount) {
Object runningCount,
Object stoppedCount,
) {
return '$runningCount個が実行中$stoppedCount個が停止中';
}

View File

@@ -148,7 +148,9 @@ class AppLocalizationsNl extends AppLocalizations {
@override
String dockerStatusRunningAndStoppedFmt(
Object runningCount, Object stoppedCount) {
Object runningCount,
Object stoppedCount,
) {
return '$runningCount actief, $stoppedCount container gestopt.';
}

View File

@@ -148,7 +148,9 @@ class AppLocalizationsPt extends AppLocalizations {
@override
String dockerStatusRunningAndStoppedFmt(
Object runningCount, Object stoppedCount) {
Object runningCount,
Object stoppedCount,
) {
return '$runningCount em execução, $stoppedCount parados';
}

View File

@@ -148,7 +148,9 @@ class AppLocalizationsRu extends AppLocalizations {
@override
String dockerStatusRunningAndStoppedFmt(
Object runningCount, Object stoppedCount) {
Object runningCount,
Object stoppedCount,
) {
return '$runningCount запущено, $stoppedCount остановлено';
}

View File

@@ -147,7 +147,9 @@ class AppLocalizationsTr extends AppLocalizations {
@override
String dockerStatusRunningAndStoppedFmt(
Object runningCount, Object stoppedCount) {
Object runningCount,
Object stoppedCount,
) {
return '$runningCount çalışıyor, $stoppedCount konteyner durdurulmuş.';
}

View File

@@ -149,7 +149,9 @@ class AppLocalizationsUk extends AppLocalizations {
@override
String dockerStatusRunningAndStoppedFmt(
Object runningCount, Object stoppedCount) {
Object runningCount,
Object stoppedCount,
) {
return '$runningCount запущено, $stoppedCount контейнерів зупинено.';
}

View File

@@ -141,7 +141,9 @@ class AppLocalizationsZh extends AppLocalizations {
@override
String dockerStatusRunningAndStoppedFmt(
Object runningCount, Object stoppedCount) {
Object runningCount,
Object stoppedCount,
) {
return '$runningCount 个正在运行, $stoppedCount 个已停止';
}
@@ -858,7 +860,9 @@ class AppLocalizationsZhTw extends AppLocalizationsZh {
@override
String dockerStatusRunningAndStoppedFmt(
Object runningCount, Object stoppedCount) {
Object runningCount,
Object stoppedCount,
) {
return '$runningCount 個正在運行, $stoppedCount 個已停止';
}

View File

@@ -0,0 +1,21 @@
import 'package:hive_ce/hive.dart';
import 'package:server_box/data/model/app/menu/server_func.dart';
import 'package:server_box/data/model/app/net_view.dart';
import 'package:server_box/data/model/server/custom.dart';
import 'package:server_box/data/model/server/private_key_info.dart';
import 'package:server_box/data/model/server/server_private_info.dart';
import 'package:server_box/data/model/server/snippet.dart';
import 'package:server_box/data/model/server/wol_cfg.dart';
import 'package:server_box/data/model/ssh/virtual_key.dart';
@GenerateAdapters([
AdapterSpec<PrivateKeyInfo>(),
AdapterSpec<Snippet>(),
AdapterSpec<Spi>(),
AdapterSpec<VirtKey>(),
AdapterSpec<NetViewType>(),
AdapterSpec<ServerFuncBtn>(),
AdapterSpec<ServerCustom>(),
AdapterSpec<WakeOnLanCfg>(),
])
part 'hive_adapters.g.dart';

View File

@@ -0,0 +1,555 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'hive_adapters.dart';
// **************************************************************************
// AdaptersGenerator
// **************************************************************************
class PrivateKeyInfoAdapter extends TypeAdapter<PrivateKeyInfo> {
@override
final typeId = 1;
@override
PrivateKeyInfo read(BinaryReader reader) {
final numOfFields = reader.readByte();
final fields = <int, dynamic>{
for (int i = 0; i < numOfFields; i++) reader.readByte(): reader.read(),
};
return PrivateKeyInfo(id: fields[0] as String, key: fields[1] as String);
}
@override
void write(BinaryWriter writer, PrivateKeyInfo obj) {
writer
..writeByte(2)
..writeByte(0)
..write(obj.id)
..writeByte(1)
..write(obj.key);
}
@override
int get hashCode => typeId.hashCode;
@override
bool operator ==(Object other) =>
identical(this, other) ||
other is PrivateKeyInfoAdapter &&
runtimeType == other.runtimeType &&
typeId == other.typeId;
}
class SnippetAdapter extends TypeAdapter<Snippet> {
@override
final typeId = 2;
@override
Snippet read(BinaryReader reader) {
final numOfFields = reader.readByte();
final fields = <int, dynamic>{
for (int i = 0; i < numOfFields; i++) reader.readByte(): reader.read(),
};
return Snippet(
name: fields[0] as String,
script: fields[1] as String,
tags: (fields[2] as List?)?.cast<String>(),
note: fields[3] as String?,
autoRunOn: (fields[4] as List?)?.cast<String>(),
);
}
@override
void write(BinaryWriter writer, Snippet obj) {
writer
..writeByte(5)
..writeByte(0)
..write(obj.name)
..writeByte(1)
..write(obj.script)
..writeByte(2)
..write(obj.tags)
..writeByte(3)
..write(obj.note)
..writeByte(4)
..write(obj.autoRunOn);
}
@override
int get hashCode => typeId.hashCode;
@override
bool operator ==(Object other) =>
identical(this, other) ||
other is SnippetAdapter &&
runtimeType == other.runtimeType &&
typeId == other.typeId;
}
class SpiAdapter extends TypeAdapter<Spi> {
@override
final typeId = 3;
@override
Spi read(BinaryReader reader) {
final numOfFields = reader.readByte();
final fields = <int, dynamic>{
for (int i = 0; i < numOfFields; i++) reader.readByte(): reader.read(),
};
return Spi(
name: fields[0] as String,
ip: fields[1] as String,
port: (fields[2] as num).toInt(),
user: fields[3] as String,
pwd: fields[4] as String?,
keyId: fields[5] as String?,
tags: (fields[6] as List?)?.cast<String>(),
alterUrl: fields[7] as String?,
autoConnect: fields[8] == null ? true : fields[8] as bool,
jumpId: fields[9] as String?,
custom: fields[10] as ServerCustom?,
wolCfg: fields[11] as WakeOnLanCfg?,
envs: (fields[12] as Map?)?.cast<String, String>(),
id: fields[13] == null ? '' : fields[13] as String,
);
}
@override
void write(BinaryWriter writer, Spi obj) {
writer
..writeByte(14)
..writeByte(0)
..write(obj.name)
..writeByte(1)
..write(obj.ip)
..writeByte(2)
..write(obj.port)
..writeByte(3)
..write(obj.user)
..writeByte(4)
..write(obj.pwd)
..writeByte(5)
..write(obj.keyId)
..writeByte(6)
..write(obj.tags)
..writeByte(7)
..write(obj.alterUrl)
..writeByte(8)
..write(obj.autoConnect)
..writeByte(9)
..write(obj.jumpId)
..writeByte(10)
..write(obj.custom)
..writeByte(11)
..write(obj.wolCfg)
..writeByte(12)
..write(obj.envs)
..writeByte(13)
..write(obj.id);
}
@override
int get hashCode => typeId.hashCode;
@override
bool operator ==(Object other) =>
identical(this, other) ||
other is SpiAdapter &&
runtimeType == other.runtimeType &&
typeId == other.typeId;
}
class VirtKeyAdapter extends TypeAdapter<VirtKey> {
@override
final typeId = 4;
@override
VirtKey read(BinaryReader reader) {
switch (reader.readByte()) {
case 0:
return VirtKey.esc;
case 1:
return VirtKey.alt;
case 2:
return VirtKey.home;
case 3:
return VirtKey.up;
case 4:
return VirtKey.end;
case 5:
return VirtKey.sftp;
case 6:
return VirtKey.snippet;
case 7:
return VirtKey.tab;
case 8:
return VirtKey.ctrl;
case 9:
return VirtKey.left;
case 10:
return VirtKey.down;
case 11:
return VirtKey.right;
case 12:
return VirtKey.clipboard;
case 13:
return VirtKey.ime;
case 14:
return VirtKey.pgup;
case 15:
return VirtKey.pgdn;
case 16:
return VirtKey.slash;
case 17:
return VirtKey.backSlash;
case 18:
return VirtKey.underscore;
case 19:
return VirtKey.plus;
case 20:
return VirtKey.equal;
case 21:
return VirtKey.minus;
case 22:
return VirtKey.parenLeft;
case 23:
return VirtKey.parenRight;
case 24:
return VirtKey.bracketLeft;
case 25:
return VirtKey.bracketRight;
case 26:
return VirtKey.braceLeft;
case 27:
return VirtKey.braceRight;
case 28:
return VirtKey.chevronLeft;
case 29:
return VirtKey.chevronRight;
case 30:
return VirtKey.colon;
case 31:
return VirtKey.semicolon;
case 32:
return VirtKey.f1;
case 33:
return VirtKey.f2;
case 34:
return VirtKey.f3;
case 35:
return VirtKey.f4;
case 36:
return VirtKey.f5;
case 37:
return VirtKey.f6;
case 38:
return VirtKey.f7;
case 39:
return VirtKey.f8;
case 40:
return VirtKey.f9;
case 41:
return VirtKey.f10;
case 42:
return VirtKey.f11;
case 43:
return VirtKey.f12;
default:
return VirtKey.esc;
}
}
@override
void write(BinaryWriter writer, VirtKey obj) {
switch (obj) {
case VirtKey.esc:
writer.writeByte(0);
case VirtKey.alt:
writer.writeByte(1);
case VirtKey.home:
writer.writeByte(2);
case VirtKey.up:
writer.writeByte(3);
case VirtKey.end:
writer.writeByte(4);
case VirtKey.sftp:
writer.writeByte(5);
case VirtKey.snippet:
writer.writeByte(6);
case VirtKey.tab:
writer.writeByte(7);
case VirtKey.ctrl:
writer.writeByte(8);
case VirtKey.left:
writer.writeByte(9);
case VirtKey.down:
writer.writeByte(10);
case VirtKey.right:
writer.writeByte(11);
case VirtKey.clipboard:
writer.writeByte(12);
case VirtKey.ime:
writer.writeByte(13);
case VirtKey.pgup:
writer.writeByte(14);
case VirtKey.pgdn:
writer.writeByte(15);
case VirtKey.slash:
writer.writeByte(16);
case VirtKey.backSlash:
writer.writeByte(17);
case VirtKey.underscore:
writer.writeByte(18);
case VirtKey.plus:
writer.writeByte(19);
case VirtKey.equal:
writer.writeByte(20);
case VirtKey.minus:
writer.writeByte(21);
case VirtKey.parenLeft:
writer.writeByte(22);
case VirtKey.parenRight:
writer.writeByte(23);
case VirtKey.bracketLeft:
writer.writeByte(24);
case VirtKey.bracketRight:
writer.writeByte(25);
case VirtKey.braceLeft:
writer.writeByte(26);
case VirtKey.braceRight:
writer.writeByte(27);
case VirtKey.chevronLeft:
writer.writeByte(28);
case VirtKey.chevronRight:
writer.writeByte(29);
case VirtKey.colon:
writer.writeByte(30);
case VirtKey.semicolon:
writer.writeByte(31);
case VirtKey.f1:
writer.writeByte(32);
case VirtKey.f2:
writer.writeByte(33);
case VirtKey.f3:
writer.writeByte(34);
case VirtKey.f4:
writer.writeByte(35);
case VirtKey.f5:
writer.writeByte(36);
case VirtKey.f6:
writer.writeByte(37);
case VirtKey.f7:
writer.writeByte(38);
case VirtKey.f8:
writer.writeByte(39);
case VirtKey.f9:
writer.writeByte(40);
case VirtKey.f10:
writer.writeByte(41);
case VirtKey.f11:
writer.writeByte(42);
case VirtKey.f12:
writer.writeByte(43);
}
}
@override
int get hashCode => typeId.hashCode;
@override
bool operator ==(Object other) =>
identical(this, other) ||
other is VirtKeyAdapter &&
runtimeType == other.runtimeType &&
typeId == other.typeId;
}
class NetViewTypeAdapter extends TypeAdapter<NetViewType> {
@override
final typeId = 5;
@override
NetViewType read(BinaryReader reader) {
switch (reader.readByte()) {
case 0:
return NetViewType.conn;
case 1:
return NetViewType.speed;
case 2:
return NetViewType.traffic;
default:
return NetViewType.conn;
}
}
@override
void write(BinaryWriter writer, NetViewType obj) {
switch (obj) {
case NetViewType.conn:
writer.writeByte(0);
case NetViewType.speed:
writer.writeByte(1);
case NetViewType.traffic:
writer.writeByte(2);
}
}
@override
int get hashCode => typeId.hashCode;
@override
bool operator ==(Object other) =>
identical(this, other) ||
other is NetViewTypeAdapter &&
runtimeType == other.runtimeType &&
typeId == other.typeId;
}
class ServerFuncBtnAdapter extends TypeAdapter<ServerFuncBtn> {
@override
final typeId = 6;
@override
ServerFuncBtn read(BinaryReader reader) {
switch (reader.readByte()) {
case 0:
return ServerFuncBtn.terminal;
case 1:
return ServerFuncBtn.sftp;
case 2:
return ServerFuncBtn.container;
case 3:
return ServerFuncBtn.process;
case 5:
return ServerFuncBtn.snippet;
case 6:
return ServerFuncBtn.iperf;
case 8:
return ServerFuncBtn.systemd;
default:
return ServerFuncBtn.terminal;
}
}
@override
void write(BinaryWriter writer, ServerFuncBtn obj) {
switch (obj) {
case ServerFuncBtn.terminal:
writer.writeByte(0);
case ServerFuncBtn.sftp:
writer.writeByte(1);
case ServerFuncBtn.container:
writer.writeByte(2);
case ServerFuncBtn.process:
writer.writeByte(3);
case ServerFuncBtn.snippet:
writer.writeByte(5);
case ServerFuncBtn.iperf:
writer.writeByte(6);
case ServerFuncBtn.systemd:
writer.writeByte(8);
}
}
@override
int get hashCode => typeId.hashCode;
@override
bool operator ==(Object other) =>
identical(this, other) ||
other is ServerFuncBtnAdapter &&
runtimeType == other.runtimeType &&
typeId == other.typeId;
}
class ServerCustomAdapter extends TypeAdapter<ServerCustom> {
@override
final typeId = 7;
@override
ServerCustom read(BinaryReader reader) {
final numOfFields = reader.readByte();
final fields = <int, dynamic>{
for (int i = 0; i < numOfFields; i++) reader.readByte(): reader.read(),
};
return ServerCustom(
pveAddr: fields[1] as String?,
pveIgnoreCert: fields[2] == null ? false : fields[2] as bool,
cmds: (fields[3] as Map?)?.cast<String, String>(),
preferTempDev: fields[4] as String?,
logoUrl: fields[5] as String?,
netDev: fields[6] as String?,
scriptDir: fields[7] as String?,
);
}
@override
void write(BinaryWriter writer, ServerCustom obj) {
writer
..writeByte(7)
..writeByte(1)
..write(obj.pveAddr)
..writeByte(2)
..write(obj.pveIgnoreCert)
..writeByte(3)
..write(obj.cmds)
..writeByte(4)
..write(obj.preferTempDev)
..writeByte(5)
..write(obj.logoUrl)
..writeByte(6)
..write(obj.netDev)
..writeByte(7)
..write(obj.scriptDir);
}
@override
int get hashCode => typeId.hashCode;
@override
bool operator ==(Object other) =>
identical(this, other) ||
other is ServerCustomAdapter &&
runtimeType == other.runtimeType &&
typeId == other.typeId;
}
class WakeOnLanCfgAdapter extends TypeAdapter<WakeOnLanCfg> {
@override
final typeId = 8;
@override
WakeOnLanCfg read(BinaryReader reader) {
final numOfFields = reader.readByte();
final fields = <int, dynamic>{
for (int i = 0; i < numOfFields; i++) reader.readByte(): reader.read(),
};
return WakeOnLanCfg(
mac: fields[0] as String,
ip: fields[1] as String,
pwd: fields[2] as String?,
);
}
@override
void write(BinaryWriter writer, WakeOnLanCfg obj) {
writer
..writeByte(3)
..writeByte(0)
..write(obj.mac)
..writeByte(1)
..write(obj.ip)
..writeByte(2)
..write(obj.pwd);
}
@override
int get hashCode => typeId.hashCode;
@override
bool operator ==(Object other) =>
identical(this, other) ||
other is WakeOnLanCfgAdapter &&
runtimeType == other.runtimeType &&
typeId == other.typeId;
}

View File

@@ -0,0 +1,207 @@
# Generated by Hive CE
# Manual modifications may be necessary for certain migrations
# Check in to version control
nextTypeId: 9
types:
PrivateKeyInfo:
typeId: 1
nextIndex: 2
fields:
id:
index: 0
key:
index: 1
Snippet:
typeId: 2
nextIndex: 5
fields:
name:
index: 0
script:
index: 1
tags:
index: 2
note:
index: 3
autoRunOn:
index: 4
Spi:
typeId: 3
nextIndex: 14
fields:
name:
index: 0
ip:
index: 1
port:
index: 2
user:
index: 3
pwd:
index: 4
keyId:
index: 5
tags:
index: 6
alterUrl:
index: 7
autoConnect:
index: 8
jumpId:
index: 9
custom:
index: 10
wolCfg:
index: 11
envs:
index: 12
id:
index: 13
VirtKey:
typeId: 4
nextIndex: 44
fields:
esc:
index: 0
alt:
index: 1
home:
index: 2
up:
index: 3
end:
index: 4
sftp:
index: 5
snippet:
index: 6
tab:
index: 7
ctrl:
index: 8
left:
index: 9
down:
index: 10
right:
index: 11
clipboard:
index: 12
ime:
index: 13
pgup:
index: 14
pgdn:
index: 15
slash:
index: 16
backSlash:
index: 17
underscore:
index: 18
plus:
index: 19
equal:
index: 20
minus:
index: 21
parenLeft:
index: 22
parenRight:
index: 23
bracketLeft:
index: 24
bracketRight:
index: 25
braceLeft:
index: 26
braceRight:
index: 27
chevronLeft:
index: 28
chevronRight:
index: 29
colon:
index: 30
semicolon:
index: 31
f1:
index: 32
f2:
index: 33
f3:
index: 34
f4:
index: 35
f5:
index: 36
f6:
index: 37
f7:
index: 38
f8:
index: 39
f9:
index: 40
f10:
index: 41
f11:
index: 42
f12:
index: 43
NetViewType:
typeId: 5
nextIndex: 3
fields:
conn:
index: 0
speed:
index: 1
traffic:
index: 2
ServerFuncBtn:
typeId: 6
nextIndex: 9
fields:
terminal:
index: 0
sftp:
index: 1
container:
index: 2
process:
index: 3
snippet:
index: 5
iperf:
index: 6
systemd:
index: 8
ServerCustom:
typeId: 7
nextIndex: 8
fields:
pveAddr:
index: 1
pveIgnoreCert:
index: 2
cmds:
index: 3
preferTempDev:
index: 4
logoUrl:
index: 5
netDev:
index: 6
scriptDir:
index: 7
WakeOnLanCfg:
typeId: 8
nextIndex: 3
fields:
mac:
index: 0
ip:
index: 1
pwd:
index: 2

View File

@@ -0,0 +1,32 @@
// Generated by Hive CE
// Do not modify
// Check in to version control
import 'package:hive_ce/hive.dart';
import 'package:server_box/hive/hive_adapters.dart';
extension HiveRegistrar on HiveInterface {
void registerAdapters() {
registerAdapter(NetViewTypeAdapter());
registerAdapter(PrivateKeyInfoAdapter());
registerAdapter(ServerCustomAdapter());
registerAdapter(ServerFuncBtnAdapter());
registerAdapter(SnippetAdapter());
registerAdapter(SpiAdapter());
registerAdapter(VirtKeyAdapter());
registerAdapter(WakeOnLanCfgAdapter());
}
}
extension IsolatedHiveRegistrar on IsolatedHiveInterface {
void registerAdapters() {
registerAdapter(NetViewTypeAdapter());
registerAdapter(PrivateKeyInfoAdapter());
registerAdapter(ServerCustomAdapter());
registerAdapter(ServerFuncBtnAdapter());
registerAdapter(SnippetAdapter());
registerAdapter(SpiAdapter());
registerAdapter(VirtKeyAdapter());
registerAdapter(WakeOnLanCfgAdapter());
}
}

View File

@@ -6,19 +6,12 @@ import 'package:computer/computer.dart';
import 'package:fl_lib/fl_lib.dart';
import 'package:flutter/material.dart';
import 'package:flutter_displaymode/flutter_displaymode.dart';
import 'package:hive_flutter/hive_flutter.dart';
import 'package:hive_ce_flutter/hive_flutter.dart';
import 'package:logging/logging.dart';
import 'package:server_box/app.dart';
import 'package:server_box/core/sync.dart';
import 'package:server_box/data/model/app/menu/server_func.dart';
import 'package:server_box/data/model/app/net_view.dart';
import 'package:server_box/data/model/app/server_detail_card.dart';
import 'package:server_box/data/model/server/custom.dart';
import 'package:server_box/data/model/server/private_key_info.dart';
import 'package:server_box/data/model/server/server_private_info.dart';
import 'package:server_box/data/model/server/snippet.dart';
import 'package:server_box/data/model/server/wol_cfg.dart';
import 'package:server_box/data/model/ssh/virtual_key.dart';
import 'package:server_box/data/provider/private_key.dart';
import 'package:server_box/data/provider/server.dart';
import 'package:server_box/data/provider/sftp.dart';
@@ -26,6 +19,7 @@ import 'package:server_box/data/provider/snippet.dart';
import 'package:server_box/data/res/build_data.dart';
import 'package:server_box/data/res/store.dart';
import 'package:server_box/data/store/server.dart';
import 'package:server_box/hive/hive_registrar.g.dart';
Future<void> main() async {
_runInZone(() async {
@@ -41,37 +35,24 @@ void _runInZone(void Function() body) {
},
);
runZonedGuarded(
body,
(e, s) => print('[ZONE] $e\n$s'),
zoneSpecification: zoneSpec,
);
runZonedGuarded(body, (e, s) => print('[ZONE] $e\n$s'), zoneSpecification: zoneSpec);
}
Future<void> _initApp() async {
WidgetsFlutterBinding.ensureInitialized();
await Paths.init(BuildData.name, bakName: 'srvbox_bak.json');
await _initData();
_setupDebug();
await _initWindow();
FontUtils.loadFrom(Stores.setting.fontPath.fetch());
_doPlatformRelated();
}
Future<void> _initData() async {
await Hive.initFlutter();
await Paths.init(BuildData.name, bakName: 'srvbox_bak.json');
// Ordered by typeId
Hive.registerAdapter(PrivateKeyInfoAdapter()); // 1
Hive.registerAdapter(SnippetAdapter()); // 2
Hive.registerAdapter(SpiAdapter()); // 3
Hive.registerAdapter(VirtKeyAdapter()); // 4
Hive.registerAdapter(NetViewTypeAdapter()); // 5
Hive.registerAdapter(ServerFuncBtnAdapter()); // 6
Hive.registerAdapter(ServerCustomAdapter()); // 7
Hive.registerAdapter(WakeOnLanCfgAdapter()); // 8
await Hive.initFlutter();
Hive.registerAdapters();
await PrefStore.shared.init(); // Call this before accessing any store
await Stores.init();
@@ -87,13 +68,15 @@ Future<void> _initData() async {
SftpProvider.instance.load();
if (Stores.setting.betaTest.fetch()) AppUpdate.chan = AppUpdateChan.beta;
FontUtils.loadFrom(Stores.setting.fontPath.fetch());
}
void _setupDebug() {
Logger.root.level = Level.ALL;
Logger.root.onRecord.listen((record) {
DebugProvider.addLog(record);
print(record);
lprint(record);
if (record.error != null) print(record.error);
if (record.stackTrace != null) print(record.stackTrace);
});
@@ -106,8 +89,7 @@ void _doPlatformRelated() async {
}
final serversCount = Stores.server.keys().length;
// Plus 1 to avoid 0.
Computer.shared.turnOn(workersCount: (serversCount / 3).round() + 1);
Computer.shared.turnOn(workersCount: (serversCount / 3).round() + 1); // Plus 1 to avoid 0.
bakSync.sync();
}
@@ -135,7 +117,7 @@ Future<void> _initWindow() async {
final hideTitleBar = Stores.setting.hideTitleBar.fetch();
await SystemUIs.initDesktopWindow(
hideTitleBar: hideTitleBar,
size: windowState?.size,
size: windowState?.size ?? Size(947, 487),
position: windowState?.position,
listener: WindowStateListener(windowStateProp),
);

View File

@@ -6,7 +6,8 @@ import 'package:fl_lib/fl_lib.dart';
import 'package:flutter/material.dart';
import 'package:server_box/core/extension/context/locale.dart';
import 'package:server_box/core/sync.dart';
import 'package:server_box/data/model/app/backup.dart';
import 'package:server_box/data/model/app/bak/backup2.dart';
import 'package:server_box/data/model/app/bak/utils.dart';
import 'package:server_box/data/model/server/server_private_info.dart';
import 'package:server_box/data/model/server/snippet.dart';
import 'package:server_box/data/provider/snippet.dart';
@@ -27,14 +28,11 @@ class BackupPage extends StatefulWidget {
);
}
final class _BackupPageState extends State<BackupPage>
with AutomaticKeepAliveClientMixin {
final icloudLoading = false.vn;
final class _BackupPageState extends State<BackupPage> with AutomaticKeepAliveClientMixin {
final webdavLoading = false.vn;
@override
void dispose() {
icloudLoading.dispose();
webdavLoading.dispose();
super.dispose();
}
@@ -89,7 +87,7 @@ final class _BackupPageState extends State<BackupPage>
title: Text(libL10n.backup),
trailing: const Icon(Icons.save),
onTap: () async {
final path = await Backup.backup();
final path = await BackupV2.backup();
await Pfs.sharePaths(paths: [path]);
},
),
@@ -110,19 +108,15 @@ final class _BackupPageState extends State<BackupPage>
title: const Text('iCloud'),
trailing: StoreSwitch(
prop: PrefProps.icloudSync,
validator: (p0) {
validator: (p0) async {
if (p0 && PrefProps.webdavSync.get()) {
context.showSnackBar(l10n.autoBackupConflict);
return false;
}
return true;
},
callback: (val) async {
if (val) {
icloudLoading.value = true;
if (p0) {
await bakSync.sync(rs: icloud);
icloudLoading.value = false;
}
return true;
},
),
),
@@ -145,7 +139,11 @@ final class _BackupPageState extends State<BackupPage>
title: Text(libL10n.auto),
trailing: StoreSwitch(
prop: PrefProps.webdavSync,
validator: (p0) {
validator: (p0) async {
if (p0 && PrefProps.icloudSync.get()) {
context.showSnackBar(l10n.autoBackupConflict);
return false;
}
if (p0) {
final url = PrefProps.webdavUrl.get();
final user = PrefProps.webdavUser.get();
@@ -162,28 +160,20 @@ final class _BackupPageState extends State<BackupPage>
context.showSnackBar(l10n.webdavSettingEmpty);
return false;
}
}
if (PrefProps.icloudSync.get()) {
context.showSnackBar(l10n.autoBackupConflict);
return false;
}
return true;
},
callback: (val) async {
if (val) {
webdavLoading.value = true;
await bakSync.sync(rs: Webdav.shared);
webdavLoading.value = false;
}
return true;
},
),
),
ListTile(
title: Text(l10n.manual),
trailing: ListenableBuilder(
listenable: webdavLoading,
builder: (_, __) {
if (webdavLoading.value) return SizedLoading.small;
trailing: webdavLoading.listenVal(
(loading) {
if (loading) return SizedLoading.small;
return Row(
mainAxisSize: MainAxisSize.min,
@@ -217,7 +207,7 @@ final class _BackupPageState extends State<BackupPage>
title: Text(libL10n.backup),
trailing: const Icon(Icons.save),
onTap: () async {
final path = await Backup.backup();
final path = await BackupV2.backup();
Pfs.copy(await File(path).readAsString());
context.showSnackBar(libL10n.success);
},
@@ -310,22 +300,18 @@ final class _BackupPageState extends State<BackupPage>
try {
final (backup, err) = await context.showLoadingDialog(
fn: () => Computer.shared.start(Backup.fromJsonString, text.trim()),
fn: () => Computer.shared.start(MergeableUtils.fromJsonString, text.trim()),
);
if (err != null || backup == null) return;
if (backupFormatVersion != backup.version) {
context.showSnackBar(l10n.backupVersionNotMatch);
return;
}
await context.showRoundDialog(
title: libL10n.restore,
child: Text(libL10n.askContinue(
'${libL10n.restore} ${libL10n.backup}(${backup.date})',
'${libL10n.restore} ${libL10n.backup}(${backup.$2})',
)),
actions: Btn.ok(
onTap: () async {
await backup.merge(force: true);
await backup.$1.merge(force: true);
context.pop();
},
).toList,
@@ -350,7 +336,7 @@ final class _BackupPageState extends State<BackupPage>
await Webdav.shared.download(relativePath: fileName);
final dlFile = await File('${Paths.doc}/$fileName').readAsString();
final dlBak = await Computer.shared.start(Backup.fromJsonString, dlFile);
final dlBak = await Computer.shared.start(BackupV2.fromJsonString, dlFile);
await dlBak.merge(force: true);
} catch (e, s) {
context.showErrDialog(e, s, libL10n.restore);
@@ -365,7 +351,7 @@ final class _BackupPageState extends State<BackupPage>
final date = DateTime.now().ymdhms(ymdSep: '-', hmsSep: '-', sep: '-');
final bakName = '$date-${Miscs.bakFileName}';
try {
await Backup.backup(bakName);
await BackupV2.backup(bakName);
await Webdav.shared.upload(relativePath: bakName);
Loggers.app.info('Upload webdav backup success');
} catch (e, s) {
@@ -421,8 +407,7 @@ final class _BackupPageState extends State<BackupPage>
await Webdav.test(url_, user_, pwd_);
context.showSnackBar(libL10n.success);
Webdav.shared.client =
WebdavClient.basicAuth(url: url_, user: user_, pwd: pwd_);
Webdav.shared.client = WebdavClient.basicAuth(url: url_, user: user_, pwd: pwd_);
PrefProps.webdavUrl.set(url_);
PrefProps.webdavUser.set(user_);
PrefProps.webdavPwd.set(pwd_);
@@ -441,23 +426,18 @@ final class _BackupPageState extends State<BackupPage>
try {
final (backup, err) = await context.showLoadingDialog(
fn: () => Computer.shared.start(Backup.fromJsonString, text.trim()),
fn: () => Computer.shared.start(MergeableUtils.fromJsonString, text.trim()),
);
if (err != null || backup == null) return;
if (backupFormatVersion != backup.version) {
context.showSnackBar(l10n.backupVersionNotMatch);
return;
}
await context.showRoundDialog(
title: libL10n.restore,
child: Text(libL10n.askContinue(
'${libL10n.restore} ${libL10n.backup}(${backup.date})',
'${libL10n.restore} ${libL10n.backup}(${backup.$2})',
)),
actions: Btn.ok(
onTap: () async {
await backup.merge(force: true);
await backup.$1.merge(force: true);
context.pop();
},
).toList,

View File

@@ -7,8 +7,10 @@ extension on _ServerPageState {
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
ConstrainedBox(
constraints: BoxConstraints(maxWidth: _media.size.width / 2.3),
LayoutBuilder(
builder: (_, cons) {
return ConstrainedBox(
constraints: BoxConstraints(maxWidth: cons.maxWidth / 2.3),
child: Hero(
tag: 'home_card_title_${s.spi.id}',
transitionOnUserGestures: true,
@@ -16,20 +18,16 @@ extension on _ServerPageState {
color: Colors.transparent,
child: Text(
s.spi.name,
style: UIs.text13Bold.copyWith(
color: context.isDark ? Colors.white : Colors.black,
),
style: UIs.text13Bold.copyWith(color: context.isDark ? Colors.white : Colors.black),
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
),
),
);
},
),
const Icon(
Icons.keyboard_arrow_right,
size: 17,
color: Colors.grey,
),
const Icon(Icons.keyboard_arrow_right, size: 17, color: Colors.grey),
const Spacer(),
_buildTopRightText(s),
_buildTopRightWidget(s),
@@ -60,7 +58,7 @@ extension on _ServerPageState {
),
ServerConn.disconnected => (
const Icon(MingCute.link_3_line, size: 19, color: Colors.grey),
() => ServerProvider.refresh(spi: s.spi)
() => ServerProvider.refresh(spi: s.spi),
),
ServerConn.finished => (
const Icon(MingCute.unlink_2_line, size: 17, color: Colors.grey),
@@ -73,11 +71,7 @@ extension on _ServerPageState {
? child
: SizedBox(height: _ServerPageState._kCardHeightMin, width: 27, child: child);
if (onTap == null) return wrapped.paddingOnly(left: 10);
return InkWell(
borderRadius: BorderRadius.circular(7),
onTap: onTap,
child: wrapped,
).paddingOnly(left: 5);
return InkWell(borderRadius: BorderRadius.circular(7), onTap: onTap, child: wrapped).paddingOnly(left: 5);
}
Widget _buildTopRightText(Server s) {
@@ -94,7 +88,8 @@ extension on _ServerPageState {
}
void _showFailReason(ServerStatus ss) {
final md = '''
final md =
'''
${ss.err?.solution ?? l10n.unknown}
```sh
@@ -103,12 +98,7 @@ ${ss.err?.message ?? 'null'}
context.showRoundDialog(
title: libL10n.error,
child: SingleChildScrollView(child: SimpleMarkdown(data: md)),
actions: [
TextButton(
onPressed: () => Pfs.copy(md),
child: Text(libL10n.copy),
)
],
actions: [TextButton(onPressed: () => Pfs.copy(md), child: Text(libL10n.copy))],
);
}
@@ -156,13 +146,7 @@ ${ss.err?.message ?? 'null'}
);
}
Widget _buildIOData(
String up,
String down, {
void Function()? onTap,
Key? key,
int maxLines = 2
}) {
Widget _buildIOData(String up, String down, {void Function()? onTap, Key? key, int maxLines = 2}) {
final child = Column(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center,
@@ -181,7 +165,7 @@ ${ss.err?.message ?? 'null'}
textAlign: TextAlign.center,
textScaler: _textFactor,
maxLines: maxLines,
)
),
],
);
if (onTap == null) return child;

View File

@@ -28,9 +28,7 @@ extension on _ServerPageState {
Widget _buildLandscapeBody() {
return ServerProvider.serverOrder.listenVal((order) {
if (order.isEmpty) {
return Center(
child: Text(libL10n.empty, textAlign: TextAlign.center),
);
return Center(child: Text(libL10n.empty, textAlign: TextAlign.center));
}
return PageView.builder(
@@ -42,14 +40,9 @@ extension on _ServerPageState {
return srv.listenVal((srv) {
final title = _buildServerCardTitle(srv);
final List<Widget> children = [
title,
_buildNormalCard(srv.status, srv.spi),
];
final List<Widget> children = [title, _buildNormalCard(srv.status, srv.spi)];
return Padding(
padding: _media.padding,
child: ListenableBuilder(
return ListenableBuilder(
listenable: _getCardNoti(id),
builder: (_, __) {
return Column(
@@ -59,7 +52,6 @@ extension on _ServerPageState {
children: children,
);
},
),
);
});
},

View File

@@ -37,18 +37,13 @@ class ServerPage extends StatefulWidget {
@override
State<ServerPage> createState() => _ServerPageState();
static const route = AppRouteNoArg(
page: ServerPage.new,
path: '/servers',
);
static const route = AppRouteNoArg(page: ServerPage.new, path: '/servers');
}
const _cardPad = 74.0;
const _cardPadSingle = 13.0;
class _ServerPageState extends State<ServerPage> with AutomaticKeepAliveClientMixin, AfterLayoutMixin {
late MediaQueryData _media;
late double _textFactorDouble;
double _offset = 1;
late TextScaler _textFactor;
@@ -80,7 +75,6 @@ class _ServerPageState extends State<ServerPage> with AutomaticKeepAliveClientMi
@override
void didChangeDependencies() {
super.didChangeDependencies();
_media = MediaQuery.of(context);
_updateOffset();
_updateTextScaler();
}
@@ -88,7 +82,8 @@ class _ServerPageState extends State<ServerPage> with AutomaticKeepAliveClientMi
@override
Widget build(BuildContext context) {
super.build(context);
return OrientationBuilder(builder: (_, orientation) {
return OrientationBuilder(
builder: (_, orientation) {
if (orientation == Orientation.landscape) {
final useFullScreen = Stores.setting.fullScreen.fetch();
// Only enter landscape mode when the screen is wide enough and the
@@ -96,16 +91,13 @@ class _ServerPageState extends State<ServerPage> with AutomaticKeepAliveClientMi
if (useFullScreen) return _buildLandscape();
}
return _buildPortrait();
});
},
);
}
Widget _buildScaffold(Widget child) {
return Scaffold(
appBar: _TopBar(
tags: ServerProvider.tags,
onTagChanged: (p0) => _tag.value = p0,
initTag: _tag.value,
),
appBar: _TopBar(tags: ServerProvider.tags, onTagChanged: (p0) => _tag.value = p0, initTag: _tag.value),
body: GestureDetector(
behavior: HitTestBehavior.opaque,
onTap: () => _autoHideCtrl.show(),
@@ -134,10 +126,8 @@ class _ServerPageState extends State<ServerPage> with AutomaticKeepAliveClientMi
Widget _buildPortrait() {
// final isMobile = ResponsiveBreakpoints.of(context).isMobile;
return ServerProvider.serverOrder.listenVal(
(order) {
return _tag.listenVal(
(val) {
return ServerProvider.serverOrder.listenVal((order) {
return _tag.listenVal((val) {
final filtered = _filterServers(order);
final child = _buildScaffold(_buildBodySmall(filtered: filtered));
// if (isMobile) {
@@ -151,10 +141,8 @@ class _ServerPageState extends State<ServerPage> with AutomaticKeepAliveClientMi
// initialRight: Center(child: CircularProgressIndicator()),
// leftBuilder: (_, __) => child,
// );
},
);
},
);
});
});
}
Widget _buildBodySmall({
@@ -165,34 +153,38 @@ class _ServerPageState extends State<ServerPage> with AutomaticKeepAliveClientMi
return Center(child: Text(libL10n.empty, textAlign: TextAlign.center));
}
return LayoutBuilder(
builder: (_, cons) {
// Calculate number of columns based on available width
final columnsCount = math.max(1, (_media.size.width / UIs.columnWidth).floor());
final columnsCount = math.max(1, (cons.maxWidth / UIs.columnWidth).floor());
// Calculate number of rows needed
final rowCount = (filtered.length + columnsCount - 1) ~/ columnsCount;
return ListView.builder(
controller: _scrollController,
padding: padding,
itemCount: rowCount + 1, // +1 for the bottom space
itemBuilder: (_, rowIndex) {
// Bottom space
if (rowIndex == rowCount) return UIs.height77;
// Create a row of server cards
return Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: List.generate(columnsCount, (colIndex) {
final index = rowIndex * columnsCount + colIndex;
if (index >= filtered.length) return Expanded(child: Container());
final vnode = ServerProvider.pick(id: filtered[index]);
if (vnode == null) return Expanded(child: UIs.placeholder);
// Calculate which servers belong in this column
final serversInThisColumn = <String>[];
for (int i = colIndex; i < filtered.length; i += columnsCount) {
serversInThisColumn.add(filtered[i]);
}
final lens = serversInThisColumn.length;
return Expanded(
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 4.0),
child: ListView.builder(
controller: colIndex == 0 ? _scrollController : null,
padding: padding,
itemCount: lens + 1, // Add 1 for bottom spacing
itemBuilder: (context, index) {
// Last item is just spacing
if (index == lens) return SizedBox(height: 77);
final vnode = ServerProvider.pick(id: serversInThisColumn[index]);
if (vnode == null) return UIs.placeholder;
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 0),
child: vnode.listenVal(_buildEachServerCard),
);
},
),
);
}),
@@ -227,13 +219,12 @@ class _ServerPageState extends State<ServerPage> with AutomaticKeepAliveClientMi
/// The child's width mat not equal to 1/4 of the screen width,
/// so we need to wrap it with a SizedBox.
Widget _wrapWithSizedbox(Widget child, double maxWidth, [bool circle = false]) {
return LayoutBuilder(builder: (_, cons) {
return LayoutBuilder(
builder: (_, cons) {
final width = (maxWidth - _cardPad) / 4;
return SizedBox(
width: width,
child: child,
return SizedBox(width: width, child: child);
},
);
});
}
Widget _buildRealServerCard(Server srv) {
@@ -300,12 +291,13 @@ class _ServerPageState extends State<ServerPage> with AutomaticKeepAliveClientMi
icon: const Icon(Icons.edit, color: color),
text: libL10n.edit,
textStyle: textStyle,
)
),
];
return Padding(
padding: const EdgeInsets.only(top: 9),
child: LayoutBuilder(builder: (_, cons) {
child: LayoutBuilder(
builder: (_, cons) {
final width = (cons.maxWidth - _cardPad) / children.length;
return Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
@@ -314,12 +306,14 @@ class _ServerPageState extends State<ServerPage> with AutomaticKeepAliveClientMi
return SizedBox(width: width, child: e);
}).toList(),
);
}),
},
),
);
}
Widget _buildNormalCard(ServerStatus ss, Spi spi) {
return LayoutBuilder(builder: (_, cons) {
return LayoutBuilder(
builder: (_, cons) {
final maxWidth = cons.maxWidth;
return Column(
mainAxisSize: MainAxisSize.min,
@@ -329,11 +323,7 @@ class _ServerPageState extends State<ServerPage> with AutomaticKeepAliveClientMi
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
_wrapWithSizedbox(PercentCircle(percent: ss.cpu.usedPercent()), maxWidth, true),
_wrapWithSizedbox(
PercentCircle(percent: ss.mem.usedPercent * 100),
maxWidth,
true,
),
_wrapWithSizedbox(PercentCircle(percent: ss.mem.usedPercent * 100), maxWidth, true),
_wrapWithSizedbox(_buildNet(ss, spi.id), maxWidth),
_wrapWithSizedbox(_buildDisk(ss, spi.id), maxWidth),
],
@@ -342,13 +332,11 @@ class _ServerPageState extends State<ServerPage> with AutomaticKeepAliveClientMi
if (Stores.setting.moveServerFuncs.fetch() &&
// Discussion #146
!Stores.setting.serverTabUseOldUI.fetch())
SizedBox(
height: 27,
child: ServerFuncBtns(spi: spi),
),
SizedBox(height: 27, child: ServerFuncBtns(spi: spi)),
],
);
});
},
);
}
@override

View File

@@ -164,7 +164,7 @@ extension _Utils on _ServerPageState {
void _updateOffset() {
if (!Stores.setting.fullScreenJitter.fetch()) return;
final x = _media.size.height * 0.03;
final x = MediaQuery.sizeOf(context).height * 0.03;
final r = math.Random().nextDouble();
final n = math.Random().nextBool() ? 1 : -1;
_offset = x * r * n;

View File

@@ -2,6 +2,7 @@ import 'dart:ui';
import 'package:fl_lib/fl_lib.dart';
import 'package:flutter/material.dart';
import 'package:server_box/core/extension/context/locale.dart';
import 'package:server_box/data/model/server/server_private_info.dart';
import 'package:server_box/data/provider/server.dart';
import 'package:server_box/data/res/store.dart';
@@ -35,17 +36,13 @@ class _ServerOrderPageState extends State<ServerOrderPage> {
final double scale = lerpDouble(1, 1.02, animValue)!;
return Transform.scale(
scale: scale,
// Create a Card based on the color and the content of the dragged one
// and set its elevation to the animated value.
child: Card(
elevation: elevation,
// color: cards[index].color,
// child: cards[index].child,
child: _buildCardTile(index),
child: child,
),
);
},
// child: child,
child: _buildCardTile(index),
);
}
@@ -57,28 +54,34 @@ class _ServerOrderPageState extends State<ServerOrderPage> {
}
return ReorderableListView.builder(
footer: const SizedBox(height: 77),
onReorder: (oldIndex, newIndex) => setState(() {
onReorder: (oldIndex, newIndex) {
setState(() {
orders.value.move(
oldIndex,
newIndex,
property: Stores.setting.serverOrder,
);
orders.notify();
}),
padding: const EdgeInsets.symmetric(horizontal: 7, vertical: 3),
});
},
padding: const EdgeInsets.all(8),
buildDefaultDragHandles: false,
itemBuilder: (_, idx) => _buildItem(idx),
itemBuilder: (_, idx) => _buildItem(idx, order[idx]),
itemCount: order.length,
proxyDecorator: _proxyDecorator,
);
});
}
Widget _buildItem(int index) {
Widget _buildItem(int index, String id) {
return ReorderableDelayedDragStartListener(
key: ValueKey('$index'),
key: ValueKey('server_item_$id'),
index: index,
child: CardX(child: _buildCardTile(index)),
child: Padding(
padding: const EdgeInsets.only(bottom: 8),
child: CardX(
child: _buildCardTile(index),
),
),
);
}
@@ -90,9 +93,14 @@ class _ServerOrderPageState extends State<ServerOrderPage> {
}
return ListTile(
title: Text(spi.name),
subtitle: Text(spi.id, style: UIs.textGrey),
title: Text(
spi.name,
style: const TextStyle(fontWeight: FontWeight.w500),
),
subtitle: Text(spi.oldId, style: UIs.textGrey),
leading: CircleAvatar(
backgroundColor: Theme.of(context).colorScheme.primary,
foregroundColor: Theme.of(context).colorScheme.onPrimary,
child: Text(spi.name[0]),
),
trailing: ReorderableDragStartListener(

View File

@@ -52,7 +52,7 @@ class ServerFuncBtns extends StatelessWidget {
if (btns.isEmpty) return UIs.placeholder;
return SizedBox(
height: 74,
height: 77,
child: ListView.builder(
itemCount: btns.length,
scrollDirection: Axis.horizontal,

View File

@@ -1,19 +1,19 @@
import 'package:fl_lib/fl_lib.dart';
import 'package:flutter/material.dart';
final class RWX {
final class UnixPermOp {
final bool r;
final bool w;
final bool x;
const RWX({
const UnixPermOp({
required this.r,
required this.w,
required this.x,
});
RWX copyWith({bool? r, bool? w, bool? x}) {
return RWX(r: r ?? this.r, w: w ?? this.w, x: x ?? this.x);
UnixPermOp copyWith({bool? r, bool? w, bool? x}) {
return UnixPermOp(r: r ?? this.r, w: w ?? this.w, x: x ?? this.x);
}
int get value {
@@ -37,9 +37,9 @@ enum UnixPermScope {
}
final class UnixPerm {
final RWX user;
final RWX group;
final RWX other;
final UnixPermOp user;
final UnixPermOp group;
final UnixPermOp other;
const UnixPerm({
required this.user,
@@ -47,7 +47,7 @@ final class UnixPerm {
required this.other,
});
UnixPerm copyWith({RWX? user, RWX? group, RWX? other}) {
UnixPerm copyWith({UnixPermOp? user, UnixPermOp? group, UnixPermOp? other}) {
return UnixPerm(
user: user ?? this.user,
group: group ?? this.group,
@@ -55,7 +55,7 @@ final class UnixPerm {
);
}
UnixPerm copyWithScope(UnixPermScope scope, RWX rwx) {
UnixPerm copyWithScope(UnixPermScope scope, UnixPermOp rwx) {
switch (scope) {
case UnixPermScope.user:
return copyWith(user: rwx);
@@ -72,9 +72,9 @@ final class UnixPerm {
}
static UnixPerm get empty => const UnixPerm(
user: RWX(r: false, w: false, x: false),
group: RWX(r: false, w: false, x: false),
other: RWX(r: false, w: false, x: false),
user: UnixPermOp(r: false, w: false, x: false),
group: UnixPermOp(r: false, w: false, x: false),
other: UnixPermOp(r: false, w: false, x: false),
);
}
@@ -110,7 +110,7 @@ final class _UnixPermEditorState extends State<UnixPermEditor> {
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
Text('Read'),
Text('Write'),
Text('Writ'), // Keep it short to fit UI
Text('Exec'),
],
).paddingOnly(left: 13),
@@ -122,7 +122,7 @@ final class _UnixPermEditorState extends State<UnixPermEditor> {
);
}
Widget _buildRow(UnixPermScope scope, RWX rwx) {
Widget _buildRow(UnixPermScope scope, UnixPermOp rwx) {
return Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [

View File

@@ -27,7 +27,7 @@ PODS:
- FlutterMacOS
- wakelock_plus (0.0.1):
- FlutterMacOS
- window_manager (0.2.0):
- window_manager (0.5.0):
- FlutterMacOS
DEPENDENCIES:
@@ -90,7 +90,7 @@ SPEC CHECKSUMS:
shared_preferences_foundation: 9e1978ff2562383bd5676f64ec4e9aa8fa06a6f7
url_launcher_macos: 0fba8ddabfc33ce0a9afe7c5fef5aab3d8d2d673
wakelock_plus: 21ddc249ac4b8d018838dbdabd65c5976c308497
window_manager: 1d01fa7ac65a6e6f83b965471b1a7fdd3f06166c
window_manager: b729e31d38fb04905235df9ea896128991cad99e
PODFILE CHECKSUM: 8cdf29216ea1ab6b9743188287968d22b4579c1d

View File

@@ -5,31 +5,26 @@ packages:
dependency: transitive
description:
name: _fe_analyzer_shared
sha256: "16e298750b6d0af7ce8a3ba7c18c69c3785d11b15ec83f6dcd0ad2a0009b3cab"
sha256: dc27559385e905ad30838356c5f5d574014ba39872d732111cd07ac0beff4c57
url: "https://pub.dev"
source: hosted
version: "76.0.0"
_macros:
dependency: transitive
description: dart
source: sdk
version: "0.3.3"
version: "80.0.0"
analyzer:
dependency: transitive
dependency: "direct dev"
description:
name: analyzer
sha256: "1f14db053a8c23e260789e9b0980fa27f2680dd640932cae5e1137cce0e46e1e"
sha256: "192d1c5b944e7e53b24b5586db760db934b177d4147c42fbca8c8c5f1eb8d11e"
url: "https://pub.dev"
source: hosted
version: "6.11.0"
version: "7.3.0"
analyzer_plugin:
dependency: transitive
description:
name: analyzer_plugin
sha256: "9661b30b13a685efaee9f02e5d01ed9f2b423bd889d28a304d02d704aee69161"
sha256: b3075265c5ab222f8b3188342dcb50b476286394a40323e85d1fa725035d40a4
url: "https://pub.dev"
source: hosted
version: "0.11.3"
version: "0.13.0"
animations:
dependency: transitive
description:
@@ -178,10 +173,10 @@ packages:
dependency: transitive
description:
name: built_value
sha256: ea90e81dc4a25a043d9bee692d20ed6d1c4a1662a28c03a96417446c093ed6b4
sha256: "082001b5c3dc495d4a42f1d5789990505df20d8547d42507c29050af6933ee27"
url: "https://pub.dev"
source: hosted
version: "8.9.5"
version: "8.10.1"
camera:
dependency: transitive
description:
@@ -194,10 +189,10 @@ packages:
dependency: transitive
description:
name: camera_android_camerax
sha256: f0dcbce91623f75030840609de9b64d0d73f86df279c6e9588c1501245a05eb2
sha256: "0bd3d1645df00af2540a22df13ba466ac5fb2838a09bce4089cecdb1712a9e94"
url: "https://pub.dev"
source: hosted
version: "0.6.15+2"
version: "0.6.18"
camera_avfoundation:
dependency: transitive
description:
@@ -254,14 +249,6 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.3.2"
ci:
dependency: transitive
description:
name: ci
sha256: "145d095ce05cddac4d797a158bc4cf3b6016d1fe63d8c3d2fbd7212590adca13"
url: "https://pub.dev"
source: hosted
version: "0.1.0"
circle_chart:
dependency: "direct main"
description:
@@ -271,14 +258,6 @@ packages:
url: "https://github.com/lollipopkit/circle_chart"
source: git
version: "0.0.3"
cli_util:
dependency: transitive
description:
name: cli_util
sha256: ff6785f7e9e3c38ac98b2fb035701789de90154024a75b6cb926445e83197d1c
url: "https://pub.dev"
source: hosted
version: "0.4.2"
clock:
dependency: transitive
description:
@@ -344,46 +323,30 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.0.2"
custom_lint:
dependency: "direct dev"
description:
name: custom_lint
sha256: "3486c470bb93313a9417f926c7dd694a2e349220992d7b9d14534dc49c15bba9"
url: "https://pub.dev"
source: hosted
version: "0.7.0"
custom_lint_builder:
dependency: transitive
description:
name: custom_lint_builder
sha256: "42cdc41994eeeddab0d7a722c7093ec52bd0761921eeb2cbdbf33d192a234759"
url: "https://pub.dev"
source: hosted
version: "0.7.0"
custom_lint_core:
dependency: transitive
description:
name: custom_lint_core
sha256: "02450c3e45e2a6e8b26c4d16687596ab3c4644dd5792e3313aa9ceba5a49b7f5"
sha256: "31110af3dde9d29fb10828ca33f1dce24d2798477b167675543ce3d208dee8be"
url: "https://pub.dev"
source: hosted
version: "0.7.0"
version: "0.7.5"
custom_lint_visitor:
dependency: transitive
description:
name: custom_lint_visitor
sha256: bfe9b7a09c4775a587b58d10ebb871d4fe618237639b1e84d5ec62d7dfef25f9
sha256: "36282d85714af494ee2d7da8c8913630aa6694da99f104fb2ed4afcf8fc857d8"
url: "https://pub.dev"
source: hosted
version: "1.0.0+6.11.0"
version: "1.0.0+7.3.0"
dart_style:
dependency: transitive
description:
name: dart_style
sha256: "7306ab8a2359a48d22310ad823521d723acfed60ee1f7e37388e8986853b6820"
sha256: "5b236382b47ee411741447c1f1e111459c941ea1b3f2b540dde54c210a3662af"
url: "https://pub.dev"
source: hosted
version: "2.3.8"
version: "3.1.0"
dartssh2:
dependency: "direct main"
description:
@@ -517,9 +480,11 @@ packages:
fl_lib:
dependency: "direct main"
description:
path: "../fl_lib"
relative: true
source: path
path: "."
ref: "v1.0.313"
resolved-ref: "234dc4cd1f4c7bbcdb12834dc674f65c243dd8e4"
url: "https://github.com/lppcg/fl_lib"
source: git
version: "0.0.1"
flutter:
dependency: "direct main"
@@ -559,10 +524,10 @@ packages:
dependency: transitive
description:
name: flutter_markdown
sha256: "634622a3a826d67cb05c0e3e576d1812c430fa98404e95b60b131775c73d76ec"
sha256: "08fb8315236099ff8e90cb87bb2b935e0a724a3af1623000a9cec930468e0f27"
url: "https://pub.dev"
source: hosted
version: "0.7.7"
version: "0.7.7+1"
flutter_markdown_latex:
dependency: transitive
description:
@@ -576,7 +541,7 @@ packages:
description:
path: "."
ref: HEAD
resolved-ref: "127cf24e01bff00a4e25a4820295a871020f7a94"
resolved-ref: "2f270aee06d3ca02ca6d108420921472fd10e5cb"
url: "https://github.com/simpleclub/flutter_math"
source: git
version: "0.7.4"
@@ -626,10 +591,10 @@ packages:
dependency: "direct dev"
description:
name: freezed
sha256: "44c19278dd9d89292cf46e97dc0c1e52ce03275f40a97c5a348e802a924bf40e"
sha256: "59a584c24b3acdc5250bb856d0d3e9c0b798ed14a4af1ddb7dc1c7b41df91c9c"
url: "https://pub.dev"
source: hosted
version: "2.5.7"
version: "2.5.8"
freezed_annotation:
dependency: "direct main"
description:
@@ -678,38 +643,30 @@ packages:
url: "https://pub.dev"
source: hosted
version: "0.7.0"
hive:
hive_ce:
dependency: transitive
description:
name: hive
sha256: "8dcf6db979d7933da8217edcec84e9df1bdb4e4edc7fc77dbd5aa74356d6d941"
name: hive_ce
sha256: "708bb39050998707c5d422752159f91944d3c81ab42d80e1bd0ee37d8e130658"
url: "https://pub.dev"
source: hosted
version: "2.2.3"
hive_flutter:
version: "2.11.3"
hive_ce_flutter:
dependency: "direct main"
description:
name: hive_flutter
sha256: dca1da446b1d808a51689fb5d0c6c9510c0a2ba01e22805d492c73b68e33eecc
name: hive_ce_flutter
sha256: a0989670652eab097b47544f1e5a4456e861b1b01b050098ea0b80a5fabe9909
url: "https://pub.dev"
source: hosted
version: "1.1.0"
hive_generator:
version: "2.3.1"
hive_ce_generator:
dependency: "direct dev"
description:
name: hive_generator
sha256: "06cb8f58ace74de61f63500564931f9505368f45f98958bd7a6c35ba24159db4"
name: hive_ce_generator
sha256: "609678c10ebee7503505a0007050af40a0a4f498b1fb7def3220df341e573a89"
url: "https://pub.dev"
source: hosted
version: "2.0.1"
hotreloader:
dependency: transitive
description:
name: hotreloader
sha256: bc167a1163807b03bada490bfe2df25b0d744df359227880220a5cbd04e5734b
url: "https://pub.dev"
source: hosted
version: "4.3.0"
version: "1.9.2"
html:
dependency: transitive
description:
@@ -722,10 +679,10 @@ packages:
dependency: transitive
description:
name: http
sha256: fe7ab022b76f3034adc518fb6ea04a82387620e19977665ea18d30a1cf43442f
sha256: "2c11f3f94c687ee9bad77c171151672986360b2b001d109814ee7140b2cf261b"
url: "https://pub.dev"
source: hosted
version: "1.3.0"
version: "1.4.0"
http_client_helper:
dependency: transitive
description:
@@ -790,6 +747,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.0.5"
isolate_channel:
dependency: transitive
description:
name: isolate_channel
sha256: f3d36f783b301e6b312c3450eeb2656b0e7d1db81331af2a151d9083a3f6b18d
url: "https://pub.dev"
source: hosted
version: "0.2.2+1"
isolate_contactor:
dependency: transitive
description:
@@ -826,10 +791,10 @@ packages:
dependency: "direct dev"
description:
name: json_serializable
sha256: c2fcb3920cf2b6ae6845954186420fca40bc0a8abcc84903b7801f17d7050d7c
sha256: c50ef5fc083d5b5e12eef489503ba3bf5ccc899e487d691584699b4bdefeea8c
url: "https://pub.dev"
source: hosted
version: "6.9.0"
version: "6.9.5"
leak_tracker:
dependency: transitive
description:
@@ -918,14 +883,6 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.3.0"
macros:
dependency: transitive
description:
name: macros
sha256: "1d9e801cd66f7ea3663c45fc708450db1fa57f988142c64289142c9b7ee80656"
url: "https://pub.dev"
source: hosted
version: "0.1.3-main.0"
markdown:
dependency: transitive
description:
@@ -1147,10 +1104,10 @@ packages:
dependency: transitive
description:
name: provider
sha256: "489024f942069c2920c844ee18bb3d467c69e48955a4f32d1677f71be103e310"
sha256: "4abbd070a04e9ddc287673bf5a030c7ca8b685ff70218720abab8b092f53dd84"
url: "https://pub.dev"
source: hosted
version: "6.1.4"
version: "6.1.5"
pub_semver:
dependency: transitive
description:
@@ -1235,10 +1192,10 @@ packages:
dependency: transitive
description:
name: riverpod_analyzer_utils
sha256: c6b8222b2b483cb87ae77ad147d6408f400c64f060df7a225b127f4afef4f8c8
sha256: "837a6dc33f490706c7f4632c516bcd10804ee4d9ccc8046124ca56388715fdf3"
url: "https://pub.dev"
source: hosted
version: "0.5.8"
version: "0.5.9"
riverpod_annotation:
dependency: "direct main"
description:
@@ -1251,26 +1208,10 @@ packages:
dependency: "direct dev"
description:
name: riverpod_generator
sha256: "63546d70952015f0981361636bf8f356d9cfd9d7f6f0815e3c07789a41233188"
sha256: "120d3310f687f43e7011bb213b90a436f1bbc300f0e4b251a72c39bccb017a4f"
url: "https://pub.dev"
source: hosted
version: "2.6.3"
riverpod_lint:
dependency: "direct dev"
description:
name: riverpod_lint
sha256: "83e4caa337a9840469b7b9bd8c2351ce85abad80f570d84146911b32086fbd99"
url: "https://pub.dev"
source: hosted
version: "2.6.3"
rxdart:
dependency: transitive
description:
name: rxdart
sha256: "5c3004a4a8dbb94bd4bf5412a4def4acdaa12e12f269737a5751369e12d1a962"
url: "https://pub.dev"
source: hosted
version: "0.28.0"
version: "2.6.4"
screen_retriever:
dependency: transitive
description:
@@ -1416,10 +1357,10 @@ packages:
dependency: transitive
description:
name: source_gen
sha256: "14658ba5f669685cd3d63701d01b31ea748310f7ab854e471962670abcf57832"
sha256: "35c8150ece9e8c8d263337a265153c3329667640850b9304861faea59fc98f6b"
url: "https://pub.dev"
source: hosted
version: "1.5.0"
version: "2.0.0"
source_helper:
dependency: transitive
description:
@@ -1624,10 +1565,10 @@ packages:
dependency: transitive
description:
name: vector_graphics_compiler
sha256: "1b4b9e706a10294258727674a340ae0d6e64a7231980f9f9a3d12e4b42407aad"
sha256: "557a315b7d2a6dbb0aaaff84d857967ce6bdc96a63dc6ee2a57ce5a6ee5d3331"
url: "https://pub.dev"
source: hosted
version: "1.1.16"
version: "1.1.17"
vector_math:
dependency: transitive
description:
@@ -1697,10 +1638,10 @@ packages:
dependency: transitive
description:
name: web_socket
sha256: bfe6f435f6ec49cb6c01da1e275ae4228719e59a6b067048c51e72d9d63bcc4b
sha256: "34d64019aa8e36bf9842ac014bb5d2f5586ca73df5e4d9bf5c936975cae6982c"
url: "https://pub.dev"
source: hosted
version: "1.0.0"
version: "1.0.1"
web_socket_channel:
dependency: transitive
description:
@@ -1721,18 +1662,18 @@ packages:
dependency: transitive
description:
name: win32
sha256: dc6ecaa00a7c708e5b4d10ee7bec8c270e9276dfcab1783f57e9962d7884305f
sha256: "329edf97fdd893e0f1e3b9e88d6a0e627128cc17cc316a8d67fda8f1451178ba"
url: "https://pub.dev"
source: hosted
version: "5.12.0"
version: "5.13.0"
window_manager:
dependency: transitive
description:
name: window_manager
sha256: "732896e1416297c63c9e3fb95aea72d0355f61390263982a47fd519169dc5059"
sha256: "51d50168ab267d344b975b15390426b1243600d436770d3f13de67e55b05ec16"
url: "https://pub.dev"
source: hosted
version: "0.4.3"
version: "0.5.0"
xdg_directories:
dependency: transitive
description:
@@ -1766,6 +1707,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "3.1.3"
yaml_writer:
dependency: transitive
description:
name: yaml_writer
sha256: "69651cd7238411179ac32079937d4aa9a2970150d6b2ae2c6fe6de09402a5dc5"
url: "https://pub.dev"
source: hosted
version: "2.1.0"
zmodem:
dependency: transitive
description:
@@ -1783,5 +1732,5 @@ packages:
source: hosted
version: "1.1.2"
sdks:
dart: ">=3.7.0 <4.0.0"
flutter: ">=3.29.0"
dart: ">=3.8.0 <4.0.0"
flutter: ">=3.32.1"

View File

@@ -4,14 +4,15 @@ publish_to: "none"
version: 1.0.1128+1128
environment:
sdk: ">=3.0.0"
sdk: ">=3.8.0"
flutter: ">=3.32.1"
dependencies:
flutter:
sdk: flutter
flutter_localizations:
sdk: flutter
hive_flutter: ^1.1.0
hive_ce_flutter: ^2.3.1
dio: ^5.2.1
easy_isolate: ^1.3.0
intl: ^0.20.2
@@ -61,7 +62,7 @@ dependencies:
fl_lib:
git:
url: https://github.com/lppcg/fl_lib
ref: v1.0.300
ref: v1.0.313
dependency_overrides:
# webdav_client_plus:
@@ -70,24 +71,23 @@ dependency_overrides:
# path: ../dartssh2
# xterm:
# path: ../xterm.dart
fl_lib:
path: ../fl_lib
# fl_lib:
# path: ../fl_lib
# fl_build:
# path: ../fl_build
flutter_math_fork:
flutter_math_fork: # Refer to https://github.com/simpleclub/flutter_math/issues/110
git:
url: https://github.com/simpleclub/flutter_math
dev_dependencies:
analyzer: ^7.3.0
flutter_native_splash: ^2.1.6
hive_generator: ^2.0.0
hive_ce_generator: ^1.9.2
build_runner: ^2.4.15
flutter_lints: ^5.0.0
json_serializable: ^6.8.0
freezed: ^2.5.7
riverpod_generator: ^2.6.3
custom_lint: ^0.7.0
riverpod_lint: ^2.6.3
flutter_test:
sdk: flutter
fl_build: