verify mnemonic passphrase dialog

This commit is contained in:
julian 2023-08-22 17:06:30 -06:00
parent e20ce631e6
commit 244a1914b3
3 changed files with 245 additions and 1 deletions

View file

@ -0,0 +1,218 @@
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:stackwallet/notifications/show_flush_bar.dart';
import 'package:stackwallet/pages/add_wallet_views/new_wallet_options/new_wallet_options_view.dart';
import 'package:stackwallet/themes/stack_colors.dart';
import 'package:stackwallet/utilities/assets.dart';
import 'package:stackwallet/utilities/constants.dart';
import 'package:stackwallet/utilities/text_styles.dart';
import 'package:stackwallet/utilities/util.dart';
import 'package:stackwallet/widgets/conditional_parent.dart';
import 'package:stackwallet/widgets/desktop/desktop_dialog.dart';
import 'package:stackwallet/widgets/desktop/desktop_dialog_close_button.dart';
import 'package:stackwallet/widgets/desktop/primary_button.dart';
import 'package:stackwallet/widgets/desktop/secondary_button.dart';
import 'package:stackwallet/widgets/stack_dialog.dart';
import 'package:stackwallet/widgets/stack_text_field.dart';
class VerifyMnemonicPassphraseDialog extends ConsumerStatefulWidget {
const VerifyMnemonicPassphraseDialog({super.key});
@override
ConsumerState<VerifyMnemonicPassphraseDialog> createState() =>
_VerifyMnemonicPassphraseDialogState();
}
class _VerifyMnemonicPassphraseDialogState
extends ConsumerState<VerifyMnemonicPassphraseDialog> {
late final FocusNode passwordFocusNode;
late final TextEditingController passwordController;
bool hidePassword = true;
bool _verifyLock = false;
void _verify() {
if (_verifyLock) {
return;
}
_verifyLock = true;
if (passwordController.text ==
ref.read(pNewWalletOptions.state).state!.mnemonicPassphrase) {
Navigator.of(context, rootNavigator: Util.isDesktop).pop("verified");
} else {
showFloatingFlushBar(
type: FlushBarType.warning,
message: "Passphrase does not match",
context: context,
);
}
_verifyLock = false;
}
@override
void initState() {
passwordController = TextEditingController();
passwordFocusNode = FocusNode();
super.initState();
}
@override
void dispose() {
passwordController.dispose();
passwordFocusNode.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return ConditionalParent(
condition: Util.isDesktop,
builder: (child) => DesktopDialog(
maxHeight: double.infinity,
child: Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Padding(
padding: const EdgeInsets.only(
left: 32,
),
child: Text(
"Verify mnemonic passphrase",
style: STextStyles.desktopH3(context),
),
),
const DesktopDialogCloseButton(),
],
),
Padding(
padding: const EdgeInsets.only(
left: 32,
right: 32,
bottom: 32,
),
child: child,
),
],
),
),
child: ConditionalParent(
condition: !Util.isDesktop,
builder: (child) => StackDialogBase(
keyboardPaddingAmount: MediaQuery.of(context).viewInsets.bottom,
child: child,
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
if (!Util.isDesktop)
Text(
"Verify mnemonic passphrase",
style: STextStyles.pageTitleH2(context),
),
const SizedBox(
height: 24,
),
ClipRRect(
borderRadius: BorderRadius.circular(
Constants.size.circularBorderRadius,
),
child: TextField(
key: const Key("mnemonicPassphraseFieldKey1"),
focusNode: passwordFocusNode,
controller: passwordController,
style: Util.isDesktop
? STextStyles.desktopTextMedium(context).copyWith(
height: 2,
)
: STextStyles.field(context),
obscureText: hidePassword,
enableSuggestions: false,
autocorrect: false,
decoration: standardInputDecoration(
"Recovery phrase password",
passwordFocusNode,
context,
).copyWith(
suffixIcon: UnconstrainedBox(
child: ConditionalParent(
condition: Util.isDesktop,
builder: (child) => SizedBox(
height: 70,
child: child,
),
child: Row(
children: [
SizedBox(
width: Util.isDesktop ? 24 : 16,
),
GestureDetector(
key: const Key(
"mnemonicPassphraseFieldShowPasswordButtonKey"),
onTap: () async {
setState(() {
hidePassword = !hidePassword;
});
},
child: SvgPicture.asset(
hidePassword
? Assets.svg.eye
: Assets.svg.eyeSlash,
color: Theme.of(context)
.extension<StackColors>()!
.textDark3,
width: Util.isDesktop ? 24 : 16,
height: Util.isDesktop ? 24 : 16,
),
),
const SizedBox(
width: 12,
),
],
),
),
),
),
),
),
SizedBox(
height: Util.isDesktop ? 48 : 24,
),
ConditionalParent(
condition: !Util.isDesktop,
builder: (child) => Row(
children: [
Expanded(
child: SecondaryButton(
label: "Cancel",
onPressed: Navigator.of(
context,
rootNavigator: Util.isDesktop,
).pop,
),
),
const SizedBox(
width: 16,
),
Expanded(
child: child,
),
],
),
child: PrimaryButton(
label: "Verify",
onPressed: _verify,
),
),
],
),
),
);
}
}

View file

@ -16,9 +16,11 @@ import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:stackwallet/notifications/show_flush_bar.dart';
import 'package:stackwallet/pages/add_wallet_views/add_token_view/edit_wallet_tokens_view.dart';
import 'package:stackwallet/pages/add_wallet_views/new_wallet_options/new_wallet_options_view.dart';
import 'package:stackwallet/pages/add_wallet_views/new_wallet_recovery_phrase_view/new_wallet_recovery_phrase_view.dart';
import 'package:stackwallet/pages/add_wallet_views/select_wallet_for_token_view.dart';
import 'package:stackwallet/pages/add_wallet_views/verify_recovery_phrase_view/sub_widgets/word_table.dart';
import 'package:stackwallet/pages/add_wallet_views/verify_recovery_phrase_view/verify_mnemonic_passphrase_dialog.dart';
import 'package:stackwallet/pages/home_view/home_view.dart';
import 'package:stackwallet/pages_desktop_specific/desktop_home_view.dart';
import 'package:stackwallet/pages_desktop_specific/my_stack_view/exit_to_my_stack_button.dart';
@ -98,8 +100,25 @@ class _VerifyRecoveryPhraseViewState
// }
// }
Future<bool> _verifyMnemonicPassphrase() async {
final result = await showDialog<String?>(
context: context,
builder: (_) => const VerifyMnemonicPassphraseDialog(),
);
return result == "verified";
}
Future<void> _continue(bool isMatch) async {
if (isMatch) {
if (ref.read(pNewWalletOptions.state).state != null) {
final passphraseVerified = await _verifyMnemonicPassphrase();
if (!passphraseVerified) {
return;
}
}
await ref.read(walletsServiceChangeNotifierProvider).setMnemonicVerified(
walletId: _manager.walletId,
);

View file

@ -18,15 +18,22 @@ class StackDialogBase extends StatelessWidget {
Key? key,
this.child,
this.padding = const EdgeInsets.all(24),
this.keyboardPaddingAmount = 0,
}) : super(key: key);
final EdgeInsets padding;
final Widget? child;
final double keyboardPaddingAmount;
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.all(16),
padding: EdgeInsets.only(
top: 16,
left: 16,
right: 16,
bottom: 16 + keyboardPaddingAmount,
),
child: Column(
mainAxisAlignment:
!Util.isDesktop ? MainAxisAlignment.end : MainAxisAlignment.center,