Moved execution of onSubmit from ButtonWidget associated with TextInputWidget to within TextInputWidget

This commit is contained in:
ashilkn 2023-02-08 11:13:46 +05:30
parent b5c0ee7ce6
commit 5208ff3e13
5 changed files with 66 additions and 39 deletions

View file

@ -159,11 +159,11 @@ class Actions extends StatelessWidget {
class TextInputDialog extends StatefulWidget { class TextInputDialog extends StatefulWidget {
final String title; final String title;
final String? body; final String? body;
final String confirmationButtonLabel; final String submitButtonLabel;
final IconData? icon; final IconData? icon;
final String? label; final String? label;
final String? message; final String? message;
final FutureVoidCallbackParamStr onConfirm; final FutureVoidCallbackParamStr onSubmit;
final String? hintText; final String? hintText;
final IconData? prefixIcon; final IconData? prefixIcon;
final String? initialValue; final String? initialValue;
@ -172,8 +172,8 @@ class TextInputDialog extends StatefulWidget {
const TextInputDialog({ const TextInputDialog({
required this.title, required this.title,
this.body, this.body,
required this.confirmationButtonLabel, required this.submitButtonLabel,
required this.onConfirm, required this.onSubmit,
this.icon, this.icon,
this.label, this.label,
this.message, this.message,
@ -190,7 +190,8 @@ class TextInputDialog extends StatefulWidget {
} }
class _TextInputDialogState extends State<TextInputDialog> { class _TextInputDialogState extends State<TextInputDialog> {
final TextEditingController _textController = TextEditingController(); //the value of this ValueNotifier has no significance
final _submitNotifier = ValueNotifier(false);
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final widthOfScreen = MediaQuery.of(context).size.width; final widthOfScreen = MediaQuery.of(context).size.width;
@ -219,7 +220,6 @@ class _TextInputDialogState extends State<TextInputDialog> {
Padding( Padding(
padding: const EdgeInsets.only(top: 19), padding: const EdgeInsets.only(top: 19),
child: TextInputWidget( child: TextInputWidget(
textController: _textController,
label: widget.label, label: widget.label,
message: widget.message, message: widget.message,
hintText: widget.hintText, hintText: widget.hintText,
@ -228,6 +228,8 @@ class _TextInputDialogState extends State<TextInputDialog> {
alignMessage: widget.alignMessage, alignMessage: widget.alignMessage,
autoFocus: true, autoFocus: true,
maxLength: widget.maxLength, maxLength: widget.maxLength,
submitNotifier: _submitNotifier,
onSubmit: widget.onSubmit,
), ),
), ),
const SizedBox(height: 36), const SizedBox(height: 36),
@ -247,10 +249,10 @@ class _TextInputDialogState extends State<TextInputDialog> {
child: ButtonWidget( child: ButtonWidget(
buttonSize: ButtonSize.small, buttonSize: ButtonSize.small,
buttonType: ButtonType.neutral, buttonType: ButtonType.neutral,
labelText: widget.confirmationButtonLabel, labelText: widget.submitButtonLabel,
onTap: _onTap, onTap: () async {
isInAlert: true, _submitNotifier.value = !_submitNotifier.value;
shouldShowSuccessConfirmation: true, },
), ),
), ),
], ],
@ -260,8 +262,4 @@ class _TextInputDialogState extends State<TextInputDialog> {
), ),
); );
} }
Future<void> _onTap() async {
await widget.onConfirm.call(_textController.text);
}
} }

View file

@ -1,10 +1,10 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:photos/theme/ente_theme.dart'; import 'package:photos/theme/ente_theme.dart';
import 'package:photos/ui/components/dialog_widget.dart';
import 'package:photos/utils/separators_util.dart'; import 'package:photos/utils/separators_util.dart';
class TextInputWidget extends StatelessWidget { class TextInputWidget extends StatefulWidget {
final TextEditingController textController;
final String? label; final String? label;
final String? message; final String? message;
final String? hintText; final String? hintText;
@ -13,8 +13,12 @@ class TextInputWidget extends StatelessWidget {
final Alignment? alignMessage; final Alignment? alignMessage;
final bool? autoFocus; final bool? autoFocus;
final int? maxLength; final int? maxLength;
final ValueNotifier? submitNotifier;
final bool alwaysShowSuccessState;
final bool showOnlyLoadingState;
final FutureVoidCallbackParamStr onSubmit;
const TextInputWidget({ const TextInputWidget({
required this.textController, required this.onSubmit,
this.label, this.label,
this.message, this.message,
this.hintText, this.hintText,
@ -23,33 +27,57 @@ class TextInputWidget extends StatelessWidget {
this.alignMessage, this.alignMessage,
this.autoFocus, this.autoFocus,
this.maxLength, this.maxLength,
this.submitNotifier,
this.alwaysShowSuccessState = false,
this.showOnlyLoadingState = false,
super.key, super.key,
}); });
@override
State<TextInputWidget> createState() => _TextInputWidgetState();
}
class _TextInputWidgetState extends State<TextInputWidget> {
final _textController = TextEditingController();
@override
void initState() {
widget.submitNotifier?.addListener(() {
widget.onSubmit.call(_textController.text);
});
super.initState();
}
@override
void dispose() {
widget.submitNotifier?.dispose();
super.dispose();
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
if (initialValue != null) { if (widget.initialValue != null) {
textController.value = TextEditingValue( _textController.value = TextEditingValue(
text: initialValue!, text: widget.initialValue!,
selection: TextSelection.collapsed(offset: initialValue!.length), selection: TextSelection.collapsed(offset: widget.initialValue!.length),
); );
} }
final colorScheme = getEnteColorScheme(context); final colorScheme = getEnteColorScheme(context);
final textTheme = getEnteTextTheme(context); final textTheme = getEnteTextTheme(context);
var textInputChildren = <Widget>[]; var textInputChildren = <Widget>[];
if (label != null) textInputChildren.add(Text(label!)); if (widget.label != null) textInputChildren.add(Text(widget.label!));
textInputChildren.add( textInputChildren.add(
ClipRRect( ClipRRect(
borderRadius: const BorderRadius.all(Radius.circular(8)), borderRadius: const BorderRadius.all(Radius.circular(8)),
child: Material( child: Material(
child: TextFormField( child: TextFormField(
autofocus: autoFocus ?? false, autofocus: widget.autoFocus ?? false,
controller: textController, controller: _textController,
inputFormatters: maxLength != null inputFormatters: widget.maxLength != null
? [LengthLimitingTextInputFormatter(50)] ? [LengthLimitingTextInputFormatter(50)]
: null, : null,
decoration: InputDecoration( decoration: InputDecoration(
hintText: hintText, hintText: widget.hintText,
hintStyle: textTheme.body.copyWith(color: colorScheme.textMuted), hintStyle: textTheme.body.copyWith(color: colorScheme.textMuted),
filled: true, filled: true,
contentPadding: const EdgeInsets.symmetric( contentPadding: const EdgeInsets.symmetric(
@ -75,25 +103,26 @@ class TextInputWidget extends StatelessWidget {
minHeight: 44, minHeight: 44,
minWidth: 44, minWidth: 44,
), ),
prefixIcon: prefixIcon != null prefixIcon: widget.prefixIcon != null
? Icon( ? Icon(
prefixIcon, widget.prefixIcon,
color: colorScheme.strokeMuted, color: colorScheme.strokeMuted,
) )
: null, : null,
), ),
onEditingComplete: () {},
), ),
), ),
), ),
); );
if (message != null) { if (widget.message != null) {
textInputChildren.add( textInputChildren.add(
Padding( Padding(
padding: const EdgeInsets.symmetric(horizontal: 8), padding: const EdgeInsets.symmetric(horizontal: 8),
child: Align( child: Align(
alignment: alignMessage ?? Alignment.centerLeft, alignment: widget.alignMessage ?? Alignment.centerLeft,
child: Text( child: Text(
message!, widget.message!,
style: textTheme.small.copyWith(color: colorScheme.textMuted), style: textTheme.small.copyWith(color: colorScheme.textMuted),
), ),
), ),

View file

@ -114,9 +114,9 @@ class _GalleryAppBarWidgetState extends State<GalleryAppBarWidget> {
final result = await showTextInputDialog( final result = await showTextInputDialog(
context, context,
title: "Rename album", title: "Rename album",
confirmationButtonLabel: "Rename", submitButtonLabel: "Rename",
hintText: "Enter album name", hintText: "Enter album name",
onConfirm: (String text) async { onSubmit: (String text) async {
// indicates user cancelled the rename request // indicates user cancelled the rename request
if (text == "" || text.trim() == _appBarTitle!.trim()) { if (text == "" || text.trim() == _appBarTitle!.trim()) {
return; return;

View file

@ -256,12 +256,12 @@ Future<ButtonAction?> showTextInputDialog(
BuildContext context, { BuildContext context, {
required String title, required String title,
String? body, String? body,
required String confirmationButtonLabel, required String submitButtonLabel,
IconData? icon, IconData? icon,
String? label, String? label,
String? message, String? message,
String? hintText, String? hintText,
required FutureVoidCallbackParamStr onConfirm, required FutureVoidCallbackParamStr onSubmit,
IconData? prefixIcon, IconData? prefixIcon,
String? initialValue, String? initialValue,
Alignment? alignMessage, Alignment? alignMessage,
@ -282,8 +282,8 @@ Future<ButtonAction?> showTextInputDialog(
label: label, label: label,
body: body, body: body,
icon: icon, icon: icon,
confirmationButtonLabel: confirmationButtonLabel, submitButtonLabel: submitButtonLabel,
onConfirm: onConfirm, onSubmit: onSubmit,
hintText: hintText, hintText: hintText,
prefixIcon: prefixIcon, prefixIcon: prefixIcon,
initialValue: initialValue, initialValue: initialValue,

View file

@ -103,13 +103,13 @@ Future<void> editFilename(
await showTextInputDialog( await showTextInputDialog(
context, context,
title: "Rename file", title: "Rename file",
confirmationButtonLabel: "Rename", submitButtonLabel: "Rename",
initialValue: nameWithoutExt, initialValue: nameWithoutExt,
message: extName, message: extName,
alignMessage: Alignment.centerRight, alignMessage: Alignment.centerRight,
hintText: "Enter file name", hintText: "Enter file name",
maxLength: 50, maxLength: 50,
onConfirm: (String text) async { onSubmit: (String text) async {
try { try {
if (text.isEmpty || text.trim() == nameWithoutExt.trim()) { if (text.isEmpty || text.trim() == nameWithoutExt.trim()) {
return; return;