-
Notifications
You must be signed in to change notification settings - Fork 243
Add username unavailability indicator and validation to Edit Profile … #580
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: dev
Are you sure you want to change the base?
Changes from 7 commits
06db5ac
847dd64
8e79723
be91e5a
e9851b9
4602600
0a0ec5f
1c427f9
ec564d6
d024bd3
9c49bb7
a8926cd
1f65dea
0bf8294
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,11 +1,13 @@ | ||
| import 'dart:io'; | ||
|
|
||
| import 'package:flutter/material.dart'; | ||
| import 'package:get/get.dart'; | ||
| import 'package:loading_animation_widget/loading_animation_widget.dart'; | ||
| import 'package:resonate/themes/theme_controller.dart'; | ||
| import 'package:resonate/utils/debouncer.dart'; | ||
| import 'package:resonate/utils/enums/log_type.dart'; | ||
| import 'package:resonate/utils/ui_sizes.dart'; | ||
| import 'package:resonate/views/widgets/loading_dialog.dart'; | ||
| import 'package:resonate/views/widgets/snackbar.dart'; | ||
| import 'package:resonate/l10n/app_localizations.dart'; | ||
|
|
||
| import '../../controllers/auth_state_controller.dart'; | ||
|
|
@@ -22,6 +24,7 @@ class EditProfileScreen extends StatelessWidget { | |
| final AuthStateController authStateController = Get.put( | ||
| AuthStateController(), | ||
| ); | ||
| final debouncer = Debouncer(milliseconds: 800); | ||
|
|
||
| @override | ||
| Widget build(BuildContext context) { | ||
|
|
@@ -30,9 +33,7 @@ class EditProfileScreen extends StatelessWidget { | |
| !(editProfileController.isLoading.value || | ||
| editProfileController.isThereUnsavedChanges()), | ||
| onPopInvokedWithResult: (didPop, result) async { | ||
| if (didPop) { | ||
| return; | ||
| } | ||
| if (didPop) return; | ||
|
|
||
| if (!editProfileController.isLoading.value && | ||
| editProfileController.isThereUnsavedChanges()) { | ||
|
|
@@ -112,16 +113,25 @@ class EditProfileScreen extends StatelessWidget { | |
| keyboardType: TextInputType.text, | ||
| autocorrect: false, | ||
| decoration: InputDecoration( | ||
| // hintText: "Name", | ||
| labelText: AppLocalizations.of(context)!.name, | ||
| prefixIcon: Icon(Icons.abc_rounded), | ||
| ), | ||
| ), | ||
| SizedBox(height: UiSizes.height_20), | ||
| Obx( | ||
| () => TextFormField( | ||
| autovalidateMode: AutovalidateMode.onUserInteraction, | ||
| maxLength: 36, | ||
| validator: (value) { | ||
| if (value!.length > 5) { | ||
| if (value!.length >= 7) { | ||
| final validUsername = RegExp( | ||
| r'^[a-zA-Z0-9._-]+$', | ||
| ).hasMatch(value.trim()); | ||
| if (!validUsername) { | ||
| return AppLocalizations.of( | ||
| context, | ||
| )!.usernameInvalidOrTaken; | ||
| } | ||
| return null; | ||
| } else { | ||
| return AppLocalizations.of( | ||
|
|
@@ -131,22 +141,55 @@ class EditProfileScreen extends StatelessWidget { | |
| }, | ||
| controller: controller.usernameController, | ||
| onChanged: (value) async { | ||
| if (value.length > 5) { | ||
| controller.usernameAvailable.value = | ||
| await controller.isUsernameAvailable( | ||
| value.trim(), | ||
| Get.closeCurrentSnackbar(); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If you are no longer opening snackbars for validation then this is unnecessary
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We are still showing snackbars for validation errors (invalid format and username taken), so Get.closeCurrentSnackbar() is needed isnt
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. but you said AutoValidator will handle those inline so the only snackbar is shown when the submit button is pressed it looks like |
||
|
|
||
| if (value.length >= 7) { | ||
| final validUsername = RegExp( | ||
| r'^[a-zA-Z0-9._-]+$', | ||
| ).hasMatch(value.trim()); | ||
M4dhav marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| if (!validUsername || value.trim().length > 36) { | ||
| controller.usernameAvailable.value = false; | ||
| controller.usernameChecking.value = false; | ||
| return; | ||
| } | ||
|
|
||
| controller.usernameChecking.value = true; | ||
| controller.usernameAvailable.value = false; | ||
|
|
||
| debouncer.run(() async { | ||
| final available = await controller | ||
| .isUsernameAvailable(value.trim()); | ||
|
|
||
| controller.usernameChecking.value = false; | ||
| controller.usernameAvailable.value = available; | ||
|
|
||
| if (!available) { | ||
| customSnackbar( | ||
| AppLocalizations.of( | ||
| context, | ||
| )!.usernameUnavailable, | ||
| AppLocalizations.of( | ||
| context, | ||
| )!.usernameInvalidOrTaken, | ||
| LogType.error, | ||
| snackbarDuration: 1, | ||
| ); | ||
| } | ||
| }); | ||
| } else { | ||
| controller.usernameAvailable.value = false; | ||
| controller.usernameChecking.value = false; | ||
|
||
| } | ||
| }, | ||
| keyboardType: TextInputType.text, | ||
| autocorrect: false, | ||
| decoration: InputDecoration( | ||
| // hintText: "Username", | ||
| labelText: AppLocalizations.of(context)!.username, | ||
| prefixIcon: const Icon(Icons.person), | ||
| suffixIcon: controller.usernameAvailable.value | ||
| suffixIcon: | ||
| !controller.usernameChecking.value && | ||
| controller.usernameAvailable.value | ||
| ? const Icon( | ||
| Icons.verified_outlined, | ||
| color: Colors.green, | ||
|
|
@@ -298,12 +341,9 @@ class EditProfileScreen extends StatelessWidget { | |
| Column( | ||
| children: [ | ||
| IconButton( | ||
| tooltip: AppLocalizations.of( | ||
| context, | ||
| )!.clickPictureCamera, | ||
| tooltip: AppLocalizations.of(context)!.clickPictureCamera, | ||
| onPressed: () { | ||
| Navigator.pop(context); | ||
| // Display Loading Dialog | ||
| loadingDialog(context); | ||
| editProfileController.pickImageFromCamera(); | ||
| }, | ||
|
|
@@ -322,8 +362,6 @@ class EditProfileScreen extends StatelessWidget { | |
| tooltip: AppLocalizations.of(context)!.pickImageGallery, | ||
| onPressed: () { | ||
| Navigator.pop(context); | ||
|
|
||
| // Display Loading Dialog | ||
| loadingDialog(context); | ||
| editProfileController.pickImageFromGallery(); | ||
| }, | ||
|
|
@@ -358,4 +396,4 @@ class EditProfileScreen extends StatelessWidget { | |
| ], | ||
| ); | ||
| } | ||
| } | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please make a separate string for invalid username and taken username so user can have proper feedback