new: backup support settings

This commit is contained in:
lollipopkit
2023-08-28 18:21:43 +08:00
parent 0420793e21
commit d06ffdacd0
3 changed files with 64 additions and 54 deletions

View File

@@ -10,6 +10,7 @@ class Backup {
final List<Snippet> snippets; final List<Snippet> snippets;
final List<PrivateKeyInfo> keys; final List<PrivateKeyInfo> keys;
final Map<String, String> dockerHosts; final Map<String, String> dockerHosts;
final Map<String, dynamic> settings;
Backup({ Backup({
required this.version, required this.version,
@@ -18,6 +19,7 @@ class Backup {
required this.snippets, required this.snippets,
required this.keys, required this.keys,
required this.dockerHosts, required this.dockerHosts,
required this.settings,
}); });
Backup.fromJson(Map<String, dynamic> json) Backup.fromJson(Map<String, dynamic> json)
@@ -31,7 +33,8 @@ class Backup {
keys = (json['keys'] as List) keys = (json['keys'] as List)
.map((e) => PrivateKeyInfo.fromJson(e)) .map((e) => PrivateKeyInfo.fromJson(e))
.toList(), .toList(),
dockerHosts = json['dockerHosts'] ?? {}; dockerHosts = json['dockerHosts'] ?? {},
settings = json['settings'] ?? {};
Map<String, dynamic> toJson() => { Map<String, dynamic> toJson() => {
'version': version, 'version': version,
@@ -39,5 +42,7 @@ class Backup {
'spis': spis, 'spis': spis,
'snippets': snippets, 'snippets': snippets,
'keys': keys, 'keys': keys,
'dockerHosts': dockerHosts,
'settings': settings,
}; };
} }

View File

@@ -7,16 +7,16 @@ import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart'; import 'package:flutter_gen/gen_l10n/l10n.dart';
import 'package:toolbox/core/extension/context.dart'; import 'package:toolbox/core/extension/context.dart';
import 'package:toolbox/data/res/path.dart'; import 'package:toolbox/data/res/path.dart';
import 'package:toolbox/view/widget/round_rect_card.dart';
import '../../core/extension/colorx.dart';
import '../../core/utils/misc.dart'; import '../../core/utils/misc.dart';
import '../../core/utils/ui.dart'; import '../../core/utils/ui.dart';
import '../../data/model/app/backup.dart'; import '../../data/model/app/backup.dart';
import '../../data/res/color.dart';
import '../../data/res/ui.dart'; import '../../data/res/ui.dart';
import '../../data/store/docker.dart'; import '../../data/store/docker.dart';
import '../../data/store/private_key.dart'; import '../../data/store/private_key.dart';
import '../../data/store/server.dart'; import '../../data/store/server.dart';
import '../../data/store/setting.dart';
import '../../data/store/snippet.dart'; import '../../data/store/snippet.dart';
import '../../locator.dart'; import '../../locator.dart';
import '../widget/custom_appbar.dart'; import '../widget/custom_appbar.dart';
@@ -30,6 +30,7 @@ class BackupPage extends StatelessWidget {
final _snippet = locator<SnippetStore>(); final _snippet = locator<SnippetStore>();
final _privateKey = locator<PrivateKeyStore>(); final _privateKey = locator<PrivateKeyStore>();
final _dockerHosts = locator<DockerStore>(); final _dockerHosts = locator<DockerStore>();
final _setting = locator<SettingStore>();
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@@ -56,21 +57,13 @@ class BackupPage extends StatelessWidget {
textAlign: TextAlign.center, textAlign: TextAlign.center,
), ),
), ),
const SizedBox(height: 107), height77,
_buildCard(s.restore, Icons.download, media, () async { _buildCard(
final path = await pickOneFile(); s.restore,
if (path == null) { Icons.download,
showSnackBar(context, Text(s.notSelected)); media,
return; () => _onRestore(context, s),
} ),
final file = File(path);
if (!file.existsSync()) {
showSnackBar(context, Text(s.fileNotExist(path)));
return;
}
final text = await file.readAsString();
_import(text, context, s);
}),
height13, height13,
const SizedBox( const SizedBox(
width: 37, width: 37,
@@ -79,25 +72,9 @@ class BackupPage extends StatelessWidget {
height13, height13,
_buildCard( _buildCard(
s.backup, s.backup,
Icons.file_upload, Icons.save,
media, media,
() async { () => _onBackup(context, s),
final result = _diyEncrtpt(
json.encode(
Backup(
version: backupFormatVersion,
date: DateTime.now().toString().split('.').first,
spis: _server.fetch(),
snippets: _snippet.fetch(),
keys: _privateKey.fetch(),
dockerHosts: _dockerHosts.fetchAll(),
),
),
);
final path = '${(await docDir).path}/srvbox_bak.json';
await File(path).writeAsString(result);
await shareFiles(context, [path]);
},
) )
], ],
)); ));
@@ -109,24 +86,18 @@ class BackupPage extends StatelessWidget {
MediaQueryData media, MediaQueryData media,
FutureOr Function() onTap, FutureOr Function() onTap,
) { ) {
final textColor = primaryColor.isBrightColor ? Colors.black : Colors.white; return RoundRectCard(
return GestureDetector( InkWell(
onTap: onTap, onTap: onTap,
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(37), color: primaryColor),
child: Padding( child: Padding(
padding: const EdgeInsets.symmetric(vertical: 7, horizontal: 17), padding: const EdgeInsets.symmetric(vertical: 7, horizontal: 17),
child: Row( child: Row(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
children: [ children: [
Icon( Icon(icon, size: 20),
icon,
color: textColor,
),
width7, width7,
Text(text, style: TextStyle(color: textColor)), Text(text),
], ],
), ),
), ),
@@ -134,6 +105,40 @@ class BackupPage extends StatelessWidget {
); );
} }
Future<void> _onRestore(BuildContext context, S s) async {
final path = await pickOneFile();
if (path == null) {
showSnackBar(context, Text(s.notSelected));
return;
}
final file = File(path);
if (!file.existsSync()) {
showSnackBar(context, Text(s.fileNotExist(path)));
return;
}
final text = await file.readAsString();
_import(text, context, s);
}
Future<void> _onBackup(BuildContext context, S s) async {
final result = _diyEncrtpt(
json.encode(
Backup(
version: backupFormatVersion,
date: DateTime.now().toString().split('.').first,
spis: _server.fetch(),
snippets: _snippet.fetch(),
keys: _privateKey.fetch(),
dockerHosts: _dockerHosts.fetchAll(),
settings: _setting.toJson(),
),
),
);
final path = '${(await docDir).path}/srvbox_bak.json';
await File(path).writeAsString(result);
await shareFiles(context, [path]);
}
Future<void> _import(String text, BuildContext context, S s) async { Future<void> _import(String text, BuildContext context, S s) async {
if (text.isEmpty) { if (text.isEmpty) {
showSnackBar(context, Text(s.fieldMustNotEmpty)); showSnackBar(context, Text(s.fieldMustNotEmpty));

View File

@@ -241,20 +241,20 @@ class _HomePageState extends State<HomePage>
onTap: () => AppRoute.keyList().go(context), onTap: () => AppRoute.keyList().go(context),
), ),
ListTile( ListTile(
leading: const Icon(Icons.download), leading: const Icon(Icons.file_open),
title: Text(_s.download), title: Text(_s.files),
onTap: () => AppRoute.localStorage().go(context), onTap: () => AppRoute.localStorage().go(context),
), ),
ListTile(
leading: const Icon(Icons.import_export),
title: Text(_s.backup),
onTap: () => AppRoute.backup().go(context),
),
ListTile( ListTile(
leading: const Icon(Icons.code), leading: const Icon(Icons.code),
title: Text(_s.convert), title: Text(_s.convert),
onTap: () => AppRoute.convert().go(context), onTap: () => AppRoute.convert().go(context),
), ),
ListTile(
leading: const Icon(Icons.import_export),
title: Text(_s.backupAndRestore),
onTap: () => AppRoute.backup().go(context),
),
ListTile( ListTile(
leading: const Icon(Icons.text_snippet), leading: const Icon(Icons.text_snippet),
title: Text('${_s.about} & ${_s.feedback}'), title: Text('${_s.about} & ${_s.feedback}'),