opt.: backup & titlebar

This commit is contained in:
lollipopkit
2023-12-09 18:48:22 +08:00
parent b2eb96ec16
commit 73752bffc3
27 changed files with 191 additions and 266 deletions

4
.vscode/launch.json vendored
View File

@@ -5,7 +5,7 @@
"version": "0.2.0", "version": "0.2.0",
"configurations": [ "configurations": [
{ {
"name": "toolbox", "name": "debug",
"request": "launch", "request": "launch",
"type": "dart", "type": "dart",
// "args": [ // "args": [
@@ -13,7 +13,7 @@
// ] // ]
}, },
{ {
"name": "toolbox (profile mode)", "name": "profile",
"request": "launch", "request": "launch",
"type": "dart", "type": "dart",
"flutterMode": "profile", "flutterMode": "profile",

View File

@@ -72,7 +72,7 @@ EXTERNAL SOURCES:
SPEC CHECKSUMS: SPEC CHECKSUMS:
countly_flutter: d880b352f212d4f6453a87c85f0455f3b4b9c611 countly_flutter: d880b352f212d4f6453a87c85f0455f3b4b9c611
file_picker: 1d63c4949e05e386da864365f8c13e1e64787675 file_picker: 880e54928ebe4aa405aaf4577f29a76a078341c6
Flutter: f04841e97a9d0b0a8025694d0796dd46242b2854 Flutter: f04841e97a9d0b0a8025694d0796dd46242b2854
flutter_native_splash: 52501b97d1c0a5f898d687f1646226c1f93c56ef flutter_native_splash: 52501b97d1c0a5f898d687f1646226c1f93c56ef
icloud_storage: d9ac7a33ced81df08ba7ea1bf3099cc0ee58f60a icloud_storage: d9ac7a33ced81df08ba7ea1bf3099cc0ee58f60a

View File

@@ -6,8 +6,7 @@ import 'package:toolbox/data/model/app/backup.dart';
import 'package:toolbox/data/model/app/error.dart'; import 'package:toolbox/data/model/app/error.dart';
import 'package:toolbox/data/res/path.dart'; import 'package:toolbox/data/res/path.dart';
import 'package:toolbox/data/res/store.dart'; import 'package:toolbox/data/res/store.dart';
// ignore: implementation_imports import 'package:webdav_client/webdav_client.dart';
import 'package:webdav_client/src/client.dart';
abstract final class Webdav { abstract final class Webdav {
static var _client = WebdavClient( static var _client = WebdavClient(
@@ -73,6 +72,9 @@ abstract final class Webdav {
static void changeClient(String url, String user, String pwd) { static void changeClient(String url, String user, String pwd) {
_client = WebdavClient(url: url, user: user, pwd: pwd); _client = WebdavClient(url: url, user: user, pwd: pwd);
Stores.setting.webdavUrl.put(url);
Stores.setting.webdavUser.put(user);
Stores.setting.webdavPwd.put(pwd);
} }
static Future<void> sync() async { static Future<void> sync() async {

View File

@@ -315,7 +315,7 @@ class ServerProvider extends ChangeNotifier {
final completer = Completer(); final completer = Completer();
final homePath = (await s.client?.run('echo \$HOME').string)?.trim(); final homePath = (await s.client?.run('echo \$HOME').string)?.trim();
if (homePath == null || homePath.isEmpty) { if (homePath == null || homePath.isEmpty) {
throw Exception('Got home path: $homePath'); throw Exception('Got empty home path');
} }
final remotePath = ShellFunc.getShellPath(homePath); final remotePath = ShellFunc.getShellPath(homePath);
final reqId = Pros.sftp.add( final reqId = Pros.sftp.add(

View File

@@ -33,7 +33,7 @@ import 'data/provider/sftp.dart';
import 'data/provider/snippet.dart'; import 'data/provider/snippet.dart';
import 'data/res/color.dart'; import 'data/res/color.dart';
import 'locator.dart'; import 'locator.dart';
import 'view/widget/custom_appbar.dart'; import 'view/widget/appbar.dart';
Future<void> main() async { Future<void> main() async {
_runInZone(() async { _runInZone(() async {

View File

@@ -6,6 +6,7 @@ import 'package:toolbox/core/extension/context/common.dart';
import 'package:toolbox/core/extension/context/dialog.dart'; import 'package:toolbox/core/extension/context/dialog.dart';
import 'package:toolbox/core/extension/context/locale.dart'; import 'package:toolbox/core/extension/context/locale.dart';
import 'package:toolbox/core/extension/context/snackbar.dart'; import 'package:toolbox/core/extension/context/snackbar.dart';
import 'package:toolbox/core/utils/misc.dart';
import 'package:toolbox/core/utils/sync/icloud.dart'; import 'package:toolbox/core/utils/sync/icloud.dart';
import 'package:toolbox/core/utils/platform/base.dart'; import 'package:toolbox/core/utils/platform/base.dart';
import 'package:toolbox/core/utils/share.dart'; import 'package:toolbox/core/utils/share.dart';
@@ -14,16 +15,14 @@ import 'package:toolbox/data/model/app/backup.dart';
import 'package:toolbox/data/res/logger.dart'; import 'package:toolbox/data/res/logger.dart';
import 'package:toolbox/data/res/path.dart'; import 'package:toolbox/data/res/path.dart';
import 'package:toolbox/data/res/store.dart'; import 'package:toolbox/data/res/store.dart';
import 'package:toolbox/data/res/ui.dart';
import 'package:toolbox/view/widget/appbar.dart';
import 'package:toolbox/view/widget/expand_tile.dart'; import 'package:toolbox/view/widget/expand_tile.dart';
import 'package:toolbox/view/widget/cardx.dart'; import 'package:toolbox/view/widget/cardx.dart';
import 'package:toolbox/view/widget/input_field.dart'; import 'package:toolbox/view/widget/input_field.dart';
import 'package:toolbox/view/widget/store_switch.dart'; import 'package:toolbox/view/widget/store_switch.dart';
import 'package:toolbox/view/widget/value_notifier.dart'; import 'package:toolbox/view/widget/value_notifier.dart';
import '../../core/utils/misc.dart';
import '../../data/res/ui.dart';
import '../widget/custom_appbar.dart';
class BackupPage extends StatelessWidget { class BackupPage extends StatelessWidget {
BackupPage({super.key}); BackupPage({super.key});
@@ -86,57 +85,7 @@ class BackupPage extends StatelessWidget {
ListTile( ListTile(
trailing: const Icon(Icons.restore), trailing: const Icon(Icons.restore),
title: Text(l10n.restore), title: Text(l10n.restore),
onTap: () async { onTap: () async => _onTapFileRestore(context),
final path = await pickOneFile();
if (path == null) return;
final file = File(path);
if (!await file.exists()) {
context.showSnackBar(l10n.fileNotExist(path));
return;
}
final text = await file.readAsString();
if (text.isEmpty) {
context.showSnackBar(l10n.fieldMustNotEmpty);
return;
}
try {
context.showLoadingDialog();
final backup =
await compute(Backup.fromJsonString, text.trim());
if (backupFormatVersion != backup.version) {
context.showSnackBar(l10n.backupVersionNotMatch);
return;
}
await context.showRoundDialog(
title: Text(l10n.restore),
child: Text(l10n.askContinue(
'${l10n.restore} ${l10n.backup}(${backup.date})',
)),
actions: [
TextButton(
onPressed: () => context.pop(),
child: Text(l10n.cancel),
),
TextButton(
onPressed: () async {
await backup.restore(force: true);
context.pop();
},
child: Text(l10n.ok),
),
],
);
} catch (e, trace) {
Loggers.app.warning('Import backup failed', e, trace);
context.showSnackBar(e.toString());
} finally {
context.pop();
}
},
), ),
], ],
), ),
@@ -145,13 +94,8 @@ class BackupPage extends StatelessWidget {
Widget _buildIcloud(BuildContext context) { Widget _buildIcloud(BuildContext context) {
return CardX( return CardX(
ExpandTile(
leading: const Icon(Icons.cloud),
title: const Text('iCloud'),
initiallyExpanded: true,
children: [
ListTile( ListTile(
title: Text(l10n.auto), title: const Text('iCloud'),
trailing: StoreSwitch( trailing: StoreSwitch(
prop: Stores.setting.icloudSync, prop: Stores.setting.icloudSync,
validator: (p0) { validator: (p0) {
@@ -170,68 +114,6 @@ class BackupPage extends StatelessWidget {
}, },
), ),
), ),
ListTile(
title: Text(l10n.manual),
trailing: ValueBuilder(
listenable: icloudLoading,
build: () {
if (icloudLoading.value) {
return UIs.centerSizedLoadingSmall;
}
return Row(
mainAxisSize: MainAxisSize.min,
children: [
TextButton(
onPressed: () async {
icloudLoading.value = true;
try {
final result = await ICloud.download(
relativePath: Paths.bakName,
);
if (result != null) {
Loggers.app
.warning('Download backup failed: $result');
return;
}
} catch (e, s) {
Loggers.app.warning('Download backup failed', e, s);
context.showSnackBar(e.toString());
icloudLoading.value = false;
return;
}
final dlFile =
await File(await Paths.bak).readAsString();
final dlBak =
await compute(Backup.fromJsonString, dlFile);
await dlBak.restore(force: true);
icloudLoading.value = false;
},
child: Text(l10n.download),
),
UIs.width7,
TextButton(
onPressed: () async {
icloudLoading.value = true;
await Backup.backup();
final uploadResult =
await ICloud.upload(relativePath: Paths.bakName);
if (uploadResult != null) {
Loggers.app.warning(
'Upload iCloud backup failed: $uploadResult');
} else {
Loggers.app.info('Upload iCloud backup success');
}
icloudLoading.value = false;
},
child: Text(l10n.upload),
),
],
);
},
),
),
],
),
); );
} }
@@ -245,67 +127,7 @@ class BackupPage extends StatelessWidget {
ListTile( ListTile(
title: Text(l10n.setting), title: Text(l10n.setting),
trailing: const Icon(Icons.settings), trailing: const Icon(Icons.settings),
onTap: () async { onTap: () async => _onTapWebdavSetting(context),
final urlCtrl = TextEditingController(
text: Stores.setting.webdavUrl.fetch(),
);
final userCtrl = TextEditingController(
text: Stores.setting.webdavUser.fetch(),
);
final pwdCtrl = TextEditingController(
text: Stores.setting.webdavPwd.fetch(),
);
final result = await context.showRoundDialog<bool>(
title: const Text('WebDAV'),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Input(
label: 'URL',
hint: 'https://example.com/webdav/',
controller: urlCtrl,
),
Input(
label: l10n.user,
controller: userCtrl,
),
Input(
label: l10n.pwd,
controller: pwdCtrl,
),
],
),
actions: [
TextButton(
onPressed: () {
context.pop(true);
},
child: Text(l10n.ok),
),
],
);
if (result == true) {
final result = await Webdav.test(
urlCtrl.text,
userCtrl.text,
pwdCtrl.text,
);
if (result == null) {
context.showSnackBar(l10n.success);
} else {
context.showSnackBar(result);
return;
}
Webdav.changeClient(
urlCtrl.text,
userCtrl.text,
pwdCtrl.text,
);
Stores.setting.webdavUrl.put(urlCtrl.text);
Stores.setting.webdavUser.put(userCtrl.text);
Stores.setting.webdavPwd.put(pwdCtrl.text);
}
},
), ),
ListTile( ListTile(
title: Text(l10n.auto), title: Text(l10n.auto),
@@ -347,48 +169,12 @@ class BackupPage extends StatelessWidget {
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: [ children: [
TextButton( TextButton(
onPressed: () async { onPressed: () async => _onTapWebdavDl(context),
webdavLoading.value = true;
try {
final result = await Webdav.download(
relativePath: Paths.bakName,
);
if (result != null) {
Loggers.app.warning(
'Download webdav backup failed: $result');
return;
}
} catch (e, s) {
Loggers.app
.warning('Download webdav backup failed', e, s);
context.showSnackBar(e.toString());
webdavLoading.value = false;
return;
}
final dlFile =
await File(await Paths.bak).readAsString();
final dlBak =
await compute(Backup.fromJsonString, dlFile);
await dlBak.restore(force: true);
webdavLoading.value = false;
},
child: Text(l10n.download), child: Text(l10n.download),
), ),
UIs.width7, UIs.width7,
TextButton( TextButton(
onPressed: () async { onPressed: () async => _onTapWebdavUp(context),
webdavLoading.value = true;
await Backup.backup();
final uploadResult =
await Webdav.upload(relativePath: Paths.bakName);
if (uploadResult != null) {
Loggers.app.warning(
'Upload webdav backup failed: $uploadResult');
} else {
Loggers.app.info('Upload webdav backup success');
}
webdavLoading.value = false;
},
child: Text(l10n.upload), child: Text(l10n.upload),
), ),
], ],
@@ -400,4 +186,141 @@ class BackupPage extends StatelessWidget {
), ),
); );
} }
Future<void> _onTapFileRestore(BuildContext context) async {
final path = await pickOneFile();
if (path == null) return;
final file = File(path);
if (!await file.exists()) {
context.showSnackBar(l10n.fileNotExist(path));
return;
}
final text = await file.readAsString();
if (text.isEmpty) {
context.showSnackBar(l10n.fieldMustNotEmpty);
return;
}
try {
context.showLoadingDialog();
final backup = await compute(Backup.fromJsonString, text.trim());
if (backupFormatVersion != backup.version) {
context.showSnackBar(l10n.backupVersionNotMatch);
return;
}
await context.showRoundDialog(
title: Text(l10n.restore),
child: Text(l10n.askContinue(
'${l10n.restore} ${l10n.backup}(${backup.date})',
)),
actions: [
TextButton(
onPressed: () => context.pop(),
child: Text(l10n.cancel),
),
TextButton(
onPressed: () async {
await backup.restore(force: true);
context.pop();
},
child: Text(l10n.ok),
),
],
);
} catch (e, trace) {
Loggers.app.warning('Import backup failed', e, trace);
context.showSnackBar(e.toString());
} finally {
context.pop();
}
}
Future<void> _onTapWebdavDl(BuildContext context) async {
webdavLoading.value = true;
try {
final result = await Webdav.download(
relativePath: Paths.bakName,
);
if (result != null) {
Loggers.app.warning('Download webdav backup failed: $result');
return;
}
} catch (e, s) {
Loggers.app.warning('Download webdav backup failed', e, s);
context.showSnackBar(e.toString());
webdavLoading.value = false;
return;
}
final dlFile = await File(await Paths.bak).readAsString();
final dlBak = await compute(Backup.fromJsonString, dlFile);
await dlBak.restore(force: true);
webdavLoading.value = false;
}
Future<void> _onTapWebdavUp(BuildContext context) async {
webdavLoading.value = true;
await Backup.backup();
final uploadResult = await Webdav.upload(relativePath: Paths.bakName);
if (uploadResult != null) {
Loggers.app.warning('Upload webdav backup failed: $uploadResult');
} else {
Loggers.app.info('Upload webdav backup success');
}
webdavLoading.value = false;
}
Future<void> _onTapWebdavSetting(BuildContext context) async {
final urlCtrl = TextEditingController(
text: Stores.setting.webdavUrl.fetch(),
);
final userCtrl = TextEditingController(
text: Stores.setting.webdavUser.fetch(),
);
final pwdCtrl = TextEditingController(
text: Stores.setting.webdavPwd.fetch(),
);
final result = await context.showRoundDialog<bool>(
title: const Text('WebDAV'),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Input(
label: 'URL',
hint: 'https://example.com/webdav/',
controller: urlCtrl,
),
Input(
label: l10n.user,
controller: userCtrl,
),
Input(
label: l10n.pwd,
controller: pwdCtrl,
),
],
),
actions: [
TextButton(
onPressed: () {
context.pop(true);
},
child: Text(l10n.ok),
),
],
);
if (result == true) {
final result =
await Webdav.test(urlCtrl.text, userCtrl.text, pwdCtrl.text);
if (result == null) {
context.showSnackBar(l10n.success);
} else {
context.showSnackBar(result);
return;
}
Webdav.changeClient(urlCtrl.text, userCtrl.text, pwdCtrl.text);
}
}
} }

View File

@@ -3,7 +3,7 @@ import 'package:provider/provider.dart';
import 'package:toolbox/core/extension/context/common.dart'; import 'package:toolbox/core/extension/context/common.dart';
import 'package:toolbox/data/provider/debug.dart'; import 'package:toolbox/data/provider/debug.dart';
import '../widget/custom_appbar.dart'; import '../widget/appbar.dart';
class DebugPage extends StatefulWidget { class DebugPage extends StatefulWidget {
const DebugPage({super.key}); const DebugPage({super.key});

View File

@@ -18,7 +18,7 @@ import '../../data/model/app/error.dart';
import '../../data/model/app/menu.dart'; import '../../data/model/app/menu.dart';
import '../../data/res/ui.dart'; import '../../data/res/ui.dart';
import '../../data/res/url.dart'; import '../../data/res/url.dart';
import '../widget/custom_appbar.dart'; import '../widget/appbar.dart';
import '../widget/popup_menu.dart'; import '../widget/popup_menu.dart';
import '../widget/cardx.dart'; import '../widget/cardx.dart';
import '../widget/two_line_text.dart'; import '../widget/two_line_text.dart';

View File

@@ -14,7 +14,7 @@ import 'package:toolbox/core/utils/misc.dart';
import 'package:toolbox/data/res/highlight.dart'; import 'package:toolbox/data/res/highlight.dart';
import 'package:toolbox/data/res/store.dart'; import 'package:toolbox/data/res/store.dart';
import '../widget/custom_appbar.dart'; import '../widget/appbar.dart';
import '../widget/two_line_text.dart'; import '../widget/two_line_text.dart';
class EditorPage extends StatefulWidget { class EditorPage extends StatefulWidget {

View File

@@ -26,7 +26,7 @@ import '../../data/res/build_data.dart';
import '../../data/res/misc.dart'; import '../../data/res/misc.dart';
import '../../data/res/ui.dart'; import '../../data/res/ui.dart';
import '../../data/res/url.dart'; import '../../data/res/url.dart';
import '../widget/custom_appbar.dart'; import '../widget/appbar.dart';
import '../widget/cardx.dart'; import '../widget/cardx.dart';
import '../widget/url_text.dart'; import '../widget/url_text.dart';
import '../widget/value_notifier.dart'; import '../widget/value_notifier.dart';

View File

@@ -16,7 +16,7 @@ import 'package:toolbox/view/widget/input_field.dart';
import '../../../core/utils/server.dart'; import '../../../core/utils/server.dart';
import '../../../data/model/server/private_key_info.dart'; import '../../../data/model/server/private_key_info.dart';
import '../../../data/res/ui.dart'; import '../../../data/res/ui.dart';
import '../../widget/custom_appbar.dart'; import '../../widget/appbar.dart';
const _format = 'text/plain'; const _format = 'text/plain';

View File

@@ -14,7 +14,7 @@ import '../../../core/route.dart';
import '../../../data/model/server/private_key_info.dart'; import '../../../data/model/server/private_key_info.dart';
import '../../../data/provider/private_key.dart'; import '../../../data/provider/private_key.dart';
import '../../../data/res/ui.dart'; import '../../../data/res/ui.dart';
import '../../widget/custom_appbar.dart'; import '../../widget/appbar.dart';
import '../../widget/cardx.dart'; import '../../widget/cardx.dart';
class PrivateKeysListPage extends StatefulWidget { class PrivateKeysListPage extends StatefulWidget {

View File

@@ -14,7 +14,7 @@ import '../../data/model/app/shell_func.dart';
import '../../data/model/server/proc.dart'; import '../../data/model/server/proc.dart';
import '../../data/model/server/server_private_info.dart'; import '../../data/model/server/server_private_info.dart';
import '../../data/res/ui.dart'; import '../../data/res/ui.dart';
import '../widget/custom_appbar.dart'; import '../widget/appbar.dart';
import '../widget/cardx.dart'; import '../widget/cardx.dart';
import '../widget/two_line_text.dart'; import '../widget/two_line_text.dart';

View File

@@ -21,7 +21,7 @@ import '../../../data/provider/server.dart';
import '../../../data/res/color.dart'; import '../../../data/res/color.dart';
import '../../../data/res/default.dart'; import '../../../data/res/default.dart';
import '../../../data/res/ui.dart'; import '../../../data/res/ui.dart';
import '../../widget/custom_appbar.dart'; import '../../widget/appbar.dart';
import '../../widget/cardx.dart'; import '../../widget/cardx.dart';
class ServerDetailPage extends StatefulWidget { class ServerDetailPage extends StatefulWidget {

View File

@@ -13,7 +13,7 @@ import '../../../data/model/server/private_key_info.dart';
import '../../../data/model/server/server_private_info.dart'; import '../../../data/model/server/server_private_info.dart';
import '../../../data/provider/private_key.dart'; import '../../../data/provider/private_key.dart';
import '../../../data/res/ui.dart'; import '../../../data/res/ui.dart';
import '../../widget/custom_appbar.dart'; import '../../widget/appbar.dart';
import '../../widget/input_field.dart'; import '../../widget/input_field.dart';
import '../../widget/cardx.dart'; import '../../widget/cardx.dart';
import '../../widget/tag.dart'; import '../../widget/tag.dart';

View File

@@ -9,7 +9,7 @@ import 'package:toolbox/core/extension/context/snackbar.dart';
import 'package:toolbox/core/utils/platform/auth.dart'; import 'package:toolbox/core/utils/platform/auth.dart';
import 'package:toolbox/data/res/store.dart'; import 'package:toolbox/data/res/store.dart';
import 'package:toolbox/view/page/setting/platform_pub.dart'; import 'package:toolbox/view/page/setting/platform_pub.dart';
import 'package:toolbox/view/widget/custom_appbar.dart'; import 'package:toolbox/view/widget/appbar.dart';
import 'package:toolbox/view/widget/input_field.dart'; import 'package:toolbox/view/widget/input_field.dart';
import 'package:toolbox/view/widget/cardx.dart'; import 'package:toolbox/view/widget/cardx.dart';
import 'package:toolbox/view/widget/store_switch.dart'; import 'package:toolbox/view/widget/store_switch.dart';

View File

@@ -29,7 +29,7 @@ import '../../../data/res/color.dart';
import '../../../data/res/path.dart'; import '../../../data/res/path.dart';
import '../../../data/res/ui.dart'; import '../../../data/res/ui.dart';
import '../../widget/color_picker.dart'; import '../../widget/color_picker.dart';
import '../../widget/custom_appbar.dart'; import '../../widget/appbar.dart';
import '../../widget/input_field.dart'; import '../../widget/input_field.dart';
import '../../widget/cardx.dart'; import '../../widget/cardx.dart';
import '../../widget/store_switch.dart'; import '../../widget/store_switch.dart';

View File

@@ -13,7 +13,7 @@ import 'package:toolbox/data/res/misc.dart';
import 'package:toolbox/data/res/store.dart'; import 'package:toolbox/data/res/store.dart';
import 'package:toolbox/data/res/ui.dart'; import 'package:toolbox/data/res/ui.dart';
import 'package:toolbox/view/page/setting/platform_pub.dart'; import 'package:toolbox/view/page/setting/platform_pub.dart';
import 'package:toolbox/view/widget/custom_appbar.dart'; import 'package:toolbox/view/widget/appbar.dart';
import 'package:toolbox/view/widget/future_widget.dart'; import 'package:toolbox/view/widget/future_widget.dart';
import 'package:toolbox/view/widget/cardx.dart'; import 'package:toolbox/view/widget/cardx.dart';
import 'package:toolbox/view/widget/store_switch.dart'; import 'package:toolbox/view/widget/store_switch.dart';

View File

@@ -3,7 +3,7 @@ import 'package:toolbox/core/extension/context/locale.dart';
import 'package:toolbox/data/res/store.dart'; import 'package:toolbox/data/res/store.dart';
import '../../../core/extension/order.dart'; import '../../../core/extension/order.dart';
import '../../widget/custom_appbar.dart'; import '../../widget/appbar.dart';
import '../../widget/cardx.dart'; import '../../widget/cardx.dart';
class ServerDetailOrderPage extends StatefulWidget { class ServerDetailOrderPage extends StatefulWidget {

View File

@@ -6,7 +6,7 @@ import 'package:toolbox/data/res/store.dart';
import 'package:toolbox/data/res/ui.dart'; import 'package:toolbox/data/res/ui.dart';
import 'package:toolbox/view/widget/cardx.dart'; import 'package:toolbox/view/widget/cardx.dart';
import '../../widget/custom_appbar.dart'; import '../../widget/appbar.dart';
class ServerOrderPage extends StatefulWidget { class ServerOrderPage extends StatefulWidget {
const ServerOrderPage({super.key}); const ServerOrderPage({super.key});

View File

@@ -8,7 +8,7 @@ import 'package:toolbox/data/res/store.dart';
import 'package:toolbox/data/res/ui.dart'; import 'package:toolbox/data/res/ui.dart';
import 'package:toolbox/view/widget/cardx.dart'; import 'package:toolbox/view/widget/cardx.dart';
import '../../widget/custom_appbar.dart'; import '../../widget/appbar.dart';
class SSHVirtKeySettingPage extends StatefulWidget { class SSHVirtKeySettingPage extends StatefulWidget {
const SSHVirtKeySettingPage({super.key}); const SSHVirtKeySettingPage({super.key});

View File

@@ -9,7 +9,7 @@ import 'package:toolbox/view/widget/input_field.dart';
import '../../../data/model/server/snippet.dart'; import '../../../data/model/server/snippet.dart';
import '../../../data/res/ui.dart'; import '../../../data/res/ui.dart';
import '../../widget/custom_appbar.dart'; import '../../widget/appbar.dart';
import '../../widget/tag.dart'; import '../../widget/tag.dart';
class SnippetEditPage extends StatefulWidget { class SnippetEditPage extends StatefulWidget {

View File

@@ -3,7 +3,7 @@ import 'package:toolbox/core/extension/context/locale.dart';
import 'package:toolbox/data/model/server/snippet.dart'; import 'package:toolbox/data/model/server/snippet.dart';
import 'package:toolbox/data/res/ui.dart'; import 'package:toolbox/data/res/ui.dart';
import 'package:toolbox/view/widget/cardx.dart'; import 'package:toolbox/view/widget/cardx.dart';
import 'package:toolbox/view/widget/custom_appbar.dart'; import 'package:toolbox/view/widget/appbar.dart';
import 'package:toolbox/view/widget/expand_tile.dart'; import 'package:toolbox/view/widget/expand_tile.dart';
class SnippetResultPage extends StatelessWidget { class SnippetResultPage extends StatelessWidget {

View File

@@ -20,7 +20,7 @@ import '../../../core/utils/misc.dart';
import '../../../data/model/app/path_with_prefix.dart'; import '../../../data/model/app/path_with_prefix.dart';
import '../../../data/res/path.dart'; import '../../../data/res/path.dart';
import '../../../data/res/ui.dart'; import '../../../data/res/ui.dart';
import '../../widget/custom_appbar.dart'; import '../../widget/appbar.dart';
import '../../widget/fade_in.dart'; import '../../widget/fade_in.dart';
class LocalStoragePage extends StatefulWidget { class LocalStoragePage extends StatefulWidget {

View File

@@ -25,7 +25,7 @@ import '../../../data/model/sftp/browser_status.dart';
import '../../../data/model/sftp/req.dart'; import '../../../data/model/sftp/req.dart';
import '../../../data/res/path.dart'; import '../../../data/res/path.dart';
import '../../../data/res/ui.dart'; import '../../../data/res/ui.dart';
import '../../widget/custom_appbar.dart'; import '../../widget/appbar.dart';
import '../../widget/fade_in.dart'; import '../../widget/fade_in.dart';
import '../../widget/input_field.dart'; import '../../widget/input_field.dart';
import '../../widget/two_line_text.dart'; import '../../widget/two_line_text.dart';

View File

@@ -12,7 +12,7 @@ import '../../../core/extension/numx.dart';
import '../../../data/model/sftp/req.dart'; import '../../../data/model/sftp/req.dart';
import '../../../data/provider/sftp.dart'; import '../../../data/provider/sftp.dart';
import '../../../data/res/ui.dart'; import '../../../data/res/ui.dart';
import '../../widget/custom_appbar.dart'; import '../../widget/appbar.dart';
import '../../widget/cardx.dart'; import '../../widget/cardx.dart';
class SftpMissionPage extends StatefulWidget { class SftpMissionPage extends StatefulWidget {