TF-1963 Use viewState to update result from interactor

(cherry picked from commit 335536fb94b32d978082578048ec06f70d21edcb)
This commit is contained in:
dab246
2023-06-26 21:01:30 +07:00
committed by Dat Vu
parent 8be3eb53e9
commit cffd27c3bf
9 changed files with 173 additions and 252 deletions
-1
View File
@@ -101,7 +101,6 @@ export 'data/network/download/downloaded_response.dart';
// State
export 'presentation/state/success.dart';
export 'presentation/state/failure.dart';
export 'presentation/state/app_state.dart';
// Model
export 'data/model/source_type/data_source_type.dart';
@@ -1,15 +0,0 @@
import 'package:core/presentation/state/failure.dart';
import 'package:core/presentation/state/success.dart';
import 'package:dartz/dartz.dart';
import 'package:equatable/equatable.dart';
import 'package:flutter/material.dart';
@immutable
abstract class AppState with EquatableMixin {
final Either<Failure, Success> viewState;
AppState(this.viewState);
@override
List<Object?> get props => [viewState];
}
@@ -126,7 +126,7 @@ class HomeController extends BaseController {
failure is GetAuthenticatedAccountFailure ||
failure is GetStoredTokenOidcFailure ||
failure is GetCredentialFailure) {
_goToLogin(arguments: LoginArguments(LoginFormType.credentialForm));
_goToLogin(arguments: LoginArguments(LoginFormType.baseUrlForm));
}
}
@@ -1,17 +1,25 @@
import 'package:core/presentation/extensions/color_extension.dart';
import 'package:core/presentation/resources/image_paths.dart';
import 'package:core/presentation/state/failure.dart';
import 'package:core/presentation/state/success.dart';
import 'package:core/presentation/utils/responsive_utils.dart';
import 'package:core/presentation/views/text/type_ahead_form_field_builder.dart';
import 'package:dartz/dartz.dart';
import 'package:flutter/material.dart';
import 'package:flutter_typeahead/flutter_typeahead.dart';
import 'package:get/get.dart';
import 'package:tmail_ui_user/features/base/widget/recent_item_tile_widget.dart';
import 'package:tmail_ui_user/features/login/data/network/oidc_error.dart';
import 'package:tmail_ui_user/features/login/domain/exceptions/authentication_exception.dart';
import 'package:tmail_ui_user/features/login/domain/model/recent_login_username.dart';
import 'package:tmail_ui_user/features/login/domain/state/authenticate_oidc_on_browser_state.dart';
import 'package:tmail_ui_user/features/login/domain/state/authentication_user_state.dart';
import 'package:tmail_ui_user/features/login/domain/state/check_oidc_is_available_state.dart';
import 'package:tmail_ui_user/features/login/domain/state/get_oidc_configuration_state.dart';
import 'package:tmail_ui_user/features/login/domain/state/get_oidc_is_available_state.dart';
import 'package:tmail_ui_user/features/login/domain/state/get_token_oidc_state.dart';
import 'package:tmail_ui_user/features/login/presentation/login_controller.dart';
import 'package:tmail_ui_user/features/login/presentation/login_form_type.dart';
import 'package:tmail_ui_user/features/login/presentation/state/login_state.dart';
import 'package:tmail_ui_user/features/login/presentation/widgets/login_input_decoration_builder.dart';
import 'package:tmail_ui_user/features/login/presentation/widgets/login_text_input_builder.dart';
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
@@ -25,27 +33,26 @@ abstract class BaseLoginView extends GetWidget<LoginController> {
final FocusNode passFocusNode = FocusNode();
Widget buildLoginMessage(BuildContext context, LoginState loginState) {
Widget buildLoginMessage(BuildContext context, Either<Failure, Success> viewState) {
return Padding(
padding: const EdgeInsets.only(top: 11, bottom: 36, left: 58, right: 58),
child: SizedBox(
width: responsiveUtils.getWidthLoginTextField(context),
child: Text(
loginState.viewState.fold(
viewState.fold(
(failure) {
if (failure is LoginMissUrlAction) {
return AppLocalizations.of(context).requiredUrl;
} else if (failure is LoginMissUsernameAction) {
return AppLocalizations.of(context).requiredEmail;
} else if (failure is LoginMissPasswordAction) {
return AppLocalizations.of(context).requiredPassword;
} else if (failure is LoginSSONotAvailableAction) {
return AppLocalizations.of(context).ssoNotAvailable;
} else if (failure is GetOIDCConfigurationFailure
|| failure is LoginCanNotVerifySSOConfigurationAction) {
if (failure is CheckOIDCIsAvailableFailure) {
return _getMessageFailure(context, failure.exception);
} else if (failure is AuthenticationUserFailure) {
return _getMessageFailure(context, failure.exception);
} else if (failure is GetOIDCIsAvailableFailure) {
return _getMessageFailure(context, failure.exception);
} else if (failure is GetTokenOIDCFailure) {
return _getMessageFailure(context, failure.exception);
} else if (failure is AuthenticateOidcOnBrowserFailure) {
return _getMessageFailure(context, failure.exception);
} else if (failure is GetOIDCConfigurationFailure) {
return AppLocalizations.of(context).canNotVerifySSOConfiguration;
} else if (failure is GetTokenOIDCFailure || failure is LoginCanNotGetTokenAction) {
return AppLocalizations.of(context).canNotGetToken;
} else {
return AppLocalizations.of(context).unknownError;
}
@@ -63,13 +70,29 @@ abstract class BaseLoginView extends GetWidget<LoginController> {
style: TextStyle(
fontSize: 15,
fontWeight: FontWeight.w400,
color: loginState.viewState.fold(
color: viewState.fold(
(failure) => AppColor.textFieldErrorBorderColor,
(success) => AppColor.colorNameEmail)),
))
);
}
String _getMessageFailure(BuildContext context, dynamic exception) {
if (exception is CanNotFoundBaseUrl) {
return AppLocalizations.of(context).requiredUrl;
} else if (exception is CanNotFoundUserName) {
return AppLocalizations.of(context).requiredEmail;
} else if (exception is CanNotFoundPassword) {
return AppLocalizations.of(context).requiredPassword;
} else if (exception is CanNotFoundOIDCLinks) {
return AppLocalizations.of(context).ssoNotAvailable;
} else if (exception is CanNotFoundToken) {
return AppLocalizations.of(context).canNotGetToken;
} else {
return '';
}
}
Widget buildLoginButton(BuildContext context) {
return Container(
margin: const EdgeInsets.only(bottom: 16, left: 24, right: 24),
@@ -6,7 +6,6 @@ import 'package:core/utils/app_logger.dart';
import 'package:core/utils/platform_info.dart';
import 'package:dartz/dartz.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart';
import 'package:get/get.dart';
import 'package:jmap_dart_client/jmap/core/session/session.dart';
@@ -17,6 +16,8 @@ import 'package:model/oidc/request/oidc_request.dart';
import 'package:model/oidc/response/oidc_response.dart';
import 'package:model/oidc/token_oidc.dart';
import 'package:tmail_ui_user/features/base/reloadable/reloadable_controller.dart';
import 'package:tmail_ui_user/features/login/data/network/oidc_error.dart';
import 'package:tmail_ui_user/features/login/domain/exceptions/authentication_exception.dart';
import 'package:tmail_ui_user/features/login/domain/model/login_constants.dart';
import 'package:tmail_ui_user/features/login/domain/model/recent_login_url.dart';
import 'package:tmail_ui_user/features/login/domain/model/recent_login_username.dart';
@@ -47,7 +48,6 @@ import 'package:tmail_ui_user/features/login/domain/usecases/save_login_username
import 'package:tmail_ui_user/features/login/domain/usecases/update_authentication_account_interactor.dart';
import 'package:tmail_ui_user/features/login/presentation/login_form_type.dart';
import 'package:tmail_ui_user/features/login/presentation/model/login_arguments.dart';
import 'package:tmail_ui_user/features/login/presentation/state/login_state.dart';
import 'package:tmail_ui_user/features/manage_account/domain/usecases/log_out_oidc_interactor.dart';
import 'package:tmail_ui_user/main/routes/app_routes.dart';
import 'package:tmail_ui_user/main/routes/navigation_router.dart';
@@ -98,7 +98,6 @@ class LoginController extends ReloadableController {
updateAuthenticationAccountInteractor
);
var loginState = LoginState(Right(LoginInitAction())).obs;
final loginFormType = LoginFormType.baseUrlForm.obs;
String? _urlText;
@@ -144,17 +143,9 @@ class LoginController extends ReloadableController {
if (failure is GetAuthenticationInfoFailure) {
getAuthenticatedAccountAction();
} else if (failure is CheckOIDCIsAvailableFailure ||
failure is GetStoredOidcConfigurationFailure) {
failure is GetStoredOidcConfigurationFailure ||
failure is GetOIDCIsAvailableFailure) {
_showFormLoginWithCredentialAction();
} else if (failure is GetOIDCIsAvailableFailure) {
loginState.value = LoginState(Left(LoginSSONotAvailableAction()));
_showFormLoginWithCredentialAction();
} else if (failure is AuthenticationUserFailure) {
_loginFailureAction(failure);
} else if (failure is GetOIDCConfigurationFailure ||
failure is GetTokenOIDCFailure ||
failure is AuthenticateOidcOnBrowserFailure) {
loginState.value = LoginState(Left(failure));
}
}
@@ -166,9 +157,8 @@ class LoginController extends ReloadableController {
} else if (success is GetStoredOidcConfigurationSuccess) {
_getTokenOIDCAction(success.oidcConfiguration);
} else if (success is CheckOIDCIsAvailableSuccess) {
_showFormLoginWithSSOAction(success);
_redirectToSSOLoginScreen(success);
} else if (success is GetOIDCIsAvailableSuccess) {
loginState.value = LoginState(Right(success));
_oidcResponse = success.oidcResponse;
_getOIDCConfiguration();
} else if (success is GetOIDCConfigurationSuccess) {
@@ -177,21 +167,13 @@ class LoginController extends ReloadableController {
_getTokenOIDCSuccess(success);
} else if (success is AuthenticationUserSuccess) {
_loginSuccessAction(success);
} else if (success is GetAuthenticationInfoLoading ||
success is CheckOIDCIsAvailableLoading ||
success is GetStoredOidcConfigurationLoading ||
success is GetOIDCConfigurationLoading ||
success is GetTokenOIDCLoading ||
success is AuthenticationUserLoading ||
success is GetOIDCIsAvailableLoading) {
loginState.value = LoginState(Right(LoginLoadingAction()));
}
}
@override
void handleExceptionAction({Failure? failure, Exception? exception}) {
super.handleExceptionAction(failure: failure, exception: exception);
loginState.value = LoginState(Right(LoginInitAction()));
clearState();
}
@override
@@ -215,29 +197,31 @@ class LoginController extends ReloadableController {
}
void _checkOIDCIsAvailable() {
final baseUri = PlatformInfo.isWeb ? _parseUri(AppConfig.baseUrl) : _parseUri(_urlText);
if (baseUri == null) {
loginState.value = LoginState(Left(LoginMissUrlAction()));
final baseUrl = _getBaseUrl();
if (baseUrl == null) {
dispatchState(Left(CheckOIDCIsAvailableFailure(CanNotFoundBaseUrl())));
} else {
consumeState(_checkOIDCIsAvailableInteractor.execute(OIDCRequest(
baseUrl: baseUri.toString(),
resourceUrl: baseUri.origin)));
consumeState(_checkOIDCIsAvailableInteractor.execute(
OIDCRequest(
baseUrl: baseUrl.toString(),
resourceUrl: baseUrl.origin
)
));
}
}
void _showFormLoginWithSSOAction(CheckOIDCIsAvailableSuccess success) {
loginState.value = LoginState(Right(success));
loginFormType.value = LoginFormType.ssoForm;
void _redirectToSSOLoginScreen(CheckOIDCIsAvailableSuccess success) {
_oidcResponse = success.oidcResponse;
handleSSOPressed();
}
void handleBackInCredentialForm() {
loginState.value = LoginState(Right(LoginInitAction()));
clearState();
loginFormType.value = LoginFormType.baseUrlForm;
}
void _showFormLoginWithCredentialAction() {
loginState.value = LoginState(Right(InputUrlCompletion()));
clearState();
loginFormType.value = LoginFormType.credentialForm;
}
@@ -249,29 +233,25 @@ class LoginController extends ReloadableController {
if (loginFormType.value == LoginFormType.ssoForm) {
_getOIDCConfiguration();
} else {
final baseUri = kIsWeb ? _parseUri(AppConfig.baseUrl) : _parseUri(_urlText);
final baseUrl = _getBaseUrl();
final userName = _parseUserName(_userNameText);
final password = _parsePassword(_passwordText);
if (baseUri != null && userName != null && password != null) {
_loginAction(baseUri, userName, password);
} else if (baseUri == null) {
loginState.value = LoginState(Left(LoginMissUrlAction()));
} else if (userName == null) {
loginState.value = LoginState(Left(LoginMissUsernameAction()));
} else if (password == null) {
loginState.value = LoginState(Left(LoginMissPasswordAction()));
}
_loginAction(baseUrl: baseUrl, userName: userName, password: password);
}
}
void handleSSOPressed() {
final baseUri = _parseUri(AppConfig.baseUrl);
if (baseUri != null) {
consumeState(_getOIDCIsAvailableInteractor.execute(OIDCRequest(
baseUrl: baseUri.toString(),
resourceUrl: baseUri.origin)));
} else {
loginState.value = LoginState(Left(LoginCanNotAuthenticationSSOAction()));
final baseUrl = _getBaseUrl();
if (baseUrl != null) {
consumeState(_getOIDCIsAvailableInteractor.execute(
OIDCRequest(
baseUrl: baseUrl.toString(),
resourceUrl: baseUrl.origin
)
));
} else {
dispatchState(Left(GetOIDCIsAvailableFailure(CanNotFoundBaseUrl())));
}
}
@@ -279,13 +259,12 @@ class LoginController extends ReloadableController {
if (_oidcResponse != null) {
consumeState(_getOIDCConfigurationInteractor.execute(_oidcResponse!));
} else {
loginState.value = LoginState(Left(LoginCanNotAuthenticationSSOAction()));
dispatchState(Left(GetOIDCIsAvailableFailure(CanNotFoundOIDCLinks())));
}
}
void _getOIDCConfigurationSuccess(GetOIDCConfigurationSuccess success) {
log('LoginController::_getOIDCConfigurationSuccess():success: $success');
loginState.value = LoginState(Right(success));
if (PlatformInfo.isWeb) {
_authenticateOidcOnBrowserAction(success.oidcConfiguration);
} else {
@@ -294,11 +273,11 @@ class LoginController extends ReloadableController {
}
void _getTokenOIDCAction(OIDCConfiguration config) async {
final baseUri = kIsWeb ? _parseUri(AppConfig.baseUrl) : _parseUri(_urlText);
final baseUri = _getBaseUrl();
if (baseUri != null) {
consumeState(_getTokenOIDCInteractor.execute(baseUri, config));
consumeState(_getTokenOIDCInteractor.execute(baseUri, config));
} else {
loginState.value = LoginState(Left(LoginCanNotGetTokenAction()));
dispatchState(Left(GetTokenOIDCFailure(CanNotFoundBaseUrl())));
}
}
@@ -309,7 +288,7 @@ class LoginController extends ReloadableController {
if (baseUri != null) {
consumeState(_authenticateOidcOnBrowserInteractor.execute(baseUri, config));
} else {
loginState.value = LoginState(Left(LoginCanNotAuthenticationSSOAction()));
dispatchState(Left(AuthenticateOidcOnBrowserFailure(CanNotFoundBaseUrl())));
}
}
@@ -322,9 +301,8 @@ class LoginController extends ReloadableController {
void _getTokenOIDCSuccess(GetTokenOIDCSuccess success) {
log('LoginController::_getTokenOIDCSuccess(): ${success.tokenOIDC.toString()}');
loginState.value = LoginState(Right(success));
_dynamicUrlInterceptors.setJmapUrl(PlatformInfo.isWeb ? AppConfig.baseUrl : _urlText);
_dynamicUrlInterceptors.changeBaseUrl(PlatformInfo.isWeb ? AppConfig.baseUrl : _urlText);
_dynamicUrlInterceptors.setJmapUrl(_getBaseUrl().toString());
_dynamicUrlInterceptors.changeBaseUrl(_getBaseUrl().toString());
authorizationInterceptors.setTokenAndAuthorityOidc(
newToken: success.tokenOIDC.toToken(),
newConfig: success.configuration);
@@ -334,24 +312,22 @@ class LoginController extends ReloadableController {
pushAndPop(AppRoutes.session, arguments: _dynamicUrlInterceptors.baseUrl);
}
void _loginAction(Uri baseUrl, UserName userName, Password password) async {
consumeState(_authenticationInteractor.execute(baseUrl, userName, password));
void _loginAction({Uri? baseUrl, UserName? userName, Password? password}) {
consumeState(_authenticationInteractor.execute(
baseUrl: baseUrl,
userName: userName,
password: password
));
}
void _loginSuccessAction(AuthenticationUserSuccess success) {
loginState.value = LoginState(Right(success));
_dynamicUrlInterceptors.setJmapUrl(PlatformInfo.isWeb ? AppConfig.baseUrl : _urlText);
_dynamicUrlInterceptors.changeBaseUrl(PlatformInfo.isWeb ? AppConfig.baseUrl : _urlText);
_dynamicUrlInterceptors.setJmapUrl(_getBaseUrl().toString());
_dynamicUrlInterceptors.changeBaseUrl(_getBaseUrl().toString());
authorizationInterceptors.setBasicAuthorization(_userNameText, _passwordText);
authorizationIsolateInterceptors.setBasicAuthorization(_userNameText, _passwordText);
pushAndPop(AppRoutes.session, arguments: _dynamicUrlInterceptors.baseUrl);
}
void _loginFailureAction(FeatureFailure failure) {
logError('LoginController::_loginFailureAction(): $failure');
loginState.value = LoginState(Left(failure));
}
void formatUrl(String url) {
log('LoginController::formatUrl(): $url');
if (url.isValid()) {
@@ -364,7 +340,7 @@ class LoginController extends ReloadableController {
if (_urlText?.isNotEmpty == true && PlatformInfo.isMobile) {
final recentLoginUrl = RecentLoginUrl.now(_urlText!);
log('LoginController::_saveRecentLoginUrl(): $recentLoginUrl');
consumeState(_saveLoginUrlOnMobileInteractor.execute(recentLoginUrl));
_saveLoginUrlOnMobileInteractor.execute(recentLoginUrl);
}
}
@@ -391,7 +367,7 @@ class LoginController extends ReloadableController {
}
final recentLoginUsername = RecentLoginUsername.now(_userNameText!);
log('LoginController::_saveRecentLoginUsername(): $recentLoginUsername');
consumeState(_saveLoginUsernameOnMobileInteractor.execute(recentLoginUsername));
_saveLoginUsernameOnMobileInteractor.execute(recentLoginUsername);
}
Future<List<RecentLoginUsername>> getAllRecentLoginUsernameAction(String pattern) async {
@@ -405,9 +381,12 @@ class LoginController extends ReloadableController {
));
}
Uri? _getBaseUrl() => PlatformInfo.isWeb ? _parseUri(AppConfig.baseUrl) : _parseUri(_urlText);
@override
void onClose() {
urlInputController.clear();
urlInputController.dispose();
usernameInputController.dispose();
super.onClose();
}
}
+36 -26
View File
@@ -1,4 +1,5 @@
import 'package:core/presentation/extensions/color_extension.dart';
import 'package:core/presentation/state/success.dart';
import 'package:core/presentation/views/text/type_ahead_form_field_builder.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
@@ -9,7 +10,6 @@ import 'package:tmail_ui_user/features/login/domain/model/recent_login_url.dart'
import 'package:tmail_ui_user/features/login/presentation/base_login_view.dart';
import 'package:tmail_ui_user/features/login/presentation/login_form_type.dart';
import 'package:tmail_ui_user/features/login/presentation/privacy_link_widget.dart';
import 'package:tmail_ui_user/features/login/presentation/state/login_state.dart';
import 'package:tmail_ui_user/features/login/presentation/widgets/login_input_decoration_builder.dart';
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
@@ -72,7 +72,7 @@ class LoginView extends BaseLoginView {
style: const TextStyle(fontSize: 32, color: AppColor.colorNameEmail, fontWeight: FontWeight.w900)
)
),
Obx(() => buildLoginMessage(context, loginController.loginState.value)),
Obx(() => buildLoginMessage(context, loginController.viewState.value)),
Obx(() {
switch (controller.loginFormType.value) {
case LoginFormType.baseUrlForm:
@@ -83,30 +83,7 @@ class LoginView extends BaseLoginView {
return const SizedBox.shrink();
}
}),
Obx(() {
switch (controller.loginFormType.value) {
case LoginFormType.baseUrlForm:
return Obx(() => loginController.loginState.value.viewState.fold(
(failure) => _buildNextButtonInContext(context),
(success) => success is LoginLoadingAction
? buildLoadingCircularProgress()
: _buildNextButtonInContext(context)));
case LoginFormType.credentialForm:
return Obx(() => loginController.loginState.value.viewState.fold(
(failure) => _buildLoginButtonInContext(context),
(success) => success is LoginLoadingAction
? buildLoadingCircularProgress()
: _buildLoginButtonInContext(context)));
case LoginFormType.ssoForm:
return Obx(() => loginController.loginState.value.viewState.fold(
(failure) => _buildLoginButtonInContext(context),
(success) => success is LoginLoadingAction
? buildLoadingCircularProgress()
: _buildLoginButtonInContext(context)));
default:
return const SizedBox.shrink();
}
}),
_buildLoadingProgress(context),
const Padding(
padding: EdgeInsets.only(top: 16),
child: PrivacyLinkWidget(),
@@ -209,4 +186,37 @@ class LoginView extends BaseLoginView {
bool _supportScrollForm(BuildContext context) {
return !(responsiveUtils.isMobile(context) && responsiveUtils.isPortrait(context));
}
Widget _buildLoadingProgress(BuildContext context) {
return Obx(() => loginController.viewState.value.fold(
(failure) {
switch (controller.loginFormType.value) {
case LoginFormType.baseUrlForm:
return _buildNextButtonInContext(context);
case LoginFormType.credentialForm:
return _buildLoginButtonInContext(context);
case LoginFormType.ssoForm:
return _buildLoginButtonInContext(context);
default:
return const SizedBox.shrink();
}
},
(success) {
if (success is LoadingState) {
return buildLoadingCircularProgress();
} else {
switch (controller.loginFormType.value) {
case LoginFormType.baseUrlForm:
return _buildNextButtonInContext(context);
case LoginFormType.credentialForm:
return _buildLoginButtonInContext(context);
case LoginFormType.ssoForm:
return _buildLoginButtonInContext(context);
default:
return const SizedBox.shrink();
}
}
}
));
}
}
@@ -1,11 +1,13 @@
import 'package:core/core.dart';
import 'package:core/presentation/extensions/color_extension.dart';
import 'package:core/presentation/state/success.dart';
import 'package:core/presentation/views/responsive/responsive_widget.dart';
import 'package:core/presentation/views/text/slogan_builder.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:get/get_state_manager/src/rx_flutter/rx_obx_widget.dart';
import 'package:tmail_ui_user/features/login/presentation/base_login_view.dart';
import 'package:tmail_ui_user/features/login/presentation/login_form_type.dart';
import 'package:tmail_ui_user/features/login/presentation/privacy_link_widget.dart';
import 'package:tmail_ui_user/features/login/presentation/state/login_state.dart';
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
class LoginView extends BaseLoginView {
@@ -45,7 +47,7 @@ class LoginView extends BaseLoginView {
style: const TextStyle(fontSize: 32, color: AppColor.colorNameEmail, fontWeight: FontWeight.w900)
)
),
Obx(() => buildLoginMessage(context, loginController.loginState.value)),
Obx(() => buildLoginMessage(context, loginController.viewState.value)),
Obx(() {
switch (controller.loginFormType.value) {
case LoginFormType.credentialForm:
@@ -56,30 +58,7 @@ class LoginView extends BaseLoginView {
return const SizedBox.shrink();
}
}),
Obx(() {
switch (controller.loginFormType.value) {
case LoginFormType.baseUrlForm:
return Obx(() => loginController.loginState.value.viewState.fold(
(failure) => const SizedBox.shrink(),
(success) => success is LoginLoadingAction
? buildLoadingCircularProgress()
: const SizedBox.shrink()));
case LoginFormType.credentialForm:
return Obx(() => loginController.loginState.value.viewState.fold(
(failure) => buildLoginButton(context),
(success) => success is LoginLoadingAction
? buildLoadingCircularProgress()
: buildLoginButton(context)));
case LoginFormType.ssoForm:
return Obx(() => loginController.loginState.value.viewState.fold(
(failure) => _buildSSOButton(context),
(success) => success is LoginLoadingAction
? buildLoadingCircularProgress()
: _buildSSOButton(context)));
default:
return const SizedBox.shrink();
}
}),
_buildLoadingProgress(context),
const Padding(
padding: EdgeInsets.only(top: 16),
child: PrivacyLinkWidget(),
@@ -200,7 +179,7 @@ class LoginView extends BaseLoginView {
style: const TextStyle(fontSize: 32, color: AppColor.colorNameEmail, fontWeight: FontWeight.w900)
)
),
Obx(() => buildLoginMessage(context, loginController.loginState.value)),
Obx(() => buildLoginMessage(context, loginController.viewState.value)),
Obx(() {
switch (controller.loginFormType.value) {
case LoginFormType.credentialForm:
@@ -211,30 +190,7 @@ class LoginView extends BaseLoginView {
return const SizedBox.shrink();
}
}),
Obx(() {
switch (controller.loginFormType.value) {
case LoginFormType.baseUrlForm:
return Obx(() => loginController.loginState.value.viewState.fold(
(failure) => const SizedBox.shrink(),
(success) => success is LoginLoadingAction
? buildLoadingCircularProgress()
: const SizedBox.shrink()));
case LoginFormType.credentialForm:
return Obx(() => loginController.loginState.value.viewState.fold(
(failure) => buildLoginButton(context),
(success) => success is LoginLoadingAction
? buildLoadingCircularProgress()
: buildLoginButton(context)));
case LoginFormType.ssoForm:
return Obx(() => loginController.loginState.value.viewState.fold(
(failure) => _buildSSOButton(context),
(success) => success is LoginLoadingAction
? buildLoadingCircularProgress()
: _buildSSOButton(context)));
default:
return const SizedBox.shrink();
}
}),
_buildLoadingProgress(context),
const Padding(
padding: EdgeInsets.only(top: 16),
child: PrivacyLinkWidget()
@@ -300,4 +256,37 @@ class LoginView extends BaseLoginView {
)
);
}
Widget _buildLoadingProgress(BuildContext context) {
return Obx(() => loginController.viewState.value.fold(
(failure) {
switch (controller.loginFormType.value) {
case LoginFormType.baseUrlForm:
return const SizedBox.shrink();
case LoginFormType.credentialForm:
return buildLoginButton(context);
case LoginFormType.ssoForm:
return _buildSSOButton(context);
default:
return const SizedBox.shrink();
}
},
(success) {
if (success is LoadingState) {
return buildLoadingCircularProgress();
} else {
switch (controller.loginFormType.value) {
case LoginFormType.baseUrlForm:
return const SizedBox.shrink();
case LoginFormType.credentialForm:
return buildLoginButton(context);
case LoginFormType.ssoForm:
return _buildSSOButton(context);
default:
return const SizedBox.shrink();
}
}
}
));
}
}
@@ -1,66 +0,0 @@
import 'package:core/core.dart';
import 'package:dartz/dartz.dart';
import 'package:flutter/material.dart';
@immutable
class LoginState extends AppState {
LoginState(Either<Failure, Success> viewState) : super(viewState);
}
@immutable
class InputUrlCompletion extends ViewState {
@override
List<Object?> get props => [];
}
@immutable
class LoginLoadingAction extends ViewState {
@override
List<Object?> get props => [];
}
@immutable
class LoginInitAction extends ViewState {
@override
List<Object?> get props => [];
}
@immutable
class LoginMissUrlAction extends Failure {
@override
List<Object?> get props => [];
}
@immutable
class LoginMissUsernameAction extends Failure {
@override
List<Object?> get props => [];
}
@immutable
class LoginMissPasswordAction extends Failure {
@override
List<Object?> get props => [];
}
@immutable
class LoginCanNotVerifySSOConfigurationAction extends Failure {
@override
List<Object?> get props => [];
}
@immutable
class LoginCanNotGetTokenAction extends Failure {
@override
List<Object?> get props => [];
}
class LoginSSONotAvailableAction extends Failure {
@override
List<Object?> get props => [];
}
class LoginCanNotAuthenticationSSOAction extends Failure {
@override
List<Object?> get props => [];
}
@@ -102,8 +102,10 @@ class SessionController extends ReloadableController {
} else if (sessionException is BadCredentialsException && currentContext != null) {
errorMessage = AppLocalizations.of(currentContext!).badCredentials;
} else if (sessionException is UnknownError && currentContext != null) {
if (sessionException.message != null) {
if (sessionException.message != null && sessionException.code != null) {
errorMessage = '[${sessionException.code}] ${sessionException.message}';
} else if (sessionException.message != null) {
errorMessage = sessionException.message!;
} else {
errorMessage = AppLocalizations.of(currentContext!).unknownError;
}