veilidchat/lib/pages/new_account.dart

153 lines
5.3 KiB
Dart
Raw Normal View History

2023-07-24 03:13:21 +00:00
import 'package:awesome_extensions/awesome_extensions.dart';
2023-07-26 19:58:38 +00:00
import 'package:flutter/foundation.dart';
2023-01-11 02:04:18 +00:00
import 'package:flutter/material.dart';
2023-07-26 18:20:29 +00:00
import 'package:flutter_form_builder/flutter_form_builder.dart';
2023-01-11 02:04:18 +00:00
import 'package:flutter_riverpod/flutter_riverpod.dart';
2023-07-24 03:13:21 +00:00
import 'package:flutter_translate/flutter_translate.dart';
2023-07-24 13:31:51 +00:00
import 'package:form_builder_validators/form_builder_validators.dart';
2023-07-25 05:04:34 +00:00
import 'package:quickalert/quickalert.dart';
2023-07-24 03:13:21 +00:00
import '../components/default_app_bar.dart';
2023-07-25 05:04:34 +00:00
import '../entities/proto.dart' as proto;
2023-07-24 13:31:51 +00:00
import '../providers/local_accounts.dart';
2023-07-25 05:04:34 +00:00
import '../providers/logins.dart';
2023-07-24 03:13:21 +00:00
import '../tools/tools.dart';
2023-07-25 05:04:34 +00:00
import '../veilid_support/veilid_support.dart';
2023-01-11 02:04:18 +00:00
2023-07-24 13:31:51 +00:00
class NewAccountPage extends ConsumerStatefulWidget {
2023-01-11 02:04:18 +00:00
const NewAccountPage({super.key});
static const path = '/new_account';
@override
2023-07-26 18:20:29 +00:00
NewAccountPageState createState() => NewAccountPageState();
2023-07-24 13:31:51 +00:00
}
class NewAccountPageState extends ConsumerState<NewAccountPage> {
final _formKey = GlobalKey<FormBuilderState>();
late bool isInAsyncCall = false;
2023-07-26 18:20:29 +00:00
static const String formFieldName = 'name';
static const String formFieldTitle = 'title';
2023-07-25 05:04:34 +00:00
Future<void> createAccount() async {
final imws = await newIdentityMaster();
try {
final localAccounts = ref.read(localAccountsProvider.notifier);
final logins = ref.read(loginsProvider.notifier);
2023-07-26 19:58:38 +00:00
final profile = proto.Profile()
..name = _formKey.currentState!.fields[formFieldName]!.value as String
..title =
_formKey.currentState!.fields[formFieldTitle]!.value as String;
final account = proto.Account()..profile = profile;
2023-07-25 05:04:34 +00:00
final localAccount = await localAccounts.newAccount(
identityMaster: imws.identityMaster,
identitySecret: imws.identitySecret,
account: account);
// Log in the new account by default with no pin
final ok = await logins
.loginWithNone(localAccount.identityMaster.masterRecordKey);
2023-07-26 19:58:38 +00:00
assert(ok == true, 'login with none should never fail');
} on Exception catch (_) {
2023-07-25 05:04:34 +00:00
await imws.delete();
rethrow;
}
}
2023-07-24 13:31:51 +00:00
Widget _newAccountForm(BuildContext context,
2023-07-26 19:58:38 +00:00
{required Future<void> Function(GlobalKey<FormBuilderState>)
onSubmit}) =>
FormBuilder(
key: _formKey,
child: ListView(
children: [
Text(translate('new_account_page.header'))
.textStyle(context.headlineSmall)
.paddingSymmetric(vertical: 16),
FormBuilderTextField(
autofocus: true,
name: formFieldName,
decoration:
InputDecoration(hintText: translate('account.form_name')),
maxLength: 64,
// The validator receives the text that the user has entered.
validator: FormBuilderValidators.compose([
FormBuilderValidators.required(),
]),
),
FormBuilderTextField(
name: formFieldTitle,
maxLength: 64,
decoration:
InputDecoration(hintText: translate('account.form_title')),
),
Row(children: [
const Spacer(),
Text(translate('new_account_page.instructions'))
.toCenter()
.flexible(flex: 6),
const Spacer(),
]).paddingSymmetric(vertical: 4),
ElevatedButton(
onPressed: () async {
if (_formKey.currentState?.saveAndValidate() ?? false) {
2023-07-24 13:31:51 +00:00
setState(() {
2023-07-26 19:58:38 +00:00
isInAsyncCall = true;
2023-07-24 13:31:51 +00:00
});
2023-07-26 19:58:38 +00:00
try {
await onSubmit(_formKey);
} finally {
setState(() {
isInAsyncCall = false;
});
}
2023-07-24 13:31:51 +00:00
}
2023-07-26 19:58:38 +00:00
},
child: Text(translate('new_account_page.create')),
).paddingSymmetric(vertical: 4).alignAtCenterRight(),
],
),
);
2023-07-24 13:31:51 +00:00
@override
Widget build(BuildContext context) {
2023-07-24 03:13:21 +00:00
enableTitleBar(true);
2023-07-24 13:31:51 +00:00
portraitOnly();
2023-07-25 05:04:34 +00:00
// final localAccountsData = ref.watch(localAccountsProvider);
final displayModalHUD = isInAsyncCall; // || !localAccountsData.hasValue;
2023-07-24 03:13:21 +00:00
2023-01-11 02:04:18 +00:00
return Scaffold(
2023-07-24 13:31:51 +00:00
// resizeToAvoidBottomInset: false,
appBar: DefaultAppBar(context,
2023-07-26 18:20:29 +00:00
title: Text(translate('new_account_page.titlebar'))),
2023-07-24 13:31:51 +00:00
body: _newAccountForm(
context,
onSubmit: (formKey) async {
debugPrint(_formKey.currentState?.value.toString());
FocusScope.of(context).unfocus();
2023-07-25 05:04:34 +00:00
try {
await createAccount();
2023-07-26 19:58:38 +00:00
} on Exception catch (e) {
2023-07-26 18:20:29 +00:00
await QuickAlert.show(
2023-07-25 05:04:34 +00:00
context: context,
type: QuickAlertType.error,
2023-07-26 18:20:29 +00:00
title: translate('new_account_page.error'),
text: 'Exception: $e',
2023-07-25 05:04:34 +00:00
//backgroundColor: Colors.black,
//titleColor: Colors.white,
//textColor: Colors.white,
);
}
2023-07-24 13:31:51 +00:00
},
).paddingSymmetric(horizontal: 24, vertical: 8),
2023-07-25 05:04:34 +00:00
).withModalHUD(context, displayModalHUD);
2023-01-11 02:04:18 +00:00
}
2023-07-26 19:58:38 +00:00
2023-07-26 18:20:29 +00:00
@override
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
super.debugFillProperties(properties);
properties.add(DiagnosticsProperty<bool>('isInAsyncCall', isInAsyncCall));
}
2023-01-11 02:04:18 +00:00
}