refactor(authentication)!: use mixins, and remove use of onSignUpSuccess
This commit is contained in:
parent
adcd98f47b
commit
33cb4f6f06
@ -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,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
@ -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,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
@ -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,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
@ -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,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
@ -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,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
|
@ -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';
|
||||
|
Loading…
x
Reference in New Issue
Block a user