refactor(authentication)!: use mixins, and remove use of onSignUpSuccess

This commit is contained in:
Hugo Pointcheval 2022-12-29 17:04:26 +01:00
parent adcd98f47b
commit 33cb4f6f06
Signed by: hugo
GPG Key ID: 3AAC487E131E00BC
9 changed files with 646 additions and 345 deletions

View File

@ -0,0 +1,97 @@
// Copyright (C) 2022 WYATT GROUP
// Please see the AUTHORS file for details.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
part of 'sign_in_cubit.dart';
abstract class BaseSignInCubit<Extra> extends FormDataCubit<SignInState> {
BaseSignInCubit({
required this.authenticationRepository,
}) : super(
SignInState(
form: authenticationRepository.formRepository
.accessForm(AuthFormName.signInForm),
),
);
final AuthenticationRepository<Extra> authenticationRepository;
FormRepository get formRepository => authenticationRepository.formRepository;
@override
String get formName => AuthFormName.signInForm;
@override
FutureOr<void> dataChanged<Value>(
String key,
FormInputValidator<Value, ValidationError> dirtyValue,
) {
final form = formRepository.accessForm(formName).clone();
try {
form.updateValidator(key, dirtyValue);
formRepository.updateForm(form);
} catch (e) {
rethrow;
}
emit(
SignInState(form: form, status: form.validate()),
);
}
@override
FutureOr<void> reset() {
final form = state.form.reset();
formRepository.updateForm(form);
emit(
SignInState(form: form, status: form.validate()),
);
}
@override
FutureOr<void> update(
WyattForm form, {
SetOperation operation = SetOperation.replace,
}) {
final WyattForm current = formRepository.accessForm(formName).clone();
final WyattForm newForm = operation.operation.call(current, form);
formRepository.updateForm(newForm);
emit(
SignInState(form: newForm, status: newForm.validate()),
);
}
@override
FutureOr<void> validate() {
final WyattForm form = formRepository.accessForm(formName);
emit(
SignInState(form: form, status: form.validate()),
);
}
@override
FutureOr<void> submit() async {
final WyattForm form = formRepository.accessForm(formName);
const error = '`submit()` is not implemented for BaseSignUpCubit, '
'please use `signUpWithEmailAndPassword()`.';
emit(
SignInState(
form: form,
errorMessage: error,
status: FormStatus.submissionFailure,
),
);
}
}

View File

@ -0,0 +1,66 @@
// Copyright (C) 2022 WYATT GROUP
// Please see the AUTHORS file for details.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
import 'dart:async';
import 'package:wyatt_architecture/wyatt_architecture.dart';
import 'package:wyatt_authentication_bloc/src/domain/entities/account.dart';
import 'package:wyatt_authentication_bloc/src/features/sign_in/cubit/sign_in_cubit.dart';
import 'package:wyatt_form_bloc/wyatt_form_bloc.dart';
import 'package:wyatt_type_utils/wyatt_type_utils.dart';
mixin SignInAnonymously<Extra> on BaseSignInCubit<Extra> {
FutureOrResult<void> onSignInAnonymously(
Result<Account, AppException> result,
WyattForm form,
);
FutureOr<void> signInAnonymously() async {
if (state.status.isSubmissionInProgress) {
return;
}
final form = formRepository.accessForm(formName);
emit(SignInState(form: form, status: FormStatus.submissionInProgress));
final result = await authenticationRepository.signInAnonymously();
// Here custom code
final callbackResponse = await onSignInAnonymously(result, form);
if (callbackResponse.isErr) {
final error = callbackResponse.err!;
emit(
SignInState(
form: form,
errorMessage: error.message,
status: FormStatus.submissionFailure,
),
);
}
emit(
result.fold(
(value) =>
SignInState(form: form, status: FormStatus.submissionSuccess),
(error) => SignInState(
form: form,
errorMessage: error.message,
status: FormStatus.submissionFailure,
),
),
);
}
}

View File

