Compare commits
	
		
			3 Commits
		
	
	
		
			76a655ac63
			...
			fcc439a311
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| fcc439a311 | |||
| 5a3eeed7b5 | |||
| 0e5e2403ce | 
@ -1,16 +1,6 @@
 | 
				
			|||||||
# example_router
 | 
					# example_router
 | 
				
			||||||
 | 
					
 | 
				
			||||||
A new Flutter project.
 | 
					```sh
 | 
				
			||||||
 | 
					firebase emulators:start --only auth
 | 
				
			||||||
## Getting Started
 | 
					flutter run --target lib/main_development.dart --dart-define="dev_mode=emulator"
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
This project is a starting point for a Flutter application.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
A few resources to get you started if this is your first Flutter project:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
- [Lab: Write your first Flutter app](https://docs.flutter.dev/get-started/codelab)
 | 
					 | 
				
			||||||
- [Cookbook: Useful Flutter samples](https://docs.flutter.dev/cookbook)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
For help getting started with Flutter development, view the
 | 
					 | 
				
			||||||
[online documentation](https://docs.flutter.dev/), which offers tutorials,
 | 
					 | 
				
			||||||
samples, guidance on mobile development, and a full API reference.
 | 
					 | 
				
			||||||
 | 
				
			|||||||
@ -10,11 +10,11 @@ PODS:
 | 
				
			|||||||
    - FirebaseAuth (~> 10.3.0)
 | 
					    - FirebaseAuth (~> 10.3.0)
 | 
				
			||||||
  - Firebase/CoreOnly (10.3.0):
 | 
					  - Firebase/CoreOnly (10.3.0):
 | 
				
			||||||
    - FirebaseCore (= 10.3.0)
 | 
					    - FirebaseCore (= 10.3.0)
 | 
				
			||||||
  - firebase_auth (4.2.0):
 | 
					  - firebase_auth (4.2.9):
 | 
				
			||||||
    - Firebase/Auth (= 10.3.0)
 | 
					    - Firebase/Auth (= 10.3.0)
 | 
				
			||||||
    - firebase_core
 | 
					    - firebase_core
 | 
				
			||||||
    - Flutter
 | 
					    - Flutter
 | 
				
			||||||
  - firebase_core (2.4.0):
 | 
					  - firebase_core (2.7.0):
 | 
				
			||||||
    - Firebase/CoreOnly (= 10.3.0)
 | 
					    - Firebase/CoreOnly (= 10.3.0)
 | 
				
			||||||
    - Flutter
 | 
					    - Flutter
 | 
				
			||||||
  - FirebaseAuth (10.3.0):
 | 
					  - FirebaseAuth (10.3.0):
 | 
				
			||||||
@ -29,6 +29,8 @@ PODS:
 | 
				
			|||||||
  - FirebaseCoreInternal (10.3.0):
 | 
					  - FirebaseCoreInternal (10.3.0):
 | 
				
			||||||
    - "GoogleUtilities/NSData+zlib (~> 7.8)"
 | 
					    - "GoogleUtilities/NSData+zlib (~> 7.8)"
 | 
				
			||||||
  - Flutter (1.0.0)
 | 
					  - Flutter (1.0.0)
 | 
				
			||||||
 | 
					  - flutter_secure_storage (6.0.0):
 | 
				
			||||||
 | 
					    - Flutter
 | 
				
			||||||
  - google_sign_in_ios (0.0.1):
 | 
					  - google_sign_in_ios (0.0.1):
 | 
				
			||||||
    - Flutter
 | 
					    - Flutter
 | 
				
			||||||
    - GoogleSignIn (~> 6.2)
 | 
					    - GoogleSignIn (~> 6.2)
 | 
				
			||||||
@ -61,6 +63,7 @@ DEPENDENCIES:
 | 
				
			|||||||
  - firebase_auth (from `.symlinks/plugins/firebase_auth/ios`)
 | 
					  - firebase_auth (from `.symlinks/plugins/firebase_auth/ios`)
 | 
				
			||||||
  - firebase_core (from `.symlinks/plugins/firebase_core/ios`)
 | 
					  - firebase_core (from `.symlinks/plugins/firebase_core/ios`)
 | 
				
			||||||
  - Flutter (from `Flutter`)
 | 
					  - Flutter (from `Flutter`)
 | 
				
			||||||
 | 
					  - flutter_secure_storage (from `.symlinks/plugins/flutter_secure_storage/ios`)
 | 
				
			||||||
  - google_sign_in_ios (from `.symlinks/plugins/google_sign_in_ios/ios`)
 | 
					  - google_sign_in_ios (from `.symlinks/plugins/google_sign_in_ios/ios`)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
SPEC REPOS:
 | 
					SPEC REPOS:
 | 
				
			||||||
@ -83,19 +86,22 @@ EXTERNAL SOURCES:
 | 
				
			|||||||
    :path: ".symlinks/plugins/firebase_core/ios"
 | 
					    :path: ".symlinks/plugins/firebase_core/ios"
 | 
				
			||||||
  Flutter:
 | 
					  Flutter:
 | 
				
			||||||
    :path: Flutter
 | 
					    :path: Flutter
 | 
				
			||||||
 | 
					  flutter_secure_storage:
 | 
				
			||||||
 | 
					    :path: ".symlinks/plugins/flutter_secure_storage/ios"
 | 
				
			||||||
  google_sign_in_ios:
 | 
					  google_sign_in_ios:
 | 
				
			||||||
    :path: ".symlinks/plugins/google_sign_in_ios/ios"
 | 
					    :path: ".symlinks/plugins/google_sign_in_ios/ios"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
SPEC CHECKSUMS:
 | 
					SPEC CHECKSUMS:
 | 
				
			||||||
  AppAuth: 8fca6b5563a5baef2c04bee27538025e4ceb2add
 | 
					  AppAuth: 8fca6b5563a5baef2c04bee27538025e4ceb2add
 | 
				
			||||||
  Firebase: f92fc551ead69c94168d36c2b26188263860acd9
 | 
					  Firebase: f92fc551ead69c94168d36c2b26188263860acd9
 | 
				
			||||||
  firebase_auth: 579a0dc15451491cc83fccaa5102296635f24938
 | 
					  firebase_auth: 4e8c693e848ed13b263de2d702d55fa82ed04a79
 | 
				
			||||||
  firebase_core: 6f2f753e316765799d88568232ed59e300ff53db
 | 
					  firebase_core: 128d8c43c3a453a4a67463314fc3761bedff860b
 | 
				
			||||||
  FirebaseAuth: 0e415d29d846c1dce2fb641e46f35e9888d9bec6
 | 
					  FirebaseAuth: 0e415d29d846c1dce2fb641e46f35e9888d9bec6
 | 
				
			||||||
  FirebaseCore: 988754646ab3bd4bdcb740f1bfe26b9f6c0d5f2a
 | 
					  FirebaseCore: 988754646ab3bd4bdcb740f1bfe26b9f6c0d5f2a
 | 
				
			||||||
  FirebaseCoreInternal: 29b76f784d607df8b2a1259d73c3f04f1210137b
 | 
					  FirebaseCoreInternal: 29b76f784d607df8b2a1259d73c3f04f1210137b
 | 
				
			||||||
  Flutter: f04841e97a9d0b0a8025694d0796dd46242b2854
 | 
					  Flutter: f04841e97a9d0b0a8025694d0796dd46242b2854
 | 
				
			||||||
  google_sign_in_ios: 4f85eb9f937450765c8573bb85fd8cd6a5af675c
 | 
					  flutter_secure_storage: 23fc622d89d073675f2eaa109381aefbcf5a49be
 | 
				
			||||||
 | 
					  google_sign_in_ios: 1256ff9d941db546373826966720b0c24804bcdd
 | 
				
			||||||
  GoogleSignIn: 5651ce3a61e56ca864160e79b484cd9ed3f49b7a
 | 
					  GoogleSignIn: 5651ce3a61e56ca864160e79b484cd9ed3f49b7a
 | 
				
			||||||
  GoogleUtilities: bad72cb363809015b1f7f19beb1f1cd23c589f95
 | 
					  GoogleUtilities: bad72cb363809015b1f7f19beb1f1cd23c589f95
 | 
				
			||||||
  GTMAppAuth: 0ff230db599948a9ad7470ca667337803b3fc4dd
 | 
					  GTMAppAuth: 0ff230db599948a9ad7470ca667337803b3fc4dd
 | 
				
			||||||
 | 
				
			|||||||
@ -9,6 +9,7 @@
 | 
				
			|||||||
/* Begin PBXBuildFile section */
 | 
					/* Begin PBXBuildFile section */
 | 
				
			||||||
		1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };
 | 
							1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };
 | 
				
			||||||
		3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
 | 
							3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
 | 
				
			||||||
 | 
							44F5B6790A35D9BA26574F6B /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = F6E17622FCECE9BFC2543397 /* GoogleService-Info.plist */; };
 | 
				
			||||||
		69F3BBCD5DEB05A456F6B74F /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B0A061B2E527F311149C3581 /* Pods_Runner.framework */; };
 | 
							69F3BBCD5DEB05A456F6B74F /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B0A061B2E527F311149C3581 /* Pods_Runner.framework */; };
 | 
				
			||||||
		74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; };
 | 
							74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; };
 | 
				
			||||||
		97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; };
 | 
							97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; };
 | 
				
			||||||
@ -46,6 +47,7 @@
 | 
				
			|||||||
		97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
 | 
							97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
 | 
				
			||||||
		B0A061B2E527F311149C3581 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; };
 | 
							B0A061B2E527F311149C3581 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; };
 | 
				
			||||||
		F0D7945BAE0BEA457137ED73 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = "<group>"; };
 | 
							F0D7945BAE0BEA457137ED73 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = "<group>"; };
 | 
				
			||||||
 | 
							F6E17622FCECE9BFC2543397 /* GoogleService-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; name = "GoogleService-Info.plist"; path = "Runner/GoogleService-Info.plist"; sourceTree = "<group>"; };
 | 
				
			||||||
		F9340E3A859C31E59380BD0F /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = "<group>"; };
 | 
							F9340E3A859C31E59380BD0F /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = "<group>"; };
 | 
				
			||||||
/* End PBXFileReference section */
 | 
					/* End PBXFileReference section */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -91,6 +93,7 @@
 | 
				
			|||||||
				97C146EF1CF9000F007C117D /* Products */,
 | 
									97C146EF1CF9000F007C117D /* Products */,
 | 
				
			||||||
				66B357379C2757D2844F12BB /* Pods */,
 | 
									66B357379C2757D2844F12BB /* Pods */,
 | 
				
			||||||
				BC1E25CE0DADDF7B7201CCF8 /* Frameworks */,
 | 
									BC1E25CE0DADDF7B7201CCF8 /* Frameworks */,
 | 
				
			||||||
 | 
									F6E17622FCECE9BFC2543397 /* GoogleService-Info.plist */,
 | 
				
			||||||
			);
 | 
								);
 | 
				
			||||||
			sourceTree = "<group>";
 | 
								sourceTree = "<group>";
 | 
				
			||||||
		};
 | 
							};
 | 
				
			||||||
@ -192,6 +195,7 @@
 | 
				
			|||||||
				3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */,
 | 
									3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */,
 | 
				
			||||||
				97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */,
 | 
									97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */,
 | 
				
			||||||
				97C146FC1CF9000F007C117D /* Main.storyboard in Resources */,
 | 
									97C146FC1CF9000F007C117D /* Main.storyboard in Resources */,
 | 
				
			||||||
 | 
									44F5B6790A35D9BA26574F6B /* GoogleService-Info.plist in Resources */,
 | 
				
			||||||
			);
 | 
								);
 | 
				
			||||||
			runOnlyForDeploymentPostprocessing = 0;
 | 
								runOnlyForDeploymentPostprocessing = 0;
 | 
				
			||||||
		};
 | 
							};
 | 
				
			||||||
 | 
				
			|||||||
@ -0,0 +1,38 @@
 | 
				
			|||||||
 | 
					<?xml version="1.0" encoding="UTF-8"?>
 | 
				
			||||||
 | 
					<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
 | 
				
			||||||
 | 
					<plist version="1.0">
 | 
				
			||||||
 | 
					<dict>
 | 
				
			||||||
 | 
						<key>CLIENT_ID</key>
 | 
				
			||||||
 | 
						<string>136771801992-p629tpo9bk3hcm2955s5ahivdla57ln9.apps.googleusercontent.com</string>
 | 
				
			||||||
 | 
						<key>REVERSED_CLIENT_ID</key>
 | 
				
			||||||
 | 
						<string>com.googleusercontent.apps.136771801992-p629tpo9bk3hcm2955s5ahivdla57ln9</string>
 | 
				
			||||||
 | 
						<key>ANDROID_CLIENT_ID</key>
 | 
				
			||||||
 | 
						<string>136771801992-n2pq8oqutvrqj58e05hbavvc7n1jdfjb.apps.googleusercontent.com</string>
 | 
				
			||||||
 | 
						<key>API_KEY</key>
 | 
				
			||||||
 | 
						<string>AIzaSyCDbbhjbFrQwLXuIANdJzjkDk8uOETnn7w</string>
 | 
				
			||||||
 | 
						<key>GCM_SENDER_ID</key>
 | 
				
			||||||
 | 
						<string>136771801992</string>
 | 
				
			||||||
 | 
						<key>PLIST_VERSION</key>
 | 
				
			||||||
 | 
						<string>1</string>
 | 
				
			||||||
 | 
						<key>BUNDLE_ID</key>
 | 
				
			||||||
 | 
						<string>com.example.exampleRouter</string>
 | 
				
			||||||
 | 
						<key>PROJECT_ID</key>
 | 
				
			||||||
 | 
						<string>tchat-beta</string>
 | 
				
			||||||
 | 
						<key>STORAGE_BUCKET</key>
 | 
				
			||||||
 | 
						<string>tchat-beta.appspot.com</string>
 | 
				
			||||||
 | 
						<key>IS_ADS_ENABLED</key>
 | 
				
			||||||
 | 
						<false></false>
 | 
				
			||||||
 | 
						<key>IS_ANALYTICS_ENABLED</key>
 | 
				
			||||||
 | 
						<false></false>
 | 
				
			||||||
 | 
						<key>IS_APPINVITE_ENABLED</key>
 | 
				
			||||||
 | 
						<true></true>
 | 
				
			||||||
 | 
						<key>IS_GCM_ENABLED</key>
 | 
				
			||||||
 | 
						<true></true>
 | 
				
			||||||
 | 
						<key>IS_SIGNIN_ENABLED</key>
 | 
				
			||||||
 | 
						<true></true>
 | 
				
			||||||
 | 
						<key>GOOGLE_APP_ID</key>
 | 
				
			||||||
 | 
						<string>1:136771801992:ios:bcdca68d2b7d227097203d</string>
 | 
				
			||||||
 | 
						<key>DATABASE_URL</key>
 | 
				
			||||||
 | 
						<string>https://tchat-beta.firebaseio.com</string>
 | 
				
			||||||
 | 
					</dict>
 | 
				
			||||||
 | 
					</plist>
 | 
				
			||||||
@ -18,11 +18,8 @@ import 'dart:async';
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import 'package:example_router/core/dependency_injection/get_it.dart';
 | 
					import 'package:example_router/core/dependency_injection/get_it.dart';
 | 
				
			||||||
import 'package:example_router/core/utils/app_bloc_observer.dart';
 | 
					import 'package:example_router/core/utils/app_bloc_observer.dart';
 | 
				
			||||||
import 'package:example_router/firebase_options.dart';
 | 
					 | 
				
			||||||
import 'package:firebase_core/firebase_core.dart';
 | 
					 | 
				
			||||||
import 'package:flutter/widgets.dart';
 | 
					import 'package:flutter/widgets.dart';
 | 
				
			||||||
import 'package:flutter_bloc/flutter_bloc.dart';
 | 
					import 'package:flutter_bloc/flutter_bloc.dart';
 | 
				
			||||||
import 'package:wyatt_authentication_bloc/wyatt_authentication_bloc.dart';
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
class MockSettings {
 | 
					class MockSettings {
 | 
				
			||||||
  static MockSettings? _instance;
 | 
					  static MockSettings? _instance;
 | 
				
			||||||
@ -70,12 +67,6 @@ Future<void> bootstrap(FutureOr<Widget> Function() builder) async {
 | 
				
			|||||||
        debugPrint(details.toString());
 | 
					        debugPrint(details.toString());
 | 
				
			||||||
      };
 | 
					      };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      if (MockSettings.isDisable()) {
 | 
					 | 
				
			||||||
        await Firebase.initializeApp(
 | 
					 | 
				
			||||||
          options: DefaultFirebaseOptions.currentPlatform,
 | 
					 | 
				
			||||||
        );
 | 
					 | 
				
			||||||
        await FirebaseAuth.instance.useAuthEmulator('localhost', 9099);
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
      await GetItInitializer.init();
 | 
					      await GetItInitializer.init();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      runApp(await builder());
 | 
					      runApp(await builder());
 | 
				
			||||||
 | 
				
			|||||||
@ -14,20 +14,81 @@
 | 
				
			|||||||
// 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 'package:example_router/core/enums/dev_mode.dart';
 | 
				
			||||||
 | 
					import 'package:example_router/core/flavors/flavor.dart';
 | 
				
			||||||
import 'package:example_router/firebase_options.dart';
 | 
					import 'package:example_router/firebase_options.dart';
 | 
				
			||||||
 | 
					import 'package:firebase_core/firebase_core.dart';
 | 
				
			||||||
import 'package:get_it/get_it.dart';
 | 
					import 'package:get_it/get_it.dart';
 | 
				
			||||||
import 'package:wyatt_authentication_bloc/wyatt_authentication_bloc.dart';
 | 
					import 'package:wyatt_authentication_bloc/wyatt_authentication_bloc.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
final getIt = GetIt.I;
 | 
					final getIt = GetIt.I;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// Service and Data Source locator
 | 
				
			||||||
abstract class GetItInitializer {
 | 
					abstract class GetItInitializer {
 | 
				
			||||||
  static Future<void> init() async {
 | 
					  static FutureOr<void> _initCommon() async {
 | 
				
			||||||
    getIt.registerLazySingleton<AuthenticationRemoteDataSource<int>>(
 | 
					    // Initialize common sources/services
 | 
				
			||||||
      () => AuthenticationFirebaseDataSourceImpl<int>(
 | 
					    getIt.registerLazySingleton<AuthenticationSessionDataSource<int>>(
 | 
				
			||||||
          firebaseAuth: FirebaseAuth.instance,
 | 
					      () => AuthenticationSessionDataSourceImpl<int>(),
 | 
				
			||||||
          googleSignIn:
 | 
					 | 
				
			||||||
              GoogleSignIn(clientId: DefaultFirebaseOptions.ios.iosClientId)),
 | 
					 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static FutureOr<void> _initEmulator() async {
 | 
				
			||||||
 | 
					    // Initialize emulator sources/services
 | 
				
			||||||
 | 
					    final firebaseAuth = FirebaseAuth.instance;
 | 
				
			||||||
 | 
					    await firebaseAuth.useAuthEmulator('localhost', 9099);
 | 
				
			||||||
 | 
					    getIt
 | 
				
			||||||
 | 
					      ..registerLazySingleton<AuthenticationRemoteDataSource<int>>(
 | 
				
			||||||
 | 
					        () => AuthenticationFirebaseDataSourceImpl<int>(
 | 
				
			||||||
 | 
					            firebaseAuth: firebaseAuth,
 | 
				
			||||||
 | 
					            googleSignIn:
 | 
				
			||||||
 | 
					                GoogleSignIn(clientId: DefaultFirebaseOptions.ios.iosClientId)),
 | 
				
			||||||
 | 
					      )
 | 
				
			||||||
 | 
					      ..registerLazySingleton<AuthenticationCacheDataSource<int>>(
 | 
				
			||||||
 | 
					        () => AuthenticationFirebaseCacheDataSourceImpl<int>(
 | 
				
			||||||
 | 
					          firebaseAuth: firebaseAuth,
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					      );
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static FutureOr<void> _initFirebase() async {
 | 
				
			||||||
 | 
					    // Initialize firebase sources/services.
 | 
				
			||||||
 | 
					    getIt
 | 
				
			||||||
 | 
					      ..registerLazySingleton<AuthenticationRemoteDataSource<int>>(
 | 
				
			||||||
 | 
					        () => AuthenticationFirebaseDataSourceImpl<int>(
 | 
				
			||||||
 | 
					            firebaseAuth: FirebaseAuth.instance,
 | 
				
			||||||
 | 
					            googleSignIn:
 | 
				
			||||||
 | 
					                GoogleSignIn(clientId: DefaultFirebaseOptions.ios.iosClientId)),
 | 
				
			||||||
 | 
					      )
 | 
				
			||||||
 | 
					      ..registerLazySingleton<AuthenticationCacheDataSource<int>>(
 | 
				
			||||||
 | 
					        () => AuthenticationFirebaseCacheDataSourceImpl<int>(
 | 
				
			||||||
 | 
					          firebaseAuth: FirebaseAuth.instance,
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					      );
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static FutureOr<void> _initRest() async {
 | 
				
			||||||
 | 
					    // Initialize rest api sources/services
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static FutureOr<void> init() async {
 | 
				
			||||||
 | 
					    await _initCommon();
 | 
				
			||||||
 | 
					    final flavor = Flavor.get();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (flavor.devMode == DevMode.rest) {
 | 
				
			||||||
 | 
					      await _initRest();
 | 
				
			||||||
 | 
					    } else if (flavor.devMode == DevMode.emulator) {
 | 
				
			||||||
 | 
					      await Firebase.initializeApp(
 | 
				
			||||||
 | 
					        options: DefaultFirebaseOptions.currentPlatform,
 | 
				
			||||||
 | 
					      );
 | 
				
			||||||
 | 
					      await _initEmulator();
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					      await Firebase.initializeApp(
 | 
				
			||||||
 | 
					        options: DefaultFirebaseOptions.currentPlatform,
 | 
				
			||||||
 | 
					      );
 | 
				
			||||||
 | 
					      await _initFirebase();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    await getIt.allReady();
 | 
					    await getIt.allReady();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
				
			|||||||
@ -0,0 +1,44 @@
 | 
				
			|||||||
 | 
					// Copyright (C) 2023 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/>.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum DevMode {
 | 
				
			||||||
 | 
					  /// Mocked values
 | 
				
			||||||
 | 
					  mock,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// Real values from REST API
 | 
				
			||||||
 | 
					  rest,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// Emulated values with Firebase Emulator
 | 
				
			||||||
 | 
					  emulator,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// Real values from Firebase
 | 
				
			||||||
 | 
					  real;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  @override
 | 
				
			||||||
 | 
					  String toString() => name;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// Tries to parse String and returns mode. Fallback is returned if there
 | 
				
			||||||
 | 
					  /// is an error during parsing.
 | 
				
			||||||
 | 
					  static DevMode fromString(String? mode, {DevMode fallback = DevMode.mock}) {
 | 
				
			||||||
 | 
					    for (final m in values) {
 | 
				
			||||||
 | 
					      if (m.name == mode) {
 | 
				
			||||||
 | 
					        return m;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return fallback;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -0,0 +1,72 @@
 | 
				
			|||||||
 | 
					// Copyright (C) 2023 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 'package:example_router/core/enums/dev_mode.dart';
 | 
				
			||||||
 | 
					import 'package:flutter/material.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					abstract class Flavor {
 | 
				
			||||||
 | 
					  Flavor._({
 | 
				
			||||||
 | 
					    this.banner,
 | 
				
			||||||
 | 
					    this.bannerColor = Colors.red,
 | 
				
			||||||
 | 
					    this.devMode,
 | 
				
			||||||
 | 
					  }) {
 | 
				
			||||||
 | 
					    _instance = this;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static Flavor? _instance;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  final String? banner;
 | 
				
			||||||
 | 
					  final Color bannerColor;
 | 
				
			||||||
 | 
					  final DevMode? devMode;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// Returns [Flavor] instance.
 | 
				
			||||||
 | 
					  static Flavor get() {
 | 
				
			||||||
 | 
					    if (_instance == null) {
 | 
				
			||||||
 | 
					      throw Exception('Flavor not initialized!');
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return _instance!;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  @override
 | 
				
			||||||
 | 
					  String toString() => runtimeType.toString().replaceAll('Flavor', '');
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class DevelopmentFlavor extends Flavor {
 | 
				
			||||||
 | 
					  factory DevelopmentFlavor() {
 | 
				
			||||||
 | 
					    const modeString = String.fromEnvironment('dev_mode', defaultValue: 'mock');
 | 
				
			||||||
 | 
					    final mode = DevMode.fromString(modeString);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return DevelopmentFlavor._(devMode: mode);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  DevelopmentFlavor._({
 | 
				
			||||||
 | 
					    required super.devMode,
 | 
				
			||||||
 | 
					  }) : super._(
 | 
				
			||||||
 | 
					          banner: 'Dev',
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class StagingFlavor extends Flavor {
 | 
				
			||||||
 | 
					  StagingFlavor()
 | 
				
			||||||
 | 
					      : super._(
 | 
				
			||||||
 | 
					          banner: 'Staging',
 | 
				
			||||||
 | 
					          bannerColor: Colors.green,
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class ProductionFlavor extends Flavor {
 | 
				
			||||||
 | 
					  ProductionFlavor() : super._();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -65,8 +65,10 @@ class DefaultFirebaseOptions {
 | 
				
			|||||||
    projectId: 'tchat-beta',
 | 
					    projectId: 'tchat-beta',
 | 
				
			||||||
    databaseURL: 'https://tchat-beta.firebaseio.com',
 | 
					    databaseURL: 'https://tchat-beta.firebaseio.com',
 | 
				
			||||||
    storageBucket: 'tchat-beta.appspot.com',
 | 
					    storageBucket: 'tchat-beta.appspot.com',
 | 
				
			||||||
    androidClientId: '136771801992-n2pq8oqutvrqj58e05hbavvc7n1jdfjb.apps.googleusercontent.com',
 | 
					    androidClientId:
 | 
				
			||||||
    iosClientId: '136771801992-p629tpo9bk3hcm2955s5ahivdla57ln9.apps.googleusercontent.com',
 | 
					        '136771801992-n2pq8oqutvrqj58e05hbavvc7n1jdfjb.apps.googleusercontent.com',
 | 
				
			||||||
 | 
					    iosClientId:
 | 
				
			||||||
 | 
					        '136771801992-p629tpo9bk3hcm2955s5ahivdla57ln9.apps.googleusercontent.com',
 | 
				
			||||||
    iosBundleId: 'com.example.exampleRouter',
 | 
					    iosBundleId: 'com.example.exampleRouter',
 | 
				
			||||||
  );
 | 
					  );
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -15,9 +15,13 @@
 | 
				
			|||||||
// 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 'package:example_router/bootstrap.dart';
 | 
					import 'package:example_router/bootstrap.dart';
 | 
				
			||||||
 | 
					import 'package:example_router/core/flavors/flavor.dart';
 | 
				
			||||||
import 'package:example_router/presentation/features/app/app.dart';
 | 
					import 'package:example_router/presentation/features/app/app.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void main() {
 | 
					void main(List<String> args) {
 | 
				
			||||||
  MockSettings.enable();
 | 
					  // Define environment
 | 
				
			||||||
 | 
					  ProductionFlavor();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Initialize environment and variables
 | 
				
			||||||
  bootstrap(App.new);
 | 
					  bootstrap(App.new);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -15,9 +15,13 @@
 | 
				
			|||||||
// 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 'package:example_router/bootstrap.dart';
 | 
					import 'package:example_router/bootstrap.dart';
 | 
				
			||||||
 | 
					import 'package:example_router/core/flavors/flavor.dart';
 | 
				
			||||||
import 'package:example_router/presentation/features/app/app.dart';
 | 
					import 'package:example_router/presentation/features/app/app.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void main() {
 | 
					void main(List<String> args) {
 | 
				
			||||||
  MockSettings.disable();
 | 
					  // Define environment
 | 
				
			||||||
 | 
					  DevelopmentFlavor();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Initialize environment and variables
 | 
				
			||||||
  bootstrap(App.new);
 | 
					  bootstrap(App.new);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -34,6 +34,9 @@ class App extends StatelessWidget {
 | 
				
			|||||||
      AuthenticationRepositoryImpl(
 | 
					      AuthenticationRepositoryImpl(
 | 
				
			||||||
    authenticationRemoteDataSource:
 | 
					    authenticationRemoteDataSource:
 | 
				
			||||||
        getIt<AuthenticationRemoteDataSource<int>>(),
 | 
					        getIt<AuthenticationRemoteDataSource<int>>(),
 | 
				
			||||||
 | 
					    authenticationSessionDataSource:
 | 
				
			||||||
 | 
					        getIt<AuthenticationSessionDataSource<int>>(),
 | 
				
			||||||
 | 
					    authenticationCacheDataSource: getIt<AuthenticationCacheDataSource<int>>(),
 | 
				
			||||||
    customPasswordValidator: const CustomPassword.pure(),
 | 
					    customPasswordValidator: const CustomPassword.pure(),
 | 
				
			||||||
    extraSignUpInputs: [
 | 
					    extraSignUpInputs: [
 | 
				
			||||||
      FormInput(
 | 
					      FormInput(
 | 
				
			||||||
 | 
				
			|||||||
@ -45,7 +45,8 @@ class SubPage extends StatelessWidget {
 | 
				
			|||||||
          children: [
 | 
					          children: [
 | 
				
			||||||
            const Text('Another page'),
 | 
					            const Text('Another page'),
 | 
				
			||||||
            ElevatedButton(
 | 
					            ElevatedButton(
 | 
				
			||||||
              onPressed: () => context.read<AuthenticationCubit<int>>().delete(),
 | 
					              onPressed: () =>
 | 
				
			||||||
 | 
					                  context.read<AuthenticationCubit<int>>().delete(),
 | 
				
			||||||
              child: const Text('Delete account'),
 | 
					              child: const Text('Delete account'),
 | 
				
			||||||
            ),
 | 
					            ),
 | 
				
			||||||
          ],
 | 
					          ],
 | 
				
			||||||
 | 
				
			|||||||
@ -18,8 +18,10 @@
 | 
				
			|||||||
abstract class AuthFormField {
 | 
					abstract class AuthFormField {
 | 
				
			||||||
  /// Email field: `wyattEmailField`
 | 
					  /// Email field: `wyattEmailField`
 | 
				
			||||||
  static const email = 'wyattEmailField';
 | 
					  static const email = 'wyattEmailField';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /// Password field: `wyattPasswordField`
 | 
					  /// Password field: `wyattPasswordField`
 | 
				
			||||||
  static const password = 'wyattPasswordField';
 | 
					  static const password = 'wyattPasswordField';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /// Confirm Password field: `wyattConfirmPasswordField`
 | 
					  /// Confirm Password field: `wyattConfirmPasswordField`
 | 
				
			||||||
  static const confirmPassword = 'wyattConfirmPasswordField';
 | 
					  static const confirmPassword = 'wyattConfirmPasswordField';
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -18,10 +18,13 @@
 | 
				
			|||||||
abstract class AuthFormName {
 | 
					abstract class AuthFormName {
 | 
				
			||||||
  /// Sign Up form: `wyattSignUpForm`
 | 
					  /// Sign Up form: `wyattSignUpForm`
 | 
				
			||||||
  static const String signUpForm = 'wyattSignUpForm';
 | 
					  static const String signUpForm = 'wyattSignUpForm';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /// Sign In form: `wyattSignInForm`
 | 
					  /// Sign In form: `wyattSignInForm`
 | 
				
			||||||
  static const String signInForm = 'wyattSignInForm';
 | 
					  static const String signInForm = 'wyattSignInForm';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /// Password reset form: `wyattPasswordResetForm`
 | 
					  /// Password reset form: `wyattPasswordResetForm`
 | 
				
			||||||
  static const String passwordResetForm = 'wyattPasswordResetForm';
 | 
					  static const String passwordResetForm = 'wyattPasswordResetForm';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /// Edit account form: `wyattEditAccountForm`
 | 
					  /// Edit account form: `wyattEditAccountForm`
 | 
				
			||||||
  static const String editAccountForm = 'wyattEditAccountForm';
 | 
					  static const String editAccountForm = 'wyattEditAccountForm';
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -18,8 +18,10 @@
 | 
				
			|||||||
enum AuthenticationStatus {
 | 
					enum AuthenticationStatus {
 | 
				
			||||||
  /// At the application launch.
 | 
					  /// At the application launch.
 | 
				
			||||||
  unknown,
 | 
					  unknown,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /// When the user is logged
 | 
					  /// When the user is logged
 | 
				
			||||||
  authenticated,
 | 
					  authenticated,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /// When the user is not logged
 | 
					  /// When the user is not logged
 | 
				
			||||||
  unauthenticated,
 | 
					  unauthenticated,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -21,8 +21,8 @@ import 'package:wyatt_authentication_bloc/src/domain/entities/auth_session.dart'
 | 
				
			|||||||
import 'package:wyatt_authentication_bloc/src/domain/entities/authentication_change_event/authentication_change_event.dart';
 | 
					import 'package:wyatt_authentication_bloc/src/domain/entities/authentication_change_event/authentication_change_event.dart';
 | 
				
			||||||
import 'package:wyatt_authentication_bloc/src/features/authentication/cubit/authentication_cubit.dart';
 | 
					import 'package:wyatt_authentication_bloc/src/features/authentication/cubit/authentication_cubit.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Extension that helps to quickly access useful resources like wrapper,
 | 
					/// Extension that helps to quickly access useful resources
 | 
				
			||||||
/// session, account or data.
 | 
					/// from the context.
 | 
				
			||||||
extension BuildContextExtension on BuildContext {
 | 
					extension BuildContextExtension on BuildContext {
 | 
				
			||||||
  /// Read session in context from a specific AuthenticationCubit type [T]
 | 
					  /// Read session in context from a specific AuthenticationCubit type [T]
 | 
				
			||||||
  AuthenticationSession<Data>?
 | 
					  AuthenticationSession<Data>?
 | 
				
			||||||
 | 
				
			|||||||
@ -20,10 +20,12 @@ import 'dart:async';
 | 
				
			|||||||
import 'package:wyatt_architecture/wyatt_architecture.dart';
 | 
					import 'package:wyatt_architecture/wyatt_architecture.dart';
 | 
				
			||||||
import 'package:wyatt_type_utils/wyatt_type_utils.dart';
 | 
					import 'package:wyatt_type_utils/wyatt_type_utils.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Calls on each cubit action of this package.
 | 
					/// {@template custom_routine}
 | 
				
			||||||
///
 | 
					/// A custom routine that can be used to call a routine and
 | 
				
			||||||
/// Useful to register custom logic on pre-implemented logic.
 | 
					/// attach custom logic to it.
 | 
				
			||||||
 | 
					/// {@endtemplate}
 | 
				
			||||||
class CustomRoutine<R, Data> {
 | 
					class CustomRoutine<R, Data> {
 | 
				
			||||||
 | 
					  /// {@macro custom_routine}
 | 
				
			||||||
  const CustomRoutine({
 | 
					  const CustomRoutine({
 | 
				
			||||||
    required this.routine,
 | 
					    required this.routine,
 | 
				
			||||||
    required this.attachedLogic,
 | 
					    required this.attachedLogic,
 | 
				
			||||||
@ -31,13 +33,21 @@ class CustomRoutine<R, Data> {
 | 
				
			|||||||
    required this.onSuccess,
 | 
					    required this.onSuccess,
 | 
				
			||||||
  });
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// The routine to be called
 | 
				
			||||||
  final FutureOr<Result<R, AppException>> Function() routine;
 | 
					  final FutureOr<Result<R, AppException>> Function() routine;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// The custom logic to be attached to the routine
 | 
				
			||||||
  final FutureOr<Result<Data?, AppException>> Function(
 | 
					  final FutureOr<Result<Data?, AppException>> Function(
 | 
				
			||||||
    Result<R, AppException> routineResult,
 | 
					    Result<R, AppException> routineResult,
 | 
				
			||||||
  ) attachedLogic;
 | 
					  ) attachedLogic;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// The callback to be called when an error occurs
 | 
				
			||||||
  final void Function(AppException exception) onError;
 | 
					  final void Function(AppException exception) onError;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// The callback to be called when no error occurs
 | 
				
			||||||
  final void Function(R result, Data? data) onSuccess;
 | 
					  final void Function(R result, Data? data) onSuccess;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// Calls the routine and calls the custom attached logic
 | 
				
			||||||
  FutureOr<void> call() async {
 | 
					  FutureOr<void> call() async {
 | 
				
			||||||
    final result = await routine.call();
 | 
					    final result = await routine.call();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -17,7 +17,9 @@
 | 
				
			|||||||
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';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// This class contains all the forms used in the authentication process.
 | 
				
			||||||
abstract class Forms {
 | 
					abstract class Forms {
 | 
				
			||||||
 | 
					  /// Builds a sign in form.
 | 
				
			||||||
  static WyattForm buildSignInForm(
 | 
					  static WyattForm buildSignInForm(
 | 
				
			||||||
    FormInputValidator<String?, ValidationError>? customEmailValidator,
 | 
					    FormInputValidator<String?, ValidationError>? customEmailValidator,
 | 
				
			||||||
    FormInputValidator<String?, ValidationError>? customPasswordValidator,
 | 
					    FormInputValidator<String?, ValidationError>? customPasswordValidator,
 | 
				
			||||||
@ -36,6 +38,7 @@ abstract class Forms {
 | 
				
			|||||||
        name: AuthFormName.signInForm,
 | 
					        name: AuthFormName.signInForm,
 | 
				
			||||||
      );
 | 
					      );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// Builds a sign up form.
 | 
				
			||||||
  static WyattForm buildSignUpForm(
 | 
					  static WyattForm buildSignUpForm(
 | 
				
			||||||
    FormInputValidator<String?, ValidationError>? customEmailValidator,
 | 
					    FormInputValidator<String?, ValidationError>? customEmailValidator,
 | 
				
			||||||
    FormInputValidator<String?, ValidationError>? customPasswordValidator,
 | 
					    FormInputValidator<String?, ValidationError>? customPasswordValidator,
 | 
				
			||||||
@ -57,6 +60,7 @@ abstract class Forms {
 | 
				
			|||||||
        name: AuthFormName.signUpForm,
 | 
					        name: AuthFormName.signUpForm,
 | 
				
			||||||
      );
 | 
					      );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// Builds a password reset form.
 | 
				
			||||||
  static WyattForm buildPasswordResetForm(
 | 
					  static WyattForm buildPasswordResetForm(
 | 
				
			||||||
    FormInputValidator<String?, ValidationError>? customEmailValidator,
 | 
					    FormInputValidator<String?, ValidationError>? customEmailValidator,
 | 
				
			||||||
  ) =>
 | 
					  ) =>
 | 
				
			||||||
@ -70,6 +74,7 @@ abstract class Forms {
 | 
				
			|||||||
        name: AuthFormName.passwordResetForm,
 | 
					        name: AuthFormName.passwordResetForm,
 | 
				
			||||||
      );
 | 
					      );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// Builds an edit account form.
 | 
				
			||||||
  static WyattForm buildEditAccountForm(
 | 
					  static WyattForm buildEditAccountForm(
 | 
				
			||||||
    FormInputValidator<String?, ValidationError>? customEmailValidator,
 | 
					    FormInputValidator<String?, ValidationError>? customEmailValidator,
 | 
				
			||||||
    FormInputValidator<String?, ValidationError>? customPasswordValidator,
 | 
					    FormInputValidator<String?, ValidationError>? customPasswordValidator,
 | 
				
			||||||
 | 
				
			|||||||
@ -14,4 +14,5 @@
 | 
				
			|||||||
// 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/>.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export 'remote/authentication_firebase_data_source_impl.dart';
 | 
					export 'local/local.dart';
 | 
				
			||||||
 | 
					export 'remote/remote.dart';
 | 
				
			||||||
 | 
				
			|||||||
@ -0,0 +1,56 @@
 | 
				
			|||||||
 | 
					// Copyright (C) 2023 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 'package:wyatt_authentication_bloc/src/domain/data_sources/local/authentication_cache_data_source.dart';
 | 
				
			||||||
 | 
					import 'package:wyatt_authentication_bloc/wyatt_authentication_bloc.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// {@template authentication_firebase_cache_data_source_impl}
 | 
				
			||||||
 | 
					/// A data source that manages the cache strategy.
 | 
				
			||||||
 | 
					/// This implementation uses Firebase.
 | 
				
			||||||
 | 
					/// {@endtemplate}
 | 
				
			||||||
 | 
					class AuthenticationFirebaseCacheDataSourceImpl<Data>
 | 
				
			||||||
 | 
					    extends AuthenticationCacheDataSource<Data> {
 | 
				
			||||||
 | 
					  /// {@macro authentication_firebase_cache_data_source_impl}
 | 
				
			||||||
 | 
					  AuthenticationFirebaseCacheDataSourceImpl({
 | 
				
			||||||
 | 
					    FirebaseAuth? firebaseAuth,
 | 
				
			||||||
 | 
					  }) : _firebaseAuth = firebaseAuth ?? FirebaseAuth.instance;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  final FirebaseAuth _firebaseAuth;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Already done by Firebase
 | 
				
			||||||
 | 
					  @override
 | 
				
			||||||
 | 
					  Future<void> cacheAccount(Account account) => Future.value();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  @override
 | 
				
			||||||
 | 
					  Future<Account?> getCachedAccount() async {
 | 
				
			||||||
 | 
					    final currentUser = _firebaseAuth.currentUser;
 | 
				
			||||||
 | 
					    if (currentUser == null) {
 | 
				
			||||||
 | 
					      return null;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    final jwt = await currentUser.getIdToken(true);
 | 
				
			||||||
 | 
					    final currentAccount = AccountModel.fromFirebaseUser(
 | 
				
			||||||
 | 
					      currentUser,
 | 
				
			||||||
 | 
					      accessToken: jwt,
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return currentAccount;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Already done by Firebase
 | 
				
			||||||
 | 
					  @override
 | 
				
			||||||
 | 
					  Future<void> removeCachedAccount() => Future.value();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -0,0 +1,45 @@
 | 
				
			|||||||
 | 
					// Copyright (C) 2023 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:rxdart/subjects.dart';
 | 
				
			||||||
 | 
					import 'package:wyatt_authentication_bloc/src/domain/data_sources/local/authentication_session_data_source.dart';
 | 
				
			||||||
 | 
					import 'package:wyatt_authentication_bloc/src/domain/entities/auth_session.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// {@template authentication_session_data_source_impl}
 | 
				
			||||||
 | 
					/// A data source that manages the current session.
 | 
				
			||||||
 | 
					/// {@endtemplate}
 | 
				
			||||||
 | 
					class AuthenticationSessionDataSourceImpl<Data>
 | 
				
			||||||
 | 
					    extends AuthenticationSessionDataSource<Data> {
 | 
				
			||||||
 | 
					  /// {@macro authentication_session_data_source_impl}
 | 
				
			||||||
 | 
					  AuthenticationSessionDataSourceImpl();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  final StreamController<AuthenticationSession<Data>> _sessionStream =
 | 
				
			||||||
 | 
					      BehaviorSubject();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  @override
 | 
				
			||||||
 | 
					  void addSession(AuthenticationSession<Data> session) {
 | 
				
			||||||
 | 
					    _sessionStream.add(session);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  @override
 | 
				
			||||||
 | 
					  Future<AuthenticationSession<Data>> currentSession() => sessionStream().last;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  @override
 | 
				
			||||||
 | 
					  Stream<AuthenticationSession<Data>> sessionStream() =>
 | 
				
			||||||
 | 
					      _sessionStream.stream.asBroadcastStream();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -0,0 +1,18 @@
 | 
				
			|||||||
 | 
					// Copyright (C) 2023 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/>.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export 'authentication_firebase_cache_data_source_impl.dart';
 | 
				
			||||||
 | 
					export 'authentication_session_data_source_impl.dart';
 | 
				
			||||||
@ -23,55 +23,27 @@ import 'package:wyatt_authentication_bloc/src/core/exceptions/exceptions.dart';
 | 
				
			|||||||
import 'package:wyatt_authentication_bloc/src/data/models/models.dart';
 | 
					import 'package:wyatt_authentication_bloc/src/data/models/models.dart';
 | 
				
			||||||
import 'package:wyatt_authentication_bloc/src/domain/data_sources/remote/authentication_remote_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.dart';
 | 
				
			||||||
import 'package:wyatt_authentication_bloc/src/domain/entities/auth_session.dart';
 | 
					 | 
				
			||||||
import 'package:wyatt_authentication_bloc/src/domain/entities/authentication_change_event/authentication_change_event.dart';
 | 
					 | 
				
			||||||
import 'package:wyatt_type_utils/wyatt_type_utils.dart';
 | 
					import 'package:wyatt_type_utils/wyatt_type_utils.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// {@template authentication_firebase_data_source_impl}
 | 
				
			||||||
 | 
					/// Implementation of [AuthenticationRemoteDataSource] using Firebase.
 | 
				
			||||||
 | 
					/// {@endtemplate}
 | 
				
			||||||
class AuthenticationFirebaseDataSourceImpl<Data>
 | 
					class AuthenticationFirebaseDataSourceImpl<Data>
 | 
				
			||||||
    extends AuthenticationRemoteDataSource<Data> {
 | 
					    extends AuthenticationRemoteDataSource<Data> {
 | 
				
			||||||
 | 
					  /// {@macro authentication_firebase_data_source_impl}
 | 
				
			||||||
  AuthenticationFirebaseDataSourceImpl({
 | 
					  AuthenticationFirebaseDataSourceImpl({
 | 
				
			||||||
    FirebaseAuth? firebaseAuth,
 | 
					    FirebaseAuth? firebaseAuth,
 | 
				
			||||||
    GoogleSignIn? googleSignIn,
 | 
					    GoogleSignIn? googleSignIn,
 | 
				
			||||||
  })  : _firebaseAuth = firebaseAuth ?? FirebaseAuth.instance,
 | 
					  })  : _firebaseAuth = firebaseAuth ?? FirebaseAuth.instance,
 | 
				
			||||||
        _googleSignIn = googleSignIn ?? GoogleSignIn() {
 | 
					        _googleSignIn = googleSignIn ?? GoogleSignIn() {
 | 
				
			||||||
    _latestCredentials = BehaviorSubject();
 | 
					    _latestCredentials = BehaviorSubject();
 | 
				
			||||||
    _sessionStream = BehaviorSubject();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    // Check for account in memory (persistence)
 | 
					 | 
				
			||||||
    _checkForCachedAccount();
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  late StreamController<AuthenticationSession<Data>> _sessionStream;
 | 
					 | 
				
			||||||
  late StreamController<UserCredential?> _latestCredentials;
 | 
					  late StreamController<UserCredential?> _latestCredentials;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  final FirebaseAuth _firebaseAuth;
 | 
					  final FirebaseAuth _firebaseAuth;
 | 
				
			||||||
  final GoogleSignIn _googleSignIn;
 | 
					  final GoogleSignIn _googleSignIn;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  Future<void> _checkForCachedAccount() async {
 | 
					 | 
				
			||||||
    final currentUser = _firebaseAuth.currentUser;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (currentUser == null) {
 | 
					 | 
				
			||||||
      _sessionStream.add(
 | 
					 | 
				
			||||||
        const AuthenticationSession(
 | 
					 | 
				
			||||||
          latestEvent: UnknownAuthenticationEvent(),
 | 
					 | 
				
			||||||
        ),
 | 
					 | 
				
			||||||
      );
 | 
					 | 
				
			||||||
      return;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    final jwt = await currentUser.getIdToken(true);
 | 
					 | 
				
			||||||
    final currentAccount = AccountModel.fromFirebaseUser(
 | 
					 | 
				
			||||||
      currentUser,
 | 
					 | 
				
			||||||
      accessToken: jwt,
 | 
					 | 
				
			||||||
    );
 | 
					 | 
				
			||||||
    _sessionStream.add(
 | 
					 | 
				
			||||||
      AuthenticationSession.fromEvent(
 | 
					 | 
				
			||||||
        SignedInFromCacheEvent(account: currentAccount),
 | 
					 | 
				
			||||||
      ),
 | 
					 | 
				
			||||||
    );
 | 
					 | 
				
			||||||
    return;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  Future<Account> _addToCredentialStream(
 | 
					  Future<Account> _addToCredentialStream(
 | 
				
			||||||
    UserCredential userCredential,
 | 
					    UserCredential userCredential,
 | 
				
			||||||
  ) async {
 | 
					  ) async {
 | 
				
			||||||
@ -87,23 +59,6 @@ class AuthenticationFirebaseDataSourceImpl<Data>
 | 
				
			|||||||
    return account;
 | 
					    return account;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Session related methods ===================================================
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  /// {@macro add_session}
 | 
					 | 
				
			||||||
  @override
 | 
					 | 
				
			||||||
  void addSession(AuthenticationSession<Data> session) {
 | 
					 | 
				
			||||||
    _sessionStream.add(session);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  /// {@macro session_stream}
 | 
					 | 
				
			||||||
  @override
 | 
					 | 
				
			||||||
  Stream<AuthenticationSession<Data>> sessionStream() =>
 | 
					 | 
				
			||||||
      _sessionStream.stream.asBroadcastStream();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  /// {@macro current_session}
 | 
					 | 
				
			||||||
  @override
 | 
					 | 
				
			||||||
  Future<AuthenticationSession<Data>> currentSession() => sessionStream().last;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  // SignUp/SignIn methods ====================================================
 | 
					  // SignUp/SignIn methods ====================================================
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /// {@macro signup_pwd}
 | 
					  /// {@macro signup_pwd}
 | 
				
			||||||
 | 
				
			|||||||
@ -0,0 +1,17 @@
 | 
				
			|||||||
 | 
					// Copyright (C) 2023 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/>.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export 'authentication_firebase_data_source_impl.dart';
 | 
				
			||||||
@ -18,8 +18,11 @@ import 'package:firebase_auth/firebase_auth.dart';
 | 
				
			|||||||
import 'package:wyatt_authentication_bloc/src/core/exceptions/exceptions.dart';
 | 
					import 'package:wyatt_authentication_bloc/src/core/exceptions/exceptions.dart';
 | 
				
			||||||
import 'package:wyatt_authentication_bloc/src/domain/entities/account.dart';
 | 
					import 'package:wyatt_authentication_bloc/src/domain/entities/account.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// {@template account_model}
 | 
				
			||||||
/// Account Model to parse Firebase User data
 | 
					/// Account Model to parse Firebase User data
 | 
				
			||||||
 | 
					/// {@endtemplate}
 | 
				
			||||||
class AccountModel extends Account {
 | 
					class AccountModel extends Account {
 | 
				
			||||||
 | 
					  /// {@macro account_model}
 | 
				
			||||||
  factory AccountModel.fromFirebaseUserCredential(
 | 
					  factory AccountModel.fromFirebaseUserCredential(
 | 
				
			||||||
    UserCredential? userCredential, {
 | 
					    UserCredential? userCredential, {
 | 
				
			||||||
    required String? accessToken,
 | 
					    required String? accessToken,
 | 
				
			||||||
@ -47,6 +50,7 @@ class AccountModel extends Account {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// {@macro account_model}
 | 
				
			||||||
  factory AccountModel.fromFirebaseUser(
 | 
					  factory AccountModel.fromFirebaseUser(
 | 
				
			||||||
    User? user, {
 | 
					    User? user, {
 | 
				
			||||||
    required String? accessToken,
 | 
					    required String? accessToken,
 | 
				
			||||||
@ -72,6 +76,7 @@ class AccountModel extends Account {
 | 
				
			|||||||
      throw ModelParsingFailureFirebase('null-user', 'User cannot be null');
 | 
					      throw ModelParsingFailureFirebase('null-user', 'User cannot be null');
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const AccountModel._({
 | 
					  const AccountModel._({
 | 
				
			||||||
    required this.user,
 | 
					    required this.user,
 | 
				
			||||||
    required super.id,
 | 
					    required super.id,
 | 
				
			||||||
@ -87,6 +92,7 @@ class AccountModel extends Account {
 | 
				
			|||||||
    super.accessToken,
 | 
					    super.accessToken,
 | 
				
			||||||
  });
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// The Firebase User
 | 
				
			||||||
  final User? user;
 | 
					  final User? user;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  @override
 | 
					  @override
 | 
				
			||||||
 | 
				
			|||||||
@ -16,17 +16,22 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import 'package:wyatt_architecture/wyatt_architecture.dart';
 | 
					import 'package:wyatt_architecture/wyatt_architecture.dart';
 | 
				
			||||||
import 'package:wyatt_authentication_bloc/src/core/utils/forms.dart';
 | 
					import 'package:wyatt_authentication_bloc/src/core/utils/forms.dart';
 | 
				
			||||||
import 'package:wyatt_authentication_bloc/src/domain/data_sources/remote/authentication_remote_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/entities/account.dart';
 | 
					import 'package:wyatt_authentication_bloc/src/domain/data_sources/local/authentication_session_data_source.dart';
 | 
				
			||||||
import 'package:wyatt_authentication_bloc/src/domain/entities/auth_session.dart';
 | 
					import 'package:wyatt_authentication_bloc/src/domain/domain.dart';
 | 
				
			||||||
import 'package:wyatt_authentication_bloc/src/domain/repositories/authentication_repository.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';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// {@template authentication_repository_impl}
 | 
				
			||||||
 | 
					/// The default implementation of [AuthenticationRepository].
 | 
				
			||||||
 | 
					/// {@endtemplate}
 | 
				
			||||||
class AuthenticationRepositoryImpl<Data extends Object>
 | 
					class AuthenticationRepositoryImpl<Data extends Object>
 | 
				
			||||||
    extends AuthenticationRepository<Data> {
 | 
					    extends AuthenticationRepository<Data> {
 | 
				
			||||||
 | 
					  /// {@macro authentication_repository_impl}
 | 
				
			||||||
  AuthenticationRepositoryImpl({
 | 
					  AuthenticationRepositoryImpl({
 | 
				
			||||||
    required this.authenticationRemoteDataSource,
 | 
					    required this.authenticationRemoteDataSource,
 | 
				
			||||||
 | 
					    required this.authenticationCacheDataSource,
 | 
				
			||||||
 | 
					    required this.authenticationSessionDataSource,
 | 
				
			||||||
    FormRepository? formRepository,
 | 
					    FormRepository? formRepository,
 | 
				
			||||||
    // ignore: strict_raw_type
 | 
					    // ignore: strict_raw_type
 | 
				
			||||||
    List<FormInput>? extraSignUpInputs,
 | 
					    List<FormInput>? extraSignUpInputs,
 | 
				
			||||||
@ -66,24 +71,57 @@ class AuthenticationRepositoryImpl<Data extends Object>
 | 
				
			|||||||
      );
 | 
					      );
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// The remote data source used to perform the authentication process.
 | 
				
			||||||
  final AuthenticationRemoteDataSource<Data> authenticationRemoteDataSource;
 | 
					  final AuthenticationRemoteDataSource<Data> authenticationRemoteDataSource;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// The cache data source used to cache the current account.
 | 
				
			||||||
 | 
					  final AuthenticationCacheDataSource<Data> authenticationCacheDataSource;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// The session data source used to manage the current session.
 | 
				
			||||||
 | 
					  final AuthenticationSessionDataSource<Data> authenticationSessionDataSource;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  late FormRepository _formRepository;
 | 
					  late FormRepository _formRepository;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /// {@macro form_repo}
 | 
					  /// {@macro form_repo}
 | 
				
			||||||
  @override
 | 
					  @override
 | 
				
			||||||
  FormRepository get formRepository => _formRepository;
 | 
					  FormRepository get formRepository => _formRepository;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Cache related methods ====================================================
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// {@macro check_cache_account}
 | 
				
			||||||
 | 
					  @override
 | 
				
			||||||
 | 
					  Future<void> checkForCachedAccount() async {
 | 
				
			||||||
 | 
					    final cachedAccount =
 | 
				
			||||||
 | 
					        await authenticationCacheDataSource.getCachedAccount();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (cachedAccount == null) {
 | 
				
			||||||
 | 
					      addSession(
 | 
				
			||||||
 | 
					        const AuthenticationSession(
 | 
				
			||||||
 | 
					          latestEvent: UnknownAuthenticationEvent(),
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					      );
 | 
				
			||||||
 | 
					      return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    addSession(
 | 
				
			||||||
 | 
					      AuthenticationSession.fromEvent(
 | 
				
			||||||
 | 
					        SignedInFromCacheEvent(account: cachedAccount),
 | 
				
			||||||
 | 
					      ),
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					    return;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Session related methods ===================================================
 | 
					  // Session related methods ===================================================
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /// {@macro add_session}
 | 
					  /// {@macro add_session}
 | 
				
			||||||
  @override
 | 
					  @override
 | 
				
			||||||
  void addSession(AuthenticationSession<Data> session) =>
 | 
					  void addSession(AuthenticationSession<Data> session) =>
 | 
				
			||||||
      authenticationRemoteDataSource.addSession(session);
 | 
					      authenticationSessionDataSource.addSession(session);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /// {@macro session_stream}
 | 
					  /// {@macro session_stream}
 | 
				
			||||||
  @override
 | 
					  @override
 | 
				
			||||||
  Stream<AuthenticationSession<Data>> sessionStream() =>
 | 
					  Stream<AuthenticationSession<Data>> sessionStream() =>
 | 
				
			||||||
      authenticationRemoteDataSource.sessionStream();
 | 
					      authenticationSessionDataSource.sessionStream();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /// {@macro current_session}
 | 
					  /// {@macro current_session}
 | 
				
			||||||
  @override
 | 
					  @override
 | 
				
			||||||
@ -91,7 +129,9 @@ class AuthenticationRepositoryImpl<Data extends Object>
 | 
				
			|||||||
      Result.tryCatchAsync<AuthenticationSession<Data>, AppException,
 | 
					      Result.tryCatchAsync<AuthenticationSession<Data>, AppException,
 | 
				
			||||||
          AppException>(
 | 
					          AppException>(
 | 
				
			||||||
        () async {
 | 
					        () async {
 | 
				
			||||||
          final session = await authenticationRemoteDataSource.currentSession();
 | 
					          final session =
 | 
				
			||||||
 | 
					              await authenticationSessionDataSource.currentSession();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
          return session;
 | 
					          return session;
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        (error) => error,
 | 
					        (error) => error,
 | 
				
			||||||
 | 
				
			|||||||
@ -14,4 +14,5 @@
 | 
				
			|||||||
// 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/>.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export 'remote/authentication_remote_data_source.dart';
 | 
					export 'local/local.dart';
 | 
				
			||||||
 | 
					export 'remote/remote.dart';
 | 
				
			||||||
 | 
				
			|||||||
@ -0,0 +1,40 @@
 | 
				
			|||||||
 | 
					// Copyright (C) 2023 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 'package:wyatt_architecture/wyatt_architecture.dart';
 | 
				
			||||||
 | 
					import 'package:wyatt_authentication_bloc/src/domain/entities/account.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// {@template authentication_cache_data_source}
 | 
				
			||||||
 | 
					/// A data source that manages the cache strategy.
 | 
				
			||||||
 | 
					/// {@endtemplate}
 | 
				
			||||||
 | 
					abstract class AuthenticationCacheDataSource<Data> extends BaseLocalDataSource {
 | 
				
			||||||
 | 
					  /// {@macro authentication_cache_data_source}
 | 
				
			||||||
 | 
					  const AuthenticationCacheDataSource();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// Returns the cached account if it exists.
 | 
				
			||||||
 | 
					  Future<Account?> getCachedAccount();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// Adds the current account to the cache.
 | 
				
			||||||
 | 
					  ///
 | 
				
			||||||
 | 
					  /// If an account is already cached, it will be replaced.
 | 
				
			||||||
 | 
					  Future<void> cacheAccount(Account account);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// Removes the current account from the cache.
 | 
				
			||||||
 | 
					  ///
 | 
				
			||||||
 | 
					  /// The cache will be empty after this operation.
 | 
				
			||||||
 | 
					  /// If no account is cached, nothing will happen.
 | 
				
			||||||
 | 
					  Future<void> removeCachedAccount();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -0,0 +1,36 @@
 | 
				
			|||||||
 | 
					// Copyright (C) 2023 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 'package:wyatt_architecture/wyatt_architecture.dart';
 | 
				
			||||||
 | 
					import 'package:wyatt_authentication_bloc/wyatt_authentication_bloc.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// {@template authentication_session_data_source}
 | 
				
			||||||
 | 
					/// A data source that manages the current session.
 | 
				
			||||||
 | 
					/// {@endtemplate}
 | 
				
			||||||
 | 
					abstract class AuthenticationSessionDataSource<Data>
 | 
				
			||||||
 | 
					    extends BaseLocalDataSource {
 | 
				
			||||||
 | 
					  /// {@macro authentication_session_data_source}
 | 
				
			||||||
 | 
					  const AuthenticationSessionDataSource();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// Adds a new session to the data source.
 | 
				
			||||||
 | 
					  void addSession(AuthenticationSession<Data> session);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// Returns a stream of sessions.
 | 
				
			||||||
 | 
					  Stream<AuthenticationSession<Data>> sessionStream();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// Returns the current session.
 | 
				
			||||||
 | 
					  Future<AuthenticationSession<Data>> currentSession();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -0,0 +1,18 @@
 | 
				
			|||||||
 | 
					// Copyright (C) 2023 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/>.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export 'authentication_cache_data_source.dart';
 | 
				
			||||||
 | 
					export 'authentication_session_data_source.dart';
 | 
				
			||||||
@ -16,49 +16,71 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import 'package:wyatt_architecture/wyatt_architecture.dart';
 | 
					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.dart';
 | 
				
			||||||
import 'package:wyatt_authentication_bloc/src/domain/entities/auth_session.dart';
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Is responsible for abstracting the provenance of the data.
 | 
					/// {@template authentication_remote_data_source}
 | 
				
			||||||
 | 
					/// A remote data source for authentication.
 | 
				
			||||||
 | 
					/// It is responsible for all the external communication with the authentication
 | 
				
			||||||
 | 
					/// providers.
 | 
				
			||||||
 | 
					/// {@endtemplate}
 | 
				
			||||||
abstract class AuthenticationRemoteDataSource<Data>
 | 
					abstract class AuthenticationRemoteDataSource<Data>
 | 
				
			||||||
    extends BaseRemoteDataSource {
 | 
					    extends BaseRemoteDataSource {
 | 
				
			||||||
  // Session related methods ===================================================
 | 
					  /// {@macro authentication_remote_data_source}
 | 
				
			||||||
 | 
					  const AuthenticationRemoteDataSource();
 | 
				
			||||||
  void addSession(AuthenticationSession<Data> session);
 | 
					 | 
				
			||||||
  Stream<AuthenticationSession<Data>> sessionStream();
 | 
					 | 
				
			||||||
  Future<AuthenticationSession<Data>> currentSession();
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // SignUp/SignIn methods ====================================================
 | 
					  // SignUp/SignIn methods ====================================================
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// Sign up with email and password.
 | 
				
			||||||
  Future<Account> signUpWithEmailAndPassword({
 | 
					  Future<Account> signUpWithEmailAndPassword({
 | 
				
			||||||
    required String email,
 | 
					    required String email,
 | 
				
			||||||
    required String password,
 | 
					    required String password,
 | 
				
			||||||
  });
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// Sign in with email and password.
 | 
				
			||||||
  Future<Account> signInWithEmailAndPassword({
 | 
					  Future<Account> signInWithEmailAndPassword({
 | 
				
			||||||
    required String email,
 | 
					    required String email,
 | 
				
			||||||
    required String password,
 | 
					    required String password,
 | 
				
			||||||
  });
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// Sign in anonymously.
 | 
				
			||||||
  Future<Account> signInAnonymously();
 | 
					  Future<Account> signInAnonymously();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// Sign in with Google.
 | 
				
			||||||
  Future<Account> signInWithGoogle();
 | 
					  Future<Account> signInWithGoogle();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// Sign out.
 | 
				
			||||||
  Future<void> signOut();
 | 
					  Future<void> signOut();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Account management methods ===============================================
 | 
					  // Account management methods ===============================================
 | 
				
			||||||
  
 | 
					
 | 
				
			||||||
  // Future<void> linkCurrentUserWith(AuthenticationProvider anotherProvider);
 | 
					  /// Refresh the current account.
 | 
				
			||||||
  Future<Account> refresh();
 | 
					  Future<Account> refresh();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// Reauthenticate the current account.
 | 
				
			||||||
  Future<Account> reauthenticate();
 | 
					  Future<Account> reauthenticate();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// Update the current account's email.
 | 
				
			||||||
  Future<Account> updateEmail({required String email});
 | 
					  Future<Account> updateEmail({required String email});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// Update the current account's password.
 | 
				
			||||||
  Future<Account> updatePassword({required String password});
 | 
					  Future<Account> updatePassword({required String password});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// Delete the current account.
 | 
				
			||||||
  Future<void> delete();
 | 
					  Future<void> delete();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Email related stuff ======================================================
 | 
					  // Email related stuff ======================================================
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// Send an email verification.
 | 
				
			||||||
  Future<void> sendEmailVerification();
 | 
					  Future<void> sendEmailVerification();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// Send a password reset email.
 | 
				
			||||||
  Future<void> sendPasswordResetEmail({required String email});
 | 
					  Future<void> sendPasswordResetEmail({required String email});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// Confirm password reset.
 | 
				
			||||||
  Future<void> confirmPasswordReset({
 | 
					  Future<void> confirmPasswordReset({
 | 
				
			||||||
    required String code,
 | 
					    required String code,
 | 
				
			||||||
    required String newPassword,
 | 
					    required String newPassword,
 | 
				
			||||||
  });
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// Verify password reset code.
 | 
				
			||||||
  Future<bool> verifyPasswordResetCode({required String code});
 | 
					  Future<bool> verifyPasswordResetCode({required String code});
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -0,0 +1,17 @@
 | 
				
			|||||||
 | 
					// Copyright (C) 2023 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/>.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export 'authentication_remote_data_source.dart';
 | 
				
			||||||
@ -17,9 +17,12 @@
 | 
				
			|||||||
import 'package:equatable/equatable.dart';
 | 
					import 'package:equatable/equatable.dart';
 | 
				
			||||||
import 'package:wyatt_architecture/wyatt_architecture.dart';
 | 
					import 'package:wyatt_architecture/wyatt_architecture.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Represents a user [Account] in the 
 | 
					/// {@template account}
 | 
				
			||||||
 | 
					/// Represents a user [Account] in the
 | 
				
			||||||
/// various identity provisioning systems.
 | 
					/// various identity provisioning systems.
 | 
				
			||||||
 | 
					/// {@endtemplate}
 | 
				
			||||||
class Account extends Equatable implements Entity {
 | 
					class Account extends Equatable implements Entity {
 | 
				
			||||||
 | 
					  /// {@macro account}
 | 
				
			||||||
  const Account({
 | 
					  const Account({
 | 
				
			||||||
    required this.id,
 | 
					    required this.id,
 | 
				
			||||||
    required this.isAnonymous,
 | 
					    required this.isAnonymous,
 | 
				
			||||||
 | 
				
			|||||||
@ -17,16 +17,20 @@
 | 
				
			|||||||
import 'package:equatable/equatable.dart';
 | 
					import 'package:equatable/equatable.dart';
 | 
				
			||||||
import 'package:wyatt_authentication_bloc/wyatt_authentication_bloc.dart';
 | 
					import 'package:wyatt_authentication_bloc/wyatt_authentication_bloc.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// {@template authentication_session}
 | 
				
			||||||
/// The [AuthenticationSession] object is used to transport and propagate
 | 
					/// The [AuthenticationSession] object is used to transport and propagate
 | 
				
			||||||
/// the last event issued by an authentication state change, a user account
 | 
					/// the last event issued by an authentication state change, a user account
 | 
				
			||||||
/// if connected, and the associated data.
 | 
					/// if connected, and the associated data.
 | 
				
			||||||
 | 
					/// {@endtemplate}
 | 
				
			||||||
class AuthenticationSession<Data> extends Equatable {
 | 
					class AuthenticationSession<Data> extends Equatable {
 | 
				
			||||||
 | 
					  /// {@macro authentication_session}
 | 
				
			||||||
  const AuthenticationSession({
 | 
					  const AuthenticationSession({
 | 
				
			||||||
    required this.latestEvent,
 | 
					    required this.latestEvent,
 | 
				
			||||||
    this.account,
 | 
					    this.account,
 | 
				
			||||||
    this.data,
 | 
					    this.data,
 | 
				
			||||||
  });
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// Creates a new [AuthenticationSession] from an [AuthenticationChangeEvent].
 | 
				
			||||||
  factory AuthenticationSession.fromEvent(
 | 
					  factory AuthenticationSession.fromEvent(
 | 
				
			||||||
    AuthenticationChangeEvent latestEvent, {
 | 
					    AuthenticationChangeEvent latestEvent, {
 | 
				
			||||||
    Data? data,
 | 
					    Data? data,
 | 
				
			||||||
@ -44,8 +48,13 @@ class AuthenticationSession<Data> extends Equatable {
 | 
				
			|||||||
    );
 | 
					    );
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// The last event issued by an authentication state change.
 | 
				
			||||||
  final AuthenticationChangeEvent latestEvent;
 | 
					  final AuthenticationChangeEvent latestEvent;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// The user account if connected.
 | 
				
			||||||
  final Account? account;
 | 
					  final Account? account;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// The associated data.
 | 
				
			||||||
  final Data? data;
 | 
					  final Data? data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  @override
 | 
					  @override
 | 
				
			||||||
 | 
				
			|||||||
@ -16,11 +16,14 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
part of 'authentication_change_event.dart';
 | 
					part of 'authentication_change_event.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// {@template authenticated_change_event}
 | 
				
			||||||
/// Represents every event where user is authenticated.
 | 
					/// Represents every event where user is authenticated.
 | 
				
			||||||
 | 
					/// {@endtemplate}
 | 
				
			||||||
abstract class AuthenticatedChangeEvent extends AuthenticationChangeEvent {
 | 
					abstract class AuthenticatedChangeEvent extends AuthenticationChangeEvent {
 | 
				
			||||||
 | 
					  /// {@macro authenticated_change_event}
 | 
				
			||||||
  const AuthenticatedChangeEvent({required this.account});
 | 
					  const AuthenticatedChangeEvent({required this.account});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// The user's account.
 | 
				
			||||||
  final Account account;
 | 
					  final Account account;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  @override
 | 
					  @override
 | 
				
			||||||
 | 
				
			|||||||
@ -29,9 +29,12 @@ part 'signed_up_event.dart';
 | 
				
			|||||||
part 'unknown_authentication_event.dart';
 | 
					part 'unknown_authentication_event.dart';
 | 
				
			||||||
part 'updated_event.dart';
 | 
					part 'updated_event.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// {@template authentication_change_event}
 | 
				
			||||||
/// Represents an event initiated by a change in
 | 
					/// Represents an event initiated by a change in
 | 
				
			||||||
/// the user's authentication status.
 | 
					/// the user's authentication status.
 | 
				
			||||||
 | 
					/// {@endtemplate}
 | 
				
			||||||
abstract class AuthenticationChangeEvent extends Equatable implements Entity {
 | 
					abstract class AuthenticationChangeEvent extends Equatable implements Entity {
 | 
				
			||||||
 | 
					  /// {@macro authentication_change_event}
 | 
				
			||||||
  const AuthenticationChangeEvent();
 | 
					  const AuthenticationChangeEvent();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  @override
 | 
					  @override
 | 
				
			||||||
 | 
				
			|||||||
@ -16,7 +16,10 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
part of 'authentication_change_event.dart';
 | 
					part of 'authentication_change_event.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// {@template deleted_event}
 | 
				
			||||||
/// When a user deleted his account.
 | 
					/// When a user deleted his account.
 | 
				
			||||||
 | 
					/// {@endtemplate}
 | 
				
			||||||
class DeletedEvent extends AuthenticationChangeEvent {
 | 
					class DeletedEvent extends AuthenticationChangeEvent {
 | 
				
			||||||
 | 
					  /// {@macro deleted_event}
 | 
				
			||||||
  const DeletedEvent();
 | 
					  const DeletedEvent();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -16,9 +16,12 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
part of 'authentication_change_event.dart';
 | 
					part of 'authentication_change_event.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// {@template reauthenticated_event}
 | 
				
			||||||
/// When a user re-authenticates (from the logged in state to the
 | 
					/// When a user re-authenticates (from the logged in state to the
 | 
				
			||||||
/// logged in state with a different and fresh access
 | 
					/// logged in state with a different and fresh access
 | 
				
			||||||
/// token and a different login time)
 | 
					/// token and a different login time)
 | 
				
			||||||
 | 
					/// {@endtemplate}
 | 
				
			||||||
class ReauthenticatedEvent extends AuthenticatedChangeEvent {
 | 
					class ReauthenticatedEvent extends AuthenticatedChangeEvent {
 | 
				
			||||||
 | 
					  /// {@macro reauthenticated_event}
 | 
				
			||||||
  const ReauthenticatedEvent({required super.account});
 | 
					  const ReauthenticatedEvent({required super.account});
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -16,8 +16,11 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
part of 'authentication_change_event.dart';
 | 
					part of 'authentication_change_event.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// {@template refreshed_event}
 | 
				
			||||||
/// When a user access token is refreshed (from the logged in state to the
 | 
					/// When a user access token is refreshed (from the logged in state to the
 | 
				
			||||||
/// logged in state with a different access token)
 | 
					/// logged in state with a different access token)
 | 
				
			||||||
 | 
					/// {@endtemplate}
 | 
				
			||||||
class RefreshedEvent extends AuthenticatedChangeEvent {
 | 
					class RefreshedEvent extends AuthenticatedChangeEvent {
 | 
				
			||||||
 | 
					  /// {@macro refreshed_event}
 | 
				
			||||||
  const RefreshedEvent({required super.account});
 | 
					  const RefreshedEvent({required super.account});
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -16,7 +16,10 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
part of 'authentication_change_event.dart';
 | 
					part of 'authentication_change_event.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// {@template signed_in_event}
 | 
				
			||||||
/// When a user authenticates (from not logged in to logged in).
 | 
					/// When a user authenticates (from not logged in to logged in).
 | 
				
			||||||
 | 
					/// {@endtemplate}
 | 
				
			||||||
class SignedInEvent extends AuthenticatedChangeEvent {
 | 
					class SignedInEvent extends AuthenticatedChangeEvent {
 | 
				
			||||||
 | 
					  /// {@macro signed_in_event}
 | 
				
			||||||
  const SignedInEvent({required super.account});
 | 
					  const SignedInEvent({required super.account});
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -16,7 +16,10 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
part of 'authentication_change_event.dart';
 | 
					part of 'authentication_change_event.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// {@template signed_in_from_cache_event}
 | 
				
			||||||
/// When a user authenticates automatically (from not logged in to logged in).
 | 
					/// When a user authenticates automatically (from not logged in to logged in).
 | 
				
			||||||
 | 
					/// {@endtemplate}
 | 
				
			||||||
class SignedInFromCacheEvent extends AuthenticatedChangeEvent {
 | 
					class SignedInFromCacheEvent extends AuthenticatedChangeEvent {
 | 
				
			||||||
 | 
					  /// {@macro signed_in_from_cache_event}
 | 
				
			||||||
  const SignedInFromCacheEvent({required super.account});
 | 
					  const SignedInFromCacheEvent({required super.account});
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -16,7 +16,10 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
part of 'authentication_change_event.dart';
 | 
					part of 'authentication_change_event.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// {@template signed_out_event}
 | 
				
			||||||
/// When a user logs out.
 | 
					/// When a user logs out.
 | 
				
			||||||
 | 
					/// {@endtemplate}
 | 
				
			||||||
class SignedOutEvent extends AuthenticationChangeEvent {
 | 
					class SignedOutEvent extends AuthenticationChangeEvent {
 | 
				
			||||||
 | 
					  /// {@macro signed_out_event}
 | 
				
			||||||
  const SignedOutEvent();
 | 
					  const SignedOutEvent();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -16,7 +16,10 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
part of 'authentication_change_event.dart';
 | 
					part of 'authentication_change_event.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// {@template signed_up_event}
 | 
				
			||||||
/// When a user creates an account.
 | 
					/// When a user creates an account.
 | 
				
			||||||
 | 
					/// {@endtemplate}
 | 
				
			||||||
class SignedUpEvent extends AuthenticatedChangeEvent {
 | 
					class SignedUpEvent extends AuthenticatedChangeEvent {
 | 
				
			||||||
 | 
					  /// {@macro signed_up_event}
 | 
				
			||||||
  const SignedUpEvent({required super.account});
 | 
					  const SignedUpEvent({required super.account});
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -16,7 +16,10 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
part of 'authentication_change_event.dart';
 | 
					part of 'authentication_change_event.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// {@template unknown_authentication_event}
 | 
				
			||||||
/// When a user's login status is unknown.
 | 
					/// When a user's login status is unknown.
 | 
				
			||||||
 | 
					/// {@endtemplate}
 | 
				
			||||||
class UnknownAuthenticationEvent extends AuthenticationChangeEvent {
 | 
					class UnknownAuthenticationEvent extends AuthenticationChangeEvent {
 | 
				
			||||||
 | 
					  /// {@macro unknown_authentication_event}
 | 
				
			||||||
  const UnknownAuthenticationEvent();
 | 
					  const UnknownAuthenticationEvent();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -16,7 +16,10 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
part of 'authentication_change_event.dart';
 | 
					part of 'authentication_change_event.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// {@template updated_event}
 | 
				
			||||||
/// When the user's account has been updated.
 | 
					/// When the user's account has been updated.
 | 
				
			||||||
 | 
					/// {@endtemplate}
 | 
				
			||||||
class UpdatedEvent extends AuthenticatedChangeEvent {
 | 
					class UpdatedEvent extends AuthenticatedChangeEvent {
 | 
				
			||||||
 | 
					  /// {@macro updated_event}
 | 
				
			||||||
  const UpdatedEvent({required super.account});
 | 
					  const UpdatedEvent({required super.account});
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -19,13 +19,25 @@ import 'package:wyatt_authentication_bloc/src/domain/entities/account.dart';
 | 
				
			|||||||
import 'package:wyatt_authentication_bloc/src/domain/entities/auth_session.dart';
 | 
					import 'package:wyatt_authentication_bloc/src/domain/entities/auth_session.dart';
 | 
				
			||||||
import 'package:wyatt_form_bloc/wyatt_form_bloc.dart';
 | 
					import 'package:wyatt_form_bloc/wyatt_form_bloc.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// {@template auth_repo}
 | 
				
			||||||
 | 
					/// Authentication repository interface.
 | 
				
			||||||
 | 
					/// {@endtemplate}
 | 
				
			||||||
abstract class AuthenticationRepository<Data> extends BaseRepository {
 | 
					abstract class AuthenticationRepository<Data> extends BaseRepository {
 | 
				
			||||||
  /// {@template form_repo}
 | 
					  /// {@template form_repo}
 | 
				
			||||||
  /// Form repository used in different authentication cubits/blocs
 | 
					  /// Form repository used in different authentication cubits/blocs
 | 
				
			||||||
  /// {@endtemplate}
 | 
					  /// {@endtemplate}
 | 
				
			||||||
  FormRepository get formRepository;
 | 
					  FormRepository get formRepository;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Stream related methods ===================================================
 | 
					  // Cache related methods ====================================================
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// {@template check_cache_account}
 | 
				
			||||||
 | 
					  /// Checks if there is a cached account.
 | 
				
			||||||
 | 
					  /// And if there is, it will sign in the user automatically by
 | 
				
			||||||
 | 
					  /// emitting an event.
 | 
				
			||||||
 | 
					  /// {@endtemplate}
 | 
				
			||||||
 | 
					  Future<void> checkForCachedAccount();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Session related methods ===================================================
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /// {@template add_session}
 | 
					  /// {@template add_session}
 | 
				
			||||||
  /// Add a new authentication event.
 | 
					  /// Add a new authentication event.
 | 
				
			||||||
 | 
				
			|||||||
@ -20,7 +20,11 @@ import 'package:wyatt_authentication_bloc/src/core/enums/authentication_status.d
 | 
				
			|||||||
import 'package:wyatt_authentication_bloc/src/domain/entities/auth_session.dart';
 | 
					import 'package:wyatt_authentication_bloc/src/domain/entities/auth_session.dart';
 | 
				
			||||||
import 'package:wyatt_authentication_bloc/src/features/authentication/cubit/authentication_cubit.dart';
 | 
					import 'package:wyatt_authentication_bloc/src/features/authentication/cubit/authentication_cubit.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// {@template authentication_builder}
 | 
				
			||||||
 | 
					/// A widget that builds itself based on the current authentication state.
 | 
				
			||||||
 | 
					/// {@endtemplate}
 | 
				
			||||||
class AuthenticationBuilder<Data> extends StatelessWidget {
 | 
					class AuthenticationBuilder<Data> extends StatelessWidget {
 | 
				
			||||||
 | 
					  /// {@macro authentication_builder}
 | 
				
			||||||
  const AuthenticationBuilder({
 | 
					  const AuthenticationBuilder({
 | 
				
			||||||
    required this.authenticated,
 | 
					    required this.authenticated,
 | 
				
			||||||
    required this.unauthenticated,
 | 
					    required this.unauthenticated,
 | 
				
			||||||
@ -28,11 +32,16 @@ class AuthenticationBuilder<Data> extends StatelessWidget {
 | 
				
			|||||||
    super.key,
 | 
					    super.key,
 | 
				
			||||||
  });
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// Widget to show when the user is authenticated.
 | 
				
			||||||
  final Widget Function(
 | 
					  final Widget Function(
 | 
				
			||||||
    BuildContext context,
 | 
					    BuildContext context,
 | 
				
			||||||
    AuthenticationSession<Data> session,
 | 
					    AuthenticationSession<Data> session,
 | 
				
			||||||
  ) authenticated;
 | 
					  ) authenticated;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// Widget to show when the user is unauthenticated.
 | 
				
			||||||
  final Widget Function(BuildContext context) unauthenticated;
 | 
					  final Widget Function(BuildContext context) unauthenticated;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// Widget to show when the authentication status is unknown.
 | 
				
			||||||
  final Widget Function(BuildContext context) unknown;
 | 
					  final Widget Function(BuildContext context) unknown;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  @override
 | 
					  @override
 | 
				
			||||||
 | 
				
			|||||||
@ -27,27 +27,45 @@ import 'package:wyatt_type_utils/wyatt_type_utils.dart';
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
part 'authentication_state.dart';
 | 
					part 'authentication_state.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// {@template authentication_cubit}
 | 
				
			||||||
/// Abstract authentication cubit class needs to be implemented in application.
 | 
					/// Abstract authentication cubit class needs to be implemented in application.
 | 
				
			||||||
///
 | 
					///
 | 
				
			||||||
/// This cubit is in charge of managing the global authentication state of
 | 
					/// This cubit is in charge of managing the global authentication state of
 | 
				
			||||||
/// the application.
 | 
					/// the application.
 | 
				
			||||||
///
 | 
					///
 | 
				
			||||||
/// Its here you can override every callbacks and add your custom logic.
 | 
					/// Its here you can override every callbacks and add your custom logic.
 | 
				
			||||||
 | 
					/// {@endtemplate}
 | 
				
			||||||
abstract class AuthenticationCubit<Data>
 | 
					abstract class AuthenticationCubit<Data>
 | 
				
			||||||
    extends Cubit<AuthenticationState<Data>> {
 | 
					    extends Cubit<AuthenticationState<Data>> {
 | 
				
			||||||
 | 
					  /// {@macro authentication_cubit}
 | 
				
			||||||
  AuthenticationCubit({
 | 
					  AuthenticationCubit({
 | 
				
			||||||
    required this.authenticationRepository,
 | 
					    required this.authenticationRepository,
 | 
				
			||||||
  }) : super(const AuthenticationState.unknown()) {
 | 
					  }) : super(const AuthenticationState.unknown()) {
 | 
				
			||||||
    _listenForAuthenticationChanges();
 | 
					    _init();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// The authentication repository.
 | 
				
			||||||
  final AuthenticationRepository<Data> authenticationRepository;
 | 
					  final AuthenticationRepository<Data> authenticationRepository;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// The latest session.
 | 
				
			||||||
  AuthenticationSession<Data>? _latestSession;
 | 
					  AuthenticationSession<Data>? _latestSession;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// Method that is called when the cubit is initialized.
 | 
				
			||||||
 | 
					  Future<void> _init() async {
 | 
				
			||||||
 | 
					    /// Setup listeners.
 | 
				
			||||||
 | 
					    _listenForAuthenticationChanges();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Check if there is a cached account.
 | 
				
			||||||
 | 
					    await authenticationRepository.checkForCachedAccount();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  void _listenForAuthenticationChanges() {
 | 
					  void _listenForAuthenticationChanges() {
 | 
				
			||||||
    authenticationRepository.sessionStream().asyncMap((session) async {
 | 
					    authenticationRepository.sessionStream().asyncMap((session) async {
 | 
				
			||||||
      final event = session.latestEvent;
 | 
					      final event = session.latestEvent;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      /// If the session is signed in from cache.
 | 
				
			||||||
      if (event is SignedInFromCacheEvent) {
 | 
					      if (event is SignedInFromCacheEvent) {
 | 
				
			||||||
 | 
					        /// Call the custom routine.
 | 
				
			||||||
        final customRoutineResult = await onSignInFromCache(session);
 | 
					        final customRoutineResult = await onSignInFromCache(session);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (customRoutineResult.isOk) {
 | 
					        if (customRoutineResult.isOk) {
 | 
				
			||||||
@ -64,12 +82,18 @@ abstract class AuthenticationCubit<Data>
 | 
				
			|||||||
      }
 | 
					      }
 | 
				
			||||||
      return session;
 | 
					      return session;
 | 
				
			||||||
    }).listen((session) async {
 | 
					    }).listen((session) async {
 | 
				
			||||||
 | 
					      /// Save the latest session.
 | 
				
			||||||
      _latestSession = session;
 | 
					      _latestSession = session;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      /// If there is an account: emit authenticated state.
 | 
				
			||||||
      if (session.account != null) {
 | 
					      if (session.account != null) {
 | 
				
			||||||
        emit(AuthenticationState<Data>.authenticated(session));
 | 
					        emit(AuthenticationState<Data>.authenticated(session));
 | 
				
			||||||
        return;
 | 
					        return;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      /// If there is no account: emit unauthenticated state.
 | 
				
			||||||
      emit(AuthenticationState<Data>.unauthenticated());
 | 
					      emit(AuthenticationState<Data>.unauthenticated());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      return;
 | 
					      return;
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
				
			|||||||
@ -16,22 +16,32 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
part of 'authentication_cubit.dart';
 | 
					part of 'authentication_cubit.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// {@template authentication_status}
 | 
				
			||||||
 | 
					/// The status of the authentication cubit.
 | 
				
			||||||
 | 
					/// {@endtemplate}
 | 
				
			||||||
class AuthenticationState<Data> extends Equatable {
 | 
					class AuthenticationState<Data> extends Equatable {
 | 
				
			||||||
 | 
					  /// {@macro authentication_status}
 | 
				
			||||||
  const AuthenticationState._(this.status, this.session);
 | 
					  const AuthenticationState._(this.status, this.session);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// The user is not authenticated.
 | 
				
			||||||
  const AuthenticationState.unauthenticated()
 | 
					  const AuthenticationState.unauthenticated()
 | 
				
			||||||
      : this._(AuthenticationStatus.unauthenticated, null);
 | 
					      : this._(AuthenticationStatus.unauthenticated, null);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// The user is authenticated.
 | 
				
			||||||
  const AuthenticationState.authenticated(AuthenticationSession<Data> session)
 | 
					  const AuthenticationState.authenticated(AuthenticationSession<Data> session)
 | 
				
			||||||
      : this._(
 | 
					      : this._(
 | 
				
			||||||
          AuthenticationStatus.authenticated,
 | 
					          AuthenticationStatus.authenticated,
 | 
				
			||||||
          session,
 | 
					          session,
 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// The user's authentication status is unknown.
 | 
				
			||||||
  const AuthenticationState.unknown()
 | 
					  const AuthenticationState.unknown()
 | 
				
			||||||
      : this._(AuthenticationStatus.unknown, null);
 | 
					      : this._(AuthenticationStatus.unknown, null);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// The status of the authentication cubit.
 | 
				
			||||||
  final AuthenticationStatus status;
 | 
					  final AuthenticationStatus status;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// The session of the authentication cubit.
 | 
				
			||||||
  final AuthenticationSession<Data>? session;
 | 
					  final AuthenticationSession<Data>? session;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  @override
 | 
					  @override
 | 
				
			||||||
 | 
				
			|||||||
@ -16,10 +16,13 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
part of 'edit_account_cubit.dart';
 | 
					part of 'edit_account_cubit.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// {@template edit_account_cubit}
 | 
				
			||||||
/// Abstract edit account cubit useful for implementing a cubit with fine
 | 
					/// Abstract edit account cubit useful for implementing a cubit with fine
 | 
				
			||||||
/// granularity by adding only the required mixins.
 | 
					/// granularity by adding only the required mixins.
 | 
				
			||||||
 | 
					/// {@endtemplate}
 | 
				
			||||||
abstract class BaseEditAccountCubit<Data>
 | 
					abstract class BaseEditAccountCubit<Data>
 | 
				
			||||||
    extends FormDataCubit<EditAccountState> {
 | 
					    extends FormDataCubit<EditAccountState> {
 | 
				
			||||||
 | 
					  /// {@macro edit_account_cubit}
 | 
				
			||||||
  BaseEditAccountCubit({
 | 
					  BaseEditAccountCubit({
 | 
				
			||||||
    required this.authenticationRepository,
 | 
					    required this.authenticationRepository,
 | 
				
			||||||
  }) : super(
 | 
					  }) : super(
 | 
				
			||||||
@ -28,6 +31,8 @@ abstract class BaseEditAccountCubit<Data>
 | 
				
			|||||||
                .accessForm(AuthFormName.signInForm),
 | 
					                .accessForm(AuthFormName.signInForm),
 | 
				
			||||||
          ),
 | 
					          ),
 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// The authentication repository.
 | 
				
			||||||
  final AuthenticationRepository<Data> authenticationRepository;
 | 
					  final AuthenticationRepository<Data> authenticationRepository;
 | 
				
			||||||
  FormRepository get formRepository => authenticationRepository.formRepository;
 | 
					  FormRepository get formRepository => authenticationRepository.formRepository;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -28,11 +28,14 @@ import 'package:wyatt_type_utils/wyatt_type_utils.dart';
 | 
				
			|||||||
part 'base_edit_account_cubit.dart';
 | 
					part 'base_edit_account_cubit.dart';
 | 
				
			||||||
part 'edit_account_state.dart';
 | 
					part 'edit_account_state.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// {@template edit_account_cubit}
 | 
				
			||||||
/// Fully featured edit account cubit.
 | 
					/// Fully featured edit account cubit.
 | 
				
			||||||
///
 | 
					///
 | 
				
			||||||
/// Sufficient in most cases. (Where fine granularity is not required.)
 | 
					/// Sufficient in most cases. (Where fine granularity is not required.)
 | 
				
			||||||
 | 
					/// {@endtemplate}
 | 
				
			||||||
class EditAccountCubit<Data> extends BaseEditAccountCubit<Data>
 | 
					class EditAccountCubit<Data> extends BaseEditAccountCubit<Data>
 | 
				
			||||||
    with UpdateEmail<Data>, UpdatePassword<Data> {
 | 
					    with UpdateEmail<Data>, UpdatePassword<Data> {
 | 
				
			||||||
 | 
					  /// {@macro edit_account_cubit}
 | 
				
			||||||
  EditAccountCubit({required super.authenticationRepository});
 | 
					  EditAccountCubit({required super.authenticationRepository});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  @override
 | 
					  @override
 | 
				
			||||||
 | 
				
			|||||||
@ -16,15 +16,22 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
part of 'edit_account_cubit.dart';
 | 
					part of 'edit_account_cubit.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// {@template edit_account_state}
 | 
				
			||||||
/// Edit account cubit state to manage the form.
 | 
					/// Edit account cubit state to manage the form.
 | 
				
			||||||
 | 
					/// {@endtemplate}
 | 
				
			||||||
class EditAccountState extends FormDataState {
 | 
					class EditAccountState extends FormDataState {
 | 
				
			||||||
 | 
					  /// {@macro edit_account_state}
 | 
				
			||||||
  const EditAccountState({
 | 
					  const EditAccountState({
 | 
				
			||||||
    required super.form,
 | 
					    required super.form,
 | 
				
			||||||
    super.status = FormStatus.pure,
 | 
					    super.status = FormStatus.pure,
 | 
				
			||||||
    super.errorMessage,
 | 
					    super.errorMessage,
 | 
				
			||||||
  });
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// Email validator of the form
 | 
				
			||||||
  FormInputValidator<String?, ValidationError> get email =>
 | 
					  FormInputValidator<String?, ValidationError> get email =>
 | 
				
			||||||
      form.validatorOf(AuthFormField.email);
 | 
					      form.validatorOf(AuthFormField.email);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// Password validator of the form
 | 
				
			||||||
  FormInputValidator<String?, ValidationError> get password =>
 | 
					  FormInputValidator<String?, ValidationError> get password =>
 | 
				
			||||||
      form.validatorOf(AuthFormField.password);
 | 
					      form.validatorOf(AuthFormField.password);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -19,9 +19,12 @@ import 'package:flutter_bloc/flutter_bloc.dart';
 | 
				
			|||||||
import 'package:wyatt_authentication_bloc/src/features/edit_account/cubit/edit_account_cubit.dart';
 | 
					import 'package:wyatt_authentication_bloc/src/features/edit_account/cubit/edit_account_cubit.dart';
 | 
				
			||||||
import 'package:wyatt_form_bloc/wyatt_form_bloc.dart';
 | 
					import 'package:wyatt_form_bloc/wyatt_form_bloc.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// {@template edit_account_listener}
 | 
				
			||||||
/// Widget that listens and builds a child based on the state of
 | 
					/// Widget that listens and builds a child based on the state of
 | 
				
			||||||
/// the edit account cubit
 | 
					/// the edit account cubit
 | 
				
			||||||
 | 
					/// {@endtemplate}
 | 
				
			||||||
class EditAccountListener<Data> extends StatelessWidget {
 | 
					class EditAccountListener<Data> extends StatelessWidget {
 | 
				
			||||||
 | 
					  /// {@macro edit_account_listener}
 | 
				
			||||||
  const EditAccountListener({
 | 
					  const EditAccountListener({
 | 
				
			||||||
    required this.child,
 | 
					    required this.child,
 | 
				
			||||||
    this.onProgress,
 | 
					    this.onProgress,
 | 
				
			||||||
@ -31,15 +34,25 @@ class EditAccountListener<Data> extends StatelessWidget {
 | 
				
			|||||||
    super.key,
 | 
					    super.key,
 | 
				
			||||||
  });
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// Callback to show when the edit account is in progress
 | 
				
			||||||
  final void Function(BuildContext context)? onProgress;
 | 
					  final void Function(BuildContext context)? onProgress;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// Callback to show when the edit account is successful
 | 
				
			||||||
  final void Function(BuildContext context)? onSuccess;
 | 
					  final void Function(BuildContext context)? onSuccess;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// Callback to show when the edit account is unsuccessful
 | 
				
			||||||
  final void Function(
 | 
					  final void Function(
 | 
				
			||||||
    BuildContext context,
 | 
					    BuildContext context,
 | 
				
			||||||
    FormStatus status,
 | 
					    FormStatus status,
 | 
				
			||||||
    String? errorMessage,
 | 
					    String? errorMessage,
 | 
				
			||||||
  )? onError;
 | 
					  )? onError;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// Custom builder to show when the edit account is in progress, successful,
 | 
				
			||||||
 | 
					  /// or unsuccessful
 | 
				
			||||||
  final void Function(BuildContext context, EditAccountState state)?
 | 
					  final void Function(BuildContext context, EditAccountState state)?
 | 
				
			||||||
      customBuilder;
 | 
					      customBuilder;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// Child of the widget
 | 
				
			||||||
  final Widget child;
 | 
					  final Widget child;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  @override
 | 
					  @override
 | 
				
			||||||
 | 
				
			|||||||
@ -19,7 +19,11 @@ import 'package:flutter_bloc/flutter_bloc.dart';
 | 
				
			|||||||
import 'package:wyatt_authentication_bloc/src/features/email_verification/cubit/email_verification_cubit.dart';
 | 
					import 'package:wyatt_authentication_bloc/src/features/email_verification/cubit/email_verification_cubit.dart';
 | 
				
			||||||
import 'package:wyatt_form_bloc/wyatt_form_bloc.dart';
 | 
					import 'package:wyatt_form_bloc/wyatt_form_bloc.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// {@template email_verification_builder}
 | 
				
			||||||
 | 
					/// A widget that builds itself based on the latest [EmailVerificationState].
 | 
				
			||||||
 | 
					/// {@endtemplate}
 | 
				
			||||||
class EmailVerificationBuilder<Extra> extends StatelessWidget {
 | 
					class EmailVerificationBuilder<Extra> extends StatelessWidget {
 | 
				
			||||||
 | 
					  /// {@macro email_verification_builder}
 | 
				
			||||||
  const EmailVerificationBuilder({
 | 
					  const EmailVerificationBuilder({
 | 
				
			||||||
    required this.verified,
 | 
					    required this.verified,
 | 
				
			||||||
    required this.notVerified,
 | 
					    required this.notVerified,
 | 
				
			||||||
@ -28,14 +32,21 @@ class EmailVerificationBuilder<Extra> extends StatelessWidget {
 | 
				
			|||||||
    super.key,
 | 
					    super.key,
 | 
				
			||||||
  });
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// Widget to show when the email is verified
 | 
				
			||||||
  final Widget Function(BuildContext context) verified;
 | 
					  final Widget Function(BuildContext context) verified;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// Widget to show when the email is not verified
 | 
				
			||||||
  final Widget Function(BuildContext context) notVerified;
 | 
					  final Widget Function(BuildContext context) notVerified;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// Widget to show when the email verification is unsuccessful
 | 
				
			||||||
  final Widget Function(
 | 
					  final Widget Function(
 | 
				
			||||||
    BuildContext context,
 | 
					    BuildContext context,
 | 
				
			||||||
    FormStatus status,
 | 
					    FormStatus status,
 | 
				
			||||||
    String? errorMessage,
 | 
					    String? errorMessage,
 | 
				
			||||||
  ) onError;
 | 
					  ) onError;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// Custom builder to show when the email is verified, not verified, or
 | 
				
			||||||
 | 
					  /// unsuccessful
 | 
				
			||||||
  final Widget Function(BuildContext context, EmailVerificationState)?
 | 
					  final Widget Function(BuildContext context, EmailVerificationState)?
 | 
				
			||||||
      customBuilder;
 | 
					      customBuilder;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -23,11 +23,16 @@ import 'package:wyatt_form_bloc/wyatt_form_bloc.dart';
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
part 'email_verification_state.dart';
 | 
					part 'email_verification_state.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// {@template email_verification_cubit}
 | 
				
			||||||
 | 
					/// Cubit for sending email verification.
 | 
				
			||||||
 | 
					/// {@endtemplate}
 | 
				
			||||||
class EmailVerificationCubit<Data> extends Cubit<EmailVerificationState> {
 | 
					class EmailVerificationCubit<Data> extends Cubit<EmailVerificationState> {
 | 
				
			||||||
 | 
					  /// {@macro email_verification_cubit}
 | 
				
			||||||
  EmailVerificationCubit({
 | 
					  EmailVerificationCubit({
 | 
				
			||||||
    required this.authenticationRepository,
 | 
					    required this.authenticationRepository,
 | 
				
			||||||
  }) : super(const EmailVerificationState());
 | 
					  }) : super(const EmailVerificationState());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// The [AuthenticationRepository] used to send email verification.
 | 
				
			||||||
  final AuthenticationRepository<Data> authenticationRepository;
 | 
					  final AuthenticationRepository<Data> authenticationRepository;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  FutureOr<void> sendEmailVerification() async {
 | 
					  FutureOr<void> sendEmailVerification() async {
 | 
				
			||||||
 | 
				
			|||||||
@ -16,15 +16,24 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
part of 'email_verification_cubit.dart';
 | 
					part of 'email_verification_cubit.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// {@template email_verification_state}
 | 
				
			||||||
 | 
					/// The state of the [EmailVerificationCubit].
 | 
				
			||||||
 | 
					/// {@endtemplate}
 | 
				
			||||||
class EmailVerificationState extends Equatable {
 | 
					class EmailVerificationState extends Equatable {
 | 
				
			||||||
 | 
					  /// {@macro email_verification_state}
 | 
				
			||||||
  const EmailVerificationState({
 | 
					  const EmailVerificationState({
 | 
				
			||||||
    this.isVerified = false,
 | 
					    this.isVerified = false,
 | 
				
			||||||
    this.status = FormStatus.pure,
 | 
					    this.status = FormStatus.pure,
 | 
				
			||||||
    this.errorMessage,
 | 
					    this.errorMessage,
 | 
				
			||||||
  });
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// The status of the form.
 | 
				
			||||||
  final FormStatus status;
 | 
					  final FormStatus status;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// Whether the email is verified.
 | 
				
			||||||
  final bool isVerified;
 | 
					  final bool isVerified;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// The error message if any.
 | 
				
			||||||
  final String? errorMessage;
 | 
					  final String? errorMessage;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  EmailVerificationState copyWith({
 | 
					  EmailVerificationState copyWith({
 | 
				
			||||||
 | 
				
			|||||||
@ -24,8 +24,11 @@ import 'package:wyatt_type_utils/wyatt_type_utils.dart';
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
part 'password_reset_state.dart';
 | 
					part 'password_reset_state.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// {@template password_reset_cubit}
 | 
				
			||||||
/// Cubit that allows user to reset his password
 | 
					/// Cubit that allows user to reset his password
 | 
				
			||||||
 | 
					/// {@endtemplate}
 | 
				
			||||||
class PasswordResetCubit<Extra> extends FormDataCubit<PasswordResetState> {
 | 
					class PasswordResetCubit<Extra> extends FormDataCubit<PasswordResetState> {
 | 
				
			||||||
 | 
					  /// {@macro password_reset_cubit}
 | 
				
			||||||
  PasswordResetCubit({
 | 
					  PasswordResetCubit({
 | 
				
			||||||
    required this.authenticationRepository,
 | 
					    required this.authenticationRepository,
 | 
				
			||||||
  }) : super(
 | 
					  }) : super(
 | 
				
			||||||
@ -34,6 +37,8 @@ class PasswordResetCubit<Extra> extends FormDataCubit<PasswordResetState> {
 | 
				
			|||||||
                .accessForm(AuthFormName.passwordResetForm),
 | 
					                .accessForm(AuthFormName.passwordResetForm),
 | 
				
			||||||
          ),
 | 
					          ),
 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// The repository that handles the authentication
 | 
				
			||||||
  final AuthenticationRepository<Extra> authenticationRepository;
 | 
					  final AuthenticationRepository<Extra> authenticationRepository;
 | 
				
			||||||
  FormRepository get formRepository => authenticationRepository.formRepository;
 | 
					  FormRepository get formRepository => authenticationRepository.formRepository;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -16,12 +16,18 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
part of 'password_reset_cubit.dart';
 | 
					part of 'password_reset_cubit.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// {@template password_reset_state}
 | 
				
			||||||
 | 
					/// The state of the [PasswordResetCubit].
 | 
				
			||||||
 | 
					/// {@endtemplate}
 | 
				
			||||||
class PasswordResetState extends FormDataState {
 | 
					class PasswordResetState extends FormDataState {
 | 
				
			||||||
 | 
					  /// {@macro password_reset_state}
 | 
				
			||||||
  const PasswordResetState({
 | 
					  const PasswordResetState({
 | 
				
			||||||
    required super.form,
 | 
					    required super.form,
 | 
				
			||||||
    super.status = FormStatus.pure,
 | 
					    super.status = FormStatus.pure,
 | 
				
			||||||
    super.errorMessage,
 | 
					    super.errorMessage,
 | 
				
			||||||
  });
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// The email validator of the form.
 | 
				
			||||||
  Email get email => form.validatorOf(AuthFormField.email);
 | 
					  Email get email => form.validatorOf(AuthFormField.email);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  PasswordResetState copyWith({
 | 
					  PasswordResetState copyWith({
 | 
				
			||||||
 | 
				
			|||||||
@ -16,9 +16,12 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
part of 'sign_in_cubit.dart';
 | 
					part of 'sign_in_cubit.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Abstract sign in cubit useful for implementing a cubit with fine 
 | 
					/// {@template sign_in_cubit}
 | 
				
			||||||
 | 
					/// Abstract sign in cubit useful for implementing a cubit with fine
 | 
				
			||||||
/// granularity by adding only the required mixins.
 | 
					/// granularity by adding only the required mixins.
 | 
				
			||||||
 | 
					/// {@endtemplate}
 | 
				
			||||||
abstract class BaseSignInCubit<Data> extends FormDataCubit<SignInState> {
 | 
					abstract class BaseSignInCubit<Data> extends FormDataCubit<SignInState> {
 | 
				
			||||||
 | 
					  /// {@macro sign_in_cubit}
 | 
				
			||||||
  BaseSignInCubit({
 | 
					  BaseSignInCubit({
 | 
				
			||||||
    required this.authenticationRepository,
 | 
					    required this.authenticationRepository,
 | 
				
			||||||
  }) : super(
 | 
					  }) : super(
 | 
				
			||||||
@ -27,6 +30,8 @@ abstract class BaseSignInCubit<Data> extends FormDataCubit<SignInState> {
 | 
				
			|||||||
                .accessForm(AuthFormName.signInForm),
 | 
					                .accessForm(AuthFormName.signInForm),
 | 
				
			||||||
          ),
 | 
					          ),
 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// The authentication repository.
 | 
				
			||||||
  final AuthenticationRepository<Data> authenticationRepository;
 | 
					  final AuthenticationRepository<Data> authenticationRepository;
 | 
				
			||||||
  FormRepository get formRepository => authenticationRepository.formRepository;
 | 
					  FormRepository get formRepository => authenticationRepository.formRepository;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -14,7 +14,6 @@
 | 
				
			|||||||
// 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_architecture/wyatt_architecture.dart';
 | 
				
			||||||
@ -31,14 +30,17 @@ import 'package:wyatt_type_utils/wyatt_type_utils.dart';
 | 
				
			|||||||
part 'base_sign_in_cubit.dart';
 | 
					part 'base_sign_in_cubit.dart';
 | 
				
			||||||
part 'sign_in_state.dart';
 | 
					part 'sign_in_state.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// {@template sign_in_cubit}
 | 
				
			||||||
/// Fully featured sign in cubit.
 | 
					/// Fully featured sign in cubit.
 | 
				
			||||||
/// 
 | 
					///
 | 
				
			||||||
/// Sufficient in most cases. (Where fine granularity is not required.)
 | 
					/// Sufficient in most cases. (Where fine granularity is not required.)
 | 
				
			||||||
 | 
					/// {@endtemplate}
 | 
				
			||||||
class SignInCubit<Data> extends BaseSignInCubit<Data>
 | 
					class SignInCubit<Data> extends BaseSignInCubit<Data>
 | 
				
			||||||
    with
 | 
					    with
 | 
				
			||||||
        SignInAnonymously<Data>,
 | 
					        SignInAnonymously<Data>,
 | 
				
			||||||
        SignInWithEmailPassword<Data>,
 | 
					        SignInWithEmailPassword<Data>,
 | 
				
			||||||
        SignInWithGoogle<Data> {
 | 
					        SignInWithGoogle<Data> {
 | 
				
			||||||
 | 
					  /// {@macro sign_in_cubit}
 | 
				
			||||||
  SignInCubit({required super.authenticationRepository});
 | 
					  SignInCubit({required super.authenticationRepository});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  @override
 | 
					  @override
 | 
				
			||||||
 | 
				
			|||||||
@ -16,15 +16,22 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
part of 'sign_in_cubit.dart';
 | 
					part of 'sign_in_cubit.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// {@template sign_in_state}
 | 
				
			||||||
/// Sign in cubit state to manage the form.
 | 
					/// Sign in cubit state to manage the form.
 | 
				
			||||||
 | 
					/// {@endtemplate}
 | 
				
			||||||
class SignInState extends FormDataState {
 | 
					class SignInState extends FormDataState {
 | 
				
			||||||
 | 
					  /// {@macro sign_in_state}
 | 
				
			||||||
  const SignInState({
 | 
					  const SignInState({
 | 
				
			||||||
    required super.form,
 | 
					    required super.form,
 | 
				
			||||||
    super.status = FormStatus.pure,
 | 
					    super.status = FormStatus.pure,
 | 
				
			||||||
    super.errorMessage,
 | 
					    super.errorMessage,
 | 
				
			||||||
  });
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// Email validator of the form
 | 
				
			||||||
  FormInputValidator<String?, ValidationError> get email =>
 | 
					  FormInputValidator<String?, ValidationError> get email =>
 | 
				
			||||||
      form.validatorOf(AuthFormField.email);
 | 
					      form.validatorOf(AuthFormField.email);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// Password validator of the form
 | 
				
			||||||
  FormInputValidator<String?, ValidationError> get password =>
 | 
					  FormInputValidator<String?, ValidationError> get password =>
 | 
				
			||||||
      form.validatorOf(AuthFormField.password);
 | 
					      form.validatorOf(AuthFormField.password);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -19,9 +19,12 @@ import 'package:flutter_bloc/flutter_bloc.dart';
 | 
				
			|||||||
import 'package:wyatt_authentication_bloc/src/features/sign_in/sign_in.dart';
 | 
					import 'package:wyatt_authentication_bloc/src/features/sign_in/sign_in.dart';
 | 
				
			||||||
import 'package:wyatt_form_bloc/wyatt_form_bloc.dart';
 | 
					import 'package:wyatt_form_bloc/wyatt_form_bloc.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Widget that listens and builds a child based on the state of 
 | 
					/// {@template sign_in_listener}
 | 
				
			||||||
 | 
					/// Widget that listens and builds a child based on the state of
 | 
				
			||||||
/// the sign in cubit
 | 
					/// the sign in cubit
 | 
				
			||||||
 | 
					/// {@endtemplate}
 | 
				
			||||||
class SignInListener<Data> extends StatelessWidget {
 | 
					class SignInListener<Data> extends StatelessWidget {
 | 
				
			||||||
 | 
					  /// {@macro sign_in_listener}
 | 
				
			||||||
  const SignInListener({
 | 
					  const SignInListener({
 | 
				
			||||||
    required this.child,
 | 
					    required this.child,
 | 
				
			||||||
    this.onProgress,
 | 
					    this.onProgress,
 | 
				
			||||||
@ -31,14 +34,24 @@ class SignInListener<Data> extends StatelessWidget {
 | 
				
			|||||||
    super.key,
 | 
					    super.key,
 | 
				
			||||||
  });
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// Callback to show when the sign in is in progress
 | 
				
			||||||
  final void Function(BuildContext context)? onProgress;
 | 
					  final void Function(BuildContext context)? onProgress;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// Callback to show when the sign in is successful
 | 
				
			||||||
  final void Function(BuildContext context)? onSuccess;
 | 
					  final void Function(BuildContext context)? onSuccess;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// Callback to show when the sign in is unsuccessful
 | 
				
			||||||
  final void Function(
 | 
					  final void Function(
 | 
				
			||||||
    BuildContext context,
 | 
					    BuildContext context,
 | 
				
			||||||
    FormStatus status,
 | 
					    FormStatus status,
 | 
				
			||||||
    String? errorMessage,
 | 
					    String? errorMessage,
 | 
				
			||||||
  )? onError;
 | 
					  )? onError;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// Custom builder to show when the sign in is in progress, successful, or
 | 
				
			||||||
 | 
					  /// unsuccessful
 | 
				
			||||||
  final void Function(BuildContext context, SignInState state)? customBuilder;
 | 
					  final void Function(BuildContext context, SignInState state)? customBuilder;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// Child of the widget
 | 
				
			||||||
  final Widget child;
 | 
					  final Widget child;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  @override
 | 
					  @override
 | 
				
			||||||
 | 
				
			|||||||
@ -16,9 +16,12 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
part of 'sign_up_cubit.dart';
 | 
					part of 'sign_up_cubit.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Abstract sign up cubit useful for implementing a cubit with fine 
 | 
					/// {@template base_sign_up_cubit}
 | 
				
			||||||
 | 
					/// Abstract sign up cubit useful for implementing a cubit with fine
 | 
				
			||||||
/// granularity by adding only the required mixins.
 | 
					/// granularity by adding only the required mixins.
 | 
				
			||||||
 | 
					/// {@endtemplate}
 | 
				
			||||||
abstract class BaseSignUpCubit<Data> extends FormDataCubit<SignUpState> {
 | 
					abstract class BaseSignUpCubit<Data> extends FormDataCubit<SignUpState> {
 | 
				
			||||||
 | 
					  /// {@macro base_sign_up_cubit}
 | 
				
			||||||
  BaseSignUpCubit({
 | 
					  BaseSignUpCubit({
 | 
				
			||||||
    required this.authenticationRepository,
 | 
					    required this.authenticationRepository,
 | 
				
			||||||
  }) : super(
 | 
					  }) : super(
 | 
				
			||||||
@ -27,6 +30,8 @@ abstract class BaseSignUpCubit<Data> extends FormDataCubit<SignUpState> {
 | 
				
			|||||||
                .accessForm(AuthFormName.signUpForm),
 | 
					                .accessForm(AuthFormName.signUpForm),
 | 
				
			||||||
          ),
 | 
					          ),
 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// The authentication repository.
 | 
				
			||||||
  final AuthenticationRepository<Data> authenticationRepository;
 | 
					  final AuthenticationRepository<Data> authenticationRepository;
 | 
				
			||||||
  FormRepository get formRepository => authenticationRepository.formRepository;
 | 
					  FormRepository get formRepository => authenticationRepository.formRepository;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -28,11 +28,14 @@ import 'package:wyatt_type_utils/wyatt_type_utils.dart';
 | 
				
			|||||||
part 'base_sign_up_cubit.dart';
 | 
					part 'base_sign_up_cubit.dart';
 | 
				
			||||||
part 'sign_up_state.dart';
 | 
					part 'sign_up_state.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// {@template sign_up_cubit}
 | 
				
			||||||
/// Fully featured sign up cubit.
 | 
					/// Fully featured sign up cubit.
 | 
				
			||||||
/// 
 | 
					///
 | 
				
			||||||
/// Sufficient in most cases. (Where fine granularity is not required.)
 | 
					/// Sufficient in most cases. (Where fine granularity is not required.)
 | 
				
			||||||
 | 
					/// {@endtemplate}
 | 
				
			||||||
class SignUpCubit<Data> extends BaseSignUpCubit<Data>
 | 
					class SignUpCubit<Data> extends BaseSignUpCubit<Data>
 | 
				
			||||||
    with SignUpWithEmailPassword<Data> {
 | 
					    with SignUpWithEmailPassword<Data> {
 | 
				
			||||||
 | 
					  /// {@macro sign_up_cubit}
 | 
				
			||||||
  SignUpCubit({required super.authenticationRepository});
 | 
					  SignUpCubit({required super.authenticationRepository});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  @override
 | 
					  @override
 | 
				
			||||||
 | 
				
			|||||||
@ -16,15 +16,22 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
part of 'sign_up_cubit.dart';
 | 
					part of 'sign_up_cubit.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// {@template sign_up_state}
 | 
				
			||||||
/// Sign up cubit state to manage the form.
 | 
					/// Sign up cubit state to manage the form.
 | 
				
			||||||
 | 
					/// {@endtemplate}
 | 
				
			||||||
class SignUpState extends FormDataState {
 | 
					class SignUpState extends FormDataState {
 | 
				
			||||||
 | 
					  /// {@macro sign_up_state}
 | 
				
			||||||
  const SignUpState({
 | 
					  const SignUpState({
 | 
				
			||||||
    required super.form,
 | 
					    required super.form,
 | 
				
			||||||
    super.status = FormStatus.pure,
 | 
					    super.status = FormStatus.pure,
 | 
				
			||||||
    super.errorMessage,
 | 
					    super.errorMessage,
 | 
				
			||||||
  });
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// Email validator of the form
 | 
				
			||||||
  FormInputValidator<String?, ValidationError> get email =>
 | 
					  FormInputValidator<String?, ValidationError> get email =>
 | 
				
			||||||
      form.validatorOf(AuthFormField.email);
 | 
					      form.validatorOf(AuthFormField.email);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// Password validator of the form
 | 
				
			||||||
  FormInputValidator<String?, ValidationError> get password =>
 | 
					  FormInputValidator<String?, ValidationError> get password =>
 | 
				
			||||||
      form.validatorOf(AuthFormField.password);
 | 
					      form.validatorOf(AuthFormField.password);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -42,7 +49,6 @@ class SignUpState extends FormDataState {
 | 
				
			|||||||
  @override
 | 
					  @override
 | 
				
			||||||
  List<Object?> get props => [email, password, status, form];
 | 
					  List<Object?> get props => [email, password, status, form];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  @override
 | 
					 | 
				
			||||||
  @override
 | 
					  @override
 | 
				
			||||||
  String toString() => 'SignUpState(status: ${status.name} '
 | 
					  String toString() => 'SignUpState(status: ${status.name} '
 | 
				
			||||||
      '${(errorMessage != null) ? " [$errorMessage]" : ""}, $form)';
 | 
					      '${(errorMessage != null) ? " [$errorMessage]" : ""}, $form)';
 | 
				
			||||||
 | 
				
			|||||||
@ -19,9 +19,12 @@ import 'package:flutter_bloc/flutter_bloc.dart';
 | 
				
			|||||||
import 'package:wyatt_authentication_bloc/src/features/sign_up/cubit/sign_up_cubit.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_form_bloc/wyatt_form_bloc.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Widget that listens and builds a child based on the state of 
 | 
					/// {@template sign_up_listener}
 | 
				
			||||||
 | 
					/// Widget that listens and builds a child based on the state of
 | 
				
			||||||
/// the sign up cubit
 | 
					/// the sign up cubit
 | 
				
			||||||
 | 
					/// {@endtemplate}
 | 
				
			||||||
class SignUpListener<Data> extends StatelessWidget {
 | 
					class SignUpListener<Data> extends StatelessWidget {
 | 
				
			||||||
 | 
					  /// {@macro sign_up_listener}
 | 
				
			||||||
  const SignUpListener({
 | 
					  const SignUpListener({
 | 
				
			||||||
    required this.child,
 | 
					    required this.child,
 | 
				
			||||||
    this.onProgress,
 | 
					    this.onProgress,
 | 
				
			||||||
@ -31,14 +34,24 @@ class SignUpListener<Data> extends StatelessWidget {
 | 
				
			|||||||
    super.key,
 | 
					    super.key,
 | 
				
			||||||
  });
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// Callback to show when the sign up is in progress
 | 
				
			||||||
  final void Function(BuildContext context)? onProgress;
 | 
					  final void Function(BuildContext context)? onProgress;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// Callback to show when the sign up is successful
 | 
				
			||||||
  final void Function(BuildContext context)? onSuccess;
 | 
					  final void Function(BuildContext context)? onSuccess;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// Callback to show when the sign up is unsuccessful
 | 
				
			||||||
  final void Function(
 | 
					  final void Function(
 | 
				
			||||||
    BuildContext context,
 | 
					    BuildContext context,
 | 
				
			||||||
    FormStatus status,
 | 
					    FormStatus status,
 | 
				
			||||||
    String? errorMessage,
 | 
					    String? errorMessage,
 | 
				
			||||||
  )? onError;
 | 
					  )? onError;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// Custom builder to show when the sign up is in progress, successful, or
 | 
				
			||||||
 | 
					  /// unsuccessful
 | 
				
			||||||
  final void Function(BuildContext context, SignUpState state)? customBuilder;
 | 
					  final void Function(BuildContext context, SignUpState state)? customBuilder;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// Child of the widget
 | 
				
			||||||
  final Widget child;
 | 
					  final Widget child;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  @override
 | 
					  @override
 | 
				
			||||||
 | 
				
			|||||||
@ -25,8 +25,8 @@ import 'package:wyatt_type_utils/wyatt_type_utils.dart';
 | 
				
			|||||||
class MockAuthenticationRepository extends Mock
 | 
					class MockAuthenticationRepository extends Mock
 | 
				
			||||||
    implements AuthenticationRepository<int> {}
 | 
					    implements AuthenticationRepository<int> {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class MockAuthenticationCubit extends Mock implements AuthenticationCubit<int> {
 | 
					class MockAuthenticationCubit extends Mock
 | 
				
			||||||
}
 | 
					    implements AuthenticationCubit<int> {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class MockAccount extends Mock implements Account {}
 | 
					class MockAccount extends Mock implements Account {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -25,8 +25,8 @@ import 'package:wyatt_type_utils/wyatt_type_utils.dart';
 | 
				
			|||||||
class MockAuthenticationRepository extends Mock
 | 
					class MockAuthenticationRepository extends Mock
 | 
				
			||||||
    implements AuthenticationRepository<int> {}
 | 
					    implements AuthenticationRepository<int> {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class MockAuthenticationCubit extends Mock implements AuthenticationCubit<int> {
 | 
					class MockAuthenticationCubit extends Mock
 | 
				
			||||||
}
 | 
					    implements AuthenticationCubit<int> {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class MockAccount extends Mock implements Account {}
 | 
					class MockAccount extends Mock implements Account {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user