sign_in_bloc.dart 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. import 'package:appflowy/user/application/auth/auth_service.dart';
  2. import 'package:dartz/dartz.dart';
  3. import 'package:appflowy_backend/protobuf/flowy-error/code.pb.dart';
  4. import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.dart';
  5. import 'package:appflowy_backend/protobuf/flowy-user/protobuf.dart'
  6. show UserProfilePB;
  7. import 'package:freezed_annotation/freezed_annotation.dart';
  8. import 'package:flutter_bloc/flutter_bloc.dart';
  9. part 'sign_in_bloc.freezed.dart';
  10. class SignInBloc extends Bloc<SignInEvent, SignInState> {
  11. final AuthService authService;
  12. SignInBloc(this.authService) : super(SignInState.initial()) {
  13. on<SignInEvent>((event, emit) async {
  14. await event.map(
  15. signedInWithUserEmailAndPassword: (e) async {
  16. await _performActionOnSignIn(
  17. state,
  18. emit,
  19. );
  20. },
  21. signedInWithOAuth: (value) async =>
  22. await _performActionOnSignInWithOAuth(
  23. state,
  24. emit,
  25. value.platform,
  26. ),
  27. signedInAsGuest: (value) async => await _performActionOnSignInAsGuest(
  28. state,
  29. emit,
  30. ),
  31. emailChanged: (EmailChanged value) async {
  32. emit(
  33. state.copyWith(
  34. email: value.email,
  35. emailError: none(),
  36. successOrFail: none(),
  37. ),
  38. );
  39. },
  40. passwordChanged: (PasswordChanged value) async {
  41. emit(
  42. state.copyWith(
  43. password: value.password,
  44. passwordError: none(),
  45. successOrFail: none(),
  46. ),
  47. );
  48. },
  49. );
  50. });
  51. }
  52. Future<void> _performActionOnSignIn(
  53. SignInState state,
  54. Emitter<SignInState> emit,
  55. ) async {
  56. final result = await authService.signIn(
  57. email: state.email ?? '',
  58. password: state.password ?? '',
  59. );
  60. emit(
  61. result.fold(
  62. (error) => stateFromCode(error),
  63. (userProfile) => state.copyWith(
  64. isSubmitting: false,
  65. successOrFail: some(left(userProfile)),
  66. ),
  67. ),
  68. );
  69. }
  70. Future<void> _performActionOnSignInWithOAuth(
  71. SignInState state,
  72. Emitter<SignInState> emit,
  73. String platform,
  74. ) async {
  75. emit(
  76. state.copyWith(
  77. isSubmitting: true,
  78. emailError: none(),
  79. passwordError: none(),
  80. successOrFail: none(),
  81. ),
  82. );
  83. final result = await authService.signUpWithOAuth(
  84. platform: platform,
  85. );
  86. emit(
  87. result.fold(
  88. (error) => stateFromCode(error),
  89. (userProfile) => state.copyWith(
  90. isSubmitting: false,
  91. successOrFail: some(left(userProfile)),
  92. ),
  93. ),
  94. );
  95. }
  96. Future<void> _performActionOnSignInAsGuest(
  97. SignInState state,
  98. Emitter<SignInState> emit,
  99. ) async {
  100. emit(
  101. state.copyWith(
  102. isSubmitting: true,
  103. emailError: none(),
  104. passwordError: none(),
  105. successOrFail: none(),
  106. ),
  107. );
  108. final result = await authService.signUpAsGuest();
  109. emit(
  110. result.fold(
  111. (error) => stateFromCode(error),
  112. (userProfile) => state.copyWith(
  113. isSubmitting: false,
  114. successOrFail: some(left(userProfile)),
  115. ),
  116. ),
  117. );
  118. }
  119. SignInState stateFromCode(FlowyError error) {
  120. switch (ErrorCode.valueOf(error.code)!) {
  121. case ErrorCode.EmailFormatInvalid:
  122. return state.copyWith(
  123. isSubmitting: false,
  124. emailError: some(error.msg),
  125. passwordError: none(),
  126. );
  127. case ErrorCode.PasswordFormatInvalid:
  128. return state.copyWith(
  129. isSubmitting: false,
  130. passwordError: some(error.msg),
  131. emailError: none(),
  132. );
  133. default:
  134. return state.copyWith(
  135. isSubmitting: false,
  136. successOrFail: some(right(error)),
  137. );
  138. }
  139. }
  140. }
  141. @freezed
  142. class SignInEvent with _$SignInEvent {
  143. const factory SignInEvent.signedInWithUserEmailAndPassword() =
  144. SignedInWithUserEmailAndPassword;
  145. const factory SignInEvent.signedInWithOAuth(String platform) =
  146. SignedInWithOAuth;
  147. const factory SignInEvent.signedInAsGuest() = SignedInAsGuest;
  148. const factory SignInEvent.emailChanged(String email) = EmailChanged;
  149. const factory SignInEvent.passwordChanged(String password) = PasswordChanged;
  150. }
  151. @freezed
  152. class SignInState with _$SignInState {
  153. const factory SignInState({
  154. String? email,
  155. String? password,
  156. required bool isSubmitting,
  157. required Option<String> passwordError,
  158. required Option<String> emailError,
  159. required Option<Either<UserProfilePB, FlowyError>> successOrFail,
  160. }) = _SignInState;
  161. factory SignInState.initial() => SignInState(
  162. isSubmitting: false,
  163. passwordError: none(),
  164. emailError: none(),
  165. successOrFail: none(),
  166. );
  167. }