Line data Source code
1 : import 'dart:io'; 2 : import 'package:flutter_bloc/flutter_bloc.dart'; 3 : import 'dart:async'; 4 : import 'package:equatable/equatable.dart'; 5 : import 'package:memories_app/routes/login/model/login_repository.dart'; 6 : import 'package:memories_app/routes/login/model/login_request_model.dart'; 7 : import 'package:memories_app/routes/login/model/login_response_model.dart'; 8 : import 'package:memories_app/routes/login/model/user_details_response_model.dart'; 9 : import 'package:memories_app/util/sp_helper.dart'; 10 : 11 : part 'login_event.dart'; 12 : 13 : part 'login_state.dart'; 14 : 15 : class _Constants { 16 : static const String usernameRequiredMessage = 'Username is required'; 17 : static const String passswordRequiredMessage = 'Password is required'; 18 : static const String offlineMessage = 19 : 'You are currently offline.\n Please check your internet connection!'; 20 : } 21 : 22 : class LoginBloc extends Bloc<LoginEvent, LoginState> { 23 : final LoginRepository _repository; 24 : 25 1 : LoginBloc({required LoginRepository repository}) 26 : : _repository = repository, 27 1 : super(const LoginInitial()) { 28 2 : on<LoginLoadDisplayEvent>(_onLoadDisplayEvent); 29 2 : on<LoginUsernameChangedEvent>(_onUsernameChangedEvent); 30 2 : on<LoginPasswordChangedEvent>(_onPasswordChangedEvent); 31 2 : on<LoginPressLoginButtonEvent>(_onPressLoginButtonEvent); 32 2 : on<LoginErrorPopupClosedEvent>(_onErrorPopupClosedEvent); 33 : } 34 : 35 : bool _isUsernameFieldFocused = false; 36 : String? _usernameValidationMessage; 37 : bool _isPasswordFieldFocused = false; 38 : String? _passwordValidationMessage; 39 : 40 1 : String? validateUsername(String? value) { 41 1 : if (value == null || value.isEmpty) { 42 : return _Constants.usernameRequiredMessage; 43 : } 44 : return ''; // Return empty if the validation is successful 45 : } 46 : 47 1 : String? validatePassword(String? value) { 48 1 : if (value == null || value.isEmpty) { 49 : return _Constants.passswordRequiredMessage; 50 : } 51 : return ''; // Return empty if the validation is successful 52 : } 53 : 54 1 : LoginDisplayState _displayState() { 55 1 : return LoginDisplayState( 56 1 : isUsernameFieldFocused: _isUsernameFieldFocused, 57 1 : usernameValidationMessage: _usernameValidationMessage, 58 1 : isPasswordFieldFocused: _isPasswordFieldFocused, 59 1 : passwordValidationMessage: _passwordValidationMessage); 60 : } 61 : 62 1 : void _onUsernameChangedEvent( 63 : LoginUsernameChangedEvent event, Emitter<LoginState> emit) { 64 3 : _isUsernameFieldFocused = event.username.isNotEmpty; 65 3 : _usernameValidationMessage = validateUsername(event.username); 66 2 : emit(_displayState()); 67 : } 68 : 69 1 : void _onPasswordChangedEvent( 70 : LoginPasswordChangedEvent event, Emitter<LoginState> emit) { 71 3 : _isPasswordFieldFocused = event.password.isNotEmpty; 72 3 : _passwordValidationMessage = validatePassword(event.password); 73 2 : emit(_displayState()); 74 : } 75 : 76 1 : Future<void> _onLoadDisplayEvent( 77 : LoginLoadDisplayEvent event, Emitter<LoginState> emit) async { 78 2 : emit(_displayState()); 79 : } 80 : 81 1 : Future<void> _saveRefreshToken(String refreshToken) async { 82 1 : await SPHelper.setString(SPKeys.refreshTokenKey, refreshToken); 83 : } 84 : 85 1 : Future<void> _saveLoginInfo( 86 : UserDetailsResponseModel userDetailsResponseModel) async { 87 1 : await SPHelper.setBool(SPKeys.isLoggedIn, true); 88 2 : await SPHelper.setInt(SPKeys.currentUserId, userDetailsResponseModel.id); 89 : } 90 : 91 1 : FutureOr<void> _onPressLoginButtonEvent( 92 : LoginPressLoginButtonEvent event, Emitter<LoginState> emit) async { 93 : LoginResponseModel? loginResponseModel; 94 : UserDetailsResponseModel? userDetailsResponseModel; 95 : 96 1 : LoginRequestModel request = LoginRequestModel( 97 1 : username: event.username, 98 1 : password: event.password, 99 : ); 100 : 101 : try { 102 2 : loginResponseModel = await _repository.login(request); 103 0 : } on SocketException { 104 0 : emit(const LoginOffline(offlineMessage: _Constants.offlineMessage)); 105 : } catch (error) { 106 0 : emit(LoginFailure(error: error.toString())); 107 : } 108 : 109 : if (loginResponseModel != null) { 110 2 : if (loginResponseModel.success == true && 111 1 : loginResponseModel.refresh != null) { 112 : /// INFO: save refresh token locally 113 2 : await _saveRefreshToken(loginResponseModel.refresh!); 114 2 : userDetailsResponseModel = await _repository.getUserDetails(); 115 1 : await _saveLoginInfo(userDetailsResponseModel); 116 1 : emit(const LoginSuccess()); 117 : } else { 118 4 : emit(LoginFailure(error: loginResponseModel.msg.toString())); 119 : } 120 : } 121 : } 122 : 123 1 : void _onErrorPopupClosedEvent( 124 : LoginErrorPopupClosedEvent event, Emitter<LoginState> emit) { 125 2 : emit(_displayState()); 126 : } 127 : }