1
0
mirror of https://gitlab.com/comunic/comunicmobile synced 2024-11-22 04:49:21 +00:00

Create login widget

This commit is contained in:
Pierre HUBERT 2021-04-17 09:52:05 +02:00
parent d426bf1eb6
commit dafa9e157a
3 changed files with 118 additions and 111 deletions

View File

@ -1,4 +1,3 @@
import 'package:comunic/helpers/api_helper.dart';
import 'package:comunic/helpers/preferences_helper.dart'; import 'package:comunic/helpers/preferences_helper.dart';
import 'package:comunic/helpers/push_notifications_helper.dart'; import 'package:comunic/helpers/push_notifications_helper.dart';
import 'package:comunic/helpers/websocket_helper.dart'; import 'package:comunic/helpers/websocket_helper.dart';
@ -44,11 +43,10 @@ class AccountHelper {
/// Sign in user /// Sign in user
Future<AuthResult> signIn(AuthenticationDetails auth) async { Future<AuthResult> signIn(AuthenticationDetails auth) async {
final request = APIRequest(uri: "account/login"); final response = await APIRequest.withoutLogin("account/login")
request.addString("mail", auth.email); .addString("mail", auth.email)
request.addString("password", auth.password); .addString("password", auth.password)
.exec();
final response = await APIHelper().exec(request);
// Handle errors // Handle errors
if (response.code == 401) if (response.code == 401)

View File

@ -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/create_account_route.dart';
import 'package:comunic/ui/routes/forgot_password_route.dart'; import 'package:comunic/ui/routes/forgot_password_route.dart';
import 'package:comunic/ui/widgets/init_widget.dart'; import 'package:comunic/ui/widgets/init_widget.dart';
import 'package:comunic/ui/widgets/login_scaffold.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/intl_utils.dart';
import 'package:comunic/utils/ui_utils.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
/// Login route /// Login route
@ -19,49 +16,6 @@ class LoginRoute extends StatefulWidget {
} }
class _LoginRouteState extends State<LoginRoute> { 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() { void _openCreateAccountPage() {
Navigator.of(context) Navigator.of(context)
.push(MaterialPageRoute(builder: (c) => CreateAccountRoute())); .push(MaterialPageRoute(builder: (c) => CreateAccountRoute()));
@ -72,67 +26,17 @@ class _LoginRouteState extends State<LoginRoute> {
.push(MaterialPageRoute(builder: (c) => ForgotPasswordRoute())); .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 /// Build login form
Widget _buildLoginForm() { Widget _buildLoginForm() {
// Whether the form can be submitted or not
final valid = validateEmail(_currEmail) && _currPassword.length >= 3;
return SingleChildScrollView( return SingleChildScrollView(
child: Padding( child: Padding(
padding: const EdgeInsets.all(8.0), padding: const EdgeInsets.all(8.0),
child: Column( child: Column(
children: <Widget>[ children: <Widget>[
Container( LoginWidget(
child: _buildErrorCard(), 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( InkWell(
child: Text( child: Text(
tr("Create an account"), tr("Create an account"),
@ -140,9 +44,7 @@ class _LoginRouteState extends State<LoginRoute> {
), ),
onTap: () => _openCreateAccountPage(), onTap: () => _openCreateAccountPage(),
), ),
Container(height: 10), Container(height: 10),
InkWell( InkWell(
child: Text( child: Text(
tr("Password forgotten"), tr("Password forgotten"),
@ -157,7 +59,5 @@ class _LoginRouteState extends State<LoginRoute> {
} }
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) => LoginScaffold(child: _buildLoginForm());
return LoginScaffold(child: _buildLoginForm());
}
} }

View 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;
});
}
}