Compare commits
4 Commits
0c920e8245
...
6802a56bfc
Author | SHA1 | Date | |
---|---|---|---|
6802a56bfc | |||
b2a9dac7c6 | |||
c0a91d6437 | |||
59bd3edb0d |
@ -25,7 +25,7 @@ abstract class GetItInitializer {
|
||||
..registerLazySingleton<AuthenticationRemoteDataSource>(
|
||||
() => AuthenticationFirebaseDataSourceImpl(),
|
||||
)
|
||||
..registerLazySingleton<AuthenticationLocalDataSource<int>>(
|
||||
..registerLazySingleton<AuthenticationCacheDataSource<int>>(
|
||||
() => AuthenticationCacheDataSourceImpl<int>(),
|
||||
);
|
||||
|
||||
|
@ -1,21 +0,0 @@
|
||||
// Author: Hugo Pointcheval
|
||||
// Email: git@pcl.ovh
|
||||
// -----
|
||||
// File: forms.dart
|
||||
// Created Date: 19/08/2022 12:00:31
|
||||
// Last Modified: 19/08/2022 16:35:52
|
||||
// -----
|
||||
// Copyright (c) 2022
|
||||
|
||||
import 'package:example_router/core/constants/form_field.dart';
|
||||
import 'package:wyatt_form_bloc/wyatt_form_bloc.dart';
|
||||
|
||||
class Forms {
|
||||
static FormData getNormalData() => const FormData([
|
||||
FormInput(
|
||||
AppFormField.confirmedPassword,
|
||||
ConfirmedPassword.pure(),
|
||||
metadata: FormInputMetadata<void>(export: false),
|
||||
),
|
||||
]);
|
||||
}
|
@ -3,33 +3,58 @@
|
||||
// -----
|
||||
// File: app.dart
|
||||
// Created Date: 19/08/2022 12:05:38
|
||||
// Last Modified: Wed Nov 09 2022
|
||||
// Last Modified: Thu Nov 10 2022
|
||||
// -----
|
||||
// Copyright (c) 2022
|
||||
|
||||
import 'dart:async';
|
||||
import 'dart:math';
|
||||
|
||||
import 'package:example_router/core/constants/form_field.dart';
|
||||
import 'package:example_router/core/dependency_injection/get_it.dart';
|
||||
import 'package:example_router/core/routes/router.dart';
|
||||
import 'package:example_router/core/utils/forms.dart';
|
||||
import 'package:example_router/presentation/features/home/home_page.dart';
|
||||
import 'package:example_router/presentation/features/welcome/welcome_page.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:go_router/go_router.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';
|
||||
import 'package:wyatt_architecture/wyatt_architecture.dart';
|
||||
|
||||
FutureResult<int?> onSignUpSuccess(
|
||||
Account? account,
|
||||
WyattForm form,
|
||||
) async {
|
||||
const id = -1;
|
||||
final confirmedPassword =
|
||||
form.valueOf<String?>(AppFormField.confirmedPassword);
|
||||
|
||||
debugPrint(
|
||||
'onSignUpSuccess: $account, generatedId: $id, extraFormData: $confirmedPassword');
|
||||
return const Ok<int, AppException>(id);
|
||||
}
|
||||
|
||||
FutureResult<int?> onAccountChanges(Account? account) async {
|
||||
final id = Random().nextInt(1000);
|
||||
debugPrint('onAccountChanges: $account, generatedId: $id');
|
||||
return Ok<int, AppException>(id);
|
||||
}
|
||||
|
||||
class App extends StatelessWidget {
|
||||
final AuthenticationRepository<int> authenticationRepository =
|
||||
AuthenticationRepositoryImpl(getIt<AuthenticationLocalDataSource<int>>(),
|
||||
getIt<AuthenticationRemoteDataSource>(), (account) async {
|
||||
debugPrint('onSignUpSuccess: $account');
|
||||
return const Ok(null);
|
||||
}, (account) async {
|
||||
debugPrint('onAccountChanges: $account');
|
||||
return const Ok(null);
|
||||
});
|
||||
AuthenticationRepositoryImpl(
|
||||
authenticationCacheDataSource: getIt<AuthenticationCacheDataSource<int>>(),
|
||||
authenticationRemoteDataSource: getIt<AuthenticationRemoteDataSource>(),
|
||||
onSignUpSuccess: onSignUpSuccess,
|
||||
onAuthChange: onAccountChanges,
|
||||
extraSignUpInputs: [
|
||||
FormInput(
|
||||
AppFormField.confirmedPassword,
|
||||
const ConfirmedPassword.pure(),
|
||||
metadata: const FormInputMetadata<void>(export: false),
|
||||
),
|
||||
],
|
||||
);
|
||||
|
||||
App({Key? key}) : super(key: key);
|
||||
|
||||
@ -65,12 +90,12 @@ class App extends StatelessWidget {
|
||||
if (isOnboarding) {
|
||||
return null;
|
||||
} else {
|
||||
return state.namedLocation(WelcomePage.pageName);
|
||||
return '/';
|
||||
}
|
||||
} else {
|
||||
debugPrint('Logged');
|
||||
if (isOnboarding) {
|
||||
return state.namedLocation(HomePage.pageName);
|
||||
return '/home';
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
@ -91,13 +116,12 @@ class App extends StatelessWidget {
|
||||
BlocProvider<AuthenticationCubit<int>>.value(
|
||||
value: authenticationCubit,
|
||||
),
|
||||
BlocProvider<SignUpCubit>(
|
||||
BlocProvider<SignUpCubit<int>>(
|
||||
create: (_) => SignUpCubit(
|
||||
authenticationRepository: authenticationRepository,
|
||||
formData: Forms.getNormalData(),
|
||||
),
|
||||
),
|
||||
BlocProvider<SignInCubit>(
|
||||
BlocProvider<SignInCubit<int>>(
|
||||
create: (_) => SignInCubit(
|
||||
authenticationRepository: authenticationRepository,
|
||||
),
|
||||
@ -106,9 +130,7 @@ class App extends StatelessWidget {
|
||||
child: MaterialApp.router(
|
||||
title: 'Demo Authentication',
|
||||
debugShowCheckedModeBanner: false,
|
||||
routerDelegate: router.routerDelegate,
|
||||
routeInformationParser: router.routeInformationParser,
|
||||
routeInformationProvider: router.routeInformationProvider,
|
||||
routerConfig: router,
|
||||
),
|
||||
),
|
||||
);
|
||||
|
@ -36,7 +36,7 @@ class HomePage extends StatelessWidget {
|
||||
children: [
|
||||
AuthenticationBuilder<int>(
|
||||
authenticated: (context, accountWrapper) =>
|
||||
Text('Logged as ${accountWrapper.account?.email}'),
|
||||
Text('Logged as ${accountWrapper.account?.email} | GeneratedId is ${accountWrapper.data}'),
|
||||
unauthenticated: (context) =>
|
||||
const Text('Not logged (unauthenticated)'),
|
||||
unknown: (context) => const Text('Not logged (unknown)'),
|
||||
|
@ -3,30 +3,31 @@
|
||||
// -----
|
||||
// File: sign_in_form.dart
|
||||
// Created Date: 19/08/2022 15:24:37
|
||||
// Last Modified: Wed Nov 09 2022
|
||||
// Last Modified: Thu Nov 10 2022
|
||||
// -----
|
||||
// Copyright (c) 2022
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:wyatt_authentication_bloc/wyatt_authentication_bloc.dart';
|
||||
import 'package:wyatt_form_bloc/wyatt_form_bloc.dart';
|
||||
|
||||
class _EmailInput extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return BlocBuilder<SignInCubit, SignInState>(
|
||||
buildWhen: (previous, current) => previous.email != current.email,
|
||||
builder: (context, state) {
|
||||
return InputBuilder<SignInCubit<int>>(
|
||||
field: AuthFormField.email,
|
||||
builder: ((context, cubit, state, field, inputValid) {
|
||||
return TextField(
|
||||
onChanged: (email) => context.read<SignInCubit>().emailChanged(email),
|
||||
onChanged: (email) => cubit.emailChanged(email),
|
||||
keyboardType: TextInputType.emailAddress,
|
||||
decoration: InputDecoration(
|
||||
labelText: 'Email',
|
||||
helperText: '',
|
||||
errorText: state.email.invalid ? 'Invalid email' : null,
|
||||
errorText: !inputValid ? 'Invalid email' : null,
|
||||
),
|
||||
);
|
||||
},
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -34,21 +35,19 @@ class _EmailInput extends StatelessWidget {
|
||||
class _PasswordInput extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return BlocBuilder<SignInCubit, SignInState>(
|
||||
buildWhen: (previous, current) => previous.password != current.password,
|
||||
builder: (context, state) {
|
||||
return InputBuilder<SignInCubit<int>>(
|
||||
field: AuthFormField.password,
|
||||
builder: ((context, cubit, state, field, inputValid) {
|
||||
return TextField(
|
||||
onChanged: (password) {
|
||||
context.read<SignInCubit>().passwordChanged(password);
|
||||
},
|
||||
onChanged: (pwd) => cubit.passwordChanged(pwd),
|
||||
obscureText: true,
|
||||
decoration: InputDecoration(
|
||||
labelText: 'Password',
|
||||
helperText: '',
|
||||
errorText: state.password.invalid ? 'Invalid password' : null,
|
||||
errorText: !inputValid ? 'Invalid password' : null,
|
||||
),
|
||||
);
|
||||
},
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -56,18 +55,15 @@ class _PasswordInput extends StatelessWidget {
|
||||
class _SignInButton extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return BlocBuilder<SignInCubit, SignInState>(
|
||||
builder: (context, state) {
|
||||
return state.status.isSubmissionInProgress
|
||||
return SubmitBuilder<SignInCubit<int>>(
|
||||
builder: ((context, cubit, status) {
|
||||
return status.isSubmissionInProgress
|
||||
? const CircularProgressIndicator()
|
||||
: ElevatedButton(
|
||||
onPressed: state.status.isValidated
|
||||
? () =>
|
||||
context.read<SignInCubit>().signInWithEmailAndPassword()
|
||||
: null,
|
||||
onPressed: status.isValidated ? () => cubit.submit() : null,
|
||||
child: const Text('Sign in'),
|
||||
);
|
||||
},
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -77,7 +73,7 @@ class SignInForm extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return BlocListener<SignInCubit, SignInState>(
|
||||
return BlocListener<SignInCubit<int>, SignInState>(
|
||||
listener: (context, state) {
|
||||
if (state.status.isSubmissionFailure) {
|
||||
ScaffoldMessenger.of(context)
|
||||
|
@ -3,12 +3,12 @@
|
||||
// -----
|
||||
// File: sign_up_form.dart
|
||||
// Created Date: 19/08/2022 14:41:08
|
||||
// Last Modified: Fri Aug 26 2022
|
||||
// Last Modified: Thu Nov 10 2022
|
||||
// -----
|
||||
// Copyright (c) 2022
|
||||
|
||||
import 'package:example_router/core/constants/form_field.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/material.dart' hide FormField;
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:wyatt_authentication_bloc/wyatt_authentication_bloc.dart';
|
||||
import 'package:wyatt_form_bloc/wyatt_form_bloc.dart';
|
||||
@ -16,19 +16,19 @@ import 'package:wyatt_form_bloc/wyatt_form_bloc.dart';
|
||||
class _EmailInput extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return BlocBuilder<SignUpCubit, SignUpState>(
|
||||
buildWhen: (previous, current) => previous.email != current.email,
|
||||
builder: (context, state) {
|
||||
return InputBuilder<SignUpCubit<int>>(
|
||||
field: AuthFormField.email,
|
||||
builder: ((context, cubit, state, field, inputValid) {
|
||||
return TextField(
|
||||
onChanged: (email) => context.read<SignUpCubit>().emailChanged(email),
|
||||
onChanged: (email) => cubit.emailChanged(email),
|
||||
keyboardType: TextInputType.emailAddress,
|
||||
decoration: InputDecoration(
|
||||
labelText: 'Email',
|
||||
helperText: '',
|
||||
errorText: state.email.invalid ? 'Invalid email' : null,
|
||||
errorText: !inputValid ? 'Invalid email' : null,
|
||||
),
|
||||
);
|
||||
},
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -36,33 +36,27 @@ class _EmailInput extends StatelessWidget {
|
||||
class _PasswordInput extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return BlocBuilder<SignUpCubit, SignUpState>(
|
||||
buildWhen: (previous, current) => previous.password != current.password,
|
||||
builder: (context, state) {
|
||||
return InputBuilder<SignUpCubit<int>>(
|
||||
field: AuthFormField.password,
|
||||
builder: ((context, cubit, state, field, inputValid) {
|
||||
return TextField(
|
||||
onChanged: (password) {
|
||||
context.read<SignUpCubit>().passwordChanged(password);
|
||||
context.read<SignUpCubit>().dataChanged(
|
||||
onChanged: (pwd) {
|
||||
cubit.passwordChanged(pwd);
|
||||
cubit.dataChanged(
|
||||
AppFormField.confirmedPassword,
|
||||
ConfirmedPassword.dirty(
|
||||
password: password,
|
||||
value: context
|
||||
.read<SignUpCubit>()
|
||||
.state
|
||||
.data
|
||||
.valueOf<String>(
|
||||
AppFormField.confirmedPassword),
|
||||
),
|
||||
);
|
||||
password: pwd,
|
||||
value: state.form
|
||||
.valueOf<String?>(AppFormField.confirmedPassword)));
|
||||
},
|
||||
obscureText: true,
|
||||
decoration: InputDecoration(
|
||||
labelText: 'Password',
|
||||
helperText: '',
|
||||
errorText: state.password.invalid ? 'Invalid password' : null,
|
||||
errorText: !inputValid ? 'Invalid password' : null,
|
||||
),
|
||||
);
|
||||
},
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -70,28 +64,27 @@ class _PasswordInput extends StatelessWidget {
|
||||
class _ConfirmPasswordInput extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return BlocBuilder<SignUpCubit, SignUpState>(
|
||||
builder: (context, state) {
|
||||
return InputBuilder<SignUpCubit<int>>(
|
||||
field: AppFormField.confirmedPassword,
|
||||
builder: ((context, cubit, state, field, inputValid) {
|
||||
return TextField(
|
||||
onChanged: (confirmPassword) => context
|
||||
.read<SignUpCubit>()
|
||||
.dataChanged(
|
||||
AppFormField.confirmedPassword,
|
||||
onChanged: (pwd) {
|
||||
cubit.dataChanged(
|
||||
field,
|
||||
ConfirmedPassword.dirty(
|
||||
password: context.read<SignUpCubit>().state.password.value,
|
||||
value: confirmPassword,
|
||||
),
|
||||
),
|
||||
password:
|
||||
state.form.valueOf<String?>(AuthFormField.password) ?? '',
|
||||
value: pwd),
|
||||
);
|
||||
},
|
||||
obscureText: true,
|
||||
decoration: InputDecoration(
|
||||
labelText: 'Confirm password',
|
||||
helperText: '',
|
||||
errorText: state.data.isNotValid(AppFormField.confirmedPassword)
|
||||
? 'Passwords do not match'
|
||||
: null,
|
||||
errorText: !inputValid ? 'Passwords do not match' : null,
|
||||
),
|
||||
);
|
||||
},
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -99,17 +92,15 @@ class _ConfirmPasswordInput extends StatelessWidget {
|
||||
class _SignUpButton extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return BlocBuilder<SignUpCubit, SignUpState>(
|
||||
builder: (context, state) {
|
||||
return state.status.isSubmissionInProgress
|
||||
return SubmitBuilder<SignUpCubit<int>>(
|
||||
builder: ((context, cubit, status) {
|
||||
return status.isSubmissionInProgress
|
||||
? const CircularProgressIndicator()
|
||||
: ElevatedButton(
|
||||
onPressed: state.status.isValidated
|
||||
? () => context.read<SignUpCubit>().signUpFormSubmitted()
|
||||
: null,
|
||||
onPressed: status.isValidated ? () => cubit.submit() : null,
|
||||
child: const Text('Sign up'),
|
||||
);
|
||||
},
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -119,11 +110,9 @@ class SignUpForm extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return BlocListener<SignUpCubit, SignUpState>(
|
||||
return BlocListener<SignUpCubit<int>, SignUpState>(
|
||||
listener: (context, state) {
|
||||
if (state.status.isSubmissionSuccess) {
|
||||
Navigator.of(context).pop();
|
||||
} else if (state.status.isSubmissionFailure) {
|
||||
if (state.status.isSubmissionFailure) {
|
||||
ScaffoldMessenger.of(context)
|
||||
..hideCurrentSnackBar()
|
||||
..showSnackBar(
|
||||
|
@ -42,6 +42,12 @@ dependencies:
|
||||
ref: wyatt_form_bloc-v0.0.6
|
||||
path: packages/wyatt_form_bloc
|
||||
|
||||
wyatt_type_utils:
|
||||
git:
|
||||
url: https://git.wyatt-studio.fr/Wyatt-FOSS/wyatt-packages
|
||||
ref: wyatt_type_utils-v0.0.3+1
|
||||
path: packages/wyatt_type_utils
|
||||
|
||||
# The following adds the Cupertino Icons font to your application.
|
||||
# Use with the CupertinoIcons class for iOS style icons.
|
||||
cupertino_icons: ^1.0.5
|
||||
|
@ -14,6 +14,7 @@
|
||||
// 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 'package:wyatt_architecture/wyatt_architecture.dart';
|
||||
|
||||
abstract class AuthenticationBiometricsDataSource extends BaseLocalDataSource {}
|
||||
abstract class AuthFormField {
|
||||
static const email = 'wyattEmailField';
|
||||
static const password = 'wyattPasswordField';
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
// 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/>.
|
||||
|
||||
abstract class AuthFormName {
|
||||
static const String signUpForm = 'wyattSignUpForm';
|
||||
static const String signInForm = 'wyattSignInForm';
|
||||
}
|
@ -14,6 +14,8 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
export 'constants/form_field.dart';
|
||||
export 'constants/form_name.dart';
|
||||
export 'enums/enums.dart';
|
||||
export 'exceptions/exceptions.dart';
|
||||
export 'utils/utils.dart';
|
||||
|
@ -15,29 +15,28 @@
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
import 'package:wyatt_architecture/wyatt_architecture.dart';
|
||||
import 'package:wyatt_authentication_bloc/src/domain/data_sources/local/authentication_local_data_source.dart';
|
||||
import 'package:wyatt_authentication_bloc/src/domain/entities/account.dart';
|
||||
import 'package:wyatt_authentication_bloc/wyatt_authentication_bloc.dart';
|
||||
import 'package:wyatt_type_utils/wyatt_type_utils.dart';
|
||||
|
||||
class AuthenticationCacheDataSourceImpl<T extends Object>
|
||||
extends AuthenticationLocalDataSource<T> {
|
||||
extends AuthenticationCacheDataSource<T> {
|
||||
Account? _account;
|
||||
T? _data;
|
||||
|
||||
AuthenticationCacheDataSourceImpl();
|
||||
|
||||
@override
|
||||
void storeAccount(Account? account) {
|
||||
Future<void> storeAccount(Account? account) async {
|
||||
_account = account;
|
||||
}
|
||||
|
||||
@override
|
||||
void storeData(T? data) {
|
||||
Future<void> storeData(T? data) async {
|
||||
_data = data;
|
||||
}
|
||||
|
||||
@override
|
||||
Account loadAccount() {
|
||||
Future<Account> loadAccount() async {
|
||||
if (_account.isNotNull) {
|
||||
return _account!;
|
||||
}
|
||||
@ -45,7 +44,7 @@ class AuthenticationCacheDataSourceImpl<T extends Object>
|
||||
}
|
||||
|
||||
@override
|
||||
T loadData() {
|
||||
Future<T> loadData() async {
|
||||
if (_data.isNotNull) {
|
||||
return _data!;
|
||||
}
|
||||
@ -53,8 +52,16 @@ class AuthenticationCacheDataSourceImpl<T extends Object>
|
||||
}
|
||||
|
||||
@override
|
||||
void destroy() {
|
||||
Future<void> destroy() async {
|
||||
_data = null;
|
||||
_account = null;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<AccountWrapper<T>> load() async {
|
||||
if (_account.isNull) {
|
||||
throw ClientException('Cached account is invalid');
|
||||
}
|
||||
return AccountWrapperModel(_account, _data);
|
||||
}
|
||||
}
|
||||
|
@ -15,28 +15,75 @@
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
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/data/models/account_wrapper_model.dart';
|
||||
import 'package:wyatt_authentication_bloc/src/domain/data_sources/local/authentication_local_data_source.dart';
|
||||
import 'package:wyatt_authentication_bloc/src/domain/data_sources/local/authentication_cache_data_source.dart';
|
||||
import 'package:wyatt_authentication_bloc/src/domain/data_sources/remote/authentication_remote_data_source.dart';
|
||||
import 'package:wyatt_authentication_bloc/src/domain/entities/account.dart';
|
||||
import 'package:wyatt_authentication_bloc/src/domain/entities/account_wrapper.dart';
|
||||
import 'package:wyatt_authentication_bloc/src/domain/repositories/authentication_repository.dart';
|
||||
import 'package:wyatt_form_bloc/wyatt_form_bloc.dart';
|
||||
import 'package:wyatt_type_utils/wyatt_type_utils.dart';
|
||||
|
||||
typedef OnSignUpSuccess<T> = FutureResult<T?> Function(
|
||||
Account? account,
|
||||
WyattForm form,
|
||||
);
|
||||
|
||||
typedef OnAuthChange<T> = FutureResult<T?> Function(Account? account);
|
||||
|
||||
class AuthenticationRepositoryImpl<T extends Object>
|
||||
extends AuthenticationRepository<T> {
|
||||
final AuthenticationLocalDataSource<T> _authenticationLocalDataSource;
|
||||
final AuthenticationCacheDataSource<T> _authenticationLocalDataSource;
|
||||
final AuthenticationRemoteDataSource _authenticationRemoteDataSource;
|
||||
|
||||
final FutureResult<T?> Function(Account? account)? _onSignUpSuccess;
|
||||
final FutureResult<T?> Function(Account? account)? _onAccountChanges;
|
||||
late FormRepository _formRepository;
|
||||
|
||||
AuthenticationRepositoryImpl(
|
||||
this._authenticationLocalDataSource,
|
||||
this._authenticationRemoteDataSource,
|
||||
this._onSignUpSuccess,
|
||||
this._onAccountChanges,
|
||||
final OnSignUpSuccess<T>? _onSignUpSuccess;
|
||||
|
||||
final OnAuthChange<T>? _onAccountChanges;
|
||||
|
||||
AuthenticationRepositoryImpl({
|
||||
required AuthenticationCacheDataSource<T> authenticationCacheDataSource,
|
||||
required AuthenticationRemoteDataSource authenticationRemoteDataSource,
|
||||
FormRepository? formRepository,
|
||||
// ignore: strict_raw_type
|
||||
List<FormInput>? extraSignUpInputs,
|
||||
OnSignUpSuccess<T>? onSignUpSuccess,
|
||||
OnAuthChange<T>? onAuthChange,
|
||||
}) : _authenticationLocalDataSource = authenticationCacheDataSource,
|
||||
_authenticationRemoteDataSource = authenticationRemoteDataSource,
|
||||
_onSignUpSuccess = onSignUpSuccess,
|
||||
_onAccountChanges = onAuthChange {
|
||||
_formRepository = formRepository ?? FormRepositoryImpl();
|
||||
if (formRepository != null) {
|
||||
return;
|
||||
}
|
||||
_formRepository
|
||||
..registerForm(
|
||||
WyattFormImpl(
|
||||
[
|
||||
FormInput(AuthFormField.email, const Email.pure()),
|
||||
FormInput(AuthFormField.password, const Password.pure())
|
||||
],
|
||||
name: AuthFormName.signInForm,
|
||||
),
|
||||
)
|
||||
..registerForm(
|
||||
WyattFormImpl(
|
||||
[
|
||||
FormInput(AuthFormField.email, const Email.pure()),
|
||||
FormInput(AuthFormField.password, const Password.pure()),
|
||||
...extraSignUpInputs ?? []
|
||||
],
|
||||
name: AuthFormName.signUpForm,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
FormRepository get formRepository => _formRepository;
|
||||
|
||||
@override
|
||||
FutureResult<Account> signInWithEmailAndPassword({
|
||||
@ -50,7 +97,7 @@ class AuthenticationRepositoryImpl<T extends Object>
|
||||
email: email,
|
||||
password: password,
|
||||
);
|
||||
_authenticationLocalDataSource.storeAccount(account);
|
||||
await _authenticationLocalDataSource.storeAccount(account);
|
||||
return account;
|
||||
},
|
||||
(error) => error,
|
||||
@ -61,7 +108,7 @@ class AuthenticationRepositoryImpl<T extends Object>
|
||||
Result.tryCatchAsync<void, AppException, AppException>(
|
||||
() async {
|
||||
await _authenticationRemoteDataSource.signOut();
|
||||
_authenticationLocalDataSource.destroy();
|
||||
await _authenticationLocalDataSource.destroy();
|
||||
},
|
||||
(error) => error,
|
||||
);
|
||||
@ -77,10 +124,13 @@ class AuthenticationRepositoryImpl<T extends Object>
|
||||
email: email,
|
||||
password: password,
|
||||
);
|
||||
_authenticationLocalDataSource.storeAccount(account);
|
||||
await _authenticationLocalDataSource.storeAccount(account);
|
||||
if (_onSignUpSuccess.isNotNull) {
|
||||
final dataResult = await _onSignUpSuccess!.call(account);
|
||||
dataResult.fold(
|
||||
final dataResult = await _onSignUpSuccess!.call(
|
||||
account,
|
||||
_formRepository.accessForm(AuthFormName.signUpForm).clone(),
|
||||
);
|
||||
await dataResult.foldAsync(
|
||||
_authenticationLocalDataSource.storeData,
|
||||
(error) => throw error,
|
||||
);
|
||||
@ -91,46 +141,51 @@ class AuthenticationRepositoryImpl<T extends Object>
|
||||
);
|
||||
|
||||
@override
|
||||
Result<void, AppException> destroyCache() =>
|
||||
Result.tryCatch<void, AppException, AppException>(
|
||||
FutureResult<void> destroyCache() =>
|
||||
Result.tryCatchAsync<void, AppException, AppException>(
|
||||
_authenticationLocalDataSource.destroy,
|
||||
(error) => error,
|
||||
);
|
||||
|
||||
@override
|
||||
Result<Account, AppException> getAccount() =>
|
||||
Result.tryCatch<Account, AppException, AppException>(
|
||||
FutureResult<AccountWrapper<T>> getCache() =>
|
||||
Result.tryCatchAsync<AccountWrapper<T>, AppException, AppException>(
|
||||
_authenticationLocalDataSource.load,
|
||||
(error) => error,
|
||||
);
|
||||
|
||||
@override
|
||||
FutureResult<Account> getAccount() =>
|
||||
Result.tryCatchAsync<Account, AppException, AppException>(
|
||||
_authenticationLocalDataSource.loadAccount,
|
||||
(error) => error,
|
||||
);
|
||||
|
||||
@override
|
||||
Result<Account, AppException> setAccount(
|
||||
FutureResult<void> setAccount(
|
||||
Account account,
|
||||
) =>
|
||||
Result.tryCatch<Account, AppException, AppException>(
|
||||
() {
|
||||
_authenticationLocalDataSource.storeAccount(account);
|
||||
return account;
|
||||
Result.tryCatchAsync<void, AppException, AppException>(
|
||||
() async {
|
||||
await _authenticationLocalDataSource.storeAccount(account);
|
||||
},
|
||||
(error) => error,
|
||||
);
|
||||
|
||||
@override
|
||||
Result<T, AppException> getData() =>
|
||||
Result.tryCatch<T, AppException, AppException>(
|
||||
FutureResult<T> getData() =>
|
||||
Result.tryCatchAsync<T, AppException, AppException>(
|
||||
_authenticationLocalDataSource.loadData,
|
||||
(error) => error,
|
||||
);
|
||||
|
||||
@override
|
||||
Result<T, AppException> setData(
|
||||
T data,
|
||||
FutureResult<void> setData(
|
||||
T? data,
|
||||
) =>
|
||||
Result.tryCatch<T, AppException, AppException>(
|
||||
() {
|
||||
_authenticationLocalDataSource.storeData(data);
|
||||
return data;
|
||||
Result.tryCatchAsync<void, AppException, AppException>(
|
||||
() async {
|
||||
await _authenticationLocalDataSource.storeData(data);
|
||||
},
|
||||
(error) => error,
|
||||
);
|
||||
|
@ -14,6 +14,5 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
export 'local/authentication_biometrics_data_source.dart';
|
||||
export 'local/authentication_local_data_source.dart';
|
||||
export 'local/authentication_cache_data_source.dart';
|
||||
export 'remote/authentication_remote_data_source.dart';
|
||||
|
@ -16,12 +16,14 @@
|
||||
|
||||
import 'package:wyatt_architecture/wyatt_architecture.dart';
|
||||
import 'package:wyatt_authentication_bloc/src/domain/entities/account.dart';
|
||||
import 'package:wyatt_authentication_bloc/src/domain/entities/account_wrapper.dart';
|
||||
|
||||
abstract class AuthenticationLocalDataSource<T extends Object>
|
||||
abstract class AuthenticationCacheDataSource<T extends Object>
|
||||
extends BaseLocalDataSource {
|
||||
void storeAccount(Account? account);
|
||||
void storeData(T? data);
|
||||
Account loadAccount();
|
||||
T loadData();
|
||||
void destroy();
|
||||
Future<void> storeAccount(Account? account);
|
||||
Future<void> storeData(T? data);
|
||||
Future<Account> loadAccount();
|
||||
Future<T> loadData();
|
||||
Future<AccountWrapper<T>> load();
|
||||
Future<void> destroy();
|
||||
}
|
@ -17,13 +17,14 @@
|
||||
import 'package:wyatt_architecture/wyatt_architecture.dart';
|
||||
import 'package:wyatt_authentication_bloc/src/domain/entities/account.dart';
|
||||
import 'package:wyatt_authentication_bloc/src/domain/entities/account_wrapper.dart';
|
||||
import 'package:wyatt_type_utils/wyatt_type_utils.dart';
|
||||
import 'package:wyatt_form_bloc/wyatt_form_bloc.dart';
|
||||
|
||||
abstract class AuthenticationRepository<T> extends BaseRepository {
|
||||
FormRepository get formRepository;
|
||||
|
||||
FutureResult<Account> signUp({
|
||||
required String email,
|
||||
required String password,
|
||||
|
||||
});
|
||||
|
||||
FutureResult<Account> signInWithEmailAndPassword({
|
||||
@ -37,11 +38,12 @@ abstract class AuthenticationRepository<T> extends BaseRepository {
|
||||
|
||||
FutureResult<String> getIdentityToken();
|
||||
|
||||
Result<Account, AppException> getAccount();
|
||||
Result<Account, AppException> setAccount(Account account);
|
||||
FutureResult<Account> getAccount();
|
||||
FutureResult<void> setAccount(Account account);
|
||||
|
||||
Result<T, AppException> getData();
|
||||
Result<T, AppException> setData(T data);
|
||||
FutureResult<T> getData();
|
||||
FutureResult<void> setData(T? data);
|
||||
|
||||
Result<void, AppException> destroyCache();
|
||||
FutureResult<AccountWrapper<T>> getCache();
|
||||
FutureResult<void> destroyCache();
|
||||
}
|
||||
|
@ -14,55 +14,96 @@
|
||||
// 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 'package:equatable/equatable.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'dart:async';
|
||||
|
||||
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/repositories/authentication_repository.dart';
|
||||
import 'package:wyatt_form_bloc/wyatt_form_bloc.dart';
|
||||
import 'package:wyatt_type_utils/wyatt_type_utils.dart';
|
||||
|
||||
part 'sign_in_state.dart';
|
||||
|
||||
class SignInCubit<Extra> extends Cubit<SignInState> {
|
||||
class SignInCubit<Extra> extends FormDataCubit<SignInState> {
|
||||
final AuthenticationRepository<Extra> _authenticationRepository;
|
||||
|
||||
final FormValidator _validationStrategy;
|
||||
FormRepository get _formRepository =>
|
||||
_authenticationRepository.formRepository;
|
||||
|
||||
SignInCubit({
|
||||
required AuthenticationRepository<Extra> authenticationRepository,
|
||||
FormValidator validationStrategy = const EveryInputValidator(),
|
||||
}) : _authenticationRepository = authenticationRepository,
|
||||
_validationStrategy = validationStrategy,
|
||||
super(const SignInState());
|
||||
super(
|
||||
SignInState(
|
||||
form: authenticationRepository.formRepository
|
||||
.accessForm(AuthFormName.signInForm),
|
||||
),
|
||||
);
|
||||
|
||||
@override
|
||||
String get formName => AuthFormName.signInForm;
|
||||
|
||||
void emailChanged(String value) {
|
||||
final Email email = Email.dirty(value);
|
||||
emit(
|
||||
state.copyWith(
|
||||
email: email,
|
||||
status: _validationStrategy.rawValidate([email, state.password]),
|
||||
),
|
||||
);
|
||||
dataChanged(AuthFormField.email, email);
|
||||
}
|
||||
|
||||
void passwordChanged(String value) {
|
||||
final Password password = Password.dirty(value);
|
||||
dataChanged(AuthFormField.password, password);
|
||||
}
|
||||
|
||||
@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(
|
||||
password: password,
|
||||
status: _validationStrategy.rawValidate([state.email, password]),
|
||||
),
|
||||
state.copyWith(form: form, status: form.validate()),
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> signInWithEmailAndPassword() async {
|
||||
@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.signInWithEmailAndPassword(
|
||||
email: state.email.value,
|
||||
password: state.password.value,
|
||||
email: email!,
|
||||
password: password!,
|
||||
);
|
||||
|
||||
emit(
|
||||
@ -75,4 +116,30 @@ class SignInCubit<Extra> extends Cubit<SignInState> {
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@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(),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -16,28 +16,23 @@
|
||||
|
||||
part of 'sign_in_cubit.dart';
|
||||
|
||||
class SignInState extends Equatable {
|
||||
final Email email;
|
||||
final Password password;
|
||||
final FormStatus status;
|
||||
final String? errorMessage;
|
||||
class SignInState extends FormDataState {
|
||||
Email get email => form.validatorOf(AuthFormField.email);
|
||||
Password get password => form.validatorOf(AuthFormField.password);
|
||||
|
||||
const SignInState({
|
||||
this.email = const Email.pure(),
|
||||
this.password = const Password.pure(),
|
||||
this.status = FormStatus.pure,
|
||||
this.errorMessage,
|
||||
required super.form,
|
||||
super.status = FormStatus.pure,
|
||||
super.errorMessage,
|
||||
});
|
||||
|
||||
SignInState copyWith({
|
||||
Email? email,
|
||||
Password? password,
|
||||
WyattForm? form,
|
||||
FormStatus? status,
|
||||
String? errorMessage,
|
||||
}) =>
|
||||
SignInState(
|
||||
email: email ?? this.email,
|
||||
password: password ?? this.password,
|
||||
form: form ?? this.form,
|
||||
status: status ?? this.status,
|
||||
errorMessage: errorMessage ?? this.errorMessage,
|
||||
);
|
||||
@ -46,10 +41,6 @@ class SignInState extends Equatable {
|
||||
List<Object> get props => [email, password, status];
|
||||
|
||||
@override
|
||||
String toString() => '''
|
||||
email: $email,
|
||||
password: $password,
|
||||
status: $status,
|
||||
errorMessage: $errorMessage,
|
||||
''';
|
||||
String toString() => 'SignInState(status: ${status.name} '
|
||||
'${(errorMessage != null) ? " [$errorMessage]" : ""}, $form)';
|
||||
}
|
||||
|
@ -16,132 +16,94 @@
|
||||
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:equatable/equatable.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.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/repositories/authentication_repository.dart';
|
||||
import 'package:wyatt_form_bloc/wyatt_form_bloc.dart';
|
||||
import 'package:wyatt_type_utils/wyatt_type_utils.dart';
|
||||
|
||||
part 'sign_up_state.dart';
|
||||
|
||||
class SignUpCubit<Extra> extends Cubit<SignUpState> {
|
||||
class SignUpCubit<Extra> extends FormDataCubit<SignUpState> {
|
||||
final AuthenticationRepository<Extra> _authenticationRepository;
|
||||
|
||||
final FormValidator _validationStrategy;
|
||||
FormRepository get _formRepository =>
|
||||
_authenticationRepository.formRepository;
|
||||
|
||||
SignUpCubit({
|
||||
required AuthenticationRepository<Extra> authenticationRepository,
|
||||
required FormData formData,
|
||||
FormValidator validationStrategy = const EveryInputValidator(),
|
||||
}) : _authenticationRepository = authenticationRepository,
|
||||
_validationStrategy = validationStrategy,
|
||||
super(SignUpState(data: formData));
|
||||
super(
|
||||
SignUpState(
|
||||
form: authenticationRepository.formRepository
|
||||
.accessForm(AuthFormName.signUpForm),
|
||||
),
|
||||
);
|
||||
|
||||
@override
|
||||
String get formName => AuthFormName.signUpForm;
|
||||
|
||||
void emailChanged(String value) {
|
||||
final Email email = Email.dirty(value);
|
||||
|
||||
final List<FormInputValidator<dynamic, ValidationError>> toValidate = [
|
||||
email,
|
||||
state.password,
|
||||
...state.data.validators<dynamic, ValidationError>(),
|
||||
];
|
||||
|
||||
emit(
|
||||
state.copyWith(
|
||||
email: email,
|
||||
status: _validationStrategy.rawValidate(toValidate),
|
||||
),
|
||||
);
|
||||
dataChanged(AuthFormField.email, email);
|
||||
}
|
||||
|
||||
void passwordChanged(String value) {
|
||||
final Password password = Password.dirty(value);
|
||||
|
||||
final List<FormInputValidator<dynamic, ValidationError>> toValidate = [
|
||||
state.email,
|
||||
password,
|
||||
...state.data.validators<dynamic, ValidationError>(),
|
||||
];
|
||||
|
||||
emit(
|
||||
state.copyWith(
|
||||
password: password,
|
||||
status: _validationStrategy.rawValidate(toValidate),
|
||||
),
|
||||
);
|
||||
dataChanged(AuthFormField.password, password);
|
||||
}
|
||||
|
||||
// Take from wyatt_form_bloc/wyatt_form_bloc.dart
|
||||
void dataChanged<T>(
|
||||
String field,
|
||||
FormInputValidator<T, ValidationError> dirtyValue,
|
||||
@override
|
||||
FutureOr<void> dataChanged<Value>(
|
||||
String key,
|
||||
FormInputValidator<Value, ValidationError> dirtyValue,
|
||||
) {
|
||||
final form = state.data.clone();
|
||||
final form = _formRepository.accessForm(formName).clone();
|
||||
|
||||
if (form.contains(field)) {
|
||||
form.updateValidator(field, dirtyValue);
|
||||
} else {
|
||||
throw Exception('Form field $field not found');
|
||||
try {
|
||||
form.updateValidator(key, dirtyValue);
|
||||
_formRepository.updateForm(form);
|
||||
} catch (e) {
|
||||
rethrow;
|
||||
}
|
||||
|
||||
emit(
|
||||
state.copyWith(
|
||||
data: form,
|
||||
status: _validationStrategy.rawValidate(
|
||||
[
|
||||
state.email,
|
||||
state.password,
|
||||
...state.data.validators<dynamic, ValidationError>(),
|
||||
],
|
||||
),
|
||||
),
|
||||
state.copyWith(form: form, status: form.validate()),
|
||||
);
|
||||
}
|
||||
|
||||
// Take from wyatt_form_bloc/wyatt_form_bloc.dart
|
||||
void updateFormData(
|
||||
FormData data, {
|
||||
SetOperation operation = SetOperation.replace,
|
||||
}) {
|
||||
FormData form = data;
|
||||
|
||||
switch (operation) {
|
||||
case SetOperation.replace:
|
||||
form = data;
|
||||
break;
|
||||
case SetOperation.difference:
|
||||
form = state.data.difference(data);
|
||||
break;
|
||||
case SetOperation.intersection:
|
||||
form = state.data.intersection(data);
|
||||
break;
|
||||
case SetOperation.union:
|
||||
form = state.data.union(data);
|
||||
break;
|
||||
}
|
||||
|
||||
@override
|
||||
FutureOr<void> reset() {
|
||||
final form = state.form.reset();
|
||||
_formRepository.updateForm(form);
|
||||
emit(
|
||||
state.copyWith(
|
||||
data: form,
|
||||
status: _validationStrategy.rawValidate(
|
||||
[
|
||||
state.email,
|
||||
state.password,
|
||||
...state.data.validators<dynamic, ValidationError>(),
|
||||
],
|
||||
),
|
||||
),
|
||||
state.copyWith(form: form, status: form.validate()),
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> signUpFormSubmitted() async {
|
||||
@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: state.email.value,
|
||||
password: state.password.value,
|
||||
email: email!,
|
||||
password: password!,
|
||||
);
|
||||
|
||||
emit(
|
||||
@ -154,4 +116,30 @@ class SignUpCubit<Extra> extends Cubit<SignUpState> {
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@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(),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -16,40 +16,32 @@
|
||||
|
||||
part of 'sign_up_cubit.dart';
|
||||
|
||||
class SignUpState extends Equatable {
|
||||
final Email email;
|
||||
final Password password;
|
||||
final FormStatus status;
|
||||
final FormData data;
|
||||
final String? errorMessage;
|
||||
class SignUpState extends FormDataState {
|
||||
Email get email => form.validatorOf(AuthFormField.email);
|
||||
Password get password => form.validatorOf(AuthFormField.password);
|
||||
|
||||
const SignUpState({
|
||||
required this.data,
|
||||
this.email = const Email.pure(),
|
||||
this.password = const Password.pure(),
|
||||
this.status = FormStatus.pure,
|
||||
this.errorMessage,
|
||||
required super.form,
|
||||
super.status = FormStatus.pure,
|
||||
super.errorMessage,
|
||||
});
|
||||
|
||||
SignUpState copyWith({
|
||||
Email? email,
|
||||
Password? password,
|
||||
WyattForm? form,
|
||||
FormStatus? status,
|
||||
FormData? data,
|
||||
String? errorMessage,
|
||||
}) =>
|
||||
SignUpState(
|
||||
email: email ?? this.email,
|
||||
password: password ?? this.password,
|
||||
form: form ?? this.form,
|
||||
status: status ?? this.status,
|
||||
data: data ?? this.data,
|
||||
errorMessage: errorMessage ?? this.errorMessage,
|
||||
);
|
||||
|
||||
@override
|
||||
String toString() => 'SignUpState(email: $email, password: $password, '
|
||||
'status: $status, data: $data, errorMessage: $errorMessage)';
|
||||
List<Object?> get props => [email, password, status, form];
|
||||
|
||||
@override
|
||||
List<Object?> get props => [email, password, status, data, errorMessage];
|
||||
@override
|
||||
String toString() => 'SignUpState(status: ${status.name} '
|
||||
'${(errorMessage != null) ? " [$errorMessage]" : ""}, $form)';
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user