Add done button to iOS keyboard

This commit is contained in:
Godwin Asuquo 2022-10-19 11:07:04 +03:00
parent da6fd9a9ff
commit 60a06577bc
2 changed files with 147 additions and 102 deletions

View file

@ -1,10 +1,11 @@
import 'package:cake_wallet/core/execution_state.dart'; import 'package:cake_wallet/core/execution_state.dart';
import 'package:cake_wallet/src/widgets/alert_with_one_action.dart'; import 'package:cake_wallet/src/widgets/alert_with_one_action.dart';
import 'package:cake_wallet/src/widgets/keyboard_done_button.dart';
import 'package:cake_wallet/src/widgets/standard_checkbox.dart'; import 'package:cake_wallet/src/widgets/standard_checkbox.dart';
import 'package:cake_wallet/utils/show_pop_up.dart'; import 'package:cake_wallet/utils/show_pop_up.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter_mobx/flutter_mobx.dart'; import 'package:flutter_mobx/flutter_mobx.dart';
import 'package:keyboard_actions/keyboard_actions.dart';
import 'package:mobx/mobx.dart'; import 'package:mobx/mobx.dart';
import 'package:cake_wallet/generated/i18n.dart'; import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/core/node_address_validator.dart'; import 'package:cake_wallet/core/node_address_validator.dart';
@ -68,7 +69,22 @@ class NodeCreateOrEditPage extends BasePage {
String get title => S.current.node_new; String get title => S.current.node_new;
final NodeCreateOrEditViewModel nodeCreateOrEditViewModel; final NodeCreateOrEditViewModel nodeCreateOrEditViewModel;
final _nodePortFocusNode = FocusNode();
KeyboardActionsConfig _buildConfig(BuildContext context) {
return KeyboardActionsConfig(
keyboardActionsPlatform: KeyboardActionsPlatform.IOS,
keyboardBarColor:
Theme.of(context).accentTextTheme!.bodyText1!.backgroundColor!,
nextFocus: false,
actions: [
KeyboardActionsItem(
focusNode: _nodePortFocusNode,
toolbarButtons: [(_) => KeyboardDoneButton()],
),
],
);
}
@override @override
Widget body(BuildContext context) { Widget body(BuildContext context) {
@ -104,47 +120,24 @@ class NodeCreateOrEditPage extends BasePage {
} }
}); });
return Container( return KeyboardActions(
padding: EdgeInsets.only(left: 24, right: 24), autoScroll: false,
child: ScrollableWithBottomSection( config: _buildConfig(context),
contentPadding: EdgeInsets.only(bottom: 24.0), child: Container(
content: Form( padding: EdgeInsets.only(left: 24, right: 24),
key: _formKey, child: ScrollableWithBottomSection(
child: Column( contentPadding: EdgeInsets.only(bottom: 24.0),
children: <Widget>[ content: Form(
Row( key: _formKey,
children: <Widget>[ child: Column(
Expanded( children: <Widget>[
child: BaseTextFormField(
controller: _addressController,
hintText: S.of(context).node_address,
validator: NodeAddressValidator(),
)
)
],
),
SizedBox(height: 10.0),
Row(
children: <Widget>[
Expanded(
child: BaseTextFormField(
controller: _portController,
hintText: S.of(context).node_port,
keyboardType: TextInputType.numberWithOptions(
signed: false, decimal: false),
validator: NodePortValidator(),
)
)
],
),
SizedBox(height: 10.0),
if (nodeCreateOrEditViewModel.hasAuthCredentials) ...[
Row( Row(
children: <Widget>[ children: <Widget>[
Expanded( Expanded(
child: BaseTextFormField( child: BaseTextFormField(
controller: _loginController, controller: _addressController,
hintText: S.of(context).login, hintText: S.of(context).node_address,
validator: NodeAddressValidator(),
) )
) )
], ],
@ -154,74 +147,102 @@ class NodeCreateOrEditPage extends BasePage {
children: <Widget>[ children: <Widget>[
Expanded( Expanded(
child: BaseTextFormField( child: BaseTextFormField(
controller: _passwordController, controller: _portController,
hintText: S.of(context).password, hintText: S.of(context).node_port,
focusNode: _nodePortFocusNode,
keyboardType: TextInputType.numberWithOptions(
signed: false, decimal: false),
validator: NodePortValidator(),
) )
) )
], ],
), ),
Padding( SizedBox(height: 10.0),
padding: EdgeInsets.only(top: 20), if (nodeCreateOrEditViewModel.hasAuthCredentials) ...[
child: Row( Row(
mainAxisAlignment: MainAxisAlignment.start, children: <Widget>[
mainAxisSize: MainAxisSize.max, Expanded(
children: [ child: BaseTextFormField(
Observer( controller: _loginController,
builder: (_) => StandardCheckbox( hintText: S.of(context).login,
value: nodeCreateOrEditViewModel.useSSL, )
onChanged: (value) => )
nodeCreateOrEditViewModel.useSSL = value,
caption: S.of(context).use_ssl,
))
], ],
)) ),
] SizedBox(height: 10.0),
], Row(
)), children: <Widget>[
bottomSectionPadding: EdgeInsets.only(bottom: 24), Expanded(
bottomSection: Observer( child: BaseTextFormField(
builder: (_) => Row( controller: _passwordController,
children: <Widget>[ hintText: S.of(context).password,
Flexible( )
child: Container( )
padding: EdgeInsets.only(right: 8.0), ],
child: LoadingPrimaryButton( ),
Padding(
padding: EdgeInsets.only(top: 20),
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
mainAxisSize: MainAxisSize.max,
children: [
Observer(
builder: (_) => StandardCheckbox(
value: nodeCreateOrEditViewModel.useSSL,
onChanged: (value) =>
nodeCreateOrEditViewModel.useSSL = value,
caption: S.of(context).use_ssl,
))
],
))
]
],
)),
bottomSectionPadding: EdgeInsets.only(bottom: 24),
bottomSection: Observer(
builder: (_) => Row(
children: <Widget>[
Flexible(
child: Container(
padding: EdgeInsets.only(right: 8.0),
child: LoadingPrimaryButton(
onPressed: () async {
if (_formKey.currentState != null && !_formKey.currentState!.validate()) {
return;
}
await nodeCreateOrEditViewModel.connect();
},
isLoading: nodeCreateOrEditViewModel
.connectionState is IsExecutingState,
text: S.of(context).node_test,
isDisabled: !nodeCreateOrEditViewModel.isReady,
color: Colors.orange,
textColor: Colors.white),
)),
Flexible(
child: Container(
padding: EdgeInsets.only(left: 8.0),
child: PrimaryButton(
onPressed: () async { onPressed: () async {
if (_formKey.currentState != null && !_formKey.currentState!.validate()) { if (_formKey.currentState != null && !_formKey.currentState!.validate()) {
return; return;
} }
await nodeCreateOrEditViewModel.connect(); await nodeCreateOrEditViewModel.save();
Navigator.of(context).pop();
}, },
isLoading: nodeCreateOrEditViewModel text: S.of(context).save,
.connectionState is IsExecutingState, color: Theme.of(context).accentTextTheme!.bodyText1!.color!,
text: S.of(context).node_test, textColor: Colors.white,
isDisabled: !nodeCreateOrEditViewModel.isReady, isDisabled: (!nodeCreateOrEditViewModel.isReady)||
color: Colors.orange, (nodeCreateOrEditViewModel
textColor: Colors.white), .connectionState is IsExecutingState),
)), ),
Flexible( )),
child: Container( ],
padding: EdgeInsets.only(left: 8.0), )),
child: PrimaryButton( )),
onPressed: () async { );
if (_formKey.currentState != null && !_formKey.currentState!.validate()) {
return;
}
await nodeCreateOrEditViewModel.save();
Navigator.of(context).pop();
},
text: S.of(context).save,
color: Theme.of(context).accentTextTheme!.bodyText1!.color!,
textColor: Colors.white,
isDisabled: (!nodeCreateOrEditViewModel.isReady)||
(nodeCreateOrEditViewModel
.connectionState is IsExecutingState),
),
)),
],
)),
));
} }
} }

