optimization: desktop UI (#747)
This commit is contained in:
@@ -13,13 +13,22 @@ import 'package:server_box/data/model/server/private_key_info.dart';
|
||||
|
||||
const _format = 'text/plain';
|
||||
|
||||
class PrivateKeyEditPage extends StatefulWidget {
|
||||
const PrivateKeyEditPage({super.key, this.pki});
|
||||
|
||||
final class PrivateKeyEditPageArgs {
|
||||
final PrivateKeyInfo? pki;
|
||||
const PrivateKeyEditPageArgs({this.pki});
|
||||
}
|
||||
|
||||
class PrivateKeyEditPage extends StatefulWidget {
|
||||
final PrivateKeyEditPageArgs? args;
|
||||
const PrivateKeyEditPage({super.key, this.args});
|
||||
|
||||
@override
|
||||
State<PrivateKeyEditPage> createState() => _PrivateKeyEditPageState();
|
||||
|
||||
static const route = AppRoute(
|
||||
page: PrivateKeyEditPage.new,
|
||||
path: '/private_key/edit',
|
||||
);
|
||||
}
|
||||
|
||||
class _PrivateKeyEditPageState extends State<PrivateKeyEditPage> {
|
||||
@@ -34,6 +43,8 @@ class _PrivateKeyEditPageState extends State<PrivateKeyEditPage> {
|
||||
|
||||
final _loading = ValueNotifier<Widget?>(null);
|
||||
|
||||
PrivateKeyInfo? get pki => widget.args?.pki;
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
super.dispose();
|
||||
@@ -49,9 +60,10 @@ class _PrivateKeyEditPageState extends State<PrivateKeyEditPage> {
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
if (widget.pki != null) {
|
||||
_nameController.text = widget.pki!.id;
|
||||
_keyController.text = widget.pki!.key;
|
||||
final pki = this.pki;
|
||||
if (pki != null) {
|
||||
_nameController.text = pki.id;
|
||||
_keyController.text = pki.key;
|
||||
} else {
|
||||
Clipboard.getData(_format).then((value) {
|
||||
if (value == null) return;
|
||||
@@ -79,31 +91,34 @@ class _PrivateKeyEditPageState extends State<PrivateKeyEditPage> {
|
||||
}
|
||||
|
||||
CustomAppBar _buildAppBar() {
|
||||
final actions = [
|
||||
IconButton(
|
||||
tooltip: libL10n.delete,
|
||||
onPressed: () {
|
||||
context.showRoundDialog(
|
||||
title: libL10n.attention,
|
||||
child: Text(libL10n.askContinue(
|
||||
'${libL10n.delete} ${l10n.privateKey}(${widget.pki!.id})',
|
||||
)),
|
||||
actions: Btn.ok(
|
||||
onTap: () {
|
||||
PrivateKeyProvider.delete(widget.pki!);
|
||||
context.pop();
|
||||
context.pop();
|
||||
final pki = this.pki;
|
||||
final actions = pki != null
|
||||
? [
|
||||
IconButton(
|
||||
tooltip: libL10n.delete,
|
||||
onPressed: () {
|
||||
context.showRoundDialog(
|
||||
title: libL10n.attention,
|
||||
child: Text(libL10n.askContinue(
|
||||
'${libL10n.delete} ${l10n.privateKey}(${pki.id})',
|
||||
)),
|
||||
actions: Btn.ok(
|
||||
onTap: () {
|
||||
PrivateKeyProvider.delete(pki);
|
||||
context.pop();
|
||||
context.pop();
|
||||
},
|
||||
red: true,
|
||||
).toList,
|
||||
);
|
||||
},
|
||||
red: true,
|
||||
).toList,
|
||||
);
|
||||
},
|
||||
icon: const Icon(Icons.delete),
|
||||
)
|
||||
];
|
||||
icon: const Icon(Icons.delete),
|
||||
)
|
||||
]
|
||||
: null;
|
||||
return CustomAppBar(
|
||||
title: Text(libL10n.edit),
|
||||
actions: widget.pki == null ? null : actions,
|
||||
actions: actions,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -120,8 +135,7 @@ class _PrivateKeyEditPageState extends State<PrivateKeyEditPage> {
|
||||
}
|
||||
|
||||
Widget _buildBody() {
|
||||
return ListView(
|
||||
padding: const EdgeInsets.all(13),
|
||||
return AutoMultiList(
|
||||
children: [
|
||||
Input(
|
||||
autoFocus: true,
|
||||
@@ -204,7 +218,7 @@ class _PrivateKeyEditPageState extends State<PrivateKeyEditPage> {
|
||||
try {
|
||||
final decrypted = await Computer.shared.start(decyptPem, [key, pwd]);
|
||||
final pki = PrivateKeyInfo(id: name, key: decrypted);
|
||||
final originPki = widget.pki;
|
||||
final originPki = this.pki;
|
||||
if (originPki != null) {
|
||||
PrivateKeyProvider.update(originPki, pki);
|
||||
} else {
|
||||
|
||||
@@ -6,26 +6,30 @@ import 'package:flutter/material.dart';
|
||||
import 'package:server_box/core/extension/context/locale.dart';
|
||||
import 'package:server_box/data/res/store.dart';
|
||||
|
||||
import 'package:server_box/core/route.dart';
|
||||
import 'package:server_box/data/model/server/private_key_info.dart';
|
||||
import 'package:server_box/data/provider/private_key.dart';
|
||||
import 'package:server_box/view/page/private_key/edit.dart';
|
||||
|
||||
class PrivateKeysListPage extends StatefulWidget {
|
||||
const PrivateKeysListPage({super.key});
|
||||
|
||||
@override
|
||||
State<PrivateKeysListPage> createState() => _PrivateKeyListState();
|
||||
|
||||
static const route = AppRouteNoArg(
|
||||
page: PrivateKeysListPage.new,
|
||||
path: '/private_key',
|
||||
);
|
||||
}
|
||||
|
||||
class _PrivateKeyListState extends State<PrivateKeysListPage>
|
||||
with AfterLayoutMixin {
|
||||
class _PrivateKeyListState extends State<PrivateKeysListPage> with AfterLayoutMixin {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
body: _buildBody(),
|
||||
floatingActionButton: FloatingActionButton(
|
||||
child: const Icon(Icons.add),
|
||||
onPressed: () => AppRoutes.keyEdit().go(context),
|
||||
onPressed: () => PrivateKeyEditPage.route.go(context),
|
||||
),
|
||||
);
|
||||
}
|
||||
@@ -36,33 +40,33 @@ class _PrivateKeyListState extends State<PrivateKeysListPage>
|
||||
if (pkis.isEmpty) {
|
||||
return Center(child: Text(libL10n.empty));
|
||||
}
|
||||
return ListView.builder(
|
||||
padding: const EdgeInsets.all(13),
|
||||
itemCount: pkis.length,
|
||||
itemBuilder: (context, idx) {
|
||||
final item = pkis[idx];
|
||||
return CardX(
|
||||
child: ListTile(
|
||||
leading: Text(
|
||||
'#$idx',
|
||||
style: const TextStyle(
|
||||
fontSize: 15,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
title: Text(item.id),
|
||||
subtitle: Text(item.type ?? l10n.unknown, style: UIs.textGrey),
|
||||
onTap: () => AppRoutes.keyEdit(pki: item).go(context),
|
||||
trailing: const Icon(Icons.edit),
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
final children = pkis.map(_buildKeyItem).toList();
|
||||
return AutoMultiList(children: children);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
void autoAddSystemPriavteKey() {
|
||||
Widget _buildKeyItem(PrivateKeyInfo item) {
|
||||
return ListTile(
|
||||
title: Text(item.id),
|
||||
subtitle: Text(item.type ?? l10n.unknown, style: UIs.textGrey),
|
||||
onTap: () => PrivateKeyEditPage.route.go(
|
||||
context,
|
||||
args: PrivateKeyEditPageArgs(pki: item),
|
||||
),
|
||||
trailing: const Icon(Icons.edit),
|
||||
).cardx;
|
||||
}
|
||||
|
||||
@override
|
||||
FutureOr<void> afterFirstLayout(BuildContext context) {
|
||||
_autoAddSystemPriavteKey();
|
||||
}
|
||||
}
|
||||
|
||||
extension on _PrivateKeyListState {
|
||||
void _autoAddSystemPriavteKey() async {
|
||||
// Only trigger on desktop platform and no private key saved
|
||||
if (isDesktop && Stores.snippet.box.keys.isEmpty) {
|
||||
final home = Pfs.homeDir;
|
||||
@@ -71,21 +75,19 @@ class _PrivateKeyListState extends State<PrivateKeysListPage>
|
||||
if (!idRsaFile.existsSync()) return;
|
||||
final sysPk = PrivateKeyInfo(
|
||||
id: 'system',
|
||||
key: idRsaFile.readAsStringSync(),
|
||||
key: await idRsaFile.readAsString(),
|
||||
);
|
||||
context.showRoundDialog(
|
||||
title: libL10n.attention,
|
||||
child: Text(l10n.addSystemPrivateKeyTip),
|
||||
actions: Btn.ok(onTap: () {
|
||||
context.pop();
|
||||
AppRoutes.keyEdit(pki: sysPk).go(context);
|
||||
PrivateKeyEditPage.route.go(
|
||||
context,
|
||||
args: PrivateKeyEditPageArgs(pki: sysPk),
|
||||
);
|
||||
}).toList,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
FutureOr<void> afterFirstLayout(BuildContext context) {
|
||||
autoAddSystemPriavteKey();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user