Skip to content
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

fix(authenticator): move username selection state to authenticator state #1766

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import 'package:amplify_auth_cognito/amplify_auth_cognito.dart';
import 'package:amplify_authenticator/src/l10n/auth_strings_resolver.dart';
import 'package:amplify_authenticator/src/models/username_input.dart';
import 'package:amplify_authenticator/src/state/authenticator_state.dart';
import 'package:amplify_authenticator/src/utils/validators.dart';
import 'package:amplify_authenticator/src/widgets/component.dart';
import 'package:amplify_authenticator/src/widgets/form.dart';
Expand Down Expand Up @@ -129,19 +130,29 @@ mixin AuthenticatorUsernameField<FieldType,
return ToggleButtons(
borderWidth: buttonBorderWidth,
constraints: buttonConstraints,
isSelected: [useEmail.value, !useEmail.value],
isSelected: [
state.usernameSelection == UsernameSelection.email,
state.usernameSelection == UsernameSelection.phoneNumber,
],
onPressed: (int index) {
bool useEmail = index == 0;
setState(() {
this.useEmail.value = useEmail;
});
final newUsernameSelection = index == 0
? UsernameSelection.email
: UsernameSelection.phoneNumber;
final oldUsernameSelection = state.usernameSelection;
if (oldUsernameSelection == newUsernameSelection) {
return;
}
state.usernameSelection = newUsernameSelection;
// Reset current username value to align with the current switch state.
String newUsername = useEmail
String newUsername = newUsernameSelection ==
UsernameSelection.email
? state.getAttribute(CognitoUserAttributeKey.email) ?? ''
: state.getAttribute(
CognitoUserAttributeKey.phoneNumber) ??
'';
state.username = newUsername;
// Clear attributes on switch
state.authAttributes.clear();
},
children: [
Text(emailTitle),
Expand Down Expand Up @@ -219,7 +230,7 @@ mixin AuthenticatorUsernameField<FieldType,
validator: _validator,
enabled: enabled,
errorMaxLines: errorMaxLines,
initialValue: state.getAttribute(CognitoUserAttributeKey.phoneNumber),
initialValue: state.username,
);
}
return TextFormField(
Expand Down Expand Up @@ -253,9 +264,6 @@ mixin UsernameAttributes<T extends AuthenticatorForm>
return <CognitoUserAttributeKey>{...?authConfig?.usernameAttributes};
}();

/// Toggle value for the email or phone number case.
final ValueNotifier<bool> useEmail = ValueNotifier(true);

UsernameConfigType get usernameType {
if (usernameAttributes.isEmpty) {
return UsernameConfigType.username;
Expand Down Expand Up @@ -283,7 +291,7 @@ mixin UsernameAttributes<T extends AuthenticatorForm>
case UsernameConfigType.phoneNumber:
return UsernameType.phoneNumber;
case UsernameConfigType.emailOrPhoneNumber:
if (useEmail.value) {
if (state.usernameSelection == UsernameSelection.email) {
return UsernameType.email;
}
return UsernameType.phoneNumber;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,12 @@ import 'package:amplify_authenticator/src/state/auth_state.dart';
import 'package:amplify_authenticator/src/utils/country_code.dart';
import 'package:flutter/material.dart';

/// {@macro amplify_authenticator.authenticator_state.username_selection}
enum UsernameSelection {
email,
phoneNumber,
}

@visibleForTesting
typedef BlocEventPredicate = bool Function(AuthState state);

Expand Down Expand Up @@ -98,6 +104,21 @@ class AuthenticatorState extends ChangeNotifier {

String _username = '';

/// {@template amplify_authenticator.authenticator_state.username_selection}
/// The username type to use during sign up and sign in.
///
/// For auth configurations that allow sign up via username or email,
/// this will determine which option is currently selected.
/// {@endtemplate}
UsernameSelection get usernameSelection => _usernameSelection;

set usernameSelection(UsernameSelection value) {
_usernameSelection = value;
notifyListeners();
}

UsernameSelection _usernameSelection = UsernameSelection.email;

/// The value for the password form field
///
/// This value will be used during sign up, sign in, or other actions
Expand Down
20 changes: 0 additions & 20 deletions packages/amplify_authenticator/lib/src/widgets/form.dart
Original file line number Diff line number Diff line change
Expand Up @@ -142,26 +142,6 @@ class AuthenticatorFormState<T extends AuthenticatorForm>

final ValueNotifier<bool> obscureTextToggleValue = ValueNotifier(true);

@override
void initState() {
super.initState();
useEmail.addListener(_updateUseEmail);
}

@override
void dispose() {
useEmail.removeListener(_updateUseEmail);
super.dispose();
}

void _updateUseEmail() {
// Clear attributes on switch
state.authAttributes.clear();

// Refresh state
setState(() {});
}

/// Controls optional visibility of the field.
Widget get obscureTextToggle {
return ValueListenableBuilder<bool>(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -140,10 +140,6 @@ abstract class AuthenticatorFormFieldState<FieldType, FieldValue,
UsernameType get selectedUsernameType =>
AuthenticatorFormState.of(context).selectedUsernameType;

@nonVirtual
ValueNotifier<bool> get useEmail =>
AuthenticatorFormState.of(context).useEmail;

/// Callback for when `onChanged` is triggered on the [FormField].
ValueChanged<FieldValue> get onChanged => (_) {};

Expand Down Expand Up @@ -255,8 +251,6 @@ abstract class AuthenticatorFormFieldState<FieldType, FieldValue,
.add(EnumProperty<UsernameConfigType>('usernameType', usernameType));
properties.add(EnumProperty<UsernameType>(
'selectedUsernameType', selectedUsernameType));
properties
.add(DiagnosticsProperty<ValueNotifier<bool>>('useEmail', useEmail));
properties.add(IntProperty('maxLength', maxLength));
properties.add(DiagnosticsProperty<bool>('isOptional', isOptional));
properties.add(StringProperty('labelText', labelText));
Expand Down