TF-518 Handle missing field in login form
This commit is contained in:
committed by
Dat H. Pham
parent
3fc2ae4776
commit
15cc421525
@@ -55,6 +55,6 @@ class ResponsiveUtils {
|
||||
double getWidthLoginButton() => _loginButtonWidth;
|
||||
|
||||
bool isHeightShortest(BuildContext context) {
|
||||
return MediaQuery.of(context).size.shortestSide < 600;
|
||||
return MediaQuery.of(context).size.shortestSide < heightShortest;
|
||||
}
|
||||
}
|
||||
@@ -6,7 +6,6 @@ import 'package:core/presentation/views/text/text_field_builder.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:tmail_ui_user/features/login/domain/state/authentication_user_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';
|
||||
@@ -29,9 +28,17 @@ abstract class BaseLoginView extends GetWidget<LoginController> {
|
||||
child: CenterTextBuilder()
|
||||
.key(const Key('login_message'))
|
||||
.text(loginState.viewState.fold(
|
||||
(failure) => failure is AuthenticationUserFailure
|
||||
? AppLocalizations.of(context).unknown_error_login_message
|
||||
: AppLocalizations.of(context).loginInputUrlMessage,
|
||||
(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 {
|
||||
return AppLocalizations.of(context).unknown_error_login_message;
|
||||
}
|
||||
},
|
||||
(success) {
|
||||
if (loginController.loginFormType.value == LoginFormType.credentialForm || kIsWeb) {
|
||||
return AppLocalizations.of(context).loginInputCredentialMessage;
|
||||
@@ -42,9 +49,7 @@ abstract class BaseLoginView extends GetWidget<LoginController> {
|
||||
fontSize: 15,
|
||||
fontWeight: FontWeight.w400,
|
||||
color: loginState.viewState.fold(
|
||||
(failure) => failure is AuthenticationUserFailure
|
||||
? AppColor.textFieldErrorBorderColor
|
||||
: AppColor.colorNameEmail,
|
||||
(failure) => AppColor.textFieldErrorBorderColor,
|
||||
(success) => AppColor.colorNameEmail)))
|
||||
.build()
|
||||
)
|
||||
|
||||
@@ -65,8 +65,12 @@ class LoginController extends GetxController {
|
||||
final password = _parsePassword(_passwordText);
|
||||
if (baseUri != null && userName != null && password != null) {
|
||||
_loginAction(baseUri, userName, password);
|
||||
} else {
|
||||
loginState.value = LoginState(Left(LoginMissPropertiesAction()));
|
||||
} 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()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -17,7 +17,6 @@ class LoginView extends BaseLoginView {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
resizeToAvoidBottomInset: true,
|
||||
backgroundColor: AppColor.primaryLightColor,
|
||||
body: GestureDetector(
|
||||
onTap: () => FocusScope.of(context).unfocus(),
|
||||
|
||||
@@ -100,32 +100,32 @@ class LoginView extends BaseLoginView {
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(top: 16),
|
||||
child: (SloganBuilder(arrangedByHorizontal: true, )
|
||||
..setLogoSVG(imagePaths.icEncrypted)
|
||||
..setSizeLogo(48.0)
|
||||
..setPadding(const EdgeInsets.only(left: 12))
|
||||
..setSloganText(AppLocalizations.of(context).encryptedMailbox)
|
||||
..setSloganTextStyle(const TextStyle(fontSize: 24, fontWeight: FontWeight.w400, color: AppColor.colorNameEmail)))
|
||||
.build()
|
||||
..setLogoSVG(imagePaths.icEncrypted)
|
||||
..setSizeLogo(48.0)
|
||||
..setPadding(const EdgeInsets.only(left: 12))
|
||||
..setSloganText(AppLocalizations.of(context).encryptedMailbox)
|
||||
..setSloganTextStyle(const TextStyle(fontSize: 24, fontWeight: FontWeight.w400, color: AppColor.colorNameEmail)))
|
||||
.build()
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(top: 16),
|
||||
child: (SloganBuilder(arrangedByHorizontal: true, )
|
||||
..setLogoSVG(imagePaths.icTeam)
|
||||
..setSizeLogo(48.0)
|
||||
..setPadding(const EdgeInsets.only(left: 12))
|
||||
..setSloganText(AppLocalizations.of(context).manageEmailAsATeam)
|
||||
..setSloganTextStyle(const TextStyle(fontSize: 24, fontWeight: FontWeight.w400, color: AppColor.colorNameEmail)))
|
||||
.build()
|
||||
..setLogoSVG(imagePaths.icTeam)
|
||||
..setSizeLogo(48.0)
|
||||
..setPadding(const EdgeInsets.only(left: 12))
|
||||
..setSloganText(AppLocalizations.of(context).manageEmailAsATeam)
|
||||
..setSloganTextStyle(const TextStyle(fontSize: 24, fontWeight: FontWeight.w400, color: AppColor.colorNameEmail)))
|
||||
.build()
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(top: 16),
|
||||
child: (SloganBuilder(arrangedByHorizontal: true, )
|
||||
..setLogoSVG(imagePaths.icIntegration)
|
||||
..setSizeLogo(48.0)
|
||||
..setPadding(const EdgeInsets.only(left: 12))
|
||||
..setSloganText(AppLocalizations.of(context).multipleIntegrations)
|
||||
..setSloganTextStyle(const TextStyle(fontSize: 24, fontWeight: FontWeight.w400, color: AppColor.colorNameEmail)))
|
||||
.build()
|
||||
..setLogoSVG(imagePaths.icIntegration)
|
||||
..setSizeLogo(48.0)
|
||||
..setPadding(const EdgeInsets.only(left: 12))
|
||||
..setSloganText(AppLocalizations.of(context).multipleIntegrations)
|
||||
..setSloganTextStyle(const TextStyle(fontSize: 24, fontWeight: FontWeight.w400, color: AppColor.colorNameEmail)))
|
||||
.build()
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(top: 44),
|
||||
|
||||
@@ -26,7 +26,19 @@ class LoginInitAction extends ViewState {
|
||||
}
|
||||
|
||||
@immutable
|
||||
class LoginMissPropertiesAction extends Failure {
|
||||
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 => [];
|
||||
}
|
||||
@@ -1,39 +1,3 @@
|
||||
// LinShare is an open source filesharing software, part of the LinPKI software
|
||||
// suite, developed by Linagora.
|
||||
//
|
||||
// Copyright (C) 2020 LINAGORA
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify it under the
|
||||
// terms of the GNU Affero General Public License as published by the Free Software
|
||||
// Foundation, either version 3 of the License, or (at your option) any later version,
|
||||
// provided you comply with the Additional Terms applicable for LinShare software by
|
||||
// Linagora pursuant to Section 7 of the GNU Affero General Public License,
|
||||
// subsections (b), (c), and (e), pursuant to which you must notably (i) retain the
|
||||
// display in the interface of the “LinShare™” trademark/logo, the "Libre & Free" mention,
|
||||
// the words “You are using the Free and Open Source version of LinShare™, powered by
|
||||
// Linagora © 2009–2020. Contribute to Linshare R&D by subscribing to an Enterprise
|
||||
// offer!”. You must also retain the latter notice in all asynchronous messages such as
|
||||
// e-mails sent with the Program, (ii) retain all hypertext links between LinShare and
|
||||
// http://www.linshare.org, between linagora.com and Linagora, and (iii) refrain from
|
||||
// infringing Linagora intellectual property rights over its trademarks and commercial
|
||||
// brands. Other Additional Terms apply, see
|
||||
// <http://www.linshare.org/licenses/LinShare-License_AfferoGPL-v3.pdf
|
||||
//
|
||||
// for more details.
|
||||
// This program is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
// FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for
|
||||
// more details.
|
||||
// You should have received a copy of the GNU Affero General Public License and its
|
||||
// applicable Additional Terms for LinShare along with this program. If not, see
|
||||
// <http://www.gnu.org/licenses
|
||||
// for the GNU Affero General Public License version
|
||||
//
|
||||
// 3 and <http://www.linshare.org/licenses/LinShare-License_AfferoGPL-v3.pdf
|
||||
// for
|
||||
//
|
||||
// the Additional Terms applicable to LinShare software.
|
||||
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:core/core.dart';
|
||||
|
||||
@@ -66,6 +66,21 @@ class AppLocalizations {
|
||||
name: 'signIn');
|
||||
}
|
||||
|
||||
String get requiredEmail {
|
||||
return Intl.message('Email is required',
|
||||
name: 'requiredEmail');
|
||||
}
|
||||
|
||||
String get requiredPassword {
|
||||
return Intl.message('Password is required',
|
||||
name: 'requiredPassword');
|
||||
}
|
||||
|
||||
String get requiredUrl {
|
||||
return Intl.message('Server address is required',
|
||||
name: 'requiredUrl');
|
||||
}
|
||||
|
||||
String get jmapBasedMailSolution {
|
||||
return Intl.message('JMAP-based\ncollaborative team mail solution',
|
||||
name: 'jmapBasedMailSolution');
|
||||
|
||||
Reference in New Issue
Block a user