blob: fbab7e8e1a71ff510ae9f6609802df5270ca4a6a [file] [log] [blame]
// Copyright 2021 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'package:ermine_utils/ermine_utils.dart';
import 'package:flutter/material.dart';
import 'package:flutter_mobx/flutter_mobx.dart';
import 'package:internationalization/strings.dart';
import 'package:login/src/states/oobe_state.dart';
import 'package:login/src/widgets/header.dart';
import 'package:login/src/widgets/login.dart';
import 'package:mobx/mobx.dart';
/// Defines a widget to create account password.
class Password extends StatelessWidget {
static const int kPasswordLength = 8;
final OobeState oobe;
final _formState = GlobalKey<FormState>();
final _passwordController = TextEditingController();
final _confirmPasswordController = TextEditingController();
final _showPassword = true.asObservable();
Password(this.oobe);
@override
Widget build(BuildContext context) {
return Padding(
padding: EdgeInsets.all(16),
child: FocusScope(
child: Observer(builder: (context) {
return Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
// Title and description.
Header(
title: Strings.accountPasswordTitle,
description: Strings.accountPasswordDesc(kPasswordLength),
),
// Password.
Expanded(
child: Form(
key: _formState,
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
SizedBox(height: 40),
// Password.
SizedBox(
width: kOobeBodyFieldWidth,
child: TextFormField(
key: ValueKey('password1'),
autofocus: true,
autovalidateMode: AutovalidateMode.onUserInteraction,
controller: _passwordController,
obscureText: !_showPassword.value,
decoration: InputDecoration(
border: OutlineInputBorder(),
labelText: Strings.passwordHint,
),
validator: (value) {
if (value == null ||
value.isEmpty ||
value.length < kPasswordLength) {
return Strings.accountPasswordInvalid;
}
return null;
},
),
),
SizedBox(height: 40),
// Re-enter password.
SizedBox(
width: kOobeBodyFieldWidth,
child: TextFormField(
key: ValueKey('password2'),
autovalidateMode: AutovalidateMode.onUserInteraction,
controller: _confirmPasswordController,
obscureText: !_showPassword.value,
decoration: InputDecoration(
border: OutlineInputBorder(),
labelText: Strings.confirmPasswordHint,
),
validator: (value) {
if (value != _passwordController.text) {
return Strings.accountPasswordMismatch;
}
return null;
},
onFieldSubmitted: (value) =>
_validate() ? oobe.setPassword(value) : null,
),
),
SizedBox(height: 40),
// Show password checkbox.
SizedBox(
width: kOobeBodyFieldWidth,
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Checkbox(
onChanged: (value) => runInAction(
() => _showPassword.value = value == true),
value: _showPassword.value,
),
SizedBox(height: 40),
Text(Strings.showPassword)
],
),
),
SizedBox(height: 40),
// Show spinning indicator if waiting or api errors,
// if any.
SizedBox(
height: 40,
width: kOobeBodyFieldWidth,
child: oobe.wait
? Center(child: CircularProgressIndicator())
: oobe.authError.isNotEmpty
? Text(
oobe.authError,
style: TextStyle(color: Colors.red),
)
: Offstage(),
),
],
),
),
),
// Buttons.
Container(
alignment: Alignment.center,
padding: EdgeInsets.all(24),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
// Back button.
OutlinedButton(
onPressed: oobe.wait ? null : oobe.prevScreen,
child: Text(Strings.back.toUpperCase()),
),
SizedBox(width: 24),
// Set password button.
ElevatedButton(
key: ValueKey('setPassword'),
onPressed: () => _validate() && !oobe.wait
? oobe.setPassword(_confirmPasswordController.text)
: null,
child: Text(Strings.setPassword.toUpperCase()),
),
],
),
),
],
);
}),
),
);
}
bool _validate() => _formState.currentState?.validate() ?? false;
}