Skip to content
This repository was archived by the owner on Sep 14, 2024. It is now read-only.

Commit 00da985

Browse files
committed
rework import screen
- validate input to be a url - enable submitting with the keyboard
1 parent bdaf04d commit 00da985

File tree

1 file changed

+46
-14
lines changed

1 file changed

+46
-14
lines changed

lib/src/screens/form/recipe_import_form.dart

Lines changed: 46 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import 'package:flutter_bloc/flutter_bloc.dart';
55
import 'package:flutter_spinkit/flutter_spinkit.dart';
66
import 'package:flutter_translate/flutter_translate.dart';
77
import 'package:nextcloud_cookbook_flutter/src/blocs/recipe/recipe_bloc.dart';
8+
import 'package:nextcloud_cookbook_flutter/src/util/url_validator.dart';
89

910
class RecipeImportForm extends StatefulWidget {
1011
final String importUrl;
@@ -17,6 +18,7 @@ class RecipeImportForm extends StatefulWidget {
1718

1819
class _RecipeImportFormState extends State<RecipeImportForm> {
1920
late TextEditingController _importUrlController;
21+
final _formKey = GlobalKey<FormState>();
2022

2123
@override
2224
void initState() {
@@ -42,25 +44,61 @@ class _RecipeImportFormState extends State<RecipeImportForm> {
4244
return BlocBuilder<RecipeBloc, RecipeState>(
4345
builder: (BuildContext context, RecipeState state) {
4446
final enabled = state.status != RecipeStatus.updateInProgress;
47+
48+
void onSubmit() {
49+
if (_formKey.currentState!.validate() && enabled) {
50+
_formKey.currentState!.save();
51+
}
52+
}
53+
54+
String? validate(String? value) {
55+
if (value == null || value.isEmpty) {
56+
return translate(
57+
'login.server_url.validator.pattern',
58+
);
59+
}
60+
61+
if (!URLUtils.isValid(value)) {
62+
return translate(
63+
'login.server_url.validator.pattern',
64+
);
65+
}
66+
67+
return null;
68+
}
69+
70+
Future<void> pasteClipboard() async {
71+
final clipboard = await Clipboard.getData('text/plain');
72+
final text = clipboard?.text;
73+
if (text != null) {
74+
_importUrlController.text = text;
75+
}
76+
77+
_formKey.currentState!.validate();
78+
}
79+
4580
return SingleChildScrollView(
4681
child: Padding(
4782
padding: const EdgeInsets.all(10.0),
4883
child: Form(
84+
key: _formKey,
4985
child: Column(
5086
children: [
51-
TextField(
87+
TextFormField(
5288
enabled: enabled,
5389
controller: _importUrlController,
90+
validator: validate,
91+
onSaved: (value) {
92+
BlocProvider.of<RecipeBloc>(context).add(
93+
RecipeImported(value!),
94+
);
95+
},
96+
onEditingComplete: onSubmit,
5497
decoration: InputDecoration(
5598
hintText: translate("recipe_import.field"),
5699
suffixIcon: IconButton(
57100
tooltip: translate("recipe_import.clipboard"),
58-
onPressed: () async {
59-
final clipboard =
60-
await Clipboard.getData('text/plain');
61-
final text = clipboard?.text;
62-
if (text != null) _importUrlController.text = text;
63-
},
101+
onPressed: pasteClipboard,
64102
icon: const Icon(Icons.content_copy_outlined),
65103
),
66104
),
@@ -69,13 +107,7 @@ class _RecipeImportFormState extends State<RecipeImportForm> {
69107
Center(
70108
child: enabled
71109
? OutlinedButton.icon(
72-
onPressed: () {
73-
if (enabled) {
74-
BlocProvider.of<RecipeBloc>(context).add(
75-
RecipeImported(_importUrlController.text),
76-
);
77-
}
78-
},
110+
onPressed: onSubmit,
79111
icon: const Icon(Icons.cloud_download_outlined),
80112
label: Text(translate("recipe_import.button")),
81113
style: OutlinedButton.styleFrom(

0 commit comments

Comments
 (0)