You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

74 lines
2.3KB

  1. import 'dart:async';
  2. import 'package:authentication_repository/authentication_repository.dart';
  3. import 'package:bloc/bloc.dart';
  4. import 'package:equatable/equatable.dart';
  5. import 'package:meta/meta.dart';
  6. import 'package:user_repository/user_repository.dart';
  7. part 'authentication_event.dart';
  8. part 'authentication_state.dart';
  9. class AuthenticationBloc
  10. extends Bloc<AuthenticationEvent, AuthenticationState> {
  11. AuthenticationBloc({
  12. @required AuthenticationRepository authenticationRepository,
  13. @required UserRepository userRepository,
  14. }) : assert(authenticationRepository != null),
  15. assert(userRepository != null),
  16. _authenticationRepository = authenticationRepository,
  17. _userRepository = userRepository,
  18. super(const AuthenticationState.unknown()) {
  19. _authenticationStatusSubscription = _authenticationRepository.status.listen(
  20. (status) => add(AuthenticationStatusChanged(status)),
  21. );
  22. }
  23. final AuthenticationRepository _authenticationRepository;
  24. final UserRepository _userRepository;
  25. StreamSubscription<AuthenticationStatus> _authenticationStatusSubscription;
  26. @override
  27. Stream<AuthenticationState> mapEventToState(
  28. AuthenticationEvent event,
  29. ) async* {
  30. if (event is AuthenticationStatusChanged) {
  31. yield await _mapAuthenticationStatusChangedToState(event);
  32. } else if (event is AuthenticationLogoutRequested) {
  33. _authenticationRepository.logOut();
  34. }
  35. }
  36. @override
  37. Future<void> close() {
  38. _authenticationStatusSubscription?.cancel();
  39. _authenticationRepository.dispose();
  40. return super.close();
  41. }
  42. Future<AuthenticationState> _mapAuthenticationStatusChangedToState(
  43. AuthenticationStatusChanged event,
  44. ) async {
  45. switch (event.status) {
  46. case AuthenticationStatus.unauthenticated:
  47. return const AuthenticationState.unauthenticated();
  48. case AuthenticationStatus.authenticated:
  49. final user = await _tryGetUser();
  50. return user != null
  51. ? AuthenticationState.authenticated(user)
  52. : const AuthenticationState.unauthenticated();
  53. default:
  54. return const AuthenticationState.unknown();
  55. }
  56. }
  57. Future<User> _tryGetUser() async {
  58. try {
  59. final user = await _userRepository.getUser();
  60. return user;
  61. } on Exception {
  62. return null;
  63. }
  64. }
  65. }