mirror of
https://github.com/lollipopkit/flutter_server_box.git
synced 2026-02-15 12:44:59 +01:00
Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c556c0f1b5 | ||
|
|
c42c701ffc | ||
|
|
e6db2db320 | ||
|
|
66ecb02d9e |
2
.github/workflows/release.yml
vendored
2
.github/workflows/release.yml
vendored
@@ -20,7 +20,7 @@ jobs:
|
||||
uses: subosito/flutter-action@v2
|
||||
with:
|
||||
channel: "stable"
|
||||
flutter-version: "3.32.1"
|
||||
flutter-version: "3.32.2"
|
||||
- uses: actions/setup-java@v4
|
||||
with:
|
||||
distribution: "zulu"
|
||||
|
||||
@@ -28,8 +28,8 @@ Especially thanks to <a href="https://github.com/TerminalStudio/dartssh2">dartss
|
||||
|
||||
## 📥 Install
|
||||
|
||||
| Platform | From |
|
||||
|-----------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
|Platform| From|
|
||||
|--|--|
|
||||
| iOS / macOS | [AppStore](https://apps.apple.com/app/id1586449703) |
|
||||
| Android | [GitHub](https://github.com/lollipopkit/flutter_server_box/releases) / [CDN](https://cdn.lpkt.cn/serverbox/pkg/?sort=time&order=desc&layout=grid) / [F-Droid](https://f-droid.org/packages/tech.lolli.toolbox) / [OpenAPK](https://www.openapk.net/serverbox/tech.lolli.toolbox/) |
|
||||
| Linux / Windows | [GitHub](https://github.com/lollipopkit/flutter_server_box/releases) / [CDN](https://cdn.lpkt.cn/serverbox/pkg/?sort=time&order=desc&layout=grid) |
|
||||
@@ -38,13 +38,14 @@ Please only download pkgs from the source that **you trust**!
|
||||
|
||||
## 🔖 Feature
|
||||
|
||||
- `Status chart` (CPU, Sensors, GPU...), `SSH` Term, `SFTP`, `Docker & Process & Systemd`...
|
||||
- `Status chart` (CPU, Sensors, GPU...), `SSH` Term, `SFTP`, `Docker & Process & Systemd`, `S.M.A.R.T`...
|
||||
- Platform specific: `Bio auth`、`Msg push`、`Home widget`、`watchOS App`...
|
||||
- English, 简体中文; Deutsch [@its-tom](https://github.com/its-tom), 繁體中文 [@kalashnikov](https://github.com/kalashnikov), Indonesian [@azkadev](https://github.com/azkadev), Français [@FrancXPT](https://github.com/FrancXPT), Dutch [@QazCetelic](https://github.com/QazCetelic), Türkçe [@mikropsoft](https://github.com/mikropsoft), Українська мова [@CakesTwix](https://github.com/CakesTwix); Español, Русский язык, Português, 日本語 (Generated by GPT)
|
||||
|
||||
## 🆘 Help
|
||||
|
||||
<div align="center">
|
||||
<a href="https://qm.qq.com/q/daCGa7eShG"><img alt="qq" src="https://img.shields.io/badge/QQ-Group-pink"></a>
|
||||
<a href="https://t.me/lpktg"><img alt="donate" src="https://img.shields.io/badge/Telegram-lpktg-green"></a>
|
||||
<a href="https://discord.gg/SsVNbRhK7w"><img alt="discord" src="https://img.shields.io/badge/Discord-lpkt-purple"></a>
|
||||
</div>
|
||||
|
||||
21
README_zh.md
21
README_zh.md
@@ -15,8 +15,8 @@
|
||||
特别感谢 <a href="https://github.com/TerminalStudio/dartssh2">dartssh2</a> & <a href="https://github.com/TerminalStudio/xterm.dart">xterm.dart</a>。
|
||||
</p>
|
||||
|
||||
|
||||
## 🏙️ 截屏
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<td><img width="200px" src="https://cdn.lpkt.cn/serverbox/screenshot/1.jpg"></td>
|
||||
@@ -26,20 +26,19 @@
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
|
||||
## 📥 安装
|
||||
|
||||
平台 | 下载
|
||||
----------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
平台|下载
|
||||
--|--
|
||||
iOS / macOS | [AppStore](https://apps.apple.com/app/id1586449703)
|
||||
Android | [GitHub](https://github.com/lollipopkit/flutter_server_box/releases) / [CDN](https://cdn.lpkt.cn/serverbox/pkg/?sort=time&order=desc&layout=grid) / [F-Droid](https://f-droid.org/packages/tech.lolli.toolbox) / [OpenAPK](https://www.openapk.net/serverbox/tech.lolli.toolbox/)
|
||||
Linux / Windows | [GitHub](https://github.com/lollipopkit/flutter_server_box/releases) / [CDN](https://cdn.lpkt.cn/serverbox/pkg/?sort=time&order=desc&layout=grid)
|
||||
|
||||
请从 **信任** 的来源下载!
|
||||
|
||||
|
||||
## 🔖 特点
|
||||
- `状态图表`(CPU、传感器、GPU 等), `SSH` 终端, `SFTP`, `Docker & 进程 & Systemd` 管理...
|
||||
|
||||
- `状态图表`(CPU、传感器、GPU 等), `SSH` 终端, `SFTP`, `Docker & 进程 & Systemd` 管理,`S.M.A.R.T`...
|
||||
- 特殊支持:`生物认证`、`推送`、`桌面小部件`、`watchOS App`、`跟随系统颜色`...
|
||||
- 本地化
|
||||
- English, 简体中文
|
||||
@@ -47,10 +46,10 @@ Linux / Windows | [GitHub](https://github.com/lollipopkit/flutter_server_box/rel
|
||||
- Deutsch [@its-tom](https://github.com/its-tom), 繁體中文 [@kalashnikov](https://github.com/kalashnikov), Indonesian [@azkadev](https://github.com/azkadev), Français [@FrancXPT](https://github.com/FrancXPT), Dutch [@QazCetelic](https://github.com/QazCetelic), Türkçe [@mikropsoft](https://github.com/mikropsoft), Українська мова [@CakesTwix](https://github.com/CakesTwix);
|
||||
- 感谢贡献者们!
|
||||
|
||||
|
||||
## 🆘 帮助
|
||||
|
||||
<div align="center">
|
||||
<a href="https://qm.qq.com/q/daCGa7eShG"><img alt="qq" src="https://img.shields.io/badge/QQ-群-pink"></a>
|
||||
<a href="https://t.me/lpktg"><img alt="donate" src="https://img.shields.io/badge/Telegram-lpktg-green"></a>
|
||||
<a href="https://discord.gg/SsVNbRhK7w"><img alt="discord" src="https://img.shields.io/badge/Discord-lpkt-purple"></a>
|
||||
</div>
|
||||
@@ -59,26 +58,30 @@ Linux / Windows | [GitHub](https://github.com/lollipopkit/flutter_server_box/rel
|
||||
- **常见问题** 可以在 [app wiki](https://github.com/lollipopkit/flutter_server_box/wiki/主页) 查看。
|
||||
|
||||
反馈前须知:
|
||||
|
||||
1. 反馈问题请附带 log(点击首页右上角),并以 bug 模版提交。
|
||||
2. 反馈问题前请检查是否是 serverbox 的问题。
|
||||
3. 欢迎所有有效、正面的反馈,主观(比如你觉得其他UI更好看)的反馈不一定会接受
|
||||
|
||||
|
||||
## 🧱 贡献
|
||||
|
||||
任何正面的贡献都欢迎。
|
||||
|
||||
### 开发
|
||||
|
||||
1. 安装 [Flutter](https://flutter.dev/docs/get-started/install)
|
||||
2. 克隆这个仓库, 运行 `flutter run` 启动应用
|
||||
3. 运行 `dart run fl_build -p PLATFORM` 构建应用
|
||||
|
||||
### 翻译
|
||||
|
||||
[指南](https://blog.lpkt.cn/faq/) 可在我的博客中找到。
|
||||
|
||||
## 💡 我的其它 Apps
|
||||
|
||||
- [GPT Box](https://github.com/lollipopkit/flutter_gpt_box) - 支持 OpenAI API 的 第三方全平台客户端。
|
||||
- [更多](https://github.com/lollipopkit) - 工具 & etc.
|
||||
|
||||
|
||||
## 📝 协议
|
||||
|
||||
`GPL v3 lollipopkit`
|
||||
|
||||
@@ -672,7 +672,7 @@
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
|
||||
CURRENT_PROJECT_VERSION = 1185;
|
||||
CURRENT_PROJECT_VERSION = 1189;
|
||||
DEVELOPMENT_TEAM = BA88US33G6;
|
||||
ENABLE_BITCODE = NO;
|
||||
INFOPLIST_FILE = "Runner/Info-$(CONFIGURATION).plist";
|
||||
@@ -682,7 +682,7 @@
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 1.0.1185;
|
||||
MARKETING_VERSION = 1.0.1189;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
||||
@@ -808,7 +808,7 @@
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
|
||||
CURRENT_PROJECT_VERSION = 1185;
|
||||
CURRENT_PROJECT_VERSION = 1189;
|
||||
DEVELOPMENT_TEAM = BA88US33G6;
|
||||
ENABLE_BITCODE = NO;
|
||||
INFOPLIST_FILE = "Runner/Info-$(CONFIGURATION).plist";
|
||||
@@ -818,7 +818,7 @@
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 1.0.1185;
|
||||
MARKETING_VERSION = 1.0.1189;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
||||
@@ -836,7 +836,7 @@
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
|
||||
CURRENT_PROJECT_VERSION = 1185;
|
||||
CURRENT_PROJECT_VERSION = 1189;
|
||||
DEVELOPMENT_TEAM = BA88US33G6;
|
||||
ENABLE_BITCODE = NO;
|
||||
INFOPLIST_FILE = "Runner/Info-$(CONFIGURATION).plist";
|
||||
@@ -846,7 +846,7 @@
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 1.0.1185;
|
||||
MARKETING_VERSION = 1.0.1189;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
||||
@@ -867,7 +867,7 @@
|
||||
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
|
||||
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 1185;
|
||||
CURRENT_PROJECT_VERSION = 1189;
|
||||
DEVELOPMENT_TEAM = BA88US33G6;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||
GENERATE_INFOPLIST_FILE = YES;
|
||||
@@ -880,7 +880,7 @@
|
||||
"@executable_path/Frameworks",
|
||||
"@executable_path/../../Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 1.0.1185;
|
||||
MARKETING_VERSION = 1.0.1189;
|
||||
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
|
||||
MTL_FAST_MATH = YES;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.StatusWidget;
|
||||
@@ -906,7 +906,7 @@
|
||||
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
|
||||
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 1185;
|
||||
CURRENT_PROJECT_VERSION = 1189;
|
||||
DEVELOPMENT_TEAM = BA88US33G6;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||
GENERATE_INFOPLIST_FILE = YES;
|
||||
@@ -919,7 +919,7 @@
|
||||
"@executable_path/Frameworks",
|
||||
"@executable_path/../../Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 1.0.1185;
|
||||
MARKETING_VERSION = 1.0.1189;
|
||||
MTL_FAST_MATH = YES;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.StatusWidget;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
@@ -942,7 +942,7 @@
|
||||
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
|
||||
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 1185;
|
||||
CURRENT_PROJECT_VERSION = 1189;
|
||||
DEVELOPMENT_TEAM = BA88US33G6;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||
GENERATE_INFOPLIST_FILE = YES;
|
||||
@@ -955,7 +955,7 @@
|
||||
"@executable_path/Frameworks",
|
||||
"@executable_path/../../Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 1.0.1185;
|
||||
MARKETING_VERSION = 1.0.1189;
|
||||
MTL_FAST_MATH = YES;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.StatusWidget;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
@@ -978,7 +978,7 @@
|
||||
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
|
||||
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 1185;
|
||||
CURRENT_PROJECT_VERSION = 1189;
|
||||
DEVELOPMENT_ASSET_PATHS = "";
|
||||
DEVELOPMENT_TEAM = BA88US33G6;
|
||||
ENABLE_PREVIEWS = YES;
|
||||
@@ -990,7 +990,7 @@
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 1.0.1185;
|
||||
MARKETING_VERSION = 1.0.1189;
|
||||
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
|
||||
MTL_FAST_MATH = YES;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.WatchEnd;
|
||||
@@ -1019,7 +1019,7 @@
|
||||
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
|
||||
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 1185;
|
||||
CURRENT_PROJECT_VERSION = 1189;
|
||||
DEVELOPMENT_ASSET_PATHS = "";
|
||||
DEVELOPMENT_TEAM = BA88US33G6;
|
||||
ENABLE_PREVIEWS = YES;
|
||||
@@ -1031,7 +1031,7 @@
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 1.0.1185;
|
||||
MARKETING_VERSION = 1.0.1189;
|
||||
MTL_FAST_MATH = YES;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.WatchEnd;
|
||||
PRODUCT_NAME = ServerBox;
|
||||
@@ -1057,7 +1057,7 @@
|
||||
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
|
||||
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 1185;
|
||||
CURRENT_PROJECT_VERSION = 1189;
|
||||
DEVELOPMENT_ASSET_PATHS = "";
|
||||
DEVELOPMENT_TEAM = BA88US33G6;
|
||||
ENABLE_PREVIEWS = YES;
|
||||
@@ -1069,7 +1069,7 @@
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 1.0.1185;
|
||||
MARKETING_VERSION = 1.0.1189;
|
||||
MTL_FAST_MATH = YES;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox.WatchEnd;
|
||||
PRODUCT_NAME = ServerBox;
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// dart format width=80
|
||||
// coverage:ignore-file
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
// ignore_for_file: type=lint
|
||||
@@ -9,364 +10,196 @@ part of 'backup2.dart';
|
||||
// FreezedGenerator
|
||||
// **************************************************************************
|
||||
|
||||
// dart format off
|
||||
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;
|
||||
|
||||
int get version; int get date; Map<String, Object?> get spis; Map<String, Object?> get snippets; Map<String, Object?> get keys; Map<String, Object?> get container; Map<String, Object?> get history; Map<String, Object?> get settings;
|
||||
/// Create a copy of BackupV2
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@pragma('vm:prefer-inline')
|
||||
$BackupV2CopyWith<BackupV2> get copyWith => _$BackupV2CopyWithImpl<BackupV2>(this as BackupV2, _$identity);
|
||||
|
||||
/// Serializes this BackupV2 to a JSON map.
|
||||
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
|
||||
Map<String, dynamic> toJson();
|
||||
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is BackupV2&&(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));
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'BackupV2(version: $version, date: $date, spis: $spis, snippets: $snippets, keys: $keys, container: $container, history: $history, settings: $settings)';
|
||||
}
|
||||
|
||||
|
||||
/// 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,
|
||||
});
|
||||
}
|
||||
abstract mixin class $BackupV2CopyWith<$Res> {
|
||||
factory $BackupV2CopyWith(BackupV2 value, $Res Function(BackupV2) _then) = _$BackupV2CopyWithImpl;
|
||||
@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>
|
||||
class _$BackupV2CopyWithImpl<$Res>
|
||||
implements $BackupV2CopyWith<$Res> {
|
||||
_$BackupV2CopyWithImpl(this._value, this._then);
|
||||
_$BackupV2CopyWithImpl(this._self, this._then);
|
||||
|
||||
// ignore: unused_field
|
||||
final $Val _value;
|
||||
// ignore: unused_field
|
||||
final $Res Function($Val) _then;
|
||||
final BackupV2 _self;
|
||||
final $Res Function(BackupV2) _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,
|
||||
);
|
||||
}
|
||||
/// 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(_self.copyWith(
|
||||
version: null == version ? _self.version : version // ignore: cast_nullable_to_non_nullable
|
||||
as int,date: null == date ? _self.date : date // ignore: cast_nullable_to_non_nullable
|
||||
as int,spis: null == spis ? _self.spis : spis // ignore: cast_nullable_to_non_nullable
|
||||
as Map<String, Object?>,snippets: null == snippets ? _self.snippets : snippets // ignore: cast_nullable_to_non_nullable
|
||||
as Map<String, Object?>,keys: null == keys ? _self.keys : keys // ignore: cast_nullable_to_non_nullable
|
||||
as Map<String, Object?>,container: null == container ? _self.container : container // ignore: cast_nullable_to_non_nullable
|
||||
as Map<String, Object?>,history: null == history ? _self.history : history // ignore: cast_nullable_to_non_nullable
|
||||
as Map<String, Object?>,settings: null == settings ? _self.settings : settings // ignore: cast_nullable_to_non_nullable
|
||||
as Map<String, Object?>,
|
||||
));
|
||||
}
|
||||
|
||||
/// @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);
|
||||
class _BackupV2 extends BackupV2 {
|
||||
const _BackupV2({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 _BackupV2.fromJson(Map<String, dynamic> json) => _$BackupV2FromJson(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);
|
||||
}
|
||||
@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);
|
||||
}
|
||||
|
||||
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;
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
/// Create a copy of BackupV2
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@pragma('vm:prefer-inline')
|
||||
_$BackupV2CopyWith<_BackupV2> get copyWith => __$BackupV2CopyWithImpl<_BackupV2>(this, _$identity);
|
||||
|
||||
@override
|
||||
Map<String, dynamic> toJson() {
|
||||
return _$BackupV2ToJson(this, );
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is _BackupV2&&(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));
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'BackupV2(version: $version, date: $date, spis: $spis, snippets: $snippets, keys: $keys, container: $container, history: $history, settings: $settings)';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract mixin class _$BackupV2CopyWith<$Res> implements $BackupV2CopyWith<$Res> {
|
||||
factory _$BackupV2CopyWith(_BackupV2 value, $Res Function(_BackupV2) _then) = __$BackupV2CopyWithImpl;
|
||||
@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 __$BackupV2CopyWithImpl<$Res>
|
||||
implements _$BackupV2CopyWith<$Res> {
|
||||
__$BackupV2CopyWithImpl(this._self, this._then);
|
||||
|
||||
final _BackupV2 _self;
|
||||
final $Res Function(_BackupV2) _then;
|
||||
|
||||
/// Create a copy of BackupV2
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @pragma('vm:prefer-inline') $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(_BackupV2(
|
||||
version: null == version ? _self.version : version // ignore: cast_nullable_to_non_nullable
|
||||
as int,date: null == date ? _self.date : date // ignore: cast_nullable_to_non_nullable
|
||||
as int,spis: null == spis ? _self._spis : spis // ignore: cast_nullable_to_non_nullable
|
||||
as Map<String, Object?>,snippets: null == snippets ? _self._snippets : snippets // ignore: cast_nullable_to_non_nullable
|
||||
as Map<String, Object?>,keys: null == keys ? _self._keys : keys // ignore: cast_nullable_to_non_nullable
|
||||
as Map<String, Object?>,container: null == container ? _self._container : container // ignore: cast_nullable_to_non_nullable
|
||||
as Map<String, Object?>,history: null == history ? _self._history : history // ignore: cast_nullable_to_non_nullable
|
||||
as Map<String, Object?>,settings: null == settings ? _self._settings : settings // ignore: cast_nullable_to_non_nullable
|
||||
as Map<String, Object?>,
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
// dart format on
|
||||
|
||||
@@ -6,26 +6,24 @@ 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>,
|
||||
);
|
||||
_BackupV2 _$BackupV2FromJson(Map<String, dynamic> json) => _BackupV2(
|
||||
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,
|
||||
};
|
||||
Map<String, dynamic> _$BackupV2ToJson(_BackupV2 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,
|
||||
};
|
||||
|
||||
@@ -225,7 +225,7 @@ enum StatusCmdType {
|
||||
),
|
||||
nvidia._('nvidia-smi -q -x'),
|
||||
sensors._('sensors'),
|
||||
diskSmart._('for d in \$(lsblk -dn -o KNAME); do smartctl -j /dev/\$d; echo; done'),
|
||||
diskSmart._('for d in \$(lsblk -dn -o KNAME); do smartctl -a -j /dev/\$d; echo; done'),
|
||||
cpuBrand._('cat /proc/cpuinfo | grep "model name"');
|
||||
|
||||
final String cmd;
|
||||
|
||||
@@ -7,7 +7,7 @@ part 'disk_smart.freezed.dart';
|
||||
part 'disk_smart.g.dart';
|
||||
|
||||
@freezed
|
||||
class DiskSmart with _$DiskSmart {
|
||||
abstract class DiskSmart with _$DiskSmart {
|
||||
const DiskSmart._();
|
||||
|
||||
const factory DiskSmart({
|
||||
@@ -35,7 +35,10 @@ class DiskSmart with _$DiskSmart {
|
||||
|
||||
// Basic
|
||||
final device = data['device']?['name']?.toString() ?? '';
|
||||
final healthy = data['smart_status']?['passed'] as bool?;
|
||||
|
||||
if (!_isPhysicalDisk(device)) continue;
|
||||
|
||||
final healthy = _parseHealthStatus(data);
|
||||
|
||||
// Model and Serial
|
||||
final model =
|
||||
@@ -72,6 +75,92 @@ class DiskSmart with _$DiskSmart {
|
||||
return results;
|
||||
}
|
||||
|
||||
static bool _isPhysicalDisk(String device) {
|
||||
if (device.isEmpty) return false;
|
||||
|
||||
// Common patterns for physical disks
|
||||
final patterns = [
|
||||
RegExp(r'^/dev/sd[a-z]$'), // SATA/SCSI: /dev/sda, /dev/sdb
|
||||
RegExp(r'^/dev/hd[a-z]$'), // IDE: /dev/hda, /dev/hdb
|
||||
RegExp(r'^/dev/nvme\d+n\d+$'), // NVMe: /dev/nvme0n1, /dev/nvme1n1
|
||||
RegExp(r'^/dev/mmcblk\d+$'), // MMC: /dev/mmcblk0
|
||||
RegExp(r'^/dev/vd[a-z]$'), // VirtIO: /dev/vda, /dev/vdb
|
||||
RegExp(r'^/dev/xvd[a-z]$'), // Xen: /dev/xvda, /dev/xvdb
|
||||
];
|
||||
|
||||
return patterns.any((pattern) => pattern.hasMatch(device));
|
||||
}
|
||||
|
||||
static bool? _parseHealthStatus(Map<String, dynamic> data) {
|
||||
// smart_status.passed
|
||||
final smartStatus = data['smart_status'];
|
||||
if (smartStatus is Map<String, dynamic>) {
|
||||
final passed = smartStatus['passed'];
|
||||
if (passed is bool) return passed;
|
||||
}
|
||||
|
||||
// smart_status.status
|
||||
if (smartStatus is Map<String, dynamic>) {
|
||||
final status = smartStatus['status']?.toString().toLowerCase();
|
||||
if (status != null) {
|
||||
if (status.contains('pass') || status.contains('ok')) return true;
|
||||
if (status.contains('fail')) return false;
|
||||
}
|
||||
}
|
||||
|
||||
// smart_status
|
||||
final rootSmartStatus = data['smart_status']?.toString().toLowerCase();
|
||||
if (rootSmartStatus != null) {
|
||||
if (rootSmartStatus.contains('pass') || rootSmartStatus.contains('ok')) return true;
|
||||
if (rootSmartStatus.contains('fail')) return false;
|
||||
}
|
||||
|
||||
// health attrs
|
||||
final attrTable = data['ata_smart_attributes']?['table'] as List?;
|
||||
if (attrTable != null) {
|
||||
var hasFailingAttributes = false;
|
||||
|
||||
for (final attr in attrTable) {
|
||||
if (attr is Map<String, dynamic>) {
|
||||
final whenFailed = attr['when_failed']?.toString();
|
||||
if (whenFailed != null && whenFailed.isNotEmpty && whenFailed != 'never') {
|
||||
hasFailingAttributes = true;
|
||||
break;
|
||||
}
|
||||
|
||||
// Whether the attribute is critical
|
||||
final name = attr['name']?.toString();
|
||||
final value = attr['value'] as int?;
|
||||
final thresh = attr['thresh'] as int?;
|
||||
|
||||
if (name != null && value != null && thresh != null && thresh > 0) {
|
||||
const criticalAttrs = [
|
||||
'Reallocated_Sector_Ct',
|
||||
'Reallocated_Event_Count',
|
||||
'Current_Pending_Sector',
|
||||
'Offline_Uncorrectable',
|
||||
'UDMA_CRC_Error_Count',
|
||||
];
|
||||
|
||||
if (criticalAttrs.contains(name) && value < thresh) {
|
||||
hasFailingAttributes = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (hasFailingAttributes) return false;
|
||||
}
|
||||
|
||||
if (attrTable != null && attrTable.isNotEmpty) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Uncertain status, assume healthy
|
||||
return true;
|
||||
}
|
||||
|
||||
static Map<String, SmartAttribute> _parseSmartAttributes(Map<String, dynamic> data) {
|
||||
final attributes = <String, SmartAttribute>{};
|
||||
|
||||
@@ -144,7 +233,7 @@ class DiskSmart with _$DiskSmart {
|
||||
}
|
||||
|
||||
@freezed
|
||||
class SmartAttribute with _$SmartAttribute {
|
||||
abstract class SmartAttribute with _$SmartAttribute {
|
||||
const SmartAttribute._();
|
||||
|
||||
const factory SmartAttribute({
|
||||
@@ -168,7 +257,7 @@ class SmartAttribute with _$SmartAttribute {
|
||||
}
|
||||
|
||||
@freezed
|
||||
class SmartAttributeFlags with _$SmartAttributeFlags {
|
||||
abstract class SmartAttributeFlags with _$SmartAttributeFlags {
|
||||
const SmartAttributeFlags._();
|
||||
|
||||
const factory SmartAttributeFlags({
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -6,23 +6,21 @@ part of 'disk_smart.dart';
|
||||
// JsonSerializableGenerator
|
||||
// **************************************************************************
|
||||
|
||||
_$DiskSmartImpl _$$DiskSmartImplFromJson(Map<String, dynamic> json) =>
|
||||
_$DiskSmartImpl(
|
||||
device: json['device'] as String,
|
||||
healthy: json['healthy'] as bool?,
|
||||
temperature: (json['temperature'] as num?)?.toDouble(),
|
||||
model: json['model'] as String?,
|
||||
serial: json['serial'] as String?,
|
||||
powerOnHours: (json['powerOnHours'] as num?)?.toInt(),
|
||||
powerCycleCount: (json['powerCycleCount'] as num?)?.toInt(),
|
||||
rawData: json['rawData'] as Map<String, dynamic>,
|
||||
smartAttributes: (json['smartAttributes'] as Map<String, dynamic>).map(
|
||||
(k, e) =>
|
||||
MapEntry(k, SmartAttribute.fromJson(e as Map<String, dynamic>)),
|
||||
),
|
||||
);
|
||||
_DiskSmart _$DiskSmartFromJson(Map<String, dynamic> json) => _DiskSmart(
|
||||
device: json['device'] as String,
|
||||
healthy: json['healthy'] as bool?,
|
||||
temperature: (json['temperature'] as num?)?.toDouble(),
|
||||
model: json['model'] as String?,
|
||||
serial: json['serial'] as String?,
|
||||
powerOnHours: (json['powerOnHours'] as num?)?.toInt(),
|
||||
powerCycleCount: (json['powerCycleCount'] as num?)?.toInt(),
|
||||
rawData: json['rawData'] as Map<String, dynamic>,
|
||||
smartAttributes: (json['smartAttributes'] as Map<String, dynamic>).map(
|
||||
(k, e) => MapEntry(k, SmartAttribute.fromJson(e as Map<String, dynamic>)),
|
||||
),
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$$DiskSmartImplToJson(_$DiskSmartImpl instance) =>
|
||||
Map<String, dynamic> _$DiskSmartToJson(_DiskSmart instance) =>
|
||||
<String, dynamic>{
|
||||
'device': instance.device,
|
||||
'healthy': instance.healthy,
|
||||
@@ -35,8 +33,8 @@ Map<String, dynamic> _$$DiskSmartImplToJson(_$DiskSmartImpl instance) =>
|
||||
'smartAttributes': instance.smartAttributes,
|
||||
};
|
||||
|
||||
_$SmartAttributeImpl _$$SmartAttributeImplFromJson(Map<String, dynamic> json) =>
|
||||
_$SmartAttributeImpl(
|
||||
_SmartAttribute _$SmartAttributeFromJson(Map<String, dynamic> json) =>
|
||||
_SmartAttribute(
|
||||
id: (json['id'] as num?)?.toInt(),
|
||||
name: json['name'] as String,
|
||||
value: (json['value'] as num?)?.toInt(),
|
||||
@@ -50,35 +48,33 @@ _$SmartAttributeImpl _$$SmartAttributeImplFromJson(Map<String, dynamic> json) =>
|
||||
),
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$$SmartAttributeImplToJson(
|
||||
_$SmartAttributeImpl instance,
|
||||
) => <String, dynamic>{
|
||||
'id': instance.id,
|
||||
'name': instance.name,
|
||||
'value': instance.value,
|
||||
'worst': instance.worst,
|
||||
'thresh': instance.thresh,
|
||||
'whenFailed': instance.whenFailed,
|
||||
'rawValue': instance.rawValue,
|
||||
'rawString': instance.rawString,
|
||||
'flags': instance.flags,
|
||||
};
|
||||
Map<String, dynamic> _$SmartAttributeToJson(_SmartAttribute instance) =>
|
||||
<String, dynamic>{
|
||||
'id': instance.id,
|
||||
'name': instance.name,
|
||||
'value': instance.value,
|
||||
'worst': instance.worst,
|
||||
'thresh': instance.thresh,
|
||||
'whenFailed': instance.whenFailed,
|
||||
'rawValue': instance.rawValue,
|
||||
'rawString': instance.rawString,
|
||||
'flags': instance.flags,
|
||||
};
|
||||
|
||||
_$SmartAttributeFlagsImpl _$$SmartAttributeFlagsImplFromJson(
|
||||
Map<String, dynamic> json,
|
||||
) => _$SmartAttributeFlagsImpl(
|
||||
value: (json['value'] as num?)?.toInt(),
|
||||
string: json['string'] as String?,
|
||||
prefailure: json['prefailure'] as bool? ?? false,
|
||||
updatedOnline: json['updatedOnline'] as bool? ?? false,
|
||||
performance: json['performance'] as bool? ?? false,
|
||||
errorRate: json['errorRate'] as bool? ?? false,
|
||||
eventCount: json['eventCount'] as bool? ?? false,
|
||||
autoKeep: json['autoKeep'] as bool? ?? false,
|
||||
);
|
||||
_SmartAttributeFlags _$SmartAttributeFlagsFromJson(Map<String, dynamic> json) =>
|
||||
_SmartAttributeFlags(
|
||||
value: (json['value'] as num?)?.toInt(),
|
||||
string: json['string'] as String?,
|
||||
prefailure: json['prefailure'] as bool? ?? false,
|
||||
updatedOnline: json['updatedOnline'] as bool? ?? false,
|
||||
performance: json['performance'] as bool? ?? false,
|
||||
errorRate: json['errorRate'] as bool? ?? false,
|
||||
eventCount: json['eventCount'] as bool? ?? false,
|
||||
autoKeep: json['autoKeep'] as bool? ?? false,
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$$SmartAttributeFlagsImplToJson(
|
||||
_$SmartAttributeFlagsImpl instance,
|
||||
Map<String, dynamic> _$SmartAttributeFlagsToJson(
|
||||
_SmartAttributeFlags instance,
|
||||
) => <String, dynamic>{
|
||||
'value': instance.value,
|
||||
'string': instance.string,
|
||||
|
||||
@@ -2,7 +2,6 @@ import 'dart:convert';
|
||||
|
||||
import 'package:fl_lib/fl_lib.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
import 'package:hive_ce_flutter/hive_flutter.dart';
|
||||
import 'package:server_box/data/model/app/error.dart';
|
||||
import 'package:server_box/data/model/server/custom.dart';
|
||||
import 'package:server_box/data/model/server/server.dart';
|
||||
@@ -19,11 +18,11 @@ part 'server_private_info.g.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(fromJson: false)
|
||||
@JsonSerializable(includeIfNull: false)
|
||||
class Spi with _$Spi {
|
||||
@freezed
|
||||
abstract class Spi with _$Spi {
|
||||
const Spi._();
|
||||
|
||||
@JsonSerializable(includeIfNull: false)
|
||||
const factory Spi({
|
||||
required String name,
|
||||
required String ip,
|
||||
@@ -35,7 +34,7 @@ class Spi with _$Spi {
|
||||
@JsonKey(name: 'pubKeyId') String? keyId,
|
||||
List<String>? tags,
|
||||
String? alterUrl,
|
||||
@Default(true) @JsonKey(defaultValue: true) bool autoConnect,
|
||||
@Default(true) bool autoConnect,
|
||||
|
||||
/// [id] of the jump server
|
||||
String? jumpId,
|
||||
@@ -44,7 +43,7 @@ class Spi with _$Spi {
|
||||
|
||||
/// It only applies to SSH terminal.
|
||||
Map<String, String>? envs,
|
||||
@JsonKey(fromJson: Spi.parseId) @HiveField(13, defaultValue: '') required String id,
|
||||
@Default('') @JsonKey(fromJson: Spi.parseId) String id,
|
||||
}) = _Spi;
|
||||
|
||||
factory Spi.fromJson(Map<String, dynamic> json) => _$SpiFromJson(json);
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// dart format width=80
|
||||
// coverage:ignore-file
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
// ignore_for_file: type=lint
|
||||
@@ -9,479 +10,193 @@ part of 'server_private_info.dart';
|
||||
// FreezedGenerator
|
||||
// **************************************************************************
|
||||
|
||||
// dart format off
|
||||
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',
|
||||
);
|
||||
|
||||
/// @nodoc
|
||||
mixin _$Spi {
|
||||
String get name => throw _privateConstructorUsedError;
|
||||
String get ip => throw _privateConstructorUsedError;
|
||||
int get port => throw _privateConstructorUsedError;
|
||||
String get user => throw _privateConstructorUsedError;
|
||||
String? get pwd => throw _privateConstructorUsedError;
|
||||
|
||||
/// [id] of private key
|
||||
@JsonKey(name: 'pubKeyId')
|
||||
String? get keyId => throw _privateConstructorUsedError;
|
||||
List<String>? get tags => throw _privateConstructorUsedError;
|
||||
String? get alterUrl => throw _privateConstructorUsedError;
|
||||
@JsonKey(defaultValue: true)
|
||||
bool get autoConnect => throw _privateConstructorUsedError;
|
||||
|
||||
/// [id] of the jump server
|
||||
String? get jumpId => throw _privateConstructorUsedError;
|
||||
ServerCustom? get custom => throw _privateConstructorUsedError;
|
||||
WakeOnLanCfg? get wolCfg => throw _privateConstructorUsedError;
|
||||
|
||||
/// It only applies to SSH terminal.
|
||||
Map<String, String>? get envs => throw _privateConstructorUsedError;
|
||||
@JsonKey(fromJson: Spi.parseId)
|
||||
@HiveField(13, defaultValue: '')
|
||||
String get id => throw _privateConstructorUsedError;
|
||||
String get name; String get ip; int get port; String get user; String? get pwd;/// [id] of private key
|
||||
@JsonKey(name: 'pubKeyId') String? get keyId; List<String>? get tags; String? get alterUrl; bool get autoConnect;/// [id] of the jump server
|
||||
String? get jumpId; ServerCustom? get custom; WakeOnLanCfg? get wolCfg;/// It only applies to SSH terminal.
|
||||
Map<String, String>? get envs;@JsonKey(fromJson: Spi.parseId) String get id;
|
||||
/// Create a copy of Spi
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@pragma('vm:prefer-inline')
|
||||
$SpiCopyWith<Spi> get copyWith => _$SpiCopyWithImpl<Spi>(this as Spi, _$identity);
|
||||
|
||||
/// Serializes this Spi to a JSON map.
|
||||
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
|
||||
Map<String, dynamic> toJson();
|
||||
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is Spi&&(identical(other.name, name) || other.name == name)&&(identical(other.ip, ip) || other.ip == ip)&&(identical(other.port, port) || other.port == port)&&(identical(other.user, user) || other.user == user)&&(identical(other.pwd, pwd) || other.pwd == pwd)&&(identical(other.keyId, keyId) || other.keyId == keyId)&&const DeepCollectionEquality().equals(other.tags, tags)&&(identical(other.alterUrl, alterUrl) || other.alterUrl == alterUrl)&&(identical(other.autoConnect, autoConnect) || other.autoConnect == autoConnect)&&(identical(other.jumpId, jumpId) || other.jumpId == jumpId)&&(identical(other.custom, custom) || other.custom == custom)&&(identical(other.wolCfg, wolCfg) || other.wolCfg == wolCfg)&&const DeepCollectionEquality().equals(other.envs, envs)&&(identical(other.id, id) || other.id == id));
|
||||
}
|
||||
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,name,ip,port,user,pwd,keyId,const DeepCollectionEquality().hash(tags),alterUrl,autoConnect,jumpId,custom,wolCfg,const DeepCollectionEquality().hash(envs),id);
|
||||
|
||||
|
||||
|
||||
/// Create a copy of Spi
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
$SpiCopyWith<Spi> get copyWith => throw _privateConstructorUsedError;
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract class $SpiCopyWith<$Res> {
|
||||
factory $SpiCopyWith(Spi value, $Res Function(Spi) then) =
|
||||
_$SpiCopyWithImpl<$Res, Spi>;
|
||||
@useResult
|
||||
$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,
|
||||
});
|
||||
abstract mixin class $SpiCopyWith<$Res> {
|
||||
factory $SpiCopyWith(Spi value, $Res Function(Spi) _then) = _$SpiCopyWithImpl;
|
||||
@useResult
|
||||
$Res call({
|
||||
String name, String ip, int port, String user, String? pwd,@JsonKey(name: 'pubKeyId') String? keyId, List<String>? tags, String? alterUrl, bool autoConnect, String? jumpId, ServerCustom? custom, WakeOnLanCfg? wolCfg, Map<String, String>? envs,@JsonKey(fromJson: Spi.parseId) String id
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
/// @nodoc
|
||||
class _$SpiCopyWithImpl<$Res>
|
||||
implements $SpiCopyWith<$Res> {
|
||||
_$SpiCopyWithImpl(this._self, this._then);
|
||||
|
||||
final Spi _self;
|
||||
final $Res Function(Spi) _then;
|
||||
|
||||
/// Create a copy of Spi
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@pragma('vm:prefer-inline') @override $Res call({Object? name = null,Object? ip = null,Object? port = null,Object? user = null,Object? pwd = freezed,Object? keyId = freezed,Object? tags = freezed,Object? alterUrl = freezed,Object? autoConnect = null,Object? jumpId = freezed,Object? custom = freezed,Object? wolCfg = freezed,Object? envs = freezed,Object? id = null,}) {
|
||||
return _then(_self.copyWith(
|
||||
name: null == name ? _self.name : name // ignore: cast_nullable_to_non_nullable
|
||||
as String,ip: null == ip ? _self.ip : ip // ignore: cast_nullable_to_non_nullable
|
||||
as String,port: null == port ? _self.port : port // ignore: cast_nullable_to_non_nullable
|
||||
as int,user: null == user ? _self.user : user // ignore: cast_nullable_to_non_nullable
|
||||
as String,pwd: freezed == pwd ? _self.pwd : pwd // ignore: cast_nullable_to_non_nullable
|
||||
as String?,keyId: freezed == keyId ? _self.keyId : keyId // ignore: cast_nullable_to_non_nullable
|
||||
as String?,tags: freezed == tags ? _self.tags : tags // ignore: cast_nullable_to_non_nullable
|
||||
as List<String>?,alterUrl: freezed == alterUrl ? _self.alterUrl : alterUrl // ignore: cast_nullable_to_non_nullable
|
||||
as String?,autoConnect: null == autoConnect ? _self.autoConnect : autoConnect // ignore: cast_nullable_to_non_nullable
|
||||
as bool,jumpId: freezed == jumpId ? _self.jumpId : jumpId // ignore: cast_nullable_to_non_nullable
|
||||
as String?,custom: freezed == custom ? _self.custom : custom // ignore: cast_nullable_to_non_nullable
|
||||
as ServerCustom?,wolCfg: freezed == wolCfg ? _self.wolCfg : wolCfg // ignore: cast_nullable_to_non_nullable
|
||||
as WakeOnLanCfg?,envs: freezed == envs ? _self.envs : envs // ignore: cast_nullable_to_non_nullable
|
||||
as Map<String, String>?,id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// @nodoc
|
||||
|
||||
@JsonSerializable(includeIfNull: false)
|
||||
class _Spi extends Spi {
|
||||
const _Spi({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, this.autoConnect = true, this.jumpId, this.custom, this.wolCfg, final Map<String, String>? envs, @JsonKey(fromJson: Spi.parseId) this.id = ''}): _tags = tags,_envs = envs,super._();
|
||||
factory _Spi.fromJson(Map<String, dynamic> json) => _$SpiFromJson(json);
|
||||
|
||||
@override final String name;
|
||||
@override final String ip;
|
||||
@override final int port;
|
||||
@override final String user;
|
||||
@override final String? pwd;
|
||||
/// [id] of private key
|
||||
@override@JsonKey(name: 'pubKeyId') final String? keyId;
|
||||
final List<String>? _tags;
|
||||
@override List<String>? get tags {
|
||||
final value = _tags;
|
||||
if (value == null) return null;
|
||||
if (_tags is EqualUnmodifiableListView) return _tags;
|
||||
// ignore: implicit_dynamic_type
|
||||
return EqualUnmodifiableListView(value);
|
||||
}
|
||||
|
||||
@override final String? alterUrl;
|
||||
@override@JsonKey() final bool autoConnect;
|
||||
/// [id] of the jump server
|
||||
@override final String? jumpId;
|
||||
@override final ServerCustom? custom;
|
||||
@override final WakeOnLanCfg? wolCfg;
|
||||
/// It only applies to SSH terminal.
|
||||
final Map<String, String>? _envs;
|
||||
/// It only applies to SSH terminal.
|
||||
@override Map<String, String>? get envs {
|
||||
final value = _envs;
|
||||
if (value == null) return null;
|
||||
if (_envs is EqualUnmodifiableMapView) return _envs;
|
||||
// ignore: implicit_dynamic_type
|
||||
return EqualUnmodifiableMapView(value);
|
||||
}
|
||||
|
||||
@override@JsonKey(fromJson: Spi.parseId) final String id;
|
||||
|
||||
/// Create a copy of Spi
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@pragma('vm:prefer-inline')
|
||||
_$SpiCopyWith<_Spi> get copyWith => __$SpiCopyWithImpl<_Spi>(this, _$identity);
|
||||
|
||||
@override
|
||||
Map<String, dynamic> toJson() {
|
||||
return _$SpiToJson(this, );
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is _Spi&&(identical(other.name, name) || other.name == name)&&(identical(other.ip, ip) || other.ip == ip)&&(identical(other.port, port) || other.port == port)&&(identical(other.user, user) || other.user == user)&&(identical(other.pwd, pwd) || other.pwd == pwd)&&(identical(other.keyId, keyId) || other.keyId == keyId)&&const DeepCollectionEquality().equals(other._tags, _tags)&&(identical(other.alterUrl, alterUrl) || other.alterUrl == alterUrl)&&(identical(other.autoConnect, autoConnect) || other.autoConnect == autoConnect)&&(identical(other.jumpId, jumpId) || other.jumpId == jumpId)&&(identical(other.custom, custom) || other.custom == custom)&&(identical(other.wolCfg, wolCfg) || other.wolCfg == wolCfg)&&const DeepCollectionEquality().equals(other._envs, _envs)&&(identical(other.id, id) || other.id == id));
|
||||
}
|
||||
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,name,ip,port,user,pwd,keyId,const DeepCollectionEquality().hash(_tags),alterUrl,autoConnect,jumpId,custom,wolCfg,const DeepCollectionEquality().hash(_envs),id);
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
class _$SpiCopyWithImpl<$Res, $Val extends Spi> implements $SpiCopyWith<$Res> {
|
||||
_$SpiCopyWithImpl(this._value, this._then);
|
||||
abstract mixin class _$SpiCopyWith<$Res> implements $SpiCopyWith<$Res> {
|
||||
factory _$SpiCopyWith(_Spi value, $Res Function(_Spi) _then) = __$SpiCopyWithImpl;
|
||||
@override @useResult
|
||||
$Res call({
|
||||
String name, String ip, int port, String user, String? pwd,@JsonKey(name: 'pubKeyId') String? keyId, List<String>? tags, String? alterUrl, bool autoConnect, String? jumpId, ServerCustom? custom, WakeOnLanCfg? wolCfg, Map<String, String>? envs,@JsonKey(fromJson: Spi.parseId) String id
|
||||
});
|
||||
|
||||
|
||||
|
||||
// ignore: unused_field
|
||||
final $Val _value;
|
||||
// ignore: unused_field
|
||||
final $Res Function($Val) _then;
|
||||
|
||||
/// Create a copy of Spi
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@pragma('vm:prefer-inline')
|
||||
@override
|
||||
$Res call({
|
||||
Object? name = null,
|
||||
Object? ip = null,
|
||||
Object? port = null,
|
||||
Object? user = null,
|
||||
Object? pwd = freezed,
|
||||
Object? keyId = freezed,
|
||||
Object? tags = freezed,
|
||||
Object? alterUrl = freezed,
|
||||
Object? autoConnect = null,
|
||||
Object? jumpId = freezed,
|
||||
Object? custom = freezed,
|
||||
Object? wolCfg = freezed,
|
||||
Object? envs = freezed,
|
||||
Object? id = null,
|
||||
}) {
|
||||
return _then(
|
||||
_value.copyWith(
|
||||
name: null == name
|
||||
? _value.name
|
||||
: name // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
ip: null == ip
|
||||
? _value.ip
|
||||
: ip // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
port: null == port
|
||||
? _value.port
|
||||
: port // ignore: cast_nullable_to_non_nullable
|
||||
as int,
|
||||
user: null == user
|
||||
? _value.user
|
||||
: user // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
pwd: freezed == pwd
|
||||
? _value.pwd
|
||||
: pwd // ignore: cast_nullable_to_non_nullable
|
||||
as String?,
|
||||
keyId: freezed == keyId
|
||||
? _value.keyId
|
||||
: keyId // ignore: cast_nullable_to_non_nullable
|
||||
as String?,
|
||||
tags: freezed == tags
|
||||
? _value.tags
|
||||
: tags // ignore: cast_nullable_to_non_nullable
|
||||
as List<String>?,
|
||||
alterUrl: freezed == alterUrl
|
||||
? _value.alterUrl
|
||||
: alterUrl // ignore: cast_nullable_to_non_nullable
|
||||
as String?,
|
||||
autoConnect: null == autoConnect
|
||||
? _value.autoConnect
|
||||
: autoConnect // ignore: cast_nullable_to_non_nullable
|
||||
as bool,
|
||||
jumpId: freezed == jumpId
|
||||
? _value.jumpId
|
||||
: jumpId // ignore: cast_nullable_to_non_nullable
|
||||
as String?,
|
||||
custom: freezed == custom
|
||||
? _value.custom
|
||||
: custom // ignore: cast_nullable_to_non_nullable
|
||||
as ServerCustom?,
|
||||
wolCfg: freezed == wolCfg
|
||||
? _value.wolCfg
|
||||
: wolCfg // ignore: cast_nullable_to_non_nullable
|
||||
as WakeOnLanCfg?,
|
||||
envs: freezed == envs
|
||||
? _value.envs
|
||||
: envs // ignore: cast_nullable_to_non_nullable
|
||||
as Map<String, String>?,
|
||||
id: null == id
|
||||
? _value.id
|
||||
: id // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
)
|
||||
as $Val,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract class _$$SpiImplCopyWith<$Res> implements $SpiCopyWith<$Res> {
|
||||
factory _$$SpiImplCopyWith(_$SpiImpl value, $Res Function(_$SpiImpl) then) =
|
||||
__$$SpiImplCopyWithImpl<$Res>;
|
||||
@override
|
||||
@useResult
|
||||
$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,
|
||||
});
|
||||
class __$SpiCopyWithImpl<$Res>
|
||||
implements _$SpiCopyWith<$Res> {
|
||||
__$SpiCopyWithImpl(this._self, this._then);
|
||||
|
||||
final _Spi _self;
|
||||
final $Res Function(_Spi) _then;
|
||||
|
||||
/// Create a copy of Spi
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @pragma('vm:prefer-inline') $Res call({Object? name = null,Object? ip = null,Object? port = null,Object? user = null,Object? pwd = freezed,Object? keyId = freezed,Object? tags = freezed,Object? alterUrl = freezed,Object? autoConnect = null,Object? jumpId = freezed,Object? custom = freezed,Object? wolCfg = freezed,Object? envs = freezed,Object? id = null,}) {
|
||||
return _then(_Spi(
|
||||
name: null == name ? _self.name : name // ignore: cast_nullable_to_non_nullable
|
||||
as String,ip: null == ip ? _self.ip : ip // ignore: cast_nullable_to_non_nullable
|
||||
as String,port: null == port ? _self.port : port // ignore: cast_nullable_to_non_nullable
|
||||
as int,user: null == user ? _self.user : user // ignore: cast_nullable_to_non_nullable
|
||||
as String,pwd: freezed == pwd ? _self.pwd : pwd // ignore: cast_nullable_to_non_nullable
|
||||
as String?,keyId: freezed == keyId ? _self.keyId : keyId // ignore: cast_nullable_to_non_nullable
|
||||
as String?,tags: freezed == tags ? _self._tags : tags // ignore: cast_nullable_to_non_nullable
|
||||
as List<String>?,alterUrl: freezed == alterUrl ? _self.alterUrl : alterUrl // ignore: cast_nullable_to_non_nullable
|
||||
as String?,autoConnect: null == autoConnect ? _self.autoConnect : autoConnect // ignore: cast_nullable_to_non_nullable
|
||||
as bool,jumpId: freezed == jumpId ? _self.jumpId : jumpId // ignore: cast_nullable_to_non_nullable
|
||||
as String?,custom: freezed == custom ? _self.custom : custom // ignore: cast_nullable_to_non_nullable
|
||||
as ServerCustom?,wolCfg: freezed == wolCfg ? _self.wolCfg : wolCfg // ignore: cast_nullable_to_non_nullable
|
||||
as WakeOnLanCfg?,envs: freezed == envs ? _self._envs : envs // ignore: cast_nullable_to_non_nullable
|
||||
as Map<String, String>?,id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
));
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
class __$$SpiImplCopyWithImpl<$Res> extends _$SpiCopyWithImpl<$Res, _$SpiImpl>
|
||||
implements _$$SpiImplCopyWith<$Res> {
|
||||
__$$SpiImplCopyWithImpl(_$SpiImpl _value, $Res Function(_$SpiImpl) _then)
|
||||
: super(_value, _then);
|
||||
|
||||
/// Create a copy of Spi
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@pragma('vm:prefer-inline')
|
||||
@override
|
||||
$Res call({
|
||||
Object? name = null,
|
||||
Object? ip = null,
|
||||
Object? port = null,
|
||||
Object? user = null,
|
||||
Object? pwd = freezed,
|
||||
Object? keyId = freezed,
|
||||
Object? tags = freezed,
|
||||
Object? alterUrl = freezed,
|
||||
Object? autoConnect = null,
|
||||
Object? jumpId = freezed,
|
||||
Object? custom = freezed,
|
||||
Object? wolCfg = freezed,
|
||||
Object? envs = freezed,
|
||||
Object? id = null,
|
||||
}) {
|
||||
return _then(
|
||||
_$SpiImpl(
|
||||
name: null == name
|
||||
? _value.name
|
||||
: name // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
ip: null == ip
|
||||
? _value.ip
|
||||
: ip // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
port: null == port
|
||||
? _value.port
|
||||
: port // ignore: cast_nullable_to_non_nullable
|
||||
as int,
|
||||
user: null == user
|
||||
? _value.user
|
||||
: user // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
pwd: freezed == pwd
|
||||
? _value.pwd
|
||||
: pwd // ignore: cast_nullable_to_non_nullable
|
||||
as String?,
|
||||
keyId: freezed == keyId
|
||||
? _value.keyId
|
||||
: keyId // ignore: cast_nullable_to_non_nullable
|
||||
as String?,
|
||||
tags: freezed == tags
|
||||
? _value._tags
|
||||
: tags // ignore: cast_nullable_to_non_nullable
|
||||
as List<String>?,
|
||||
alterUrl: freezed == alterUrl
|
||||
? _value.alterUrl
|
||||
: alterUrl // ignore: cast_nullable_to_non_nullable
|
||||
as String?,
|
||||
autoConnect: null == autoConnect
|
||||
? _value.autoConnect
|
||||
: autoConnect // ignore: cast_nullable_to_non_nullable
|
||||
as bool,
|
||||
jumpId: freezed == jumpId
|
||||
? _value.jumpId
|
||||
: jumpId // ignore: cast_nullable_to_non_nullable
|
||||
as String?,
|
||||
custom: freezed == custom
|
||||
? _value.custom
|
||||
: custom // ignore: cast_nullable_to_non_nullable
|
||||
as ServerCustom?,
|
||||
wolCfg: freezed == wolCfg
|
||||
? _value.wolCfg
|
||||
: wolCfg // ignore: cast_nullable_to_non_nullable
|
||||
as WakeOnLanCfg?,
|
||||
envs: freezed == envs
|
||||
? _value._envs
|
||||
: envs // ignore: cast_nullable_to_non_nullable
|
||||
as Map<String, String>?,
|
||||
id: null == id
|
||||
? _value.id
|
||||
: id // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
@JsonSerializable(createFactory: false)
|
||||
class _$SpiImpl extends _Spi {
|
||||
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,
|
||||
_envs = envs,
|
||||
super._();
|
||||
|
||||
@override
|
||||
final String name;
|
||||
@override
|
||||
final String ip;
|
||||
@override
|
||||
final int port;
|
||||
@override
|
||||
final String user;
|
||||
@override
|
||||
final String? pwd;
|
||||
|
||||
/// [id] of private key
|
||||
@override
|
||||
@JsonKey(name: 'pubKeyId')
|
||||
final String? keyId;
|
||||
final List<String>? _tags;
|
||||
@override
|
||||
List<String>? get tags {
|
||||
final value = _tags;
|
||||
if (value == null) return null;
|
||||
if (_tags is EqualUnmodifiableListView) return _tags;
|
||||
// ignore: implicit_dynamic_type
|
||||
return EqualUnmodifiableListView(value);
|
||||
}
|
||||
|
||||
@override
|
||||
final String? alterUrl;
|
||||
@override
|
||||
@JsonKey(defaultValue: true)
|
||||
final bool autoConnect;
|
||||
|
||||
/// [id] of the jump server
|
||||
@override
|
||||
final String? jumpId;
|
||||
@override
|
||||
final ServerCustom? custom;
|
||||
@override
|
||||
final WakeOnLanCfg? wolCfg;
|
||||
|
||||
/// It only applies to SSH terminal.
|
||||
final Map<String, String>? _envs;
|
||||
|
||||
/// It only applies to SSH terminal.
|
||||
@override
|
||||
Map<String, String>? get envs {
|
||||
final value = _envs;
|
||||
if (value == null) return null;
|
||||
if (_envs is EqualUnmodifiableMapView) return _envs;
|
||||
// ignore: implicit_dynamic_type
|
||||
return EqualUnmodifiableMapView(value);
|
||||
}
|
||||
|
||||
@override
|
||||
@JsonKey(fromJson: Spi.parseId)
|
||||
@HiveField(13, defaultValue: '')
|
||||
final String id;
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) ||
|
||||
(other.runtimeType == runtimeType &&
|
||||
other is _$SpiImpl &&
|
||||
(identical(other.name, name) || other.name == name) &&
|
||||
(identical(other.ip, ip) || other.ip == ip) &&
|
||||
(identical(other.port, port) || other.port == port) &&
|
||||
(identical(other.user, user) || other.user == user) &&
|
||||
(identical(other.pwd, pwd) || other.pwd == pwd) &&
|
||||
(identical(other.keyId, keyId) || other.keyId == keyId) &&
|
||||
const DeepCollectionEquality().equals(other._tags, _tags) &&
|
||||
(identical(other.alterUrl, alterUrl) ||
|
||||
other.alterUrl == alterUrl) &&
|
||||
(identical(other.autoConnect, autoConnect) ||
|
||||
other.autoConnect == autoConnect) &&
|
||||
(identical(other.jumpId, jumpId) || other.jumpId == jumpId) &&
|
||||
(identical(other.custom, custom) || other.custom == custom) &&
|
||||
(identical(other.wolCfg, wolCfg) || other.wolCfg == wolCfg) &&
|
||||
const DeepCollectionEquality().equals(other._envs, _envs) &&
|
||||
(identical(other.id, id) || other.id == id));
|
||||
}
|
||||
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@override
|
||||
int get hashCode => Object.hash(
|
||||
runtimeType,
|
||||
name,
|
||||
ip,
|
||||
port,
|
||||
user,
|
||||
pwd,
|
||||
keyId,
|
||||
const DeepCollectionEquality().hash(_tags),
|
||||
alterUrl,
|
||||
autoConnect,
|
||||
jumpId,
|
||||
custom,
|
||||
wolCfg,
|
||||
const DeepCollectionEquality().hash(_envs),
|
||||
id,
|
||||
);
|
||||
|
||||
/// Create a copy of Spi
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@override
|
||||
@pragma('vm:prefer-inline')
|
||||
_$$SpiImplCopyWith<_$SpiImpl> get copyWith =>
|
||||
__$$SpiImplCopyWithImpl<_$SpiImpl>(this, _$identity);
|
||||
|
||||
@override
|
||||
Map<String, dynamic> toJson() {
|
||||
return _$$SpiImplToJson(this);
|
||||
}
|
||||
}
|
||||
|
||||
abstract class _Spi extends Spi {
|
||||
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;
|
||||
const _Spi._() : super._();
|
||||
|
||||
@override
|
||||
String get name;
|
||||
@override
|
||||
String get ip;
|
||||
@override
|
||||
int get port;
|
||||
@override
|
||||
String get user;
|
||||
@override
|
||||
String? get pwd;
|
||||
|
||||
/// [id] of private key
|
||||
@override
|
||||
@JsonKey(name: 'pubKeyId')
|
||||
String? get keyId;
|
||||
@override
|
||||
List<String>? get tags;
|
||||
@override
|
||||
String? get alterUrl;
|
||||
@override
|
||||
@JsonKey(defaultValue: true)
|
||||
bool get autoConnect;
|
||||
|
||||
/// [id] of the jump server
|
||||
@override
|
||||
String? get jumpId;
|
||||
@override
|
||||
ServerCustom? get custom;
|
||||
@override
|
||||
WakeOnLanCfg? get wolCfg;
|
||||
|
||||
/// It only applies to SSH terminal.
|
||||
@override
|
||||
Map<String, String>? get envs;
|
||||
@override
|
||||
@JsonKey(fromJson: Spi.parseId)
|
||||
@HiveField(13, defaultValue: '')
|
||||
String get id;
|
||||
|
||||
/// Create a copy of Spi
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
_$$SpiImplCopyWith<_$SpiImpl> get copyWith =>
|
||||
throw _privateConstructorUsedError;
|
||||
}
|
||||
// dart format on
|
||||
|
||||
@@ -6,7 +6,7 @@ part of 'server_private_info.dart';
|
||||
// JsonSerializableGenerator
|
||||
// **************************************************************************
|
||||
|
||||
Spi _$SpiFromJson(Map<String, dynamic> json) => Spi(
|
||||
_Spi _$SpiFromJson(Map<String, dynamic> json) => _Spi(
|
||||
name: json['name'] as String,
|
||||
ip: json['ip'] as String,
|
||||
port: (json['port'] as num).toInt(),
|
||||
@@ -26,10 +26,10 @@ Spi _$SpiFromJson(Map<String, dynamic> json) => Spi(
|
||||
envs: (json['envs'] as Map<String, dynamic>?)?.map(
|
||||
(k, e) => MapEntry(k, e as String),
|
||||
),
|
||||
id: Spi.parseId(json['id']),
|
||||
id: json['id'] == null ? '' : Spi.parseId(json['id']),
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$SpiToJson(Spi instance) => <String, dynamic>{
|
||||
Map<String, dynamic> _$SpiToJson(_Spi instance) => <String, dynamic>{
|
||||
'name': instance.name,
|
||||
'ip': instance.ip,
|
||||
'port': instance.port,
|
||||
@@ -45,20 +45,3 @@ Map<String, dynamic> _$SpiToJson(Spi instance) => <String, dynamic>{
|
||||
if (instance.envs case final value?) 'envs': value,
|
||||
'id': instance.id,
|
||||
};
|
||||
|
||||
Map<String, dynamic> _$$SpiImplToJson(_$SpiImpl instance) => <String, dynamic>{
|
||||
'name': instance.name,
|
||||
'ip': instance.ip,
|
||||
'port': instance.port,
|
||||
'user': instance.user,
|
||||
'pwd': instance.pwd,
|
||||
'pubKeyId': instance.keyId,
|
||||
'tags': instance.tags,
|
||||
'alterUrl': instance.alterUrl,
|
||||
'autoConnect': instance.autoConnect,
|
||||
'jumpId': instance.jumpId,
|
||||
'custom': instance.custom,
|
||||
'wolCfg': instance.wolCfg,
|
||||
'envs': instance.envs,
|
||||
'id': instance.id,
|
||||
};
|
||||
|
||||
@@ -9,7 +9,7 @@ part 'snippet.g.dart';
|
||||
part 'snippet.freezed.dart';
|
||||
|
||||
@freezed
|
||||
class Snippet with _$Snippet {
|
||||
abstract class Snippet with _$Snippet {
|
||||
const factory Snippet({
|
||||
required String name,
|
||||
required String script,
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// dart format width=80
|
||||
// coverage:ignore-file
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
// ignore_for_file: type=lint
|
||||
@@ -9,280 +10,170 @@ part of 'snippet.dart';
|
||||
// FreezedGenerator
|
||||
// **************************************************************************
|
||||
|
||||
// dart format off
|
||||
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',
|
||||
);
|
||||
|
||||
Snippet _$SnippetFromJson(Map<String, dynamic> json) {
|
||||
return _Snippet.fromJson(json);
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
mixin _$Snippet {
|
||||
String get name => throw _privateConstructorUsedError;
|
||||
String get script => throw _privateConstructorUsedError;
|
||||
List<String>? get tags => throw _privateConstructorUsedError;
|
||||
String? get note => throw _privateConstructorUsedError;
|
||||
|
||||
/// List of server id that this snippet should be auto run on
|
||||
List<String>? get autoRunOn => throw _privateConstructorUsedError;
|
||||
String get name; String get script; List<String>? get tags; String? get note;/// List of server id that this snippet should be auto run on
|
||||
List<String>? get autoRunOn;
|
||||
/// Create a copy of Snippet
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@pragma('vm:prefer-inline')
|
||||
$SnippetCopyWith<Snippet> get copyWith => _$SnippetCopyWithImpl<Snippet>(this as Snippet, _$identity);
|
||||
|
||||
/// Serializes this Snippet to a JSON map.
|
||||
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
|
||||
Map<String, dynamic> toJson();
|
||||
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is Snippet&&(identical(other.name, name) || other.name == name)&&(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));
|
||||
}
|
||||
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,name,script,const DeepCollectionEquality().hash(tags),note,const DeepCollectionEquality().hash(autoRunOn));
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'Snippet(name: $name, script: $script, tags: $tags, note: $note, autoRunOn: $autoRunOn)';
|
||||
}
|
||||
|
||||
|
||||
/// Create a copy of Snippet
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
$SnippetCopyWith<Snippet> get copyWith => throw _privateConstructorUsedError;
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract class $SnippetCopyWith<$Res> {
|
||||
factory $SnippetCopyWith(Snippet value, $Res Function(Snippet) then) =
|
||||
_$SnippetCopyWithImpl<$Res, Snippet>;
|
||||
@useResult
|
||||
$Res call({
|
||||
String name,
|
||||
String script,
|
||||
List<String>? tags,
|
||||
String? note,
|
||||
List<String>? autoRunOn,
|
||||
});
|
||||
}
|
||||
abstract mixin class $SnippetCopyWith<$Res> {
|
||||
factory $SnippetCopyWith(Snippet value, $Res Function(Snippet) _then) = _$SnippetCopyWithImpl;
|
||||
@useResult
|
||||
$Res call({
|
||||
String name, String script, List<String>? tags, String? note, List<String>? autoRunOn
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
/// @nodoc
|
||||
class _$SnippetCopyWithImpl<$Res, $Val extends Snippet>
|
||||
class _$SnippetCopyWithImpl<$Res>
|
||||
implements $SnippetCopyWith<$Res> {
|
||||
_$SnippetCopyWithImpl(this._value, this._then);
|
||||
_$SnippetCopyWithImpl(this._self, this._then);
|
||||
|
||||
// ignore: unused_field
|
||||
final $Val _value;
|
||||
// ignore: unused_field
|
||||
final $Res Function($Val) _then;
|
||||
final Snippet _self;
|
||||
final $Res Function(Snippet) _then;
|
||||
|
||||
/// Create a copy of Snippet
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@pragma('vm:prefer-inline')
|
||||
@override
|
||||
$Res call({
|
||||
Object? name = null,
|
||||
Object? script = null,
|
||||
Object? tags = freezed,
|
||||
Object? note = freezed,
|
||||
Object? autoRunOn = freezed,
|
||||
}) {
|
||||
return _then(
|
||||
_value.copyWith(
|
||||
name: null == name
|
||||
? _value.name
|
||||
: name // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
script: null == script
|
||||
? _value.script
|
||||
: script // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
tags: freezed == tags
|
||||
? _value.tags
|
||||
: tags // ignore: cast_nullable_to_non_nullable
|
||||
as List<String>?,
|
||||
note: freezed == note
|
||||
? _value.note
|
||||
: note // ignore: cast_nullable_to_non_nullable
|
||||
as String?,
|
||||
autoRunOn: freezed == autoRunOn
|
||||
? _value.autoRunOn
|
||||
: autoRunOn // ignore: cast_nullable_to_non_nullable
|
||||
as List<String>?,
|
||||
)
|
||||
as $Val,
|
||||
);
|
||||
}
|
||||
/// Create a copy of Snippet
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@pragma('vm:prefer-inline') @override $Res call({Object? name = null,Object? script = null,Object? tags = freezed,Object? note = freezed,Object? autoRunOn = freezed,}) {
|
||||
return _then(_self.copyWith(
|
||||
name: null == name ? _self.name : name // ignore: cast_nullable_to_non_nullable
|
||||
as String,script: null == script ? _self.script : script // ignore: cast_nullable_to_non_nullable
|
||||
as String,tags: freezed == tags ? _self.tags : tags // ignore: cast_nullable_to_non_nullable
|
||||
as List<String>?,note: freezed == note ? _self.note : note // ignore: cast_nullable_to_non_nullable
|
||||
as String?,autoRunOn: freezed == autoRunOn ? _self.autoRunOn : autoRunOn // ignore: cast_nullable_to_non_nullable
|
||||
as List<String>?,
|
||||
));
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract class _$$SnippetImplCopyWith<$Res> implements $SnippetCopyWith<$Res> {
|
||||
factory _$$SnippetImplCopyWith(
|
||||
_$SnippetImpl value,
|
||||
$Res Function(_$SnippetImpl) then,
|
||||
) = __$$SnippetImplCopyWithImpl<$Res>;
|
||||
@override
|
||||
@useResult
|
||||
$Res call({
|
||||
String name,
|
||||
String script,
|
||||
List<String>? tags,
|
||||
String? note,
|
||||
List<String>? autoRunOn,
|
||||
});
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
class __$$SnippetImplCopyWithImpl<$Res>
|
||||
extends _$SnippetCopyWithImpl<$Res, _$SnippetImpl>
|
||||
implements _$$SnippetImplCopyWith<$Res> {
|
||||
__$$SnippetImplCopyWithImpl(
|
||||
_$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.
|
||||
@pragma('vm:prefer-inline')
|
||||
@override
|
||||
$Res call({
|
||||
Object? name = null,
|
||||
Object? script = null,
|
||||
Object? tags = freezed,
|
||||
Object? note = freezed,
|
||||
Object? autoRunOn = freezed,
|
||||
}) {
|
||||
return _then(
|
||||
_$SnippetImpl(
|
||||
name: null == name
|
||||
? _value.name
|
||||
: name // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
script: null == script
|
||||
? _value.script
|
||||
: script // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
tags: freezed == tags
|
||||
? _value._tags
|
||||
: tags // ignore: cast_nullable_to_non_nullable
|
||||
as List<String>?,
|
||||
note: freezed == note
|
||||
? _value.note
|
||||
: note // ignore: cast_nullable_to_non_nullable
|
||||
as String?,
|
||||
autoRunOn: freezed == autoRunOn
|
||||
? _value._autoRunOn
|
||||
: autoRunOn // ignore: cast_nullable_to_non_nullable
|
||||
as List<String>?,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
@JsonSerializable()
|
||||
class _$SnippetImpl implements _Snippet {
|
||||
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);
|
||||
class _Snippet implements Snippet {
|
||||
const _Snippet({required this.name, required this.script, final List<String>? tags, this.note, final List<String>? autoRunOn}): _tags = tags,_autoRunOn = autoRunOn;
|
||||
factory _Snippet.fromJson(Map<String, dynamic> json) => _$SnippetFromJson(json);
|
||||
|
||||
@override
|
||||
final String name;
|
||||
@override
|
||||
final String script;
|
||||
final List<String>? _tags;
|
||||
@override
|
||||
List<String>? get tags {
|
||||
final value = _tags;
|
||||
if (value == null) return null;
|
||||
if (_tags is EqualUnmodifiableListView) return _tags;
|
||||
// ignore: implicit_dynamic_type
|
||||
return EqualUnmodifiableListView(value);
|
||||
}
|
||||
|
||||
@override
|
||||
final String? note;
|
||||
|
||||
/// List of server id that this snippet should be auto run on
|
||||
final List<String>? _autoRunOn;
|
||||
|
||||
/// List of server id that this snippet should be auto run on
|
||||
@override
|
||||
List<String>? get autoRunOn {
|
||||
final value = _autoRunOn;
|
||||
if (value == null) return null;
|
||||
if (_autoRunOn is EqualUnmodifiableListView) return _autoRunOn;
|
||||
// ignore: implicit_dynamic_type
|
||||
return EqualUnmodifiableListView(value);
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'Snippet(name: $name, script: $script, tags: $tags, note: $note, autoRunOn: $autoRunOn)';
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) ||
|
||||
(other.runtimeType == runtimeType &&
|
||||
other is _$SnippetImpl &&
|
||||
(identical(other.name, name) || other.name == name) &&
|
||||
(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,
|
||||
));
|
||||
}
|
||||
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@override
|
||||
int get hashCode => Object.hash(
|
||||
runtimeType,
|
||||
name,
|
||||
script,
|
||||
const DeepCollectionEquality().hash(_tags),
|
||||
note,
|
||||
const DeepCollectionEquality().hash(_autoRunOn),
|
||||
);
|
||||
|
||||
/// Create a copy of Snippet
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@override
|
||||
@pragma('vm:prefer-inline')
|
||||
_$$SnippetImplCopyWith<_$SnippetImpl> get copyWith =>
|
||||
__$$SnippetImplCopyWithImpl<_$SnippetImpl>(this, _$identity);
|
||||
|
||||
@override
|
||||
Map<String, dynamic> toJson() {
|
||||
return _$$SnippetImplToJson(this);
|
||||
}
|
||||
@override final String name;
|
||||
@override final String script;
|
||||
final List<String>? _tags;
|
||||
@override List<String>? get tags {
|
||||
final value = _tags;
|
||||
if (value == null) return null;
|
||||
if (_tags is EqualUnmodifiableListView) return _tags;
|
||||
// ignore: implicit_dynamic_type
|
||||
return EqualUnmodifiableListView(value);
|
||||
}
|
||||
|
||||
abstract class _Snippet implements Snippet {
|
||||
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
|
||||
String get name;
|
||||
@override
|
||||
String get script;
|
||||
@override
|
||||
List<String>? get tags;
|
||||
@override
|
||||
String? get note;
|
||||
|
||||
/// List of server id that this snippet should be auto run on
|
||||
@override
|
||||
List<String>? get autoRunOn;
|
||||
|
||||
/// Create a copy of Snippet
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
_$$SnippetImplCopyWith<_$SnippetImpl> get copyWith =>
|
||||
throw _privateConstructorUsedError;
|
||||
@override final String? note;
|
||||
/// List of server id that this snippet should be auto run on
|
||||
final List<String>? _autoRunOn;
|
||||
/// List of server id that this snippet should be auto run on
|
||||
@override List<String>? get autoRunOn {
|
||||
final value = _autoRunOn;
|
||||
if (value == null) return null;
|
||||
if (_autoRunOn is EqualUnmodifiableListView) return _autoRunOn;
|
||||
// ignore: implicit_dynamic_type
|
||||
return EqualUnmodifiableListView(value);
|
||||
}
|
||||
|
||||
|
||||
/// Create a copy of Snippet
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@pragma('vm:prefer-inline')
|
||||
_$SnippetCopyWith<_Snippet> get copyWith => __$SnippetCopyWithImpl<_Snippet>(this, _$identity);
|
||||
|
||||
@override
|
||||
Map<String, dynamic> toJson() {
|
||||
return _$SnippetToJson(this, );
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is _Snippet&&(identical(other.name, name) || other.name == name)&&(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));
|
||||
}
|
||||
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,name,script,const DeepCollectionEquality().hash(_tags),note,const DeepCollectionEquality().hash(_autoRunOn));
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'Snippet(name: $name, script: $script, tags: $tags, note: $note, autoRunOn: $autoRunOn)';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract mixin class _$SnippetCopyWith<$Res> implements $SnippetCopyWith<$Res> {
|
||||
factory _$SnippetCopyWith(_Snippet value, $Res Function(_Snippet) _then) = __$SnippetCopyWithImpl;
|
||||
@override @useResult
|
||||
$Res call({
|
||||
String name, String script, List<String>? tags, String? note, List<String>? autoRunOn
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
/// @nodoc
|
||||
class __$SnippetCopyWithImpl<$Res>
|
||||
implements _$SnippetCopyWith<$Res> {
|
||||
__$SnippetCopyWithImpl(this._self, this._then);
|
||||
|
||||
final _Snippet _self;
|
||||
final $Res Function(_Snippet) _then;
|
||||
|
||||
/// Create a copy of Snippet
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @pragma('vm:prefer-inline') $Res call({Object? name = null,Object? script = null,Object? tags = freezed,Object? note = freezed,Object? autoRunOn = freezed,}) {
|
||||
return _then(_Snippet(
|
||||
name: null == name ? _self.name : name // ignore: cast_nullable_to_non_nullable
|
||||
as String,script: null == script ? _self.script : script // ignore: cast_nullable_to_non_nullable
|
||||
as String,tags: freezed == tags ? _self._tags : tags // ignore: cast_nullable_to_non_nullable
|
||||
as List<String>?,note: freezed == note ? _self.note : note // ignore: cast_nullable_to_non_nullable
|
||||
as String?,autoRunOn: freezed == autoRunOn ? _self._autoRunOn : autoRunOn // ignore: cast_nullable_to_non_nullable
|
||||
as List<String>?,
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
// dart format on
|
||||
|
||||
@@ -6,22 +6,20 @@ part of 'snippet.dart';
|
||||
// JsonSerializableGenerator
|
||||
// **************************************************************************
|
||||
|
||||
_$SnippetImpl _$$SnippetImplFromJson(Map<String, dynamic> json) =>
|
||||
_$SnippetImpl(
|
||||
name: json['name'] as String,
|
||||
script: json['script'] as String,
|
||||
tags: (json['tags'] as List<dynamic>?)?.map((e) => e as String).toList(),
|
||||
note: json['note'] as String?,
|
||||
autoRunOn: (json['autoRunOn'] as List<dynamic>?)
|
||||
?.map((e) => e as String)
|
||||
.toList(),
|
||||
);
|
||||
_Snippet _$SnippetFromJson(Map<String, dynamic> json) => _Snippet(
|
||||
name: json['name'] as String,
|
||||
script: json['script'] as String,
|
||||
tags: (json['tags'] as List<dynamic>?)?.map((e) => e as String).toList(),
|
||||
note: json['note'] as String?,
|
||||
autoRunOn: (json['autoRunOn'] as List<dynamic>?)
|
||||
?.map((e) => e as String)
|
||||
.toList(),
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$$SnippetImplToJson(_$SnippetImpl instance) =>
|
||||
<String, dynamic>{
|
||||
'name': instance.name,
|
||||
'script': instance.script,
|
||||
'tags': instance.tags,
|
||||
'note': instance.note,
|
||||
'autoRunOn': instance.autoRunOn,
|
||||
};
|
||||
Map<String, dynamic> _$SnippetToJson(_Snippet instance) => <String, dynamic>{
|
||||
'name': instance.name,
|
||||
'script': instance.script,
|
||||
'tags': instance.tags,
|
||||
'note': instance.note,
|
||||
'autoRunOn': instance.autoRunOn,
|
||||
};
|
||||
|
||||
@@ -6,7 +6,7 @@ part 'app.g.dart';
|
||||
part 'app.freezed.dart';
|
||||
|
||||
@freezed
|
||||
class AppState with _$AppState {
|
||||
abstract class AppState with _$AppState {
|
||||
const factory AppState({
|
||||
@Default(false) bool desktopMode,
|
||||
}) = _AppState;
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// dart format width=80
|
||||
// coverage:ignore-file
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
// ignore_for_file: type=lint
|
||||
@@ -9,140 +10,133 @@ part of 'app.dart';
|
||||
// FreezedGenerator
|
||||
// **************************************************************************
|
||||
|
||||
// dart format off
|
||||
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',
|
||||
);
|
||||
|
||||
/// @nodoc
|
||||
mixin _$AppState {
|
||||
bool get desktopMode => throw _privateConstructorUsedError;
|
||||
|
||||
/// Create a copy of AppState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
$AppStateCopyWith<AppState> get copyWith =>
|
||||
throw _privateConstructorUsedError;
|
||||
bool get desktopMode;
|
||||
/// Create a copy of AppState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@pragma('vm:prefer-inline')
|
||||
$AppStateCopyWith<AppState> get copyWith => _$AppStateCopyWithImpl<AppState>(this as AppState, _$identity);
|
||||
|
||||
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is AppState&&(identical(other.desktopMode, desktopMode) || other.desktopMode == desktopMode));
|
||||
}
|
||||
|
||||
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,desktopMode);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'AppState(desktopMode: $desktopMode)';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract class $AppStateCopyWith<$Res> {
|
||||
factory $AppStateCopyWith(AppState value, $Res Function(AppState) then) =
|
||||
_$AppStateCopyWithImpl<$Res, AppState>;
|
||||
@useResult
|
||||
$Res call({bool desktopMode});
|
||||
}
|
||||
abstract mixin class $AppStateCopyWith<$Res> {
|
||||
factory $AppStateCopyWith(AppState value, $Res Function(AppState) _then) = _$AppStateCopyWithImpl;
|
||||
@useResult
|
||||
$Res call({
|
||||
bool desktopMode
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
/// @nodoc
|
||||
class _$AppStateCopyWithImpl<$Res, $Val extends AppState>
|
||||
class _$AppStateCopyWithImpl<$Res>
|
||||
implements $AppStateCopyWith<$Res> {
|
||||
_$AppStateCopyWithImpl(this._value, this._then);
|
||||
_$AppStateCopyWithImpl(this._self, this._then);
|
||||
|
||||
// ignore: unused_field
|
||||
final $Val _value;
|
||||
// ignore: unused_field
|
||||
final $Res Function($Val) _then;
|
||||
final AppState _self;
|
||||
final $Res Function(AppState) _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(
|
||||
_value.copyWith(
|
||||
desktopMode: null == desktopMode
|
||||
? _value.desktopMode
|
||||
: desktopMode // ignore: cast_nullable_to_non_nullable
|
||||
as bool,
|
||||
)
|
||||
as $Val,
|
||||
);
|
||||
}
|
||||
/// 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(_self.copyWith(
|
||||
desktopMode: null == desktopMode ? _self.desktopMode : desktopMode // ignore: cast_nullable_to_non_nullable
|
||||
as bool,
|
||||
));
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract class _$$AppStateImplCopyWith<$Res>
|
||||
implements $AppStateCopyWith<$Res> {
|
||||
factory _$$AppStateImplCopyWith(
|
||||
_$AppStateImpl value,
|
||||
$Res Function(_$AppStateImpl) then,
|
||||
) = __$$AppStateImplCopyWithImpl<$Res>;
|
||||
@override
|
||||
@useResult
|
||||
$Res call({bool desktopMode});
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
class __$$AppStateImplCopyWithImpl<$Res>
|
||||
extends _$AppStateCopyWithImpl<$Res, _$AppStateImpl>
|
||||
implements _$$AppStateImplCopyWith<$Res> {
|
||||
__$$AppStateImplCopyWithImpl(
|
||||
_$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(
|
||||
desktopMode: null == desktopMode
|
||||
? _value.desktopMode
|
||||
: desktopMode // ignore: cast_nullable_to_non_nullable
|
||||
as bool,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
|
||||
class _$AppStateImpl implements _AppState {
|
||||
const _$AppStateImpl({this.desktopMode = false});
|
||||
|
||||
@override
|
||||
@JsonKey()
|
||||
final bool desktopMode;
|
||||
class _AppState implements AppState {
|
||||
const _AppState({this.desktopMode = false});
|
||||
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'AppState(desktopMode: $desktopMode)';
|
||||
}
|
||||
@override@JsonKey() final bool desktopMode;
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) ||
|
||||
(other.runtimeType == runtimeType &&
|
||||
other is _$AppStateImpl &&
|
||||
(identical(other.desktopMode, desktopMode) ||
|
||||
other.desktopMode == desktopMode));
|
||||
}
|
||||
/// Create a copy of AppState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@pragma('vm:prefer-inline')
|
||||
_$AppStateCopyWith<_AppState> get copyWith => __$AppStateCopyWithImpl<_AppState>(this, _$identity);
|
||||
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType, desktopMode);
|
||||
|
||||
/// Create a copy of AppState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@override
|
||||
@pragma('vm:prefer-inline')
|
||||
_$$AppStateImplCopyWith<_$AppStateImpl> get copyWith =>
|
||||
__$$AppStateImplCopyWithImpl<_$AppStateImpl>(this, _$identity);
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) || (other.runtimeType == runtimeType&&other is _AppState&&(identical(other.desktopMode, desktopMode) || other.desktopMode == desktopMode));
|
||||
}
|
||||
|
||||
abstract class _AppState implements AppState {
|
||||
const factory _AppState({final bool desktopMode}) = _$AppStateImpl;
|
||||
|
||||
@override
|
||||
bool get desktopMode;
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType,desktopMode);
|
||||
|
||||
/// Create a copy of AppState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
_$$AppStateImplCopyWith<_$AppStateImpl> get copyWith =>
|
||||
throw _privateConstructorUsedError;
|
||||
@override
|
||||
String toString() {
|
||||
return 'AppState(desktopMode: $desktopMode)';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract mixin class _$AppStateCopyWith<$Res> implements $AppStateCopyWith<$Res> {
|
||||
factory _$AppStateCopyWith(_AppState value, $Res Function(_AppState) _then) = __$AppStateCopyWithImpl;
|
||||
@override @useResult
|
||||
$Res call({
|
||||
bool desktopMode
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
/// @nodoc
|
||||
class __$AppStateCopyWithImpl<$Res>
|
||||
implements _$AppStateCopyWith<$Res> {
|
||||
__$AppStateCopyWithImpl(this._self, this._then);
|
||||
|
||||
final _AppState _self;
|
||||
final $Res Function(_AppState) _then;
|
||||
|
||||
/// Create a copy of AppState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override @pragma('vm:prefer-inline') $Res call({Object? desktopMode = null,}) {
|
||||
return _then(_AppState(
|
||||
desktopMode: null == desktopMode ? _self.desktopMode : desktopMode // ignore: cast_nullable_to_non_nullable
|
||||
as bool,
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
// dart format on
|
||||
|
||||
@@ -222,6 +222,23 @@ class ContainerProvider extends ChangeNotifier {
|
||||
|
||||
Future<ContainerErr?> restart(String id) async => await run('restart $id');
|
||||
|
||||
Future<ContainerErr?> pruneImages({bool all = true}) async {
|
||||
final cmd = 'image prune${all ? " -a" : ""} -f';
|
||||
return await run(cmd);
|
||||
}
|
||||
|
||||
Future<ContainerErr?> pruneContainers() async {
|
||||
return await run('container prune -f');
|
||||
}
|
||||
|
||||
Future<ContainerErr?> pruneVolumes() async {
|
||||
return await run('volume prune -f');
|
||||
}
|
||||
|
||||
Future<ContainerErr?> pruneSystem() async {
|
||||
return await run('system prune -a -f --volumes');
|
||||
}
|
||||
|
||||
Future<ContainerErr?> run(String cmd, {bool autoRefresh = true}) async {
|
||||
cmd = switch (type) {
|
||||
ContainerType.docker => 'docker $cmd',
|
||||
@@ -272,6 +289,8 @@ enum ContainerCmdType {
|
||||
ps,
|
||||
stats,
|
||||
images,
|
||||
// No specific commands needed for prune actions as they are simple
|
||||
// and don't require splitting output with ShellFunc.seperator
|
||||
;
|
||||
|
||||
String exec(
|
||||
|
||||
@@ -3,6 +3,6 @@
|
||||
|
||||
abstract class BuildData {
|
||||
static const String name = "ServerBox";
|
||||
static const int build = 1185;
|
||||
static const int script = 63;
|
||||
static const int build = 1189;
|
||||
static const int script = 64;
|
||||
}
|
||||
|
||||
@@ -176,8 +176,8 @@ class SettingStore extends HiveStore {
|
||||
late final containerParseStat = propertyDefault('containerParseStat', true);
|
||||
|
||||
/// Auto refresh container status
|
||||
late final contaienrAutoRefresh = propertyDefault(
|
||||
'contaienrAutoRefresh',
|
||||
late final containerAutoRefresh = propertyDefault(
|
||||
'containerAutoRefresh',
|
||||
true,
|
||||
);
|
||||
|
||||
|
||||
@@ -914,6 +914,12 @@ abstract class AppLocalizations {
|
||||
/// **'Process'**
|
||||
String get process;
|
||||
|
||||
/// No description provided for @prune.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Prune'**
|
||||
String get prune;
|
||||
|
||||
/// No description provided for @pushToken.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
|
||||
@@ -452,6 +452,9 @@ class AppLocalizationsDe extends AppLocalizations {
|
||||
@override
|
||||
String get process => 'Prozess';
|
||||
|
||||
@override
|
||||
String get prune => 'Beschneiden';
|
||||
|
||||
@override
|
||||
String get pushToken => 'Push Token';
|
||||
|
||||
|
||||
@@ -450,6 +450,9 @@ class AppLocalizationsEn extends AppLocalizations {
|
||||
@override
|
||||
String get process => 'Process';
|
||||
|
||||
@override
|
||||
String get prune => 'Prune';
|
||||
|
||||
@override
|
||||
String get pushToken => 'Push token';
|
||||
|
||||
|
||||
@@ -454,6 +454,9 @@ class AppLocalizationsEs extends AppLocalizations {
|
||||
@override
|
||||
String get process => 'Proceso';
|
||||
|
||||
@override
|
||||
String get prune => 'Podar';
|
||||
|
||||
@override
|
||||
String get pushToken => 'Token de notificaciones';
|
||||
|
||||
|
||||
@@ -455,6 +455,9 @@ class AppLocalizationsFr extends AppLocalizations {
|
||||
@override
|
||||
String get process => 'Processus';
|
||||
|
||||
@override
|
||||
String get prune => 'Élaguer';
|
||||
|
||||
@override
|
||||
String get pushToken => 'Jeton d\'identification';
|
||||
|
||||
|
||||
@@ -450,6 +450,9 @@ class AppLocalizationsId extends AppLocalizations {
|
||||
@override
|
||||
String get process => 'Proses';
|
||||
|
||||
@override
|
||||
String get prune => 'Pangkas';
|
||||
|
||||
@override
|
||||
String get pushToken => 'Dorong token';
|
||||
|
||||
|
||||
@@ -436,6 +436,9 @@ class AppLocalizationsJa extends AppLocalizations {
|
||||
@override
|
||||
String get process => 'プロセス';
|
||||
|
||||
@override
|
||||
String get prune => '剪定する';
|
||||
|
||||
@override
|
||||
String get pushToken => 'プッシュトークン';
|
||||
|
||||
|
||||
@@ -451,6 +451,9 @@ class AppLocalizationsNl extends AppLocalizations {
|
||||
@override
|
||||
String get process => 'Proces';
|
||||
|
||||
@override
|
||||
String get prune => 'Snoeien';
|
||||
|
||||
@override
|
||||
String get pushToken => 'Push-token';
|
||||
|
||||
|
||||
@@ -451,6 +451,9 @@ class AppLocalizationsPt extends AppLocalizations {
|
||||
@override
|
||||
String get process => 'Processo';
|
||||
|
||||
@override
|
||||
String get prune => 'Podar';
|
||||
|
||||
@override
|
||||
String get pushToken => 'Token de notificação push';
|
||||
|
||||
|
||||
@@ -452,6 +452,9 @@ class AppLocalizationsRu extends AppLocalizations {
|
||||
@override
|
||||
String get process => 'Процесс';
|
||||
|
||||
@override
|
||||
String get prune => 'Обрезать';
|
||||
|
||||
@override
|
||||
String get pushToken => 'Токен уведомлений';
|
||||
|
||||
|
||||
@@ -449,6 +449,9 @@ class AppLocalizationsTr extends AppLocalizations {
|
||||
@override
|
||||
String get process => 'İşlem';
|
||||
|
||||
@override
|
||||
String get prune => 'Budamak';
|
||||
|
||||
@override
|
||||
String get pushToken => 'Push belirteci';
|
||||
|
||||
|
||||
@@ -454,6 +454,9 @@ class AppLocalizationsUk extends AppLocalizations {
|
||||
@override
|
||||
String get process => 'Процес';
|
||||
|
||||
@override
|
||||
String get prune => 'Обрізати';
|
||||
|
||||
@override
|
||||
String get pushToken => 'Надіслати токен';
|
||||
|
||||
|
||||
@@ -431,6 +431,9 @@ class AppLocalizationsZh extends AppLocalizations {
|
||||
@override
|
||||
String get process => '进程';
|
||||
|
||||
@override
|
||||
String get prune => '修剪';
|
||||
|
||||
@override
|
||||
String get pushToken => '消息推送 Token';
|
||||
|
||||
@@ -1162,6 +1165,9 @@ class AppLocalizationsZhTw extends AppLocalizationsZh {
|
||||
@override
|
||||
String get process => '行程';
|
||||
|
||||
@override
|
||||
String get prune => '修剪';
|
||||
|
||||
@override
|
||||
String get pushToken => '消息推送 Token';
|
||||
|
||||
|
||||
@@ -132,6 +132,7 @@
|
||||
"preview": "Vorschau",
|
||||
"privateKey": "Private Key",
|
||||
"process": "Prozess",
|
||||
"prune": "Beschneiden",
|
||||
"pushToken": "Push Token",
|
||||
"pveIgnoreCertTip": "Nicht empfohlen, Achten Sie auf Sicherheitsrisiken! Wenn Sie das Standardzertifikat von PVE verwenden, müssen Sie diese Option aktivieren.",
|
||||
"pveLoginFailed": "Anmeldung fehlgeschlagen. Kann nicht mit Benutzername/Passwort aus der Serverkonfiguration angemeldet werden, um sich über Linux PAM anzumelden.",
|
||||
|
||||
@@ -132,6 +132,7 @@
|
||||
"preview": "Preview",
|
||||
"privateKey": "Private Key",
|
||||
"process": "Process",
|
||||
"prune": "Prune",
|
||||
"pushToken": "Push token",
|
||||
"pveIgnoreCertTip": "Not recommended to enable, beware of security risks! If you are using the default certificate from PVE, you need to enable this option.",
|
||||
"pveLoginFailed": "Login failed. Unable to authenticate with username/password from server configuration for Linux PAM login.",
|
||||
|
||||
@@ -132,6 +132,7 @@
|
||||
"preview": "Vista previa",
|
||||
"privateKey": "Llave privada",
|
||||
"process": "Proceso",
|
||||
"prune": "Podar",
|
||||
"pushToken": "Token de notificaciones",
|
||||
"pveIgnoreCertTip": "No se recomienda activarlo, ¡tenga cuidado con los riesgos de seguridad! Si está utilizando el certificado predeterminado de PVE, debe habilitar esta opción.",
|
||||
"pveLoginFailed": "Fallo al iniciar sesión. No se puede autenticar con el nombre de usuario/contraseña de la configuración del servidor para el inicio de sesión de Linux PAM.",
|
||||
|
||||
@@ -132,6 +132,7 @@
|
||||
"preview": "Aperçu",
|
||||
"privateKey": "Clé privée",
|
||||
"process": "Processus",
|
||||
"prune": "Élaguer",
|
||||
"pushToken": "Jeton d'identification",
|
||||
"pveIgnoreCertTip": "Il n'est pas recommandé de l'activer, attention aux risques de sécurité ! Si vous utilisez le certificat par défaut de PVE, vous devez activer cette option.",
|
||||
"pveLoginFailed": "Échec de la connexion. Impossible d'authentifier avec le nom d'utilisateur / mot de passe de la configuration du serveur pour la connexion Linux PAM.",
|
||||
|
||||
@@ -132,6 +132,7 @@
|
||||
"preview": "Pratinjau",
|
||||
"privateKey": "Kunci Pribadi",
|
||||
"process": "Proses",
|
||||
"prune": "Pangkas",
|
||||
"pushToken": "Dorong token",
|
||||
"pveIgnoreCertTip": "Tidak disarankan untuk diaktifkan, waspadai risiko keamanan! Jika Anda menggunakan sertifikat default dari PVE, Anda perlu mengaktifkan opsi ini.",
|
||||
"pveLoginFailed": "Login gagal. Tidak dapat mengautentikasi dengan nama pengguna/kata sandi dari konfigurasi server untuk login Linux PAM.",
|
||||
|
||||
@@ -132,6 +132,7 @@
|
||||
"preview": "プレビュー",
|
||||
"privateKey": "秘密鍵",
|
||||
"process": "プロセス",
|
||||
"prune": "剪定する",
|
||||
"pushToken": "プッシュトークン",
|
||||
"pveIgnoreCertTip": "オプションを有効にすることは推奨されません、セキュリティリスクに注意してください!PVEのデフォルト証明書を使用している場合は、このオプションを有効にする必要があります。",
|
||||
"pveLoginFailed": "ログインに失敗しました。Linux PAMログインのためにサーバー構成からのユーザー名/パスワードで認証できません。",
|
||||
|
||||
@@ -132,6 +132,7 @@
|
||||
"preview": "Voorbeeld",
|
||||
"privateKey": "Privésleutel",
|
||||
"process": "Proces",
|
||||
"prune": "Snoeien",
|
||||
"pushToken": "Push-token",
|
||||
"pveIgnoreCertTip": "Niet aanbevolen om in te schakelen, let op beveiligingsrisico's! Als u de standaardcertificaat van PVE gebruikt, moet u deze optie inschakelen.",
|
||||
"pveLoginFailed": "Aanmelden mislukt. Kan niet authenticeren met gebruikersnaam/wachtwoord van serverconfiguratie voor Linux PAM-login.",
|
||||
|
||||
@@ -132,6 +132,7 @@
|
||||
"preview": "Pré-visualização",
|
||||
"privateKey": "Chave privada",
|
||||
"process": "Processo",
|
||||
"prune": "Podar",
|
||||
"pushToken": "Token de notificação push",
|
||||
"pveIgnoreCertTip": "Não recomendado para ativar, cuidado com os riscos de segurança! Se estiver usando o certificado padrão do PVE, você precisa habilitar esta opção.",
|
||||
"pveLoginFailed": "Falha no login. Não é possível autenticar com o nome de usuário/senha da configuração do servidor para login no Linux PAM.",
|
||||
|
||||
@@ -132,6 +132,7 @@
|
||||
"preview": "Предпросмотр",
|
||||
"privateKey": "Приватный ключ",
|
||||
"process": "Процесс",
|
||||
"prune": "Обрезать",
|
||||
"pushToken": "Токен уведомлений",
|
||||
"pveIgnoreCertTip": "Не рекомендуется включать, обратите внимание на риски безопасности! Если вы используете стандартный сертификат от PVE, вам нужно включить эту опцию.",
|
||||
"pveLoginFailed": "Ошибка входа. Невозможно аутентифицироваться с помощью имени пользователя/пароля из конфигурации сервера для входа в Linux PAM.",
|
||||
|
||||
@@ -132,6 +132,7 @@
|
||||
"preview": "Önizleme",
|
||||
"privateKey": "Özel Anahtar",
|
||||
"process": "İşlem",
|
||||
"prune": "Budamak",
|
||||
"pushToken": "Push belirteci",
|
||||
"pveIgnoreCertTip": "Etkinleştirilmesi önerilmez, güvenlik risklerine dikkat edin! PVE'den varsayılan sertifikayı kullanıyorsanız, bu seçeneği etkinleştirmeniz gerekir.",
|
||||
"pveLoginFailed": "Giriş başarısız. Linux PAM girişi için sunucu yapılandırmasındaki kullanıcı adı/şifre ile kimlik doğrulama yapılamadı.",
|
||||
|
||||
@@ -132,6 +132,7 @@
|
||||
"preview": "Попередній перегляд",
|
||||
"privateKey": "Приватний ключ",
|
||||
"process": "Процес",
|
||||
"prune": "Обрізати",
|
||||
"pushToken": "Надіслати токен",
|
||||
"pveIgnoreCertTip": "Не рекомендується включати, будьте обережні з ризиками безпеки! Якщо ви використовуєте стандартний сертифікат від PVE, вам потрібно увімкнути цю опцію.",
|
||||
"pveLoginFailed": "Не вдалося увійти. Неможливо пройти аутентифікацію за допомогою імені користувача/пароля з конфігурації сервера для входу Linux PAM.",
|
||||
|
||||
@@ -132,6 +132,7 @@
|
||||
"preview": "预览",
|
||||
"privateKey": "私钥",
|
||||
"process": "进程",
|
||||
"prune": "修剪",
|
||||
"pushToken": "消息推送 Token",
|
||||
"pveIgnoreCertTip": "不推荐开启,注意安全隐患!如果你使用的 PVE 默认证书,需要开启该选项",
|
||||
"pveLoginFailed": "登录失败。无法使用服务器配置内的用户/密码,以 Linux PAM 方式登录。",
|
||||
|
||||
@@ -132,6 +132,7 @@
|
||||
"preview": "預覽",
|
||||
"privateKey": "私鑰",
|
||||
"process": "行程",
|
||||
"prune": "修剪",
|
||||
"pushToken": "消息推送 Token",
|
||||
"pveIgnoreCertTip": "不建議啟用,請注意安全風險!如果您使用的是 PVE 的默認證書,則需要啟用此選項。",
|
||||
"pveLoginFailed": "登錄失敗。無法使用伺服器配置中的使用者名稱/密碼以 Linux PAM 方式登錄。",
|
||||
|
||||
@@ -1,591 +0,0 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:fl_lib/fl_lib.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:server_box/core/extension/context/locale.dart';
|
||||
import 'package:server_box/core/route.dart';
|
||||
import 'package:server_box/data/model/app/menu/base.dart';
|
||||
import 'package:server_box/data/model/app/menu/container.dart';
|
||||
import 'package:server_box/data/model/container/image.dart';
|
||||
import 'package:server_box/data/model/container/ps.dart';
|
||||
import 'package:server_box/data/model/container/type.dart';
|
||||
import 'package:server_box/data/model/server/server_private_info.dart';
|
||||
import 'package:server_box/data/provider/container.dart';
|
||||
import 'package:server_box/data/res/store.dart';
|
||||
import 'package:server_box/view/page/ssh/page/page.dart';
|
||||
|
||||
class ContainerPage extends StatefulWidget {
|
||||
final SpiRequiredArgs args;
|
||||
const ContainerPage({required this.args, super.key});
|
||||
|
||||
@override
|
||||
State<ContainerPage> createState() => _ContainerPageState();
|
||||
|
||||
static const route = AppRouteArg(
|
||||
page: ContainerPage.new,
|
||||
path: '/container',
|
||||
);
|
||||
}
|
||||
|
||||
class _ContainerPageState extends State<ContainerPage> {
|
||||
final _textController = TextEditingController();
|
||||
late final _container = ContainerProvider(
|
||||
client: widget.args.spi.server?.value.client,
|
||||
userName: widget.args.spi.user,
|
||||
hostId: widget.args.spi.id,
|
||||
context: context,
|
||||
);
|
||||
late Size _size;
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
super.dispose();
|
||||
_textController.dispose();
|
||||
_container.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_initAutoRefresh();
|
||||
}
|
||||
|
||||
@override
|
||||
void didChangeDependencies() {
|
||||
super.didChangeDependencies();
|
||||
_size = MediaQuery.of(context).size;
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Consumer<ContainerProvider>(
|
||||
builder: (_, _, _) {
|
||||
return Scaffold(
|
||||
appBar: CustomAppBar(
|
||||
centerTitle: true,
|
||||
title: TwoLineText(up: l10n.container, down: widget.args.spi.name),
|
||||
actions: [
|
||||
IconButton(
|
||||
onPressed: () => context.showLoadingDialog(fn: () => _container.refresh()),
|
||||
icon: const Icon(Icons.refresh),
|
||||
)
|
||||
],
|
||||
),
|
||||
body: _buildMain(),
|
||||
floatingActionButton: _container.error == null ? _buildFAB() : null,
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildFAB() {
|
||||
return FloatingActionButton(
|
||||
onPressed: () async => await _showAddFAB(),
|
||||
child: const Icon(Icons.add),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildMain() {
|
||||
if (_container.error != null && _container.items == null) {
|
||||
return SizedBox.expand(
|
||||
child: Column(
|
||||
children: [
|
||||
const Spacer(),
|
||||
const Icon(
|
||||
Icons.error,
|
||||
size: 37,
|
||||
),
|
||||
UIs.height13,
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 23),
|
||||
child: Text(_container.error.toString()),
|
||||
),
|
||||
const Spacer(),
|
||||
_buildEditHost(),
|
||||
_buildSwitchProvider(),
|
||||
UIs.height13,
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
if (_container.items == null || _container.images == null) {
|
||||
return UIs.centerLoading;
|
||||
}
|
||||
|
||||
return ListView(
|
||||
padding: const EdgeInsets.only(left: 13, right: 13, top: 13, bottom: 37),
|
||||
children: <Widget>[
|
||||
_buildLoading(),
|
||||
_buildVersion(),
|
||||
_buildPs(),
|
||||
_buildImage(),
|
||||
_buildEditHost(),
|
||||
_buildSwitchProvider(),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildImage() {
|
||||
return CardX(
|
||||
child: ExpandTile(
|
||||
title: Text(l10n.imagesList),
|
||||
subtitle: Text(
|
||||
l10n.dockerImagesFmt(_container.images!.length),
|
||||
style: UIs.textGrey,
|
||||
),
|
||||
initiallyExpanded: (_container.images?.length ?? 0) <= 3,
|
||||
children: _container.images?.map(_buildImageItem).toList() ?? [],
|
||||
));
|
||||
}
|
||||
|
||||
Widget _buildImageItem(ContainerImg e) {
|
||||
return ListTile(
|
||||
title: Text(e.repository ?? l10n.unknown),
|
||||
subtitle: Text('${e.tag} - ${e.sizeMB}', style: UIs.textGrey),
|
||||
trailing: IconButton(
|
||||
padding: EdgeInsets.zero,
|
||||
alignment: Alignment.centerRight,
|
||||
icon: const Icon(Icons.delete),
|
||||
onPressed: () => _showImageRmDialog(e),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildLoading() {
|
||||
if (_container.runLog == null) return UIs.placeholder;
|
||||
return Padding(
|
||||
padding: const EdgeInsets.all(17),
|
||||
child: Column(
|
||||
children: [
|
||||
const Center(
|
||||
child: CircularProgressIndicator(),
|
||||
),
|
||||
UIs.height13,
|
||||
Text(_container.runLog ?? '...'),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildVersion() {
|
||||
return CardX(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(17),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(_container.type.name.capitalize),
|
||||
Text(_container.version ?? l10n.unknown),
|
||||
],
|
||||
),
|
||||
));
|
||||
}
|
||||
|
||||
Widget _buildPs() {
|
||||
final items = _container.items;
|
||||
if (items == null) return UIs.placeholder;
|
||||
return Column(
|
||||
children: items.map(_buildPsItem).toList(),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildPsItem(ContainerPs item) {
|
||||
return CardX(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 13, vertical: 11),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(item.name ?? l10n.unknown, style: UIs.text15),
|
||||
const SizedBox(height: 3),
|
||||
_buildMoreBtn(item),
|
||||
],
|
||||
),
|
||||
Text(
|
||||
'${item.image ?? l10n.unknown} - ${switch (item) {
|
||||
final PodmanPs ps => ps.running ? l10n.running : l10n.stopped,
|
||||
final DockerPs ps => ps.state,
|
||||
}}',
|
||||
style: UIs.text13Grey,
|
||||
),
|
||||
_buildPsItemStats(item),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildPsItemStats(ContainerPs item) {
|
||||
if (item.cpu == null || item.mem == null) return UIs.placeholder;
|
||||
return Column(
|
||||
children: [
|
||||
UIs.height13,
|
||||
Row(
|
||||
children: [
|
||||
_buildPsItemStatsItem('CPU', item.cpu, Icons.memory),
|
||||
UIs.width13,
|
||||
_buildPsItemStatsItem('Net', item.net, Icons.network_cell),
|
||||
],
|
||||
),
|
||||
Row(
|
||||
children: [
|
||||
_buildPsItemStatsItem('Mem', item.mem, Icons.settings_input_component),
|
||||
UIs.width13,
|
||||
_buildPsItemStatsItem('Disk', item.disk, Icons.storage),
|
||||
],
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildPsItemStatsItem(String title, String? value, IconData icon) {
|
||||
return SizedBox(
|
||||
width: _size.width / 2 - 41,
|
||||
child: Column(
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Icon(icon, size: 12, color: Colors.grey),
|
||||
UIs.width7,
|
||||
Text(value ?? l10n.unknown, style: UIs.text11Grey),
|
||||
],
|
||||
)
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildMoreBtn(ContainerPs dItem) {
|
||||
return PopupMenu(
|
||||
items: ContainerMenu.items(dItem.running).map((e) => PopMenu.build(e, e.icon, e.toStr)).toList(),
|
||||
onSelected: (item) => _onTapMoreBtn(item, dItem),
|
||||
);
|
||||
}
|
||||
|
||||
// String _buildPsCardSubtitle(List<ContainerPs> running) {
|
||||
// final runningCount = running.where((element) => element.running).length;
|
||||
// final stoped = running.length - runningCount;
|
||||
// if (stoped == 0) {
|
||||
// return l10n.dockerStatusRunningFmt(runningCount);
|
||||
// }
|
||||
// return l10n.dockerStatusRunningAndStoppedFmt(runningCount, stoped);
|
||||
// }
|
||||
|
||||
Widget _buildEditHost() {
|
||||
final children = <Widget>[];
|
||||
final emptyImgs = _container.images?.isEmpty ?? false;
|
||||
final emptyPs = _container.items?.isEmpty ?? false;
|
||||
if (emptyPs && emptyImgs) {
|
||||
children.add(Padding(
|
||||
padding: const EdgeInsets.fromLTRB(17, 17, 17, 0),
|
||||
child: SimpleMarkdown(data: l10n.dockerEmptyRunningItems),
|
||||
));
|
||||
}
|
||||
children.add(
|
||||
TextButton(
|
||||
onPressed: _showEditHostDialog,
|
||||
child: Text('${libL10n.edit} DOCKER_HOST'),
|
||||
),
|
||||
);
|
||||
return CardX(
|
||||
child: Column(
|
||||
children: children,
|
||||
));
|
||||
}
|
||||
|
||||
Widget _buildSwitchProvider() {
|
||||
late final Widget child;
|
||||
if (_container.type == ContainerType.podman) {
|
||||
child = TextButton(
|
||||
onPressed: () {
|
||||
_container.setType(ContainerType.docker);
|
||||
},
|
||||
child: Text(l10n.switchTo('Docker')),
|
||||
);
|
||||
} else {
|
||||
child = TextButton(
|
||||
onPressed: () {
|
||||
_container.setType(ContainerType.podman);
|
||||
},
|
||||
child: Text(l10n.switchTo('Podman')),
|
||||
);
|
||||
}
|
||||
return CardX(child: child);
|
||||
}
|
||||
|
||||
Future<void> _showAddFAB() async {
|
||||
final imageCtrl = TextEditingController();
|
||||
final nameCtrl = TextEditingController();
|
||||
final argsCtrl = TextEditingController();
|
||||
await context.showRoundDialog(
|
||||
title: l10n.newContainer,
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Input(
|
||||
autoFocus: true,
|
||||
type: TextInputType.text,
|
||||
label: l10n.image,
|
||||
hint: 'xxx:1.1',
|
||||
controller: imageCtrl,
|
||||
suggestion: false,
|
||||
),
|
||||
Input(
|
||||
type: TextInputType.text,
|
||||
controller: nameCtrl,
|
||||
label: libL10n.name,
|
||||
hint: 'xxx',
|
||||
suggestion: false,
|
||||
),
|
||||
Input(
|
||||
type: TextInputType.text,
|
||||
controller: argsCtrl,
|
||||
label: l10n.extraArgs,
|
||||
hint: '-p 2222:22 -v ~/.xxx/:/xxx',
|
||||
suggestion: false,
|
||||
),
|
||||
],
|
||||
),
|
||||
actions: Btn.ok(onTap: () async {
|
||||
context.pop();
|
||||
await _showAddCmdPreview(
|
||||
_buildAddCmd(
|
||||
imageCtrl.text.trim(),
|
||||
nameCtrl.text.trim(),
|
||||
argsCtrl.text.trim(),
|
||||
),
|
||||
);
|
||||
}).toList);
|
||||
}
|
||||
|
||||
Future<void> _showAddCmdPreview(String cmd) async {
|
||||
await context.showRoundDialog(
|
||||
title: l10n.preview,
|
||||
child: Text(cmd),
|
||||
actions: [
|
||||
TextButton(
|
||||
onPressed: () => context.pop(),
|
||||
child: Text(libL10n.cancel),
|
||||
),
|
||||
TextButton(
|
||||
onPressed: () async {
|
||||
context.pop();
|
||||
|
||||
final (result, err) = await context.showLoadingDialog(
|
||||
fn: () => _container.run(cmd),
|
||||
);
|
||||
if (err != null || result != null) {
|
||||
final e = result?.message ?? err?.toString();
|
||||
context.showRoundDialog(
|
||||
title: libL10n.error,
|
||||
child: Text(e.toString()),
|
||||
);
|
||||
}
|
||||
},
|
||||
child: Text(l10n.run),
|
||||
)
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
String _buildAddCmd(String image, String name, String args) {
|
||||
var suffix = '';
|
||||
if (args.isEmpty) {
|
||||
suffix = image;
|
||||
} else {
|
||||
suffix = '$args $image';
|
||||
}
|
||||
if (name.isEmpty) {
|
||||
return 'run -itd $suffix';
|
||||
}
|
||||
return 'run -itd --name $name $suffix';
|
||||
}
|
||||
|
||||
Future<void> _showEditHostDialog() async {
|
||||
final id = widget.args.spi.id;
|
||||
final host = Stores.container.fetch(id);
|
||||
final ctrl = TextEditingController(text: host);
|
||||
await context.showRoundDialog(
|
||||
title: libL10n.edit,
|
||||
child: Input(
|
||||
maxLines: 2,
|
||||
controller: ctrl,
|
||||
onSubmitted: _onSaveDockerHost,
|
||||
hint: 'unix:///run/user/1000/docker.sock',
|
||||
suggestion: false,
|
||||
),
|
||||
actions: Btn.ok(onTap: () => _onSaveDockerHost(ctrl.text)).toList,
|
||||
);
|
||||
}
|
||||
|
||||
void _onSaveDockerHost(String val) {
|
||||
context.pop();
|
||||
Stores.container.put(widget.args.spi.id, val.trim());
|
||||
_container.refresh();
|
||||
}
|
||||
|
||||
void _showImageRmDialog(ContainerImg e) {
|
||||
context.showRoundDialog(
|
||||
title: libL10n.attention,
|
||||
child: Text(
|
||||
libL10n.askContinue('${libL10n.delete} Image(${e.repository})'),
|
||||
),
|
||||
actions: Btn.ok(
|
||||
onTap: () async {
|
||||
context.pop();
|
||||
final result = await _container.run('rmi ${e.id} -f');
|
||||
if (result != null) {
|
||||
context.showSnackBar(result.message ?? 'null');
|
||||
}
|
||||
},
|
||||
red: true,
|
||||
).toList,
|
||||
);
|
||||
}
|
||||
|
||||
void _onTapMoreBtn(ContainerMenu item, ContainerPs dItem) async {
|
||||
final id = dItem.id;
|
||||
if (id == null) {
|
||||
context.showSnackBar('Id is null');
|
||||
return;
|
||||
}
|
||||
switch (item) {
|
||||
case ContainerMenu.rm:
|
||||
var force = false;
|
||||
context.showRoundDialog(
|
||||
title: libL10n.attention,
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Text(libL10n.askContinue(
|
||||
'${libL10n.delete} Container(${dItem.name})',
|
||||
)),
|
||||
UIs.height13,
|
||||
Row(
|
||||
children: [
|
||||
StatefulBuilder(builder: (_, setState) {
|
||||
return Checkbox(
|
||||
value: force,
|
||||
onChanged: (val) => setState(
|
||||
() => force = val ?? false,
|
||||
),
|
||||
);
|
||||
}),
|
||||
Text(l10n.force),
|
||||
],
|
||||
)
|
||||
],
|
||||
),
|
||||
actions: Btn.ok(onTap: () async {
|
||||
context.pop();
|
||||
|
||||
final (result, err) = await context.showLoadingDialog(
|
||||
fn: () => _container.delete(id, force),
|
||||
);
|
||||
if (err != null || result != null) {
|
||||
final e = result?.message ?? err?.toString();
|
||||
context.showRoundDialog(
|
||||
title: libL10n.error,
|
||||
child: Text(e ?? 'null'),
|
||||
);
|
||||
}
|
||||
}).toList,
|
||||
);
|
||||
break;
|
||||
case ContainerMenu.start:
|
||||
final (result, err) = await context.showLoadingDialog(
|
||||
fn: () => _container.start(id),
|
||||
);
|
||||
if (err != null || result != null) {
|
||||
final e = result?.message ?? err?.toString();
|
||||
context.showRoundDialog(
|
||||
title: libL10n.error,
|
||||
child: Text(e ?? 'null'),
|
||||
);
|
||||
}
|
||||
break;
|
||||
case ContainerMenu.stop:
|
||||
final (result, err) = await context.showLoadingDialog(
|
||||
fn: () => _container.stop(id),
|
||||
);
|
||||
if (err != null || result != null) {
|
||||
final e = result?.message ?? err?.toString();
|
||||
context.showRoundDialog(
|
||||
title: libL10n.error,
|
||||
child: Text(e ?? 'null'),
|
||||
);
|
||||
}
|
||||
break;
|
||||
case ContainerMenu.restart:
|
||||
final (result, err) = await context.showLoadingDialog(
|
||||
fn: () => _container.restart(id),
|
||||
);
|
||||
if (err != null || result != null) {
|
||||
final e = result?.message ?? err?.toString();
|
||||
context.showRoundDialog(
|
||||
title: libL10n.error,
|
||||
child: Text(e ?? 'null'),
|
||||
);
|
||||
}
|
||||
break;
|
||||
case ContainerMenu.logs:
|
||||
final args = SshPageArgs(
|
||||
spi: widget.args.spi,
|
||||
initCmd: '${switch (_container.type) {
|
||||
ContainerType.podman => 'podman',
|
||||
ContainerType.docker => 'docker',
|
||||
}} logs -f --tail 100 ${dItem.id}',
|
||||
);
|
||||
SSHPage.route.go(context, args);
|
||||
break;
|
||||
case ContainerMenu.terminal:
|
||||
final args = SshPageArgs(
|
||||
spi: widget.args.spi,
|
||||
initCmd: '${switch (_container.type) {
|
||||
ContainerType.podman => 'podman',
|
||||
ContainerType.docker => 'docker',
|
||||
}} exec -it ${dItem.id} sh',
|
||||
);
|
||||
SSHPage.route.go(context, args);
|
||||
break;
|
||||
// case DockerMenuType.stats:
|
||||
// showRoundDialog(
|
||||
// context: context,
|
||||
// title: Text(l10n.stats),
|
||||
// child: Text(
|
||||
// 'CPU: ${dItem.cpu}\n'
|
||||
// 'Mem: ${dItem.mem}\n'
|
||||
// 'Net: ${dItem.net}\n'
|
||||
// 'Block: ${dItem.disk}',
|
||||
// ),
|
||||
// actions: [
|
||||
// TextButton(
|
||||
// onPressed: () => context.pop(),
|
||||
// child: Text(l10n.ok),
|
||||
// ),
|
||||
// ],
|
||||
// );
|
||||
// break;
|
||||
}
|
||||
}
|
||||
|
||||
void _initAutoRefresh() {
|
||||
if (Stores.setting.contaienrAutoRefresh.fetch()) {
|
||||
Timer.periodic(
|
||||
Duration(seconds: Stores.setting.serverStatusUpdateInterval.fetch()),
|
||||
(timer) {
|
||||
if (mounted) {
|
||||
_container.refresh(isAuto: true);
|
||||
} else {
|
||||
timer.cancel();
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
232
lib/view/page/container/actions.dart
Normal file
232
lib/view/page/container/actions.dart
Normal file
@@ -0,0 +1,232 @@
|
||||
part of 'container.dart';
|
||||
|
||||
extension on _ContainerPageState {
|
||||
Future<void> _showAddFAB() async {
|
||||
final imageCtrl = TextEditingController();
|
||||
final nameCtrl = TextEditingController();
|
||||
final argsCtrl = TextEditingController();
|
||||
await context.showRoundDialog(
|
||||
title: l10n.newContainer,
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Input(
|
||||
autoFocus: true,
|
||||
type: TextInputType.text,
|
||||
label: l10n.image,
|
||||
hint: 'xxx:1.1',
|
||||
controller: imageCtrl,
|
||||
suggestion: false,
|
||||
),
|
||||
Input(
|
||||
type: TextInputType.text,
|
||||
controller: nameCtrl,
|
||||
label: libL10n.name,
|
||||
hint: 'xxx',
|
||||
suggestion: false,
|
||||
),
|
||||
Input(
|
||||
type: TextInputType.text,
|
||||
controller: argsCtrl,
|
||||
label: l10n.extraArgs,
|
||||
hint: '-p 2222:22 -v ~/.xxx/:/xxx',
|
||||
suggestion: false,
|
||||
),
|
||||
],
|
||||
),
|
||||
actions: Btn.ok(
|
||||
onTap: () async {
|
||||
context.pop();
|
||||
await _showAddCmdPreview(
|
||||
_buildAddCmd(imageCtrl.text.trim(), nameCtrl.text.trim(), argsCtrl.text.trim()),
|
||||
);
|
||||
},
|
||||
).toList,
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> _showPruneDialog({
|
||||
required String title,
|
||||
String? message,
|
||||
required Future<ContainerErr?> Function() onConfirm,
|
||||
}) async {
|
||||
await context.showRoundDialog(
|
||||
title: title,
|
||||
child: Text(message ?? libL10n.askContinue('${l10n.prune} $title')),
|
||||
actions: Btn.ok(
|
||||
onTap: () async {
|
||||
context.pop();
|
||||
final (result, err) = await context.showLoadingDialog(fn: onConfirm);
|
||||
if (err != null || result != null) {
|
||||
final e = result?.message ?? err?.toString();
|
||||
context.showRoundDialog(title: libL10n.error, child: Text(e.toString()));
|
||||
} else {
|
||||
context.showSnackBar(libL10n.success);
|
||||
}
|
||||
},
|
||||
red: true,
|
||||
).toList,
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> _showAddCmdPreview(String cmd) async {
|
||||
await context.showRoundDialog(
|
||||
title: l10n.preview,
|
||||
child: Text(cmd),
|
||||
actions: [
|
||||
TextButton(onPressed: () => context.pop(), child: Text(libL10n.cancel)),
|
||||
TextButton(
|
||||
onPressed: () async {
|
||||
context.pop();
|
||||
|
||||
final (result, err) = await context.showLoadingDialog(fn: () => _container.run(cmd));
|
||||
if (err != null || result != null) {
|
||||
final e = result?.message ?? err?.toString();
|
||||
context.showRoundDialog(title: libL10n.error, child: Text(e.toString()));
|
||||
}
|
||||
},
|
||||
child: Text(l10n.run),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> _showEditHostDialog() async {
|
||||
final id = widget.args.spi.id;
|
||||
final host = Stores.container.fetch(id);
|
||||
final ctrl = TextEditingController(text: host);
|
||||
await context.showRoundDialog(
|
||||
title: libL10n.edit,
|
||||
child: Input(
|
||||
maxLines: 2,
|
||||
controller: ctrl,
|
||||
onSubmitted: _onSaveDockerHost,
|
||||
hint: 'unix:///run/user/1000/docker.sock',
|
||||
suggestion: false,
|
||||
),
|
||||
actions: Btn.ok(onTap: () => _onSaveDockerHost(ctrl.text)).toList,
|
||||
);
|
||||
}
|
||||
|
||||
void _onSaveDockerHost(String val) {
|
||||
context.pop();
|
||||
Stores.container.put(widget.args.spi.id, val.trim());
|
||||
_container.refresh();
|
||||
}
|
||||
|
||||
void _showImageRmDialog(ContainerImg e) {
|
||||
context.showRoundDialog(
|
||||
title: libL10n.attention,
|
||||
child: Text(libL10n.askContinue('${libL10n.delete} Image(${e.repository})')),
|
||||
actions: Btn.ok(
|
||||
onTap: () async {
|
||||
context.pop();
|
||||
final result = await _container.run('rmi ${e.id} -f');
|
||||
if (result != null) {
|
||||
context.showSnackBar(result.message ?? 'null');
|
||||
}
|
||||
},
|
||||
red: true,
|
||||
).toList,
|
||||
);
|
||||
}
|
||||
|
||||
void _onTapMoreBtn(ContainerMenu item, ContainerPs dItem) async {
|
||||
final id = dItem.id;
|
||||
if (id == null) {
|
||||
context.showSnackBar('Id is null');
|
||||
return;
|
||||
}
|
||||
switch (item) {
|
||||
case ContainerMenu.rm:
|
||||
var force = false;
|
||||
context.showRoundDialog(
|
||||
title: libL10n.attention,
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Text(libL10n.askContinue('${libL10n.delete} Container(${dItem.name})')),
|
||||
UIs.height13,
|
||||
Row(
|
||||
children: [
|
||||
StatefulBuilder(
|
||||
builder: (_, setState) {
|
||||
return Checkbox(value: force, onChanged: (val) => setState(() => force = val ?? false));
|
||||
},
|
||||
),
|
||||
Text(l10n.force),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
actions: Btn.ok(
|
||||
onTap: () async {
|
||||
context.pop();
|
||||
|
||||
final (result, err) = await context.showLoadingDialog(fn: () => _container.delete(id, force));
|
||||
if (err != null || result != null) {
|
||||
final e = result?.message ?? err?.toString();
|
||||
context.showRoundDialog(title: libL10n.error, child: Text(e ?? 'null'));
|
||||
}
|
||||
},
|
||||
).toList,
|
||||
);
|
||||
break;
|
||||
case ContainerMenu.start:
|
||||
final (result, err) = await context.showLoadingDialog(fn: () => _container.start(id));
|
||||
if (err != null || result != null) {
|
||||
final e = result?.message ?? err?.toString();
|
||||
context.showRoundDialog(title: libL10n.error, child: Text(e ?? 'null'));
|
||||
}
|
||||
break;
|
||||
case ContainerMenu.stop:
|
||||
final (result, err) = await context.showLoadingDialog(fn: () => _container.stop(id));
|
||||
if (err != null || result != null) {
|
||||
final e = result?.message ?? err?.toString();
|
||||
context.showRoundDialog(title: libL10n.error, child: Text(e ?? 'null'));
|
||||
}
|
||||
break;
|
||||
case ContainerMenu.restart:
|
||||
final (result, err) = await context.showLoadingDialog(fn: () => _container.restart(id));
|
||||
if (err != null || result != null) {
|
||||
final e = result?.message ?? err?.toString();
|
||||
context.showRoundDialog(title: libL10n.error, child: Text(e ?? 'null'));
|
||||
}
|
||||
break;
|
||||
case ContainerMenu.logs:
|
||||
final args = SshPageArgs(
|
||||
spi: widget.args.spi,
|
||||
initCmd:
|
||||
'${switch (_container.type) {
|
||||
ContainerType.podman => 'podman',
|
||||
ContainerType.docker => 'docker',
|
||||
}} logs -f --tail 100 ${dItem.id}',
|
||||
);
|
||||
SSHPage.route.go(context, args);
|
||||
break;
|
||||
case ContainerMenu.terminal:
|
||||
final args = SshPageArgs(
|
||||
spi: widget.args.spi,
|
||||
initCmd:
|
||||
'${switch (_container.type) {
|
||||
ContainerType.podman => 'podman',
|
||||
ContainerType.docker => 'docker',
|
||||
}} exec -it ${dItem.id} sh',
|
||||
);
|
||||
SSHPage.route.go(context, args);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void _initAutoRefresh() {
|
||||
if (Stores.setting.containerAutoRefresh.fetch()) {
|
||||
Timer.periodic(Duration(seconds: Stores.setting.serverStatusUpdateInterval.fetch()), (timer) {
|
||||
if (mounted) {
|
||||
_container.refresh(isAuto: true);
|
||||
} else {
|
||||
timer.cancel();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
370
lib/view/page/container/container.dart
Normal file
370
lib/view/page/container/container.dart
Normal file
@@ -0,0 +1,370 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:fl_lib/fl_lib.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:icons_plus/icons_plus.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:server_box/core/extension/context/locale.dart';
|
||||
import 'package:server_box/core/route.dart';
|
||||
import 'package:server_box/data/model/app/error.dart';
|
||||
import 'package:server_box/data/model/app/menu/base.dart';
|
||||
import 'package:server_box/data/model/app/menu/container.dart';
|
||||
import 'package:server_box/data/model/container/image.dart';
|
||||
import 'package:server_box/data/model/container/ps.dart';
|
||||
import 'package:server_box/data/model/container/type.dart';
|
||||
import 'package:server_box/data/model/server/server_private_info.dart';
|
||||
import 'package:server_box/data/provider/container.dart';
|
||||
import 'package:server_box/data/res/store.dart';
|
||||
import 'package:server_box/view/page/ssh/page/page.dart';
|
||||
|
||||
part 'actions.dart';
|
||||
part 'types.dart';
|
||||
|
||||
class ContainerPage extends StatefulWidget {
|
||||
final SpiRequiredArgs args;
|
||||
const ContainerPage({required this.args, super.key});
|
||||
|
||||
@override
|
||||
State<ContainerPage> createState() => _ContainerPageState();
|
||||
|
||||
static const route = AppRouteArg(page: ContainerPage.new, path: '/container');
|
||||
}
|
||||
|
||||
class _ContainerPageState extends State<ContainerPage> {
|
||||
final _textController = TextEditingController();
|
||||
late final _container = ContainerProvider(
|
||||
client: widget.args.spi.server?.value.client,
|
||||
userName: widget.args.spi.user,
|
||||
hostId: widget.args.spi.id,
|
||||
context: context,
|
||||
);
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
super.dispose();
|
||||
_textController.dispose();
|
||||
_container.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_initAutoRefresh();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return ChangeNotifierProvider(
|
||||
create: (_) => _container,
|
||||
builder: (_, _) => Consumer<ContainerProvider>(
|
||||
builder: (_, _, _) {
|
||||
return Scaffold(
|
||||
appBar: _buildAppBar,
|
||||
body: _buildMain,
|
||||
floatingActionButton: _container.error == null ? _buildFAB : null,
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
CustomAppBar get _buildAppBar {
|
||||
return CustomAppBar(
|
||||
centerTitle: true,
|
||||
title: TwoLineText(up: l10n.container, down: widget.args.spi.name),
|
||||
actions: [
|
||||
IconButton(
|
||||
onPressed: () => context.showLoadingDialog(fn: () => _container.refresh()),
|
||||
icon: const Icon(Icons.refresh),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Widget get _buildFAB {
|
||||
return FloatingActionButton(onPressed: () async => await _showAddFAB(), child: const Icon(Icons.add));
|
||||
}
|
||||
|
||||
Widget get _buildMain {
|
||||
if (_container.error != null && _container.items == null) {
|
||||
return SizedBox.expand(
|
||||
child: Column(
|
||||
children: [
|
||||
const Spacer(),
|
||||
const Icon(Icons.error, size: 37),
|
||||
UIs.height13,
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 23),
|
||||
child: Text(_container.error.toString()),
|
||||
),
|
||||
const Spacer(),
|
||||
UIs.height13,
|
||||
_buildSettingsBtns,
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
if (_container.items == null || _container.images == null) {
|
||||
return UIs.centerLoading;
|
||||
}
|
||||
|
||||
return SafeArea(
|
||||
child: AutoMultiList(
|
||||
children: <Widget>[
|
||||
_buildLoading(),
|
||||
_buildVersion(),
|
||||
_buildPs(),
|
||||
_buildImage(),
|
||||
_buildEmptyStateMessage(),
|
||||
_buildPruneBtns,
|
||||
_buildSettingsBtns,
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildEmptyStateMessage() {
|
||||
final emptyImgs = _container.images?.isEmpty ?? true;
|
||||
final emptyPs = _container.items?.isEmpty ?? true;
|
||||
if (emptyPs && emptyImgs && _container.runLog == null) {
|
||||
return CardX(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.fromLTRB(17, 17, 17, 7),
|
||||
child: SimpleMarkdown(data: l10n.dockerEmptyRunningItems),
|
||||
),
|
||||
);
|
||||
}
|
||||
return UIs.placeholder;
|
||||
}
|
||||
|
||||
Widget _buildImage() {
|
||||
return ExpandTile(
|
||||
leading: const Icon(MingCute.clapperboard_line),
|
||||
title: Text(l10n.imagesList),
|
||||
subtitle: Text(l10n.dockerImagesFmt(_container.images!.length), style: UIs.textGrey),
|
||||
initiallyExpanded: (_container.images?.length ?? 0) <= 3,
|
||||
children: _container.images?.map(_buildImageItem).toList() ?? [],
|
||||
).cardx;
|
||||
}
|
||||
|
||||
Widget _buildImageItem(ContainerImg e) {
|
||||
final repoSplited = e.repository?.split('/');
|
||||
final title = repoSplited?.lastOrNull ?? e.repository;
|
||||
repoSplited?.removeLast();
|
||||
final reg = repoSplited?.join('/');
|
||||
return ListTile(
|
||||
title: Text(title ?? l10n.unknown, style: UIs.text15),
|
||||
subtitle: Text('${reg ?? ''} - ${e.tag} - ${e.sizeMB}', style: UIs.text13Grey),
|
||||
trailing: IconButton(
|
||||
padding: EdgeInsets.zero,
|
||||
icon: const Icon(Icons.delete),
|
||||
onPressed: () => _showImageRmDialog(e),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildLoading() {
|
||||
if (_container.runLog == null) return UIs.placeholder;
|
||||
return Padding(
|
||||
padding: const EdgeInsets.all(17),
|
||||
child: Column(
|
||||
children: [
|
||||
const Center(child: CircularProgressIndicator()),
|
||||
UIs.height13,
|
||||
Text(_container.runLog ?? '...'),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildVersion() {
|
||||
return CardX(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(17),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [Text(_container.type.name.capitalize), Text(_container.version ?? l10n.unknown)],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildPs() {
|
||||
final items = _container.items;
|
||||
if (items == null) return UIs.placeholder;
|
||||
final running = items.where((e) => e.running).length;
|
||||
final stopped = items.length - running;
|
||||
final subtitle = stopped > 0
|
||||
? l10n.dockerStatusRunningAndStoppedFmt(running, stopped)
|
||||
: l10n.dockerStatusRunningFmt(running);
|
||||
return ExpandTile(
|
||||
leading: const Icon(OctIcons.container, size: 22),
|
||||
title: Text(l10n.container),
|
||||
subtitle: Text(subtitle, style: UIs.textGrey),
|
||||
initiallyExpanded: items.length < 7,
|
||||
children: items.map(_buildPsItem).toList(),
|
||||
).cardx;
|
||||
}
|
||||
|
||||
Widget _buildPsItem(ContainerPs item) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 17, vertical: 11),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(item.name ?? l10n.unknown, style: UIs.text15),
|
||||
const SizedBox(height: 3),
|
||||
_buildMoreBtn(item),
|
||||
],
|
||||
),
|
||||
Text(
|
||||
'${item.image ?? l10n.unknown} - ${switch (item) {
|
||||
final PodmanPs ps => ps.running ? l10n.running : l10n.stopped,
|
||||
final DockerPs ps => ps.state,
|
||||
}}',
|
||||
style: UIs.text13Grey,
|
||||
),
|
||||
_buildPsItemStats(item),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildPsItemStats(ContainerPs item) {
|
||||
if (item.cpu == null || item.mem == null) return UIs.placeholder;
|
||||
return LayoutBuilder(
|
||||
builder: (_, cons) {
|
||||
final width = cons.maxWidth / 2 - 41;
|
||||
return Column(
|
||||
children: [
|
||||
UIs.height13,
|
||||
Row(
|
||||
children: [
|
||||
_buildPsItemStatsItem('CPU', item.cpu, Icons.memory, width: width),
|
||||
UIs.width13,
|
||||
_buildPsItemStatsItem('Net', item.net, Icons.network_cell, width: width),
|
||||
],
|
||||
),
|
||||
Row(
|
||||
children: [
|
||||
_buildPsItemStatsItem('Mem', item.mem, Icons.settings_input_component, width: width),
|
||||
UIs.width13,
|
||||
_buildPsItemStatsItem('Disk', item.disk, Icons.storage, width: width),
|
||||
],
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildPsItemStatsItem(String title, String? value, IconData icon, {required double width}) {
|
||||
return SizedBox(
|
||||
width: width,
|
||||
child: Column(
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Icon(icon, size: 12, color: Colors.grey),
|
||||
UIs.width7,
|
||||
Text(value ?? l10n.unknown, style: UIs.text11Grey),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildMoreBtn(ContainerPs dItem) {
|
||||
return PopupMenu(
|
||||
items: ContainerMenu.items(dItem.running).map((e) => PopMenu.build(e, e.icon, e.toStr)).toList(),
|
||||
onSelected: (item) => _onTapMoreBtn(item, dItem),
|
||||
);
|
||||
}
|
||||
|
||||
String _buildAddCmd(String image, String name, String args) {
|
||||
var suffix = '';
|
||||
if (args.isEmpty) {
|
||||
suffix = image;
|
||||
} else {
|
||||
suffix = '$args $image';
|
||||
}
|
||||
if (name.isEmpty) {
|
||||
return 'run -itd $suffix';
|
||||
}
|
||||
return 'run -itd --name $name $suffix';
|
||||
}
|
||||
|
||||
Widget get _buildPruneBtns {
|
||||
final len = _PruneTypes.values.length;
|
||||
if (len == 0) return UIs.placeholder;
|
||||
return ExpandTile(
|
||||
leading: const Icon(Icons.delete),
|
||||
title: Text(l10n.prune),
|
||||
children: _PruneTypes.values.map(_buildPruneBtn).toList(),
|
||||
).cardx;
|
||||
}
|
||||
|
||||
Widget _buildPruneBtn(_PruneTypes type) {
|
||||
final title = type.name.capitalize;
|
||||
return ListTile(
|
||||
onTap: () async {
|
||||
await _showPruneDialog(
|
||||
title: title,
|
||||
message: type.tip,
|
||||
onConfirm: switch (type) {
|
||||
_PruneTypes.images => _container.pruneImages,
|
||||
_PruneTypes.containers => () => _container.pruneContainers(),
|
||||
_PruneTypes.volumes => _container.pruneVolumes,
|
||||
_PruneTypes.system => _container.pruneSystem,
|
||||
},
|
||||
);
|
||||
},
|
||||
title: Text(title),
|
||||
trailing: const Icon(Icons.keyboard_arrow_right),
|
||||
);
|
||||
}
|
||||
|
||||
Widget get _buildSettingsBtns {
|
||||
final len = _SettingsMenuItems.values.length;
|
||||
if (len == 0) return UIs.placeholder;
|
||||
return ExpandTile(
|
||||
leading: const Icon(Icons.settings),
|
||||
title: Text(libL10n.setting),
|
||||
initiallyExpanded: _container.error != null,
|
||||
children: _SettingsMenuItems.values.map(_buildSettingTile).toList(),
|
||||
).cardx;
|
||||
}
|
||||
|
||||
Widget _buildSettingTile(_SettingsMenuItems item) {
|
||||
final String title;
|
||||
switch (item) {
|
||||
case _SettingsMenuItems.editDockerHost:
|
||||
title = '${libL10n.edit} DOCKER_HOST';
|
||||
break;
|
||||
case _SettingsMenuItems.switchProvider:
|
||||
title = _container.type == ContainerType.podman ? l10n.switchTo('Docker') : l10n.switchTo('Podman');
|
||||
break;
|
||||
}
|
||||
return ListTile(
|
||||
onTap: () {
|
||||
switch (item) {
|
||||
case _SettingsMenuItems.editDockerHost:
|
||||
_showEditHostDialog();
|
||||
break;
|
||||
case _SettingsMenuItems.switchProvider:
|
||||
_container.setType(
|
||||
_container.type == ContainerType.docker ? ContainerType.podman : ContainerType.docker,
|
||||
);
|
||||
break;
|
||||
}
|
||||
},
|
||||
title: Text(title),
|
||||
trailing: const Icon(Icons.keyboard_arrow_right),
|
||||
);
|
||||
}
|
||||
}
|
||||
18
lib/view/page/container/types.dart
Normal file
18
lib/view/page/container/types.dart
Normal file
@@ -0,0 +1,18 @@
|
||||
part of 'container.dart';
|
||||
|
||||
enum _SettingsMenuItems { editDockerHost, switchProvider }
|
||||
|
||||
enum _PruneTypes {
|
||||
images,
|
||||
containers,
|
||||
volumes,
|
||||
system;
|
||||
|
||||
String? get tip {
|
||||
return switch (this) {
|
||||
_PruneTypes.system =>
|
||||
'This will remove all unused data, including images, containers, volumes, and networks.',
|
||||
_ => null,
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -580,38 +580,133 @@ class _ServerDetailPageState extends State<ServerDetailPage> with SingleTickerPr
|
||||
}
|
||||
|
||||
Widget _buildDiskSmartItem(DiskSmart smart) {
|
||||
final isPass = smart.healthy ?? false;
|
||||
final statusText = isPass ? 'PASS' : 'FAIL';
|
||||
final statusColor = isPass ? Colors.green : Colors.red;
|
||||
final statusIcon = isPass
|
||||
? Icon(Icons.check_circle, color: Colors.green, size: 18)
|
||||
: Icon(Icons.error, color: Colors.red, size: 18);
|
||||
final healthStatus = _getDiskHealthStatus(smart);
|
||||
|
||||
return ListTile(
|
||||
dense: true,
|
||||
contentPadding: const EdgeInsets.symmetric(horizontal: 8, vertical: 0),
|
||||
leading: statusIcon,
|
||||
leading: healthStatus.icon,
|
||||
title: Text(smart.device, style: UIs.text13, textScaler: _textFactor),
|
||||
trailing: Text(
|
||||
statusText,
|
||||
style: UIs.text13.copyWith(color: statusColor, fontWeight: FontWeight.bold),
|
||||
healthStatus.text,
|
||||
style: UIs.text13.copyWith(fontWeight: FontWeight.bold),
|
||||
textScaler: _textFactor,
|
||||
),
|
||||
subtitle: _buildDiskSmartDetails(smart),
|
||||
onTap: () => _onTapDiskSmartItem(smart),
|
||||
);
|
||||
}
|
||||
|
||||
({String text, Color color, Widget icon}) _getDiskHealthStatus(DiskSmart smart) {
|
||||
if (smart.healthy == null) {
|
||||
return (
|
||||
text: libL10n.unknown,
|
||||
color: Colors.orange,
|
||||
icon: const Icon(Icons.help_outline, color: Colors.orange, size: 18),
|
||||
);
|
||||
} else if (smart.healthy!) {
|
||||
return (
|
||||
text: 'PASS',
|
||||
color: Colors.green,
|
||||
icon: const Icon(Icons.check_circle, color: Colors.green, size: 18),
|
||||
);
|
||||
} else {
|
||||
return (text: 'FAIL', color: Colors.red, icon: const Icon(Icons.error, color: Colors.red, size: 18));
|
||||
}
|
||||
}
|
||||
|
||||
Widget? _buildDiskSmartDetails(DiskSmart smart) {
|
||||
final details = <String>[];
|
||||
|
||||
if (smart.model != null) details.add(smart.model!);
|
||||
if (smart.serial != null) details.add('S/N: ${smart.serial}');
|
||||
if (smart.temperature != null) details.add('${smart.temperature!.toStringAsFixed(1)}°C');
|
||||
if (smart.powerOnHours != null) details.add('${smart.powerOnHours} hours');
|
||||
|
||||
|
||||
if (smart.model != null) {
|
||||
details.add(smart.model!);
|
||||
}
|
||||
|
||||
if (smart.temperature != null) {
|
||||
details.add('${smart.temperature!.toStringAsFixed(1)}°C');
|
||||
}
|
||||
|
||||
if (smart.powerOnHours != null) {
|
||||
final hours = smart.powerOnHours!;
|
||||
details.add('$hours ${libL10n.hour}');
|
||||
}
|
||||
|
||||
if (smart.ssdLifeLeft != null) {
|
||||
details.add('Life left: ${smart.ssdLifeLeft}%');
|
||||
}
|
||||
|
||||
if (details.isEmpty) return null;
|
||||
|
||||
return Text(details.join(' | '), style: UIs.text12, textScaler: _textFactor);
|
||||
|
||||
return Text(
|
||||
details.join(' | '),
|
||||
style: UIs.text12Grey,
|
||||
textScaler: _textFactor,
|
||||
maxLines: 2,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
);
|
||||
}
|
||||
|
||||
void _onTapDiskSmartItem(DiskSmart smart) {
|
||||
final details = <String>[];
|
||||
|
||||
if (smart.model != null) details.add('Model: ${smart.model}');
|
||||
if (smart.serial != null) details.add('Serial: ${smart.serial}');
|
||||
if (smart.temperature != null) details.add('Temperature: ${smart.temperature!.toStringAsFixed(1)}°C');
|
||||
|
||||
if (smart.powerOnHours != null) {
|
||||
details.add('Power On: ${smart.powerOnHours} ${libL10n.hour}');
|
||||
}
|
||||
if (smart.powerCycleCount != null) {
|
||||
details.add('Power Cycle: ${smart.powerCycleCount}');
|
||||
}
|
||||
|
||||
if (smart.ssdLifeLeft != null) {
|
||||
details.add('Life Left: ${smart.ssdLifeLeft}%');
|
||||
}
|
||||
if (smart.lifetimeWritesGiB != null) {
|
||||
details.add('Lifetime Write: ${smart.lifetimeWritesGiB} GiB');
|
||||
}
|
||||
if (smart.lifetimeReadsGiB != null) {
|
||||
details.add('Lifetime Read: ${smart.lifetimeReadsGiB} GiB');
|
||||
}
|
||||
if (smart.averageEraseCount != null) {
|
||||
details.add('Avg. Erase: ${smart.averageEraseCount}');
|
||||
}
|
||||
if (smart.unsafeShutdownCount != null) {
|
||||
details.add('Unsafe Shutdown: ${smart.unsafeShutdownCount}');
|
||||
}
|
||||
|
||||
final criticalAttrs = [
|
||||
'Reallocated_Sector_Ct',
|
||||
'Current_Pending_Sector',
|
||||
'Offline_Uncorrectable',
|
||||
'UDMA_CRC_Error_Count',
|
||||
];
|
||||
|
||||
for (final attrName in criticalAttrs) {
|
||||
final attr = smart.getAttribute(attrName);
|
||||
if (attr != null && attr.rawValue != null) {
|
||||
final value = attr.rawValue.toString();
|
||||
details.add('${attrName.replaceAll('_', ' ')}: $value');
|
||||
}
|
||||
}
|
||||
|
||||
if (details.isEmpty) {
|
||||
return;
|
||||
}
|
||||
|
||||
final markdown = details.join('\n\n- ');
|
||||
context.showRoundDialog(
|
||||
title: smart.device,
|
||||
child: MarkdownBody(
|
||||
data: '- $markdown',
|
||||
selectable: true,
|
||||
styleSheet: MarkdownStyleSheet.fromTheme(Theme.of(context)).copyWith(
|
||||
p: UIs.text13Grey,
|
||||
h2: UIs.text15,
|
||||
),
|
||||
),
|
||||
actions: Btnx.oks,
|
||||
);
|
||||
}
|
||||
|
||||
Widget? _buildNetView(Server si) {
|
||||
|
||||
@@ -12,7 +12,7 @@ import 'package:server_box/data/model/server/snippet.dart';
|
||||
import 'package:server_box/data/provider/server.dart';
|
||||
import 'package:server_box/data/provider/snippet.dart';
|
||||
import 'package:server_box/data/res/store.dart';
|
||||
import 'package:server_box/view/page/container.dart';
|
||||
import 'package:server_box/view/page/container/container.dart';
|
||||
import 'package:server_box/view/page/iperf.dart';
|
||||
import 'package:server_box/view/page/process.dart';
|
||||
import 'package:server_box/view/page/ssh/page/page.dart';
|
||||
|
||||
@@ -471,7 +471,7 @@
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
CURRENT_PROJECT_VERSION = 1185;
|
||||
CURRENT_PROJECT_VERSION = 1189;
|
||||
DEVELOPMENT_TEAM = BA88US33G6;
|
||||
INFOPLIST_FILE = Runner/Info.plist;
|
||||
INFOPLIST_KEY_CFBundleDisplayName = "Server Box";
|
||||
@@ -481,7 +481,7 @@
|
||||
"@executable_path/../Frameworks",
|
||||
);
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.15;
|
||||
MARKETING_VERSION = 1.0.1185;
|
||||
MARKETING_VERSION = 1.0.1189;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox;
|
||||
PRODUCT_NAME = "Server Box";
|
||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||
@@ -608,7 +608,7 @@
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
CURRENT_PROJECT_VERSION = 1185;
|
||||
CURRENT_PROJECT_VERSION = 1189;
|
||||
DEVELOPMENT_TEAM = BA88US33G6;
|
||||
INFOPLIST_FILE = Runner/Info.plist;
|
||||
INFOPLIST_KEY_CFBundleDisplayName = "Server Box";
|
||||
@@ -618,7 +618,7 @@
|
||||
"@executable_path/../Frameworks",
|
||||
);
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.15;
|
||||
MARKETING_VERSION = 1.0.1185;
|
||||
MARKETING_VERSION = 1.0.1189;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox;
|
||||
PRODUCT_NAME = "Server Box";
|
||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||
@@ -638,7 +638,7 @@
|
||||
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "3rd Party Mac Developer Application";
|
||||
CODE_SIGN_STYLE = Manual;
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
CURRENT_PROJECT_VERSION = 1185;
|
||||
CURRENT_PROJECT_VERSION = 1189;
|
||||
DEVELOPMENT_TEAM = "";
|
||||
"DEVELOPMENT_TEAM[sdk=macosx*]" = BA88US33G6;
|
||||
INFOPLIST_FILE = Runner/Info.plist;
|
||||
@@ -649,7 +649,7 @@
|
||||
"@executable_path/../Frameworks",
|
||||
);
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.15;
|
||||
MARKETING_VERSION = 1.0.1185;
|
||||
MARKETING_VERSION = 1.0.1189;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.lollipopkit.toolbox;
|
||||
PRODUCT_NAME = "Server Box";
|
||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||
|
||||
@@ -480,8 +480,8 @@ packages:
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
path: "."
|
||||
ref: "v1.0.49"
|
||||
resolved-ref: "830d1f4c95a35f440881b6ff9c57e24711002fa0"
|
||||
ref: "v1.0.51"
|
||||
resolved-ref: "430672b7c7608b68ceda785533ec11e1ac3e9ca7"
|
||||
url: "https://github.com/lppcg/fl_build.git"
|
||||
source: git
|
||||
version: "1.0.0"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
name: server_box
|
||||
description: server status & toolbox app.
|
||||
publish_to: "none"
|
||||
version: 1.0.1185+1185
|
||||
version: 1.0.1189+1189
|
||||
|
||||
environment:
|
||||
sdk: ">=3.8.0"
|
||||
@@ -91,7 +91,7 @@ dev_dependencies:
|
||||
fl_build:
|
||||
git:
|
||||
url: https://github.com/lppcg/fl_build.git
|
||||
ref: v1.0.49
|
||||
ref: v1.0.51
|
||||
|
||||
flutter:
|
||||
generate: true
|
||||
|
||||
Reference in New Issue
Block a user