1
0
mirror of https://gitlab.com/comunic/comunicmobile synced 2024-10-23 15:03:22 +00:00
comunicmobile/lib/ui/routes/password_reset_route.dart

143 lines
4.1 KiB
Dart

import 'package:comunic/helpers/account_helper.dart';
import 'package:comunic/models/res_check_password_reset_token.dart';
import 'package:comunic/ui/dialogs/input_new_password_dialog.dart';
import 'package:comunic/ui/widgets/async_screen_widget.dart';
import 'package:comunic/ui/widgets/login_routes_theme.dart';
import 'package:comunic/ui/widgets/new_password_input_widget.dart';
import 'package:comunic/ui/widgets/safe_state.dart';
import 'package:comunic/utils/intl_utils.dart';
import 'package:comunic/utils/ui_utils.dart';
import 'package:flutter/material.dart';
/// Reset user password route
///
/// @author Pierre HUBERT
class PasswordResetRoute extends StatelessWidget {
final String token;
const PasswordResetRoute({
Key key,
@required this.token,
}) : assert(token != null),
super(key: key);
@override
Widget build(BuildContext context) {
return LoginRoutesTheme(
child: Scaffold(
appBar: AppBar(
title: Text(tr("Change your password")),
),
body: _PasswordResetBody(token: token),
),
);
}
}
class _PasswordResetBody extends StatefulWidget {
final String token;
const _PasswordResetBody({Key key, @required this.token})
: assert(token != null),
super(key: key);
@override
__PasswordResetBodyState createState() => __PasswordResetBodyState();
}
enum _Status { BEFORE_CHANGE, WHILE_CHANGE, AFTER_CHANGE }
class __PasswordResetBodyState extends SafeState<_PasswordResetBody> {
final _key = GlobalKey<AsyncScreenWidgetState>();
var _status = _Status.BEFORE_CHANGE;
ResCheckPasswordToken _tokenInfo;
void _setStatus(_Status s) => setState(() => _status = s);
Future<void> _validateToken() async {
_status = _Status.BEFORE_CHANGE;
_tokenInfo = await AccountHelper.validatePasswordResetToken(widget.token);
}
@override
Widget build(BuildContext context) {
return AsyncScreenWidget(
key: _key,
onReload: _validateToken, // The first time, we validate the token
onBuild: _buildBody,
errorMessage: tr(
"Could not validate your password reset token! Maybe it has expired now..."),
);
}
Widget _buildBody() {
// The user has not requested yet to change his password
if (_status == _Status.BEFORE_CHANGE)
return Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Text(tr("You can choose a new password.")),
OutlinedButton(
onPressed: _changePassword,
child: Text(tr("Choose a new password")),
)
],
));
// Password is being changed
if (_status == _Status.WHILE_CHANGE) return buildCenteredProgressBar();
// Password was successfully changed!
if (_status == _Status.AFTER_CHANGE)
return Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Text(
tr("Congratulations! Your password has now been successfully changed!"),
textAlign: TextAlign.center,
),
OutlinedButton(
onPressed: _quitScreen,
child: Text(tr("Login")),
)
],
));
throw Exception("Unreachable statement!");
}
/// Ask the user to specify his new password
void _changePassword() async {
try {
// Ask for new password
final newPass = await showInputNewPassword(
context: context,
userInfo: UserInfoForPassword(
firstName: _tokenInfo.firstName,
lastName: _tokenInfo.lastName,
email: _tokenInfo.email,
),
);
if (newPass == null) return;
_setStatus(_Status.WHILE_CHANGE);
// Apply it
await AccountHelper.changeAccountPassword(widget.token, newPass);
_setStatus(_Status.AFTER_CHANGE);
} catch (e, s) {
print("Could not change user password! $e\n$s");
showSimpleSnack(context, tr("Could not change your password!"));
// We start everything again
_key.currentState.refresh();
}
}
/// Go back to login screen
void _quitScreen() => Navigator.of(context).pop();
}