View file

@ -1,9 +1,11 @@
import 'package:cake_wallet/src/widgets/keyboard_done_button.dart';
import 'package:cake_wallet/utils/date_picker.dart'; import 'package:cake_wallet/utils/date_picker.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:intl/intl.dart'; import 'package:intl/intl.dart';
import 'package:cake_wallet/generated/i18n.dart'; import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/monero/monero.dart'; import 'package:cake_wallet/monero/monero.dart';
import 'package:cake_wallet/src/widgets/base_text_form_field.dart'; import 'package:cake_wallet/src/widgets/base_text_form_field.dart';
import 'package:keyboard_actions/keyboard_actions.dart';
class BlockchainHeightWidget extends StatefulWidget { class BlockchainHeightWidget extends StatefulWidget {
BlockchainHeightWidget({ BlockchainHeightWidget({
@ -29,7 +31,22 @@ class BlockchainHeightState extends State<BlockchainHeightWidget> {
int get height => _height; int get height => _height;
int _height = 0; int _height = 0;
final _restoreFocusNode = FocusNode();
KeyboardActionsConfig _buildConfig(BuildContext context) {
return KeyboardActionsConfig(
keyboardActionsPlatform: KeyboardActionsPlatform.IOS,
keyboardBarColor:
Theme.of(context).accentTextTheme!.bodyText1!.backgroundColor!,
nextFocus: false,
actions: [
KeyboardActionsItem(
focusNode: _restoreFocusNode,
toolbarButtons: [(_) => KeyboardDoneButton()],
),
],
);
}
@override @override
void initState() { void initState() {
restoreHeightController.addListener(() { restoreHeightController.addListener(() {
@ -55,7 +72,11 @@ class BlockchainHeightState extends State<BlockchainHeightWidget> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Column(
return KeyboardActions(
autoScroll: false,
config: _buildConfig(context),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[ children: <Widget>[
Row( Row(
@ -64,12 +85,14 @@ class BlockchainHeightState extends State<BlockchainHeightWidget> {
child: Container( child: Container(
padding: EdgeInsets.only(top: 20.0, bottom: 10.0), padding: EdgeInsets.only(top: 20.0, bottom: 10.0),
child: BaseTextFormField( child: BaseTextFormField(
focusNode: widget.focusNode, focusNode: _restoreFocusNode,
controller: restoreHeightController, controller: restoreHeightController,
keyboardType: TextInputType.numberWithOptions( keyboardType: TextInputType.numberWithOptions(
signed: false, decimal: false), signed: false, decimal: false),
hintText: S.of(context).widgets_restore_from_blockheight, hintText: S.of(context).widgets_restore_from_blockheight,
))) ),
),
)
], ],
), ),
if (widget.hasDatePicker) ...[ if (widget.hasDatePicker) ...[
@ -112,7 +135,8 @@ class BlockchainHeightState extends State<BlockchainHeightWidget> {
) )
] ]
], ],
); ),
);
} }
Future _selectDate(BuildContext context) async { Future _selectDate(BuildContext context) async {