mirror of
				https://gitlab.com/comunic/comunicmobile
				synced 2025-10-30 17:54:57 +00:00 
			
		
		
		
	Create login widget
This commit is contained in:
		| @@ -1,4 +1,3 @@ | ||||
| import 'package:comunic/helpers/api_helper.dart'; | ||||
| import 'package:comunic/helpers/preferences_helper.dart'; | ||||
| import 'package:comunic/helpers/push_notifications_helper.dart'; | ||||
| import 'package:comunic/helpers/websocket_helper.dart'; | ||||
| @@ -44,11 +43,10 @@ class AccountHelper { | ||||
|  | ||||
|   /// Sign in user | ||||
|   Future<AuthResult> signIn(AuthenticationDetails auth) async { | ||||
|     final request = APIRequest(uri: "account/login"); | ||||
|     request.addString("mail", auth.email); | ||||
|     request.addString("password", auth.password); | ||||
|  | ||||
|     final response = await APIHelper().exec(request); | ||||
|     final response = await APIRequest.withoutLogin("account/login") | ||||
|         .addString("mail", auth.email) | ||||
|         .addString("password", auth.password) | ||||
|         .exec(); | ||||
|  | ||||
|     // Handle errors | ||||
|     if (response.code == 401) | ||||
|   | ||||
| @@ -1,12 +1,9 @@ | ||||
| import 'package:comunic/helpers/account_helper.dart'; | ||||
| import 'package:comunic/models/authentication_details.dart'; | ||||
| import 'package:comunic/ui/routes/create_account_route.dart'; | ||||
| import 'package:comunic/ui/routes/forgot_password_route.dart'; | ||||
| import 'package:comunic/ui/widgets/init_widget.dart'; | ||||
| import 'package:comunic/ui/widgets/login_scaffold.dart'; | ||||
| import 'package:comunic/utils/input_utils.dart'; | ||||
| import 'package:comunic/ui/widgets/login_widget.dart'; | ||||
| import 'package:comunic/utils/intl_utils.dart'; | ||||
| import 'package:comunic/utils/ui_utils.dart'; | ||||
| import 'package:flutter/material.dart'; | ||||
|  | ||||
| /// Login route | ||||
| @@ -19,49 +16,6 @@ class LoginRoute extends StatefulWidget { | ||||
| } | ||||
|  | ||||
| class _LoginRouteState extends State<LoginRoute> { | ||||
|   String _currEmail; | ||||
|   String _currPassword; | ||||
|   AuthResult _authResult; | ||||
|   bool _loading = false; | ||||
|  | ||||
|   @override | ||||
|   void initState() { | ||||
|     super.initState(); | ||||
|     _currEmail = ""; | ||||
|     _currPassword = ""; | ||||
|   } | ||||
|  | ||||
|   void _emailChanged(String newEmail) { | ||||
|     setState(() { | ||||
|       _currEmail = newEmail; | ||||
|     }); | ||||
|   } | ||||
|  | ||||
|   void _passwordChanged(String newValue) { | ||||
|     setState(() { | ||||
|       _currPassword = newValue; | ||||
|     }); | ||||
|   } | ||||
|  | ||||
|   /// Call this whenever the user request to perform login | ||||
|   Future<void> _submitForm(BuildContext context) async { | ||||
|     setState(() { | ||||
|       _loading = true; | ||||
|     }); | ||||
|  | ||||
|     final loginResult = await AccountHelper().signIn( | ||||
|         AuthenticationDetails(email: _currEmail, password: _currPassword)); | ||||
|  | ||||
|     if (loginResult == AuthResult.SUCCESS) | ||||
|       Navigator.pushReplacement( | ||||
|           context, MaterialPageRoute(builder: (b) => InitializeWidget())); | ||||
|     else | ||||
|       setState(() { | ||||
|         _authResult = loginResult; | ||||
|         _loading = false; | ||||
|       }); | ||||
|   } | ||||
|  | ||||
|   void _openCreateAccountPage() { | ||||
|     Navigator.of(context) | ||||
|         .push(MaterialPageRoute(builder: (c) => CreateAccountRoute())); | ||||
| @@ -72,67 +26,17 @@ class _LoginRouteState extends State<LoginRoute> { | ||||
|         .push(MaterialPageRoute(builder: (c) => ForgotPasswordRoute())); | ||||
|   } | ||||
|  | ||||
|   /// Build error card | ||||
|   Widget _buildErrorCard() { | ||||
|     if (_authResult == null) return null; | ||||
|  | ||||
|     //Determine the right message | ||||
|     final message = (_authResult == AuthResult.INVALID_CREDENTIALS | ||||
|         ? tr("Invalid credentials!") | ||||
|         : (_authResult == AuthResult.TOO_MANY_ATTEMPTS | ||||
|             ? tr( | ||||
|                 "Too many unsuccessfull login attempts! Please try again later...") | ||||
|             : tr("A network error occured!"))); | ||||
|  | ||||
|     return buildErrorCard(message); | ||||
|   } | ||||
|  | ||||
|   /// Build login form | ||||
|   Widget _buildLoginForm() { | ||||
|     // Whether the form can be submitted or not | ||||
|     final valid = validateEmail(_currEmail) && _currPassword.length >= 3; | ||||
|  | ||||
|     return SingleChildScrollView( | ||||
|       child: Padding( | ||||
|         padding: const EdgeInsets.all(8.0), | ||||
|         child: Column( | ||||
|           children: <Widget>[ | ||||
|             Container( | ||||
|               child: _buildErrorCard(), | ||||
|             LoginWidget( | ||||
|               onSignedIn: () => Navigator.pushReplacement(context, | ||||
|                   MaterialPageRoute(builder: (b) => InitializeWidget())), | ||||
|             ), | ||||
|             //Email address | ||||
|             TextField( | ||||
|               keyboardType: TextInputType.emailAddress, | ||||
|               decoration: InputDecoration( | ||||
|                   labelText: tr("Email address"), | ||||
|                   alignLabelWithHint: true, | ||||
|                   errorText: _currEmail.length > 0 && !validateEmail(_currEmail) | ||||
|                       ? tr("Invalid email address!") | ||||
|                       : null), | ||||
|               onChanged: _emailChanged, | ||||
|             ), | ||||
|  | ||||
|             //Password | ||||
|             TextField( | ||||
|               obscureText: true, | ||||
|               decoration: InputDecoration( | ||||
|                 labelText: tr("Password"), | ||||
|                 alignLabelWithHint: true, | ||||
|               ), | ||||
|               onChanged: _passwordChanged, | ||||
|               onSubmitted: valid ? (s) => _submitForm(context) : null, | ||||
|             ), | ||||
|  | ||||
|             Container( | ||||
|               padding: EdgeInsets.all(8.0), | ||||
|               child: _loading | ||||
|                   ? CircularProgressIndicator() | ||||
|                   : ElevatedButton( | ||||
|                       child: Text(tr("Sign in")), | ||||
|                       onPressed: valid ? () => _submitForm(context) : null, | ||||
|                     ), | ||||
|             ), | ||||
|  | ||||
|             InkWell( | ||||
|               child: Text( | ||||
|                 tr("Create an account"), | ||||
| @@ -140,9 +44,7 @@ class _LoginRouteState extends State<LoginRoute> { | ||||
|               ), | ||||
|               onTap: () => _openCreateAccountPage(), | ||||
|             ), | ||||
|  | ||||
|             Container(height: 10), | ||||
|  | ||||
|             InkWell( | ||||
|               child: Text( | ||||
|                 tr("Password forgotten"), | ||||
| @@ -157,7 +59,5 @@ class _LoginRouteState extends State<LoginRoute> { | ||||
|   } | ||||
|  | ||||
|   @override | ||||
|   Widget build(BuildContext context) { | ||||
|     return LoginScaffold(child: _buildLoginForm()); | ||||
|   } | ||||
|   Widget build(BuildContext context) => LoginScaffold(child: _buildLoginForm()); | ||||
| } | ||||
|   | ||||
							
								
								
									
										109
									
								
								lib/ui/widgets/login_widget.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										109
									
								
								lib/ui/widgets/login_widget.dart
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,109 @@ | ||||
| import 'package:comunic/helpers/account_helper.dart'; | ||||
| import 'package:comunic/models/authentication_details.dart'; | ||||
| import 'package:comunic/utils/input_utils.dart'; | ||||
| import 'package:comunic/utils/intl_utils.dart'; | ||||
| import 'package:comunic/utils/ui_utils.dart'; | ||||
| import 'package:flutter/material.dart'; | ||||
|  | ||||
| /// Login widget | ||||
| /// | ||||
| /// Used to authenticate user | ||||
| /// | ||||
| /// @author Pierre Hubert | ||||
|  | ||||
| class LoginWidget extends StatefulWidget { | ||||
|   final void Function() onSignedIn; | ||||
|  | ||||
|   const LoginWidget({Key key, @required this.onSignedIn}) : super(key: key); | ||||
|  | ||||
|   @override | ||||
|   _LoginWidgetState createState() => _LoginWidgetState(); | ||||
| } | ||||
|  | ||||
| class _LoginWidgetState extends State<LoginWidget> { | ||||
|   final _emailEditingController = TextEditingController(); | ||||
|   final _passwordEditionController = TextEditingController(); | ||||
|   bool _loading = false; | ||||
|   AuthResult _authResult; | ||||
|  | ||||
|   String get _currEmail => _emailEditingController.text; | ||||
|  | ||||
|   String get _currPassword => _passwordEditionController.text; | ||||
|  | ||||
|   bool get _canSubmit => validateEmail(_currEmail) && _currPassword.length >= 3; | ||||
|  | ||||
|   /// Build error card | ||||
|   Widget _buildErrorCard() { | ||||
|     if (_authResult == null) return null; | ||||
|  | ||||
|     //Determine the right message | ||||
|     final message = (_authResult == AuthResult.INVALID_CREDENTIALS | ||||
|         ? tr("Invalid credentials!") | ||||
|         : (_authResult == AuthResult.TOO_MANY_ATTEMPTS | ||||
|             ? tr( | ||||
|                 "Too many unsuccessful login attempts! Please try again later...") | ||||
|             : tr("A network error occurred!"))); | ||||
|  | ||||
|     return buildErrorCard(message); | ||||
|   } | ||||
|  | ||||
|   @override | ||||
|   Widget build(BuildContext context) => Column( | ||||
|         children: [ | ||||
|           Container( | ||||
|             child: _buildErrorCard(), | ||||
|           ), | ||||
|           //Email address | ||||
|           TextField( | ||||
|             controller: _emailEditingController, | ||||
|             keyboardType: TextInputType.emailAddress, | ||||
|             decoration: InputDecoration( | ||||
|                 labelText: tr("Email address"), | ||||
|                 alignLabelWithHint: true, | ||||
|                 errorText: _currEmail.length > 0 && !validateEmail(_currEmail) | ||||
|                     ? tr("Invalid email address!") | ||||
|                     : null), | ||||
|             onChanged: (s) => setState(() {}), | ||||
|           ), | ||||
|  | ||||
|           //Password | ||||
|           TextField( | ||||
|             obscureText: true, | ||||
|             decoration: InputDecoration( | ||||
|               labelText: tr("Password"), | ||||
|               alignLabelWithHint: true, | ||||
|             ), | ||||
|             onChanged: (s) => setState(() {}), | ||||
|             onSubmitted: _canSubmit ? (s) => _submitForm(context) : null, | ||||
|           ), | ||||
|  | ||||
|           Container( | ||||
|             padding: EdgeInsets.all(8.0), | ||||
|             child: _loading | ||||
|                 ? CircularProgressIndicator() | ||||
|                 : ElevatedButton( | ||||
|                     child: Text(tr("Sign in")), | ||||
|                     onPressed: _canSubmit ? () => _submitForm(context) : null, | ||||
|                   ), | ||||
|           ), | ||||
|         ], | ||||
|       ); | ||||
|  | ||||
|   /// Call this whenever the user request to perform login | ||||
|   Future<void> _submitForm(BuildContext context) async { | ||||
|     setState(() { | ||||
|       _loading = true; | ||||
|     }); | ||||
|  | ||||
|     final loginResult = await AccountHelper().signIn( | ||||
|         AuthenticationDetails(email: _currEmail, password: _currPassword)); | ||||
|  | ||||
|     if (loginResult == AuthResult.SUCCESS) | ||||
|       widget.onSignedIn(); | ||||
|     else | ||||
|       setState(() { | ||||
|         _authResult = loginResult; | ||||
|         _loading = false; | ||||
|       }); | ||||
|   } | ||||
| } | ||||
		Reference in New Issue
	
	Block a user