master #81
@ -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
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
|
||||||
import 'dart:async';
|
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_authentication_bloc/wyatt_authentication_bloc.dart';
|
||||||
import 'package:wyatt_form_bloc/wyatt_form_bloc.dart';
|
import 'package:wyatt_form_bloc/wyatt_form_bloc.dart';
|
||||||
import 'package:wyatt_type_utils/wyatt_type_utils.dart';
|
import 'package:wyatt_type_utils/wyatt_type_utils.dart';
|
||||||
|
|
||||||
|
part 'base_sign_in_cubit.dart';
|
||||||
part 'sign_in_state.dart';
|
part 'sign_in_state.dart';
|
||||||
|
|
||||||
class SignInCubit<Extra> extends FormDataCubit<SignInState> {
|
class SignInCubit<Extra> extends BaseSignInCubit<Extra>
|
||||||
SignInCubit({
|
with
|
||||||
required this.authenticationRepository,
|
SignInAnonymously<Extra>,
|
||||||
}) : super(
|
SignInWithEmailPassword<Extra>,
|
||||||
SignInState(
|
SignInWithGoogle<Extra> {
|
||||||
form: authenticationRepository.formRepository
|
SignInCubit({required super.authenticationRepository});
|
||||||
.accessForm(AuthFormName.signInForm),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
final AuthenticationRepository<Extra> authenticationRepository;
|
|
||||||
FormRepository get formRepository => authenticationRepository.formRepository;
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get formName => AuthFormName.signInForm;
|
FutureOrResult<void> onSignInAnonymously(
|
||||||
|
Result<Account, AppException> result,
|
||||||
void emailChanged(String value) {
|
WyattForm form,
|
||||||
final emailValidatorType = formRepository
|
) =>
|
||||||
.accessForm(formName)
|
const Ok(null);
|
||||||
.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
|
@override
|
||||||
FutureOr<void> dataChanged<Value>(
|
FutureOrResult<void> onSignInWithEmailAndPassword(
|
||||||
String key,
|
Result<Account, AppException> result,
|
||||||
FormInputValidator<Value, ValidationError> dirtyValue,
|
WyattForm form,
|
||||||
) {
|
) =>
|
||||||
final form = formRepository.accessForm(formName).clone();
|
const Ok(null);
|
||||||
|
|
||||||
try {
|
|
||||||
form.updateValidator(key, dirtyValue);
|
|
||||||
formRepository.updateForm(form);
|
|
||||||
} catch (e) {
|
|
||||||
rethrow;
|
|
||||||
}
|
|
||||||
|
|
||||||
emit(
|
|
||||||
state.copyWith(form: form, status: form.validate()),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
FutureOr<void> reset() {
|
FutureOrResult<void> onSignInWithGoogle(
|
||||||
final form = state.form.reset();
|
Result<Account, AppException> result,
|
||||||
formRepository.updateForm(form);
|
WyattForm form,
|
||||||
emit(
|
) =>
|
||||||
state.copyWith(form: form, status: form.validate()),
|
const Ok(null);
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@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,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -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 '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_field.dart';
|
||||||
import 'package:wyatt_authentication_bloc/src/core/constants/form_name.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/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_form_bloc/wyatt_form_bloc.dart';
|
||||||
import 'package:wyatt_type_utils/wyatt_type_utils.dart';
|
import 'package:wyatt_type_utils/wyatt_type_utils.dart';
|
||||||
|
|
||||||
|
part 'base_sign_up_cubit.dart';
|
||||||
part 'sign_up_state.dart';
|
part 'sign_up_state.dart';
|
||||||
|
|
||||||
class SignUpCubit<Extra> extends FormDataCubit<SignUpState> {
|
class SignUpCubit<Extra> extends BaseSignUpCubit<Extra>
|
||||||
SignUpCubit({
|
with SignUpWithEmailPassword<Extra> {
|
||||||
required this.authenticationRepository,
|
SignUpCubit({required super.authenticationRepository});
|
||||||
}) : super(
|
|
||||||
SignUpState(
|
|
||||||
form: authenticationRepository.formRepository
|
|
||||||
.accessForm(AuthFormName.signUpForm),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
final AuthenticationRepository<Extra> authenticationRepository;
|
|
||||||
FormRepository get formRepository => authenticationRepository.formRepository;
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get formName => AuthFormName.signUpForm;
|
FutureOrResult<void> onSignUpWithEmailAndPassword(
|
||||||
|
Result<Account, AppException> result,
|
||||||
void emailChanged(String value) {
|
WyattForm form,
|
||||||
final emailValidatorType = formRepository
|
) =>
|
||||||
.accessForm(formName)
|
const Ok(null);
|
||||||
.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(),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -17,7 +17,9 @@
|
|||||||
/// An authentication library for BLoC.
|
/// An authentication library for BLoC.
|
||||||
library wyatt_authentication_bloc;
|
library wyatt_authentication_bloc;
|
||||||
|
|
||||||
|
/// {@nodoc}
|
||||||
export 'package:firebase_auth/firebase_auth.dart';
|
export 'package:firebase_auth/firebase_auth.dart';
|
||||||
|
/// {@nodoc}
|
||||||
export 'package:google_sign_in/google_sign_in.dart';
|
export 'package:google_sign_in/google_sign_in.dart';
|
||||||
|
|
||||||
export 'src/src.dart';
|
export 'src/src.dart';
|
||||||
|
Loading…
x
Reference in New Issue
Block a user