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

Create account form is working

This commit is contained in:
Pierre HUBERT 2019-11-02 18:54:30 +01:00
parent 32a32224ca
commit a603d5bd3a
5 changed files with 149 additions and 9 deletions

View File

@ -3,6 +3,7 @@ import 'package:comunic/helpers/preferences_helper.dart';
import 'package:comunic/models/api_request.dart'; import 'package:comunic/models/api_request.dart';
import 'package:comunic/models/authentication_details.dart'; import 'package:comunic/models/authentication_details.dart';
import 'package:comunic/models/login_tokens.dart'; import 'package:comunic/models/login_tokens.dart';
import 'package:comunic/models/new_account.dart';
import 'package:shared_preferences/shared_preferences.dart'; import 'package:shared_preferences/shared_preferences.dart';
/// Account helper /// Account helper
@ -16,6 +17,13 @@ enum AuthResult {
INVALID_CREDENTIALS INVALID_CREDENTIALS
} }
enum CreateAccountResult {
SUCCESS,
ERROR_TOO_MANY_REQUESTS,
ERROR_EXISTING_EMAIL,
ERROR
}
class AccountHelper { class AccountHelper {
static const _USER_ID_PREFERENCE_NAME = "user_id"; static const _USER_ID_PREFERENCE_NAME = "user_id";
@ -76,6 +84,34 @@ class AccountHelper {
_currentUserID = 0; _currentUserID = 0;
} }
/// Create a new user account
Future<CreateAccountResult> createAccount(NewAccount info) async {
final response = await APIRequest(
uri: "account/create",
needLogin: false,
args: {
"firstName": info.firstName,
"lastName": info.lastName,
"emailAddress": info.email,
"password": info.password,
},
).exec();
switch (response.code) {
case 200:
return CreateAccountResult.SUCCESS;
case 409:
return CreateAccountResult.ERROR_EXISTING_EMAIL;
case 429:
return CreateAccountResult.ERROR_TOO_MANY_REQUESTS;
default:
return CreateAccountResult.ERROR;
}
}
/// Get current user ID from the server /// Get current user ID from the server
Future<int> _downloadCurrentUserID() async { Future<int> _downloadCurrentUserID() async {
final response = await APIRequest( final response = await APIRequest(

View File

@ -12,7 +12,7 @@ void main() {
apiServerSecure: false, apiServerSecure: false,
serviceName: "ComunicFlutter", serviceName: "ComunicFlutter",
serviceToken: "G9sZCBmb3IgVWJ1bnR1CkNvbW1lbnRbbmVdPeCkieCkrOCkq", serviceToken: "G9sZCBmb3IgVWJ1bnR1CkNvbW1lbnRbbmVdPeCkieCkrOCkq",
termOfServicesURL: "http://devweb.local/comunic/current/about.php?cgu", termsOfServicesURL: "http://devweb.local/comunic/current/about.php?cgu",
)); ));
subMain(); subMain();

View File

@ -11,7 +11,7 @@ class Config {
final bool apiServerSecure; final bool apiServerSecure;
final String serviceName; final String serviceName;
final String serviceToken; final String serviceToken;
final String termOfServicesURL; final String termsOfServicesURL;
const Config({ const Config({
@required this.apiServerName, @required this.apiServerName,
@ -19,13 +19,13 @@ class Config {
@required this.apiServerSecure, @required this.apiServerSecure,
@required this.serviceName, @required this.serviceName,
@required this.serviceToken, @required this.serviceToken,
@required this.termOfServicesURL, @required this.termsOfServicesURL,
}) : assert(apiServerName != null), }) : assert(apiServerName != null),
assert(apiServerUri != null), assert(apiServerUri != null),
assert(apiServerSecure != null), assert(apiServerSecure != null),
assert(serviceName != null), assert(serviceName != null),
assert(serviceToken != null), assert(serviceToken != null),
assert(termOfServicesURL != null); assert(termsOfServicesURL != null);
/// Get and set static configuration /// Get and set static configuration
static Config _config; static Config _config;

View File

@ -0,0 +1,22 @@
import 'package:flutter/widgets.dart';
/// New account information container
///
/// @author Pierre HUBERT
class NewAccount {
final String firstName;
final String lastName;
final String email;
final String password;
NewAccount({
@required this.firstName,
@required this.lastName,
@required this.email,
@required this.password,
}) : assert(firstName != null),
assert(lastName != null),
assert(email != null),
assert(password != null);
}

View File

@ -1,6 +1,10 @@
import 'package:comunic/helpers/account_helper.dart';
import 'package:comunic/models/config.dart'; import 'package:comunic/models/config.dart';
import 'package:comunic/models/new_account.dart';
import 'package:comunic/utils/input_utils.dart'; import 'package:comunic/utils/input_utils.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/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:url_launcher/url_launcher.dart'; import 'package:url_launcher/url_launcher.dart';
@ -34,6 +38,9 @@ class __CreateAccountRouteBodyState extends State<_CreateAccountRouteBody> {
final _verifyPasswordController = TextEditingController(); final _verifyPasswordController = TextEditingController();
bool _acceptedTOS = false; bool _acceptedTOS = false;
bool _isCreating = false;
CreateAccountResult _createAccountResult;
bool _showErrors = false; bool _showErrors = false;
bool get _isFirstNameValid => _firstNameController.text.length > 3; bool get _isFirstNameValid => _firstNameController.text.length > 3;
@ -55,12 +62,30 @@ class __CreateAccountRouteBodyState extends State<_CreateAccountRouteBody> {
_isPasswordConfirmationValid && _isPasswordConfirmationValid &&
_acceptedTOS; _acceptedTOS;
String get errorMessage => _createAccountResult ==
CreateAccountResult.ERROR_EXISTING_EMAIL
? tr("An account is already associated to this email address!")
: _createAccountResult == CreateAccountResult.ERROR_TOO_MANY_REQUESTS
? tr(
"Too many accounts have been created from this IP address for now. Please try again later.")
: tr(
"An error occured while creating your account. Please try again.");
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
if (_isCreating)
return Center(
child: CircularProgressIndicator(),
);
return Padding( return Padding(
padding: const EdgeInsets.all(8.0), padding: const EdgeInsets.all(8.0),
child: ListView( child: ListView(
children: <Widget>[ children: <Widget>[
_createAccountResult != null
? buildErrorCard(errorMessage)
: Container(),
// First name // First name
_InputEntry( _InputEntry(
controller: _firstNameController, controller: _firstNameController,
@ -119,9 +144,9 @@ class __CreateAccountRouteBodyState extends State<_CreateAccountRouteBody> {
: null, : null,
), ),
// TOSs // TOS
CheckboxListTile( CheckboxListTile(
title: Text("I have read and accepted the Term Of Service."), title: Text(tr("I have read and accepted the Terms Of Service.")),
value: _acceptedTOS, value: _acceptedTOS,
onChanged: (b) { onChanged: (b) {
_acceptedTOS = b; _acceptedTOS = b;
@ -129,7 +154,7 @@ class __CreateAccountRouteBodyState extends State<_CreateAccountRouteBody> {
}, },
subtitle: _showErrors && !_acceptedTOS subtitle: _showErrors && !_acceptedTOS
? Text( ? Text(
tr("You must accept the Term Of Service to continue."), tr("You must accept the Terms Of Service to continue."),
style: TextStyle(color: Colors.redAccent), style: TextStyle(color: Colors.redAccent),
) )
: null, : null,
@ -160,16 +185,73 @@ class __CreateAccountRouteBodyState extends State<_CreateAccountRouteBody> {
}); });
} }
void _submitForm() { void _submitForm() async {
if (!_isFormValid) { if (!_isFormValid) {
_showErrors = true; _showErrors = true;
_updateUI(); _updateUI();
return; return;
} }
setState(() {
_isCreating = true;
});
final result = await AccountHelper().createAccount(NewAccount(
firstName: _firstNameController.text,
lastName: _lastNameController.text,
email: _emailController.text,
password: _passwordController.text,
));
setState(() {
_isCreating = false;
});
if (result != CreateAccountResult.SUCCESS) {
_createAccountResult = result;
_showCreateAccountError();
_updateUI();
return;
}
_accountCreated();
} }
void _openTOS() { void _openTOS() {
launch(config().termOfServicesURL); launch(config().termsOfServicesURL);
}
void _showCreateAccountError() async {
await showCupertinoDialog(
context: context,
builder: (c) => CupertinoAlertDialog(
title: Text(tr("Error while creating your account")),
content: Text(errorMessage),
actions: <Widget>[
CupertinoButton(
child: Text(tr("Ok").toUpperCase()),
onPressed: () => Navigator.of(context).pop(),
)
],
),
);
}
void _accountCreated() async {
await showCupertinoDialog(
context: context,
builder: (c) => CupertinoAlertDialog(
title: Text(tr("Account created")),
content: Text(tr(
"Your account has been successfully created. You can now login to start to use it.")),
actions: <Widget>[
CupertinoButton(
child: Text(tr("Login")), onPressed: () => Navigator.of(c).pop())
],
),
);
Navigator.of(context).pop();
} }
} }