@ -0,0 +1,139 @@
// Copyright (C) 2022 WYATT GROUP
// Please see the AUTHORS file for details.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
import 'dart:async';
import 'package:wyatt_architecture/wyatt_architecture.dart';
import 'package:wyatt_authentication_bloc/src/core/constants/form_field.dart';
import 'package:wyatt_authentication_bloc/src/domain/entities/account.dart';
import 'package:wyatt_authentication_bloc/src/features/sign_in/cubit/sign_in_cubit.dart';
import 'package:wyatt_form_bloc/wyatt_form_bloc.dart';
import 'package:wyatt_type_utils/wyatt_type_utils.dart';
mixin SignInWithEmailPassword<Extra> on BaseSignInCubit<Extra> {
FutureOrResult<void> onSignInWithEmailAndPassword(
Result<Account, AppException> result,
WyattForm form,
);
void emailChanged(String value) {
final emailValidatorType = formRepository
.accessForm(formName)
.validatorOf(AuthFormField.email)
.runtimeType;
assert(
emailValidatorType == Email,
'Use emailCustomChanged(...) with validator $emailValidatorType',
);
final Email email = Email.dirty(value);
dataChanged(AuthFormField.email, email);
}
void passwordChanged(String value) {
final passwordValidatorType = formRepository
.accessForm(formName)
.validatorOf(AuthFormField.password)
.runtimeType;
assert(
passwordValidatorType == Password,
'Use passwordCustomChanged(...) with validator $passwordValidatorType',
);
final Password password = Password.dirty(value);
dataChanged(AuthFormField.password, password);
}
/// Same as [emailChanged] but with a custom [Validator].
///
/// Sort of short hand for [dataChanged].
void emailCustomChanged<
Validator extends FormInputValidator<String?, ValidationError>>(
Validator validator,
) {
dataChanged(AuthFormField.email, validator);
}
/// Same as [passwordChanged] but with a custom [Validator].
///
/// Sort of short hand for [dataChanged].
void passwordCustomChanged<
Validator extends FormInputValidator<String?, ValidationError>>(
Validator validator,
) {
dataChanged(AuthFormField.password, validator);
}
FutureOr<void> signInWithEmailAndPassword() async {
if (state.status.isSubmissionInProgress) {
return;
}
if (!state.status.isValidated) {
return;
}
final form = formRepository.accessForm(formName);
emit(
SignInState(
form: form,
status: FormStatus.submissionInProgress,
),
);
final email = form.valueOf<String?>(AuthFormField.email);
final password = form.valueOf<String?>(AuthFormField.password);
if (email.isNullOrEmpty || password.isNullOrEmpty) {
emit(
SignInState(
form: form,
errorMessage: 'An error occured while retrieving data from the form.',
status: FormStatus.submissionFailure,
),
);
}
final result = await authenticationRepository.signInWithEmailAndPassword(
email: email!,
password: password!,
);
// Here custom code
final callbackResponse = await onSignInWithEmailAndPassword(result, form);
if (callbackResponse.isErr) {
final error = callbackResponse.err!;
emit(
SignInState(
form: form,
errorMessage: error.message,
status: FormStatus.submissionFailure,
),
);
}
emit(
result.fold(
(value) =>
SignInState(form: form, status: FormStatus.submissionSuccess),
(error) => SignInState(
form: form,
errorMessage: error.message,
status: FormStatus.submissionFailure,
),
),
);
}
}

View File

@ -0,0 +1,65 @@
// Copyright (C) 2022 WYATT GROUP
// Please see the AUTHORS file for details.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
import 'dart:async';
import 'package:wyatt_architecture/wyatt_architecture.dart';
import 'package:wyatt_authentication_bloc/src/domain/entities/account.dart';
import 'package:wyatt_authentication_bloc/src/features/sign_in/cubit/sign_in_cubit.dart';
import 'package:wyatt_form_bloc/wyatt_form_bloc.dart';
import 'package:wyatt_type_utils/wyatt_type_utils.dart';
mixin SignInWithGoogle<Extra> on BaseSignInCubit<Extra> {
FutureOrResult<void> onSignInWithGoogle(
Result<Account, AppException> result,
WyattForm form,
);
FutureOr<void> signInWithGoogle() async {
if (state.status.isSubmissionInProgress) {
return;
}
final form = formRepository.accessForm(formName);
emit(SignInState(form: form, status: FormStatus.submissionInProgress));
final result = await authenticationRepository.signInWithGoogle();
// Here custom code
final callbackResponse = await onSignInWithGoogle(result, form);
if (callbackResponse.isErr) {
final error = callbackResponse.err!;
emit(
SignInState(
form: form,
errorMessage: error.message,
status: FormStatus.submissionFailure,
),
);
}
emit(
result.fold(
(value) =>
SignInState(form: form, status: FormStatus.submissionSuccess),
(error) => SignInState(
form: form,
errorMessage: error.message,
status: FormStatus.submissionFailure,
),
),
);
}
}

