mirror of
https://gitlab.com/comunic/comunicmobile
synced 2024-12-27 05:18:50 +00:00
130 lines
3.6 KiB
Dart
130 lines
3.6 KiB
Dart
|
import 'package:comunic/helpers/account_helper.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/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 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;
|
||
|
|
||
|
void _setStatus(_Status s) => setState(() => _status = s);
|
||
|
|
||
|
Future<void> _validateToken() async {
|
||
|
_status = _Status.BEFORE_CHANGE;
|
||
|
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.")),
|
||
|
OutlineButton(
|
||
|
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,
|
||
|
),
|
||
|
OutlineButton(
|
||
|
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);
|
||
|
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();
|
||
|
}
|