#29 opt. for TextInput

This commit is contained in:
lollipopkit
2023-05-07 18:25:30 +08:00
parent 29ea43a10f
commit ffae93cc72
20 changed files with 414 additions and 411 deletions

View File

@@ -3,6 +3,7 @@ import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart';
import 'package:provider/provider.dart';
import 'package:toolbox/core/utils/navigator.dart';
import 'package:toolbox/view/widget/input_field.dart';
import '../../../core/route.dart';
import '../../../core/utils/ui.dart';
@@ -10,11 +11,9 @@ import '../../../data/model/server/private_key_info.dart';
import '../../../data/model/server/server_private_info.dart';
import '../../../data/provider/private_key.dart';
import '../../../data/provider/server.dart';
import '../../../data/res/color.dart';
import '../../../data/res/ui.dart';
import '../../../data/store/private_key.dart';
import '../../../locator.dart';
import '../../widget/input_decoration.dart';
import '../private_key/edit.dart';
class ServerEditPage extends StatefulWidget {
@@ -61,224 +60,220 @@ class _ServerEditPageState extends State<ServerEditPage> with AfterLayoutMixin {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(_s.edit, style: textSize18),
actions: [
widget.spi != null
? IconButton(
onPressed: () {
showRoundDialog(
context: context,
child: Text(_s.sureToDeleteServer(widget.spi!.name)),
actions: [
TextButton(
onPressed: () {
_serverProvider.delServer(widget.spi!.id);
context.pop();
context.pop();
},
child: Text(
_s.ok,
style: const TextStyle(color: Colors.red),
),
),
TextButton(
onPressed: () => context.pop(),
child: Text(_s.cancel),
)
],
);
},
icon: const Icon(Icons.delete),
appBar: _buildAppBar(),
body: _buildForm(),
floatingActionButton: _buildFAB(),
);
}
PreferredSizeWidget _buildAppBar() {
final delBtn = IconButton(
onPressed: () {
showRoundDialog(
context: context,
child: Text(_s.sureToDeleteServer(widget.spi!.name)),
actions: [
TextButton(
onPressed: () {
_serverProvider.delServer(widget.spi!.id);
context.pop();
context.pop();
},
child: Text(
_s.ok,
style: const TextStyle(color: Colors.red),
),
),
TextButton(
onPressed: () => context.pop(),
child: Text(_s.cancel),
)
],
);
},
icon: const Icon(Icons.delete),
);
return AppBar(
title: Text(_s.edit, style: textSize18),
actions: [
widget.spi != null ? delBtn : const SizedBox(),
],
);
}
Widget _buildForm() {
return SingleChildScrollView(
padding: const EdgeInsets.all(17),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
buildInput(
controller: _nameController,
type: TextInputType.text,
node: _nameFocus,
onSubmitted: (_) => _focusScope.requestFocus(_ipFocus),
hint: _s.exampleName,
label: _s.name,
icon: Icons.info,
),
buildInput(
controller: _ipController,
type: TextInputType.text,
onSubmitted: (_) => _focusScope.requestFocus(_portFocus),
node: _ipFocus,
autoCorrect: false,
label: _s.host,
icon: Icons.storage,
hint: 'example.com',
),
buildInput(
controller: _portController,
type: TextInputType.number,
node: _portFocus,
onSubmitted: (_) => _focusScope.requestFocus(_usernameFocus),
label: _s.port,
icon: Icons.format_list_numbered,
hint: '22',
),
buildInput(
controller: _usernameController,
type: TextInputType.text,
node: _usernameFocus,
autoCorrect: false,
label: _s.user,
icon: Icons.account_box,
hint: 'root',
),
width7,
Row(
children: [
width13,
Text(_s.keyAuth),
width13,
Switch(
value: usePublicKey,
onChanged: (val) => setState(() => usePublicKey = val),
),
],
),
!usePublicKey
? buildInput(
controller: _passwordController,
obscureText: true,
type: TextInputType.text,
label: _s.pwd,
icon: Icons.password,
hint: _s.pwd,
onSubmitted: (_) => {},
)
: const SizedBox()
: const SizedBox(),
usePublicKey ? _buildKeyAuth() : const SizedBox()
],
),
body: SingleChildScrollView(
padding: const EdgeInsets.all(17),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
TextField(
controller: _nameController,
keyboardType: TextInputType.text,
focusNode: _nameFocus,
onSubmitted: (_) => _focusScope.requestFocus(_ipFocus),
decoration: buildDecoration(
_s.name,
icon: Icons.info,
hint: _s.exampleName,
),
),
TextField(
controller: _ipController,
keyboardType: TextInputType.text,
onSubmitted: (_) => _focusScope.requestFocus(_portFocus),
focusNode: _ipFocus,
autocorrect: false,
enableSuggestions: false,
decoration: buildDecoration(
_s.host,
icon: Icons.storage,
hint: 'example.com',
),
),
TextField(
controller: _portController,
keyboardType: TextInputType.number,
focusNode: _portFocus,
onSubmitted: (_) => _focusScope.requestFocus(_usernameFocus),
decoration: buildDecoration(
_s.port,
icon: Icons.format_list_numbered,
hint: '22',
),
),
TextField(
controller: _usernameController,
keyboardType: TextInputType.text,
focusNode: _usernameFocus,
autocorrect: false,
enableSuggestions: false,
decoration: buildDecoration(
_s.user,
icon: Icons.account_box,
hint: 'root',
),
),
width7,
Row(
children: [
Text(_s.keyAuth),
width13,
Switch(
value: usePublicKey,
onChanged: (val) => setState(() => usePublicKey = val),
),
],
),
!usePublicKey
? TextField(
controller: _passwordController,
obscureText: true,
keyboardType: TextInputType.text,
decoration: buildDecoration(
_s.pwd,
icon: Icons.password,
hint: _s.pwd,
),
onSubmitted: (_) => {},
)
: const SizedBox(),
usePublicKey
? Consumer<PrivateKeyProvider>(
builder: (_, key, __) {
for (var item in key.infos) {
if (item.id == widget.spi?.pubKeyId) {
_pubKeyIndex ??= key.infos.indexOf(item);
}
}
final tiles = key.infos
.map(
(e) => ListTile(
contentPadding: EdgeInsets.zero,
title: Text(e.id, textAlign: TextAlign.start),
trailing: _buildRadio(key.infos.indexOf(e), e),
),
)
.toList();
tiles.add(
ListTile(
title: Text(_s.addPrivateKey),
contentPadding: EdgeInsets.zero,
trailing: IconButton(
icon: const Icon(Icons.add),
onPressed: () => AppRoute(
const PrivateKeyEditPage(),
'private key edit page',
).go(context),
),
),
);
return ExpansionTile(
textColor: primaryColor,
iconColor: primaryColor,
tilePadding: EdgeInsets.zero,
childrenPadding: EdgeInsets.zero,
initiallyExpanded: true,
title: Text(
_s.choosePrivateKey,
style: const TextStyle(fontSize: 14),
),
children: tiles,
);
},
)
: const SizedBox()
],
),
),
floatingActionButton: FloatingActionButton(
child: const Icon(Icons.send),
onPressed: () async {
if (_ipController.text == '') {
showSnackBar(context, Text(_s.plzEnterHost));
return;
}
if (!usePublicKey && _passwordController.text == '') {
final cancel = await showRoundDialog<bool>(
context: context,
child: Text(_s.sureNoPwd),
actions: [
TextButton(
onPressed: () => context.pop(false),
child: Text(_s.ok),
),
TextButton(
onPressed: () => context.pop(true),
child: Text(_s.cancel),
)
],
);
if (cancel ?? true) {
return;
}
}
if (usePublicKey && _pubKeyIndex == -1) {
showSnackBar(context, Text(_s.plzSelectKey));
return;
}
if (_usernameController.text.isEmpty) {
_usernameController.text = 'root';
}
if (_portController.text.isEmpty) {
_portController.text = '22';
}
);
}
if (widget.spi != null && widget.spi!.pubKeyId != null) {
_keyInfo ??= locator<PrivateKeyStore>().get(widget.spi!.pubKeyId!);
Widget _buildKeyAuth() {
return Consumer<PrivateKeyProvider>(
builder: (_, key, __) {
for (var item in key.infos) {
if (item.id == widget.spi?.pubKeyId) {
_pubKeyIndex ??= key.infos.indexOf(item);
}
}
final tiles = key.infos
.map(
(e) => ListTile(
contentPadding: EdgeInsets.zero,
title: Text(e.id, textAlign: TextAlign.start),
trailing: _buildRadio(key.infos.indexOf(e), e),
),
)
.toList();
tiles.add(
ListTile(
title: Text(_s.addPrivateKey),
contentPadding: EdgeInsets.zero,
trailing: IconButton(
icon: const Icon(Icons.add),
onPressed: () => AppRoute(
const PrivateKeyEditPage(),
'private key edit page',
).go(context),
),
),
);
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 17),
child: Column(
children: tiles,
),
);
},
);
}
final authorization = _passwordController.text;
final spi = ServerPrivateInfo(
name: _nameController.text,
ip: _ipController.text,
port: int.parse(_portController.text),
user: _usernameController.text,
pwd: authorization,
pubKeyId: usePublicKey ? _keyInfo!.id : null,
Widget _buildFAB() {
return FloatingActionButton(
child: const Icon(Icons.send),
onPressed: () async {
if (_ipController.text == '') {
showSnackBar(context, Text(_s.plzEnterHost));
return;
}
if (!usePublicKey && _passwordController.text == '') {
final cancel = await showRoundDialog<bool>(
context: context,
child: Text(_s.sureNoPwd),
actions: [
TextButton(
onPressed: () => context.pop(false),
child: Text(_s.ok),
),
TextButton(
onPressed: () => context.pop(true),
child: Text(_s.cancel),
)
],
);
if (widget.spi == null) {
_serverProvider.addServer(spi);
} else {
_serverProvider.updateServer(widget.spi!, spi);
if (cancel ?? true) {
return;
}
}
if (usePublicKey && _pubKeyIndex == -1) {
showSnackBar(context, Text(_s.plzSelectKey));
return;
}
if (_usernameController.text.isEmpty) {
_usernameController.text = 'root';
}
if (_portController.text.isEmpty) {
_portController.text = '22';
}
context.pop();
},
),
if (widget.spi != null && widget.spi!.pubKeyId != null) {
_keyInfo ??= locator<PrivateKeyStore>().get(widget.spi!.pubKeyId!);
}
final authorization = _passwordController.text;
final spi = ServerPrivateInfo(
name: _nameController.text,
ip: _ipController.text,
port: int.parse(_portController.text),
user: _usernameController.text,
pwd: authorization,
pubKeyId: usePublicKey ? _keyInfo!.id : null,
);
if (widget.spi == null) {
_serverProvider.addServer(spi);
} else {
_serverProvider.updateServer(widget.spi!, spi);
}
context.pop();
},
);
}