mirror of
https://gitlab.com/comunic/comunicmobile
synced 2024-11-22 04:49:21 +00:00
Create login widget
This commit is contained in:
parent
d426bf1eb6
commit
dafa9e157a
@ -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)
|
||||||
|
@ -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());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
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;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user