mirror of
https://github.com/lollipopkit/flutter_server_box.git
synced 2025-12-17 07:14:28 +01:00
#29 opt. for TextInput
This commit is contained in:
@@ -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();
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user