View File

@ -14,213 +14,45 @@
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
import 'dart:async';
import 'package:wyatt_architecture/wyatt_architecture.dart';
import 'package:wyatt_authentication_bloc/src/features/sign_in/cubit/mixin/sign_in_anonymously.dart';
import 'package:wyatt_authentication_bloc/src/features/sign_in/cubit/mixin/sign_in_with_email_password.dart';
import 'package:wyatt_authentication_bloc/src/features/sign_in/cubit/mixin/sign_in_with_google.dart';
import 'package:wyatt_authentication_bloc/wyatt_authentication_bloc.dart';
import 'package:wyatt_form_bloc/wyatt_form_bloc.dart';
import 'package:wyatt_type_utils/wyatt_type_utils.dart';
part 'base_sign_in_cubit.dart';
part 'sign_in_state.dart';
class SignInCubit<Extra> extends FormDataCubit<SignInState> {
SignInCubit({
required this.authenticationRepository,
}) : super(
SignInState(
form: authenticationRepository.formRepository
.accessForm(AuthFormName.signInForm),
),
);
final AuthenticationRepository<Extra> authenticationRepository;
FormRepository get formRepository => authenticationRepository.formRepository;
class SignInCubit<Extra> extends BaseSignInCubit<Extra>
with
SignInAnonymously<Extra>,
SignInWithEmailPassword<Extra>,
SignInWithGoogle<Extra> {
SignInCubit({required super.authenticationRepository});
@override
String get formName => AuthFormName.signInForm;
void emailChanged(String value) {
final emailValidatorType = formRepository
.accessForm(formName)
.validatorOf(AuthFormField.email)
.runtimeType;
assert(
emailValidatorType == Email,
'Use emailCustomChanged(...) with validator $emailValidatorType',
);
final Email email = Email.dirty(value);
dataChanged(AuthFormField.email, email);
}
void passwordChanged(String value) {
final passwordValidatorType = formRepository
.accessForm(formName)
.validatorOf(AuthFormField.password)
.runtimeType;
assert(
passwordValidatorType == Password,
'Use passwordCustomChanged(...) with validator $passwordValidatorType',
);
final Password password = Password.dirty(value);
dataChanged(AuthFormField.password, password);
}
/// Same as [emailChanged] but with a custom [Validator].
///
/// Sort of short hand for [dataChanged].
void emailCustomChanged<
Validator extends FormInputValidator<String?, ValidationError>>(
Validator validator,
) {
dataChanged(AuthFormField.email, validator);
}
/// Same as [passwordChanged] but with a custom [Validator].
///
/// Sort of short hand for [dataChanged].
void passwordCustomChanged<
Validator extends FormInputValidator<String?, ValidationError>>(
Validator validator,
) {
dataChanged(AuthFormField.password, validator);
}
FutureOrResult<void> onSignInAnonymously(
Result<Account, AppException> result,
WyattForm form,
) =>
const Ok(null);
@override
FutureOr<void> dataChanged<Value>(
String key,
FormInputValidator<Value, ValidationError> dirtyValue,
) {
final form = formRepository.accessForm(formName).clone();
try {
form.updateValidator(key, dirtyValue);
formRepository.updateForm(form);
} catch (e) {
rethrow;
}
emit(
state.copyWith(form: form, status: form.validate()),
);
}
FutureOrResult<void> onSignInWithEmailAndPassword(
Result<Account, AppException> result,
WyattForm form,
) =>
const Ok(null);
@override
FutureOr<void> reset() {
final form = state.form.reset();
formRepository.updateForm(form);
emit(
state.copyWith(form: form, status: form.validate()),
);
}
@override
FutureOr<void> submit() async {
throw UnimplementedError('`submit()` is not implemented for SignInCubit, '
'please use `signInWithEmailAndPassword()` or `signInAnonymously()`');
}
@override
FutureOr<void> update(
WyattForm form, {
SetOperation operation = SetOperation.replace,
}) {
final WyattForm current = formRepository.accessForm(formName).clone();
final WyattForm newForm = operation.operation.call(current, form);
formRepository.updateForm(newForm);
emit(
state.copyWith(
form: newForm,
status: newForm.validate(),
),
);
}
@override
FutureOr<void> validate() {
emit(
state.copyWith(
status: formRepository.accessForm(formName).validate(),
),
);
}
FutureOr<void> signInWithEmailAndPassword() async {
if (state.status.isSubmissionInProgress) {
return;
}
if (!state.status.isValidated) {
return;
}
emit(state.copyWith(status: FormStatus.submissionInProgress));
final form = formRepository.accessForm(formName);
final email = form.valueOf<String?>(AuthFormField.email);
final password = form.valueOf<String?>(AuthFormField.password);
if (email.isNullOrEmpty || password.isNullOrEmpty) {
emit(
state.copyWith(
errorMessage: 'An error occured while retrieving data from the form.',
status: FormStatus.submissionFailure,
),
);
}
final uid = await authenticationRepository.signInWithEmailAndPassword(
email: email!,
password: password!,
);
emit(
uid.fold(
(value) => state.copyWith(status: FormStatus.submissionSuccess),
(error) => state.copyWith(
errorMessage: error.message,
status: FormStatus.submissionFailure,
),
),
);
}
FutureOr<void> signInAnonymously() async {
if (state.status.isSubmissionInProgress) {
return;
}
emit(state.copyWith(status: FormStatus.submissionInProgress));
final uid = await authenticationRepository.signInAnonymously();
emit(
uid.fold(
(value) => state.copyWith(status: FormStatus.submissionSuccess),
(error) => state.copyWith(
errorMessage: error.message,
status: FormStatus.submissionFailure,
),
),
);
}
FutureOr<void> signInWithGoogle() async {
if (state.status.isSubmissionInProgress) {
return;
}
// TODO(wyatt): maybe emit new state (to not carry an old errorMessage)
emit(state.copyWith(status: FormStatus.submissionInProgress));
final uid = await authenticationRepository.signInWithGoogle();
emit(
uid.fold(
(value) => state.copyWith(status: FormStatus.submissionSuccess),
(error) => state.copyWith(
errorMessage: error.message,
status: FormStatus.submissionFailure,
),
),
);
}
FutureOrResult<void> onSignInWithGoogle(
Result<Account, AppException> result,
WyattForm form,
) =>
const Ok(null);
}

View File

@ -0,0 +1,101 @@
// Copyright (C) 2022 WYATT GROUP
// Please see the AUTHORS file for details.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
part of 'sign_up_cubit.dart';
abstract class BaseSignUpCubit<Extra> extends FormDataCubit<SignUpState> {
BaseSignUpCubit({
required this.authenticationRepository,
}) : super(
SignUpState(
form: authenticationRepository.formRepository
.accessForm(AuthFormName.signUpForm),
),
);
final AuthenticationRepository<Extra> authenticationRepository;
FormRepository get formRepository => authenticationRepository.formRepository;
@override
String get formName => AuthFormName.signUpForm;
@override
FutureOr<void> dataChanged<Value>(
String key,
FormInputValidator<Value, ValidationError> dirtyValue,
) {
final form = formRepository.accessForm(formName).clone();
try {
form.updateValidator(key, dirtyValue);
formRepository.updateForm(form);
} catch (e) {
rethrow;
}
emit(
SignUpState(form: form, status: form.validate()),
);
}
@override
FutureOr<void> reset() {
final form = state.form.reset();
formRepository.updateForm(form);
emit(
SignUpState(form: form, status: form.validate()),
);
}
@override
FutureOr<void> update(
WyattForm form, {
SetOperation operation = SetOperation.replace,
}) {
final WyattForm current = formRepository.accessForm(formName).clone();
final WyattForm newForm = operation.operation.call(current, form);
formRepository.updateForm(newForm);
emit(
SignUpState(
form: newForm,
status: newForm.validate(),
),
);
}
@override
FutureOr<void> validate() {
final WyattForm form = formRepository.accessForm(formName);
emit(
SignUpState(form: form, status: form.validate()),
);
}
@override
FutureOr<void> submit() async {
final WyattForm form = formRepository.accessForm(formName);
const error = '`submit()` is not implemented for BaseSignUpCubit, '
'please use `signUpWithEmailAndPassword()`.';
emit(
SignUpState(
form: form,
errorMessage: error,
status: FormStatus.submissionFailure,
),
);
throw UnimplementedError(error);
}
}

View File

@ -0,0 +1,137 @@
// Copyright (C) 2022 WYATT GROUP
// Please see the AUTHORS file for details.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
import 'dart:async';
import 'package:wyatt_architecture/wyatt_architecture.dart';
import 'package:wyatt_authentication_bloc/src/core/constants/form_field.dart';
import 'package:wyatt_authentication_bloc/src/domain/entities/account.dart';
import 'package:wyatt_authentication_bloc/src/features/sign_up/cubit/sign_up_cubit.dart';
import 'package:wyatt_form_bloc/wyatt_form_bloc.dart';
import 'package:wyatt_type_utils/wyatt_type_utils.dart';
mixin SignUpWithEmailPassword<Extra> on BaseSignUpCubit<Extra> {
FutureOrResult<void> onSignUpWithEmailAndPassword(
Result<Account, AppException> result,
WyattForm form,
);
void emailChanged(String value) {
final emailValidatorType = formRepository
.accessForm(formName)
.validatorOf(AuthFormField.email)
.runtimeType;
assert(
emailValidatorType == Email,
'Use emailCustomChanged(...) with validator $emailValidatorType',
);
final Email email = Email.dirty(value);
dataChanged(AuthFormField.email, email);
}
void passwordChanged(String value) {
final passwordValidatorType = formRepository
.accessForm(formName)
.validatorOf(AuthFormField.password)
.runtimeType;
assert(
passwordValidatorType == Password,
'Use passwordCustomChanged(...) with validator $passwordValidatorType',
);
final Password password = Password.dirty(value);
dataChanged(AuthFormField.password, password);
}
/// Same as [emailChanged] but with a custom [Validator].
///
/// Sort of short hand for [dataChanged].
void emailCustomChanged<
Validator extends FormInputValidator<String?, ValidationError>>(
Validator validator,
) {
dataChanged(AuthFormField.email, validator);
}
/// Same as [passwordChanged] but with a custom [Validator].
///
/// Sort of short hand for [dataChanged].
void passwordCustomChanged<
Validator extends FormInputValidator<String?, ValidationError>>(
Validator validator,
) {
dataChanged(AuthFormField.password, validator);
}
FutureOr<void> signUpWithEmailPassword() async {
if (!state.status.isValidated) {
return;
}
final form = formRepository.accessForm(formName);
emit(SignUpState(form: form, status: FormStatus.submissionInProgress));
final email = form.valueOf<String?>(AuthFormField.email);
final password = form.valueOf<String?>(AuthFormField.password);
if (email.isNullOrEmpty || password.isNullOrEmpty) {
emit(
SignUpState(
form: form,
errorMessage: 'An error occured while retrieving data from the form.',
status: FormStatus.submissionFailure,
),
);
}
final result = await authenticationRepository.signUp(
email: email!,
password: password!,
);
// Here custom code on sign up
final callbackResponse = await onSignUpWithEmailAndPassword(result, form);
if (callbackResponse.isErr) {
final error = callbackResponse.err!;
emit(
SignUpState(
form: form,
errorMessage: error.message,
status: FormStatus.submissionFailure,
),
);
}
await authenticationRepository.signInWithEmailAndPassword(
email: email,
password: password,
);
emit(
result.fold(
(value) => SignUpState(
form: form,
status: FormStatus.submissionSuccess,
),
(error) => SignUpState(
form: form,
errorMessage: error.message,
status: FormStatus.submissionFailure,
),
),
);
}
}

View File

@ -16,164 +16,26 @@
import 'dart:async';
import 'package:wyatt_architecture/wyatt_architecture.dart';
import 'package:wyatt_authentication_bloc/src/core/constants/form_field.dart';
import 'package:wyatt_authentication_bloc/src/core/constants/form_name.dart';
import 'package:wyatt_authentication_bloc/src/domain/entities/account.dart';
import 'package:wyatt_authentication_bloc/src/domain/repositories/authentication_repository.dart';
import 'package:wyatt_authentication_bloc/src/features/sign_up/cubit/mixin/sign_up_with_email_password.dart';
import 'package:wyatt_form_bloc/wyatt_form_bloc.dart';
import 'package:wyatt_type_utils/wyatt_type_utils.dart';
part 'base_sign_up_cubit.dart';
part 'sign_up_state.dart';
class SignUpCubit<Extra> extends FormDataCubit<SignUpState> {
SignUpCubit({
required this.authenticationRepository,
}) : super(
SignUpState(
form: authenticationRepository.formRepository
.accessForm(AuthFormName.signUpForm),
),
);
final AuthenticationRepository<Extra> authenticationRepository;
FormRepository get formRepository => authenticationRepository.formRepository;
class SignUpCubit<Extra> extends BaseSignUpCubit<Extra>
with SignUpWithEmailPassword<Extra> {
SignUpCubit({required super.authenticationRepository});
@override
String get formName => AuthFormName.signUpForm;
void emailChanged(String value) {
final emailValidatorType = formRepository
.accessForm(formName)
.validatorOf(AuthFormField.email)
.runtimeType;
assert(
emailValidatorType == Email,
'Use emailCustomChanged(...) with validator $emailValidatorType',
);
final Email email = Email.dirty(value);
dataChanged(AuthFormField.email, email);
}
void passwordChanged(String value) {
final passwordValidatorType = formRepository
.accessForm(formName)
.validatorOf(AuthFormField.password)
.runtimeType;
assert(
passwordValidatorType == Password,
'Use passwordCustomChanged(...) with validator $passwordValidatorType',
);
final Password password = Password.dirty(value);
dataChanged(AuthFormField.password, password);
}
/// Same as [emailChanged] but with a custom [Validator].
///
/// Sort of short hand for [dataChanged].
void emailCustomChanged<
Validator extends FormInputValidator<String?, ValidationError>>(
Validator validator,
) {
dataChanged(AuthFormField.email, validator);
}
/// Same as [passwordChanged] but with a custom [Validator].
///
/// Sort of short hand for [dataChanged].
void passwordCustomChanged<
Validator extends FormInputValidator<String?, ValidationError>>(
Validator validator,
) {
dataChanged(AuthFormField.password, validator);
}
@override
FutureOr<void> dataChanged<Value>(
String key,
FormInputValidator<Value, ValidationError> dirtyValue,
) {
final form = formRepository.accessForm(formName).clone();
try {
form.updateValidator(key, dirtyValue);
formRepository.updateForm(form);
} catch (e) {
rethrow;
}
emit(
state.copyWith(form: form, status: form.validate()),
);
}
@override
FutureOr<void> reset() {
final form = state.form.reset();
formRepository.updateForm(form);
emit(
state.copyWith(form: form, status: form.validate()),
);
}
@override
FutureOr<void> submit() async {
if (!state.status.isValidated) {
return;
}
emit(state.copyWith(status: FormStatus.submissionInProgress));
final form = formRepository.accessForm(formName);
final email = form.valueOf<String?>(AuthFormField.email);
final password = form.valueOf<String?>(AuthFormField.password);
if (email.isNullOrEmpty || password.isNullOrEmpty) {
emit(
state.copyWith(
errorMessage: 'An error occured while retrieving data from the form.',
status: FormStatus.submissionFailure,
),
);
}
final uid = await authenticationRepository.signUp(
email: email!,
password: password!,
);
emit(
uid.fold(
(value) => state.copyWith(status: FormStatus.submissionSuccess),
(error) => state.copyWith(
errorMessage: error.message,
status: FormStatus.submissionFailure,
),
),
);
}
@override
FutureOr<void> update(
WyattForm form, {
SetOperation operation = SetOperation.replace,
}) {
final WyattForm current = formRepository.accessForm(formName).clone();
final WyattForm newForm = operation.operation.call(current, form);
formRepository.updateForm(newForm);
emit(
state.copyWith(
form: newForm,
status: newForm.validate(),
),
);
}
@override
FutureOr<void> validate() {
emit(
state.copyWith(
status: formRepository.accessForm(formName).validate(),
),
);
}
FutureOrResult<void> onSignUpWithEmailAndPassword(
Result<Account, AppException> result,
WyattForm form,
) =>
const Ok(null);
}

View File

@ -17,7 +17,9 @@
/// An authentication library for BLoC.
library wyatt_authentication_bloc;
/// {@nodoc}
export 'package:firebase_auth/firebase_auth.dart';
/// {@nodoc}
export 'package:google_sign_in/google_sign_in.dart';
export 'src/src.dart';