TF-518 Handle missing field in login form

This commit is contained in:
Dat PHAM HOANG
2022-05-06 17:36:14 +07:00
committed by Dat H. Pham
parent 3fc2ae4776
commit 15cc421525
8 changed files with 65 additions and 66 deletions
@@ -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 © 20092020. 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');