1
- //
2
- // ignore_for_file: lines_longer_than_80_chars
3
-
4
1
import 'dart:async' ;
5
2
6
3
import 'package:bloc/bloc.dart' ;
7
4
import 'package:equatable/equatable.dart' ;
8
- import 'package:ht_authentication_client/ht_authentication_client.dart' ;
9
- import 'package:ht_authentication_repository/ht_authentication_repository.dart' ;
5
+ import 'package:ht_auth_repository/ht_auth_repository.dart' ;
6
+ import 'package:ht_shared/ht_shared.dart'
7
+ show
8
+ AuthenticationException,
9
+ HtHttpException,
10
+ InvalidInputException,
11
+ NetworkException,
12
+ OperationFailedException,
13
+ ServerException,
14
+ User;
10
15
11
16
part 'authentication_event.dart' ;
12
17
part 'authentication_state.dart' ;
@@ -17,116 +22,126 @@ part 'authentication_state.dart';
17
22
class AuthenticationBloc
18
23
extends Bloc <AuthenticationEvent , AuthenticationState > {
19
24
/// {@macro authentication_bloc}
20
- AuthenticationBloc ({
21
- required HtAuthenticationRepository authenticationRepository,
22
- }) : _authenticationRepository = authenticationRepository,
23
- super (AuthenticationInitial ()) {
24
- on < AuthenticationSendSignInLinkRequested > (
25
- _onAuthenticationSendSignInLinkRequested,
26
- );
27
- on < AuthenticationSignInWithLinkAttempted > (
28
- _onAuthenticationSignInWithLinkAttempted,
25
+ AuthenticationBloc ({required HtAuthRepository authenticationRepository})
26
+ : _authenticationRepository = authenticationRepository,
27
+ super (AuthenticationInitial ()) {
28
+ // Listen to authentication state changes from the repository
29
+ _authenticationRepository.authStateChanges.listen (
30
+ (user) => add (_AuthenticationUserChanged (user: user)),
29
31
);
30
- on < AuthenticationGoogleSignInRequested > (
31
- _onAuthenticationGoogleSignInRequested,
32
+
33
+ on < _AuthenticationUserChanged > (_onAuthenticationUserChanged);
34
+ on < AuthenticationRequestSignInCodeRequested > (
35
+ _onAuthenticationRequestSignInCodeRequested,
32
36
);
37
+ on < AuthenticationVerifyCodeRequested > (_onAuthenticationVerifyCodeRequested);
33
38
on < AuthenticationAnonymousSignInRequested > (
34
39
_onAuthenticationAnonymousSignInRequested,
35
40
);
36
41
on < AuthenticationSignOutRequested > (_onAuthenticationSignOutRequested);
37
- on < AuthenticationDeleteAccountRequested > (
38
- _onAuthenticationDeleteAccountRequested,
39
- );
40
42
}
41
43
42
- final HtAuthenticationRepository _authenticationRepository;
44
+ final HtAuthRepository _authenticationRepository;
43
45
44
- /// Handles [AuthenticationSendSignInLinkRequested] events.
45
- Future <void > _onAuthenticationSendSignInLinkRequested (
46
- AuthenticationSendSignInLinkRequested event,
46
+ /// Handles [_AuthenticationUserChanged] events.
47
+ Future <void > _onAuthenticationUserChanged (
48
+ _AuthenticationUserChanged event,
49
+ Emitter <AuthenticationState > emit,
50
+ ) async {
51
+ if (event.user != null ) {
52
+ emit (AuthenticationAuthenticated (user: event.user! ));
53
+ } else {
54
+ emit (AuthenticationUnauthenticated ());
55
+ }
56
+ }
57
+
58
+ /// Handles [AuthenticationRequestSignInCodeRequested] events.
59
+ Future <void > _onAuthenticationRequestSignInCodeRequested (
60
+ AuthenticationRequestSignInCodeRequested event,
47
61
Emitter <AuthenticationState > emit,
48
62
) async {
49
63
// Validate email format (basic check)
50
64
if (event.email.isEmpty || ! event.email.contains ('@' )) {
51
65
emit (const AuthenticationFailure ('Please enter a valid email address.' ));
52
66
return ;
53
67
}
54
- emit (AuthenticationLinkSending ()); // Indicate link sending
68
+ emit (
69
+ AuthenticationRequestCodeLoading (),
70
+ ); // Indicate code request is sending
55
71
try {
56
- // Simply call the repository method, email temprary storage storage
57
- // is handled internally
58
- await _authenticationRepository.sendSignInLinkToEmail (email: event.email);
59
- emit (AuthenticationLinkSentSuccess ()); // Confirm link sent
60
- } on SendSignInLinkException catch (e) {
61
- emit (AuthenticationFailure ('Failed to send link: ${e .error }' ));
72
+ await _authenticationRepository.requestSignInCode (event.email);
73
+ emit (
74
+ AuthenticationCodeSentSuccess (email: event.email),
75
+ ); // Confirm code requested and include email
76
+ } on InvalidInputException catch (e) {
77
+ emit (AuthenticationFailure ('Invalid input: ${e .message }' ));
78
+ } on NetworkException catch (_) {
79
+ emit (const AuthenticationFailure ('Network error occurred.' ));
80
+ } on ServerException catch (e) {
81
+ emit (AuthenticationFailure ('Server error: ${e .message }' ));
82
+ } on OperationFailedException catch (e) {
83
+ emit (AuthenticationFailure ('Operation failed: ${e .message }' ));
84
+ } on HtHttpException catch (e) {
85
+ // Catch any other HtHttpException subtypes
86
+ emit (AuthenticationFailure ('HTTP error: ${e .message }' ));
62
87
} catch (e) {
63
88
// Catch any other unexpected errors
64
89
emit (AuthenticationFailure ('An unexpected error occurred: $e ' ));
65
90
// Optionally log the stackTrace here
66
91
}
67
92
}
68
93
69
- /// Handles [AuthenticationSignInWithLinkAttempted] events.
70
- /// This assumes the event is dispatched after the app receives the deep link.
71
- Future <void > _onAuthenticationSignInWithLinkAttempted (
72
- AuthenticationSignInWithLinkAttempted event,
94
+ /// Handles [AuthenticationVerifyCodeRequested] events.
95
+ Future <void > _onAuthenticationVerifyCodeRequested (
96
+ AuthenticationVerifyCodeRequested event,
73
97
Emitter <AuthenticationState > emit,
74
98
) async {
75
- emit (AuthenticationLoading ()); // General loading for sign-in attempt
99
+ emit (AuthenticationLoading ()); // Indicate code verification is loading
76
100
try {
77
- // Call the updated repository method (no email needed here)
78
- await _authenticationRepository.signInWithEmailLink (
79
- emailLink: event.emailLink,
80
- );
81
- // On success, AppBloc should react to the user stream change from the repo.
82
- // Resetting to Initial state here.
83
- emit (AuthenticationInitial ());
84
- } on InvalidSignInLinkException catch (e) {
85
- emit (
86
- AuthenticationFailure (
87
- 'Sign in failed: Invalid or expired link. ${e .error }' ,
88
- ),
89
- );
101
+ await _authenticationRepository.verifySignInCode (event.email, event.code);
102
+ // On success, the _AuthenticationUserChanged listener will handle
103
+ // emitting AuthenticationAuthenticated.
104
+ } on InvalidInputException catch (e) {
105
+ emit (AuthenticationFailure ('Invalid input: ${e .message }' ));
106
+ } on AuthenticationException catch (e) {
107
+ emit (AuthenticationFailure ('Authentication failed: ${e .message }' ));
108
+ } on NetworkException catch (_) {
109
+ emit (const AuthenticationFailure ('Network error occurred.' ));
110
+ } on ServerException catch (e) {
111
+ emit (AuthenticationFailure ('Server error: ${e .message }' ));
112
+ } on OperationFailedException catch (e) {
113
+ emit (AuthenticationFailure ('Operation failed: ${e .message }' ));
114
+ } on HtHttpException catch (e) {
115
+ // Catch any other HtHttpException subtypes
116
+ emit (AuthenticationFailure ('HTTP error: ${e .message }' ));
90
117
} catch (e) {
91
118
// Catch any other unexpected errors
92
- emit (
93
- AuthenticationFailure (
94
- 'An unexpected error occurred during sign in: $e ' ,
95
- ),
96
- );
119
+ emit (AuthenticationFailure ('An unexpected error occurred: $e ' ));
97
120
// Optionally log the stackTrace here
98
121
}
99
122
}
100
123
101
- /// Handles [AuthenticationGoogleSignInRequested] events.
102
- Future <void > _onAuthenticationGoogleSignInRequested (
103
- AuthenticationGoogleSignInRequested event,
104
- Emitter <AuthenticationState > emit,
105
- ) async {
106
- emit (AuthenticationLoading ());
107
- try {
108
- await _authenticationRepository.signInWithGoogle ();
109
- emit (AuthenticationInitial ());
110
- } on GoogleSignInException catch (e) {
111
- emit (AuthenticationFailure (e.toString ()));
112
- } catch (e) {
113
- emit (AuthenticationFailure (e.toString ()));
114
- }
115
- }
116
-
117
124
/// Handles [AuthenticationAnonymousSignInRequested] events.
118
125
Future <void > _onAuthenticationAnonymousSignInRequested (
119
126
AuthenticationAnonymousSignInRequested event,
120
127
Emitter <AuthenticationState > emit,
121
128
) async {
122
- emit (AuthenticationLoading ());
129
+ emit (AuthenticationLoading ()); // Indicate anonymous sign-in is loading
123
130
try {
124
131
await _authenticationRepository.signInAnonymously ();
125
- emit (AuthenticationInitial ());
126
- } on AnonymousLoginException catch (e) {
127
- emit (AuthenticationFailure (e.toString ()));
132
+ // On success, the _AuthenticationUserChanged listener will handle
133
+ // emitting AuthenticationAuthenticated.
134
+ } on NetworkException catch (_) {
135
+ emit (const AuthenticationFailure ('Network error occurred.' ));
136
+ } on ServerException catch (e) {
137
+ emit (AuthenticationFailure ('Server error: ${e .message }' ));
138
+ } on OperationFailedException catch (e) {
139
+ emit (AuthenticationFailure ('Operation failed: ${e .message }' ));
140
+ } on HtHttpException catch (e) {
141
+ // Catch any other HtHttpException subtypes
142
+ emit (AuthenticationFailure ('HTTP error: ${e .message }' ));
128
143
} catch (e) {
129
- emit (AuthenticationFailure (e. toString () ));
144
+ emit (AuthenticationFailure ('An unexpected error occurred: $ e ' ));
130
145
}
131
146
}
132
147
@@ -135,29 +150,22 @@ class AuthenticationBloc
135
150
AuthenticationSignOutRequested event,
136
151
Emitter <AuthenticationState > emit,
137
152
) async {
138
- emit (AuthenticationLoading ());
153
+ emit (AuthenticationLoading ()); // Indicate sign-out is loading
139
154
try {
140
155
await _authenticationRepository.signOut ();
141
- emit (AuthenticationInitial ());
142
- } on LogoutException catch (e) {
143
- emit (AuthenticationFailure (e.toString ()));
144
- } catch (e) {
145
- emit (AuthenticationFailure (e.toString ()));
146
- }
147
- }
148
-
149
- Future <void > _onAuthenticationDeleteAccountRequested (
150
- AuthenticationDeleteAccountRequested event,
151
- Emitter <AuthenticationState > emit,
152
- ) async {
153
- emit (AuthenticationLoading ());
154
- try {
155
- await _authenticationRepository.deleteAccount ();
156
- emit (AuthenticationInitial ());
157
- } on DeleteAccountException catch (e) {
158
- emit (AuthenticationFailure (e.toString ()));
156
+ // On success, the _AuthenticationUserChanged listener will handle
157
+ // emitting AuthenticationUnauthenticated.
158
+ } on NetworkException catch (_) {
159
+ emit (const AuthenticationFailure ('Network error occurred.' ));
160
+ } on ServerException catch (e) {
161
+ emit (AuthenticationFailure ('Server error: ${e .message }' ));
162
+ } on OperationFailedException catch (e) {
163
+ emit (AuthenticationFailure ('Operation failed: ${e .message }' ));
164
+ } on HtHttpException catch (e) {
165
+ // Catch any other HtHttpException subtypes
166
+ emit (AuthenticationFailure ('HTTP error: ${e .message }' ));
159
167
} catch (e) {
160
- emit (AuthenticationFailure (e. toString () ));
168
+ emit (AuthenticationFailure ('An unexpected error occurred: $ e ' ));
161
169
}
162
170
}
163
171
}
0 commit comments