From 98252ac4fb60955d3efb975099a6690fb97cf8a3 Mon Sep 17 00:00:00 2001 From: julian Date: Sun, 18 Sep 2022 12:26:21 -0600 Subject: [PATCH] recovery phrase view and mnemonic table view desktop ui layout --- .../new_wallet_recovery_phrase_view.dart | 344 +++++++++++------- .../sub_widgets/mnemonic_table.dart | 58 +-- .../sub_widgets/mnemonic_table_item.dart | 62 ++-- .../sub_views/recovery_phrase_view.dart | 1 + .../wallet_backup_view.dart | 1 + .../delete_wallet_recovery_phrase_view.dart | 1 + .../exit_to_my_stack_button.dart | 18 +- 7 files changed, 297 insertions(+), 188 deletions(-) diff --git a/lib/pages/add_wallet_views/new_wallet_recovery_phrase_view/new_wallet_recovery_phrase_view.dart b/lib/pages/add_wallet_views/new_wallet_recovery_phrase_view/new_wallet_recovery_phrase_view.dart index 7f12e8b6d..9bef5ce22 100644 --- a/lib/pages/add_wallet_views/new_wallet_recovery_phrase_view/new_wallet_recovery_phrase_view.dart +++ b/lib/pages/add_wallet_views/new_wallet_recovery_phrase_view/new_wallet_recovery_phrase_view.dart @@ -1,3 +1,5 @@ +import 'dart:async'; +import 'dart:io'; import 'dart:math'; import 'package:flutter/material.dart'; @@ -8,6 +10,8 @@ import 'package:stackwallet/notifications/show_flush_bar.dart'; import 'package:stackwallet/pages/add_wallet_views/new_wallet_recovery_phrase_view/sub_widgets/mnemonic_table.dart'; import 'package:stackwallet/pages/add_wallet_views/new_wallet_recovery_phrase_warning_view/new_wallet_recovery_phrase_warning_view.dart'; import 'package:stackwallet/pages/add_wallet_views/verify_recovery_phrase_view/verify_recovery_phrase_view.dart'; +import 'package:stackwallet/pages_desktop_specific/home/desktop_home_view.dart'; +import 'package:stackwallet/pages_desktop_specific/home/my_stack_view/exit_to_my_stack_button.dart'; import 'package:stackwallet/providers/providers.dart'; import 'package:stackwallet/services/coins/manager.dart'; import 'package:stackwallet/utilities/assets.dart'; @@ -17,6 +21,8 @@ import 'package:stackwallet/utilities/constants.dart'; import 'package:stackwallet/utilities/enums/flush_bar_type.dart'; import 'package:stackwallet/utilities/text_styles.dart'; import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart'; +import 'package:stackwallet/widgets/desktop/desktop_app_bar.dart'; +import 'package:stackwallet/widgets/desktop/desktop_scaffold.dart'; import 'package:tuple/tuple.dart'; class NewWalletRecoveryPhraseView extends ConsumerStatefulWidget { @@ -46,12 +52,14 @@ class _NewWalletRecoveryPhraseViewState late Manager _manager; late List _mnemonic; late ClipboardInterface _clipboardInterface; + late final bool isDesktop; @override void initState() { _manager = widget.manager; _mnemonic = widget.mnemonic; _clipboardInterface = widget.clipboardInterface; + isDesktop = Platform.isMacOS || Platform.isWindows || Platform.isLinux; super.initState(); } @@ -67,144 +75,228 @@ class _NewWalletRecoveryPhraseViewState await _manager.exitCurrentWallet(); } + Future _copy() async { + final words = await _manager.mnemonic; + await _clipboardInterface.setData(ClipboardData(text: words.join(" "))); + unawaited(showFloatingFlushBar( + type: FlushBarType.info, + message: "Copied to clipboard", + iconAsset: Assets.svg.copy, + context: context, + )); + } + @override Widget build(BuildContext context) { debugPrint("BUILD: $runtimeType"); return WillPopScope( - onWillPop: onWillPop, - child: Scaffold( - appBar: AppBar( - leading: AppBarBackButton( - onPressed: () async { - await delete(); + onWillPop: onWillPop, + child: MasterScaffold( + isDesktop: isDesktop, + appBar: isDesktop + ? DesktopAppBar( + isCompactHeight: false, + leading: AppBarBackButton( + onPressed: () async { + await delete(); - if (mounted) { - Navigator.of(context).popUntil( - ModalRoute.withName( - NewWalletRecoveryPhraseWarningView.routeName, + if (mounted) { + Navigator.of(context).popUntil( + ModalRoute.withName( + NewWalletRecoveryPhraseWarningView.routeName, + ), + ); + } + // Navigator.of(context).pop(); + }, ), - ); - } - // Navigator.of(context).pop(); - }, - ), - actions: [ - Padding( - padding: const EdgeInsets.all(10), - child: AspectRatio( - aspectRatio: 1, - child: AppBarIconButton( - color: CFColors.almostWhite, - shadows: const [], - icon: SvgPicture.asset( - Assets.svg.copy, - width: 24, - height: 24, + trailing: ExitToMyStackButton( + onPressed: () async { + await delete(); + if (mounted) { + Navigator.of(context).popUntil( + ModalRoute.withName(DesktopHomeView.routeName), + ); + } + }, ), - onPressed: () async { - final words = await _manager.mnemonic; - await _clipboardInterface - .setData(ClipboardData(text: words.join(" "))); - showFloatingFlushBar( - type: FlushBarType.info, - message: "Copied to clipboard", - iconAsset: Assets.svg.copy, - context: context, - ); - }, - ), - ), - ), - ], - ), - body: Container( - color: CFColors.almostWhite, - child: Padding( - padding: const EdgeInsets.all(16), - child: Column( - crossAxisAlignment: CrossAxisAlignment.stretch, - children: [ - const SizedBox( - height: 4, - ), - Text( - _manager.walletName, - textAlign: TextAlign.center, - style: STextStyles.label.copyWith( - fontSize: 12, - ), - ), - const SizedBox( - height: 4, - ), - Text( - "Recovery Phrase", - textAlign: TextAlign.center, - style: STextStyles.pageTitleH1, - ), - const SizedBox( - height: 16, - ), - Container( - decoration: BoxDecoration( - color: CFColors.white, - borderRadius: BorderRadius.circular( - Constants.size.circularBorderRadius), - ), - child: Padding( - padding: const EdgeInsets.all(12), - child: Text( - "Please write down your recovery phrase in the correct order and save it to keep your funds secure. You will also be asked to verify the words on the next screen.", - style: STextStyles.label.copyWith( - color: CFColors.stackAccent, - ), - ), - ), - ), - const SizedBox( - height: 8, - ), - Expanded( - child: SingleChildScrollView( - child: MnemonicTable( - words: _mnemonic, - ), - ), - ), - const SizedBox( - height: 16, - ), - TextButton( - onPressed: () async { - final int next = Random().nextInt(_mnemonic.length); - ref - .read(verifyMnemonicWordIndexStateProvider.state) - .update((state) => next); + ) + : AppBar( + leading: AppBarBackButton( + onPressed: () async { + await delete(); - ref - .read(verifyMnemonicCorrectWordStateProvider.state) - .update((state) => _mnemonic[next]); - - Navigator.of(context).pushNamed( - VerifyRecoveryPhraseView.routeName, - arguments: Tuple2(_manager, _mnemonic), - ); - }, - style: Theme.of(context).textButtonTheme.style?.copyWith( - backgroundColor: MaterialStateProperty.all( - CFColors.stackAccent, + if (mounted) { + Navigator.of(context).popUntil( + ModalRoute.withName( + NewWalletRecoveryPhraseWarningView.routeName, + ), + ); + } + }, + ), + actions: [ + Padding( + padding: const EdgeInsets.all(10), + child: AspectRatio( + aspectRatio: 1, + child: AppBarIconButton( + color: CFColors.almostWhite, + shadows: const [], + icon: SvgPicture.asset( + Assets.svg.copy, + width: 24, + height: 24, + ), + onPressed: () async { + await _copy(); + }, ), ), - child: Text( - "I saved my recovery phrase", - style: STextStyles.button, - ), + ), + ], ), - ], + body: Container( + color: CFColors.background, + width: isDesktop ? 600 : null, + child: Padding( + padding: isDesktop + ? const EdgeInsets.all(0) + : const EdgeInsets.all(16), + child: Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + if (!isDesktop) + const SizedBox( + height: 4, + ), + if (!isDesktop) + Text( + _manager.walletName, + textAlign: TextAlign.center, + style: STextStyles.label.copyWith( + fontSize: 12, + ), + ), + SizedBox( + height: isDesktop ? 24 : 4, + ), + Text( + "Recovery Phrase", + textAlign: TextAlign.center, + style: isDesktop + ? STextStyles.desktopH2 + : STextStyles.pageTitleH1, + ), + const SizedBox( + height: 16, + ), + Container( + decoration: BoxDecoration( + color: isDesktop + ? CFColors.background + : CFColors.popupBackground, + borderRadius: BorderRadius.circular( + Constants.size.circularBorderRadius), + ), + child: Padding( + padding: isDesktop + ? const EdgeInsets.all(0) + : const EdgeInsets.all(12), + child: Text( + "Please write down your recovery phrase in the correct order and save it to keep your funds secure. You will also be asked to verify the words on the next screen.", + textAlign: TextAlign.center, + style: isDesktop + ? STextStyles.desktopSubtitleH2 + : STextStyles.label.copyWith( + color: CFColors.stackAccent, + ), + ), + ), + ), + SizedBox( + height: isDesktop ? 21 : 8, + ), + if (!isDesktop) + Expanded( + child: SingleChildScrollView( + child: MnemonicTable( + words: _mnemonic, + isDesktop: isDesktop, + ), + ), + ), + if (isDesktop) + MnemonicTable( + words: _mnemonic, + isDesktop: isDesktop, + ), + SizedBox( + height: isDesktop ? 24 : 16, + ), + if (isDesktop) + SizedBox( + height: 70, + child: TextButton( + onPressed: () async { + await _copy(); + }, + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + SvgPicture.asset( + Assets.svg.copy, + width: 20, + height: 20, + ), + const SizedBox( + width: 10, + ), + Text( + "Copy to clipboard", + style: STextStyles.desktopButtonSecondaryEnabled, + ) + ], + ), + ), + ), + if (isDesktop) + const SizedBox( + height: 16, + ), + ConstrainedBox( + constraints: BoxConstraints( + minHeight: isDesktop ? 70 : 0, + ), + child: TextButton( + onPressed: () async { + final int next = Random().nextInt(_mnemonic.length); + ref + .read(verifyMnemonicWordIndexStateProvider.state) + .update((state) => next); + + ref + .read(verifyMnemonicCorrectWordStateProvider.state) + .update((state) => _mnemonic[next]); + + unawaited(Navigator.of(context).pushNamed( + VerifyRecoveryPhraseView.routeName, + arguments: Tuple2(_manager, _mnemonic), + )); + }, + style: CFColors.getPrimaryEnabledButtonColor(context), + child: Text( + "I saved my recovery phrase", + style: isDesktop + ? STextStyles.desktopButtonEnabled + : STextStyles.button, + ), + ), + ), + ], + ), ), ), - ), - ), - ); + )); } } diff --git a/lib/pages/add_wallet_views/new_wallet_recovery_phrase_view/sub_widgets/mnemonic_table.dart b/lib/pages/add_wallet_views/new_wallet_recovery_phrase_view/sub_widgets/mnemonic_table.dart index 9b33f5248..946f54d4a 100644 --- a/lib/pages/add_wallet_views/new_wallet_recovery_phrase_view/sub_widgets/mnemonic_table.dart +++ b/lib/pages/add_wallet_views/new_wallet_recovery_phrase_view/sub_widgets/mnemonic_table.dart @@ -1,19 +1,20 @@ -import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; import 'package:stackwallet/pages/add_wallet_views/new_wallet_recovery_phrase_view/sub_widgets/mnemonic_table_item.dart'; class MnemonicTable extends StatelessWidget { const MnemonicTable({ Key? key, required this.words, + required this.isDesktop, }) : super(key: key); final List words; - - static const wordsPerRow = 3; + final bool isDesktop; @override Widget build(BuildContext context) { debugPrint("BUILD: $runtimeType"); + final wordsPerRow = isDesktop ? 4 : 3; final int rows = words.length ~/ wordsPerRow; @@ -26,51 +27,54 @@ class MnemonicTable extends StatelessWidget { children: [ for (int i = 1; i <= rows; i++) Padding( - padding: const EdgeInsets.symmetric(vertical: 5), + padding: EdgeInsets.symmetric(vertical: isDesktop ? 8 : 5), child: Row( children: [ for (int j = 1; j <= wordsPerRow; j++) ...[ if (j > 1) - const SizedBox( - width: 6, + SizedBox( + width: isDesktop ? 10 : 6, ), Expanded( child: MnemonicTableItem( number: ++index, word: words[index - 1], + isDesktop: isDesktop, ), ), ], ], ), ), - Padding( - padding: const EdgeInsets.symmetric(vertical: 5), - child: Row( - children: [ - for (int i = index; i < words.length; i++) ...[ - if (i > index) + if (index != words.length) + Padding( + padding: EdgeInsets.symmetric(vertical: isDesktop ? 8 : 5), + child: Row( + children: [ + for (int i = index; i < words.length; i++) ...[ + if (i > index) + SizedBox( + width: isDesktop ? 10 : 6, + ), + Expanded( + child: MnemonicTableItem( + number: i + 1, + word: words[i], + isDesktop: isDesktop, + ), + ), + ], + for (int i = remainder; i < wordsPerRow; i++) ...[ const SizedBox( width: 6, ), - Expanded( - child: MnemonicTableItem( - number: i + 1, - word: words[i], + Expanded( + child: Container(), ), - ), + ], ], - for (int i = remainder; i < wordsPerRow; i++) ...[ - const SizedBox( - width: 6, - ), - Expanded( - child: Container(), - ), - ], - ], + ), ), - ), ], ); } diff --git a/lib/pages/add_wallet_views/new_wallet_recovery_phrase_view/sub_widgets/mnemonic_table_item.dart b/lib/pages/add_wallet_views/new_wallet_recovery_phrase_view/sub_widgets/mnemonic_table_item.dart index dfc8897f8..6a271988d 100644 --- a/lib/pages/add_wallet_views/new_wallet_recovery_phrase_view/sub_widgets/mnemonic_table_item.dart +++ b/lib/pages/add_wallet_views/new_wallet_recovery_phrase_view/sub_widgets/mnemonic_table_item.dart @@ -1,49 +1,53 @@ import 'package:flutter/material.dart'; import 'package:stackwallet/utilities/cfcolors.dart'; -import 'package:stackwallet/utilities/constants.dart'; import 'package:stackwallet/utilities/text_styles.dart'; +import 'package:stackwallet/widgets/rounded_white_container.dart'; class MnemonicTableItem extends StatelessWidget { const MnemonicTableItem({ Key? key, required this.number, required this.word, + required this.isDesktop, }) : super(key: key); final int number; final String word; + final bool isDesktop; @override Widget build(BuildContext context) { debugPrint("BUILD: $runtimeType"); - return Container( - decoration: BoxDecoration( - color: CFColors.white, - borderRadius: BorderRadius.circular( - Constants.size.circularBorderRadius, - ), - ), - child: Padding( - padding: const EdgeInsets.all(8), - child: Row( - mainAxisAlignment: MainAxisAlignment.start, - children: [ - Text( - number.toString(), - style: STextStyles.baseXS.copyWith( - color: CFColors.gray3, - fontSize: 10, - ), - ), - const SizedBox( - width: 8, - ), - Text( - word, - style: STextStyles.baseXS, - ), - ], - ), + return RoundedWhiteContainer( + padding: isDesktop + ? const EdgeInsets.symmetric(horizontal: 12, vertical: 9) + : const EdgeInsets.all(8), + child: Row( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Text( + number.toString(), + style: isDesktop + ? STextStyles.desktopTextExtraSmall.copyWith( + color: CFColors.gray3, + ) + : STextStyles.baseXS.copyWith( + color: CFColors.gray3, + fontSize: 10, + ), + ), + const SizedBox( + width: 8, + ), + Text( + word, + style: isDesktop + ? STextStyles.desktopTextExtraSmall.copyWith( + color: CFColors.textDark, + ) + : STextStyles.baseXS, + ), + ], ), ); } diff --git a/lib/pages/settings_views/global_settings_view/stack_backup_views/sub_views/recovery_phrase_view.dart b/lib/pages/settings_views/global_settings_view/stack_backup_views/sub_views/recovery_phrase_view.dart index 90b5a2c32..d46f2c7f4 100644 --- a/lib/pages/settings_views/global_settings_view/stack_backup_views/sub_views/recovery_phrase_view.dart +++ b/lib/pages/settings_views/global_settings_view/stack_backup_views/sub_views/recovery_phrase_view.dart @@ -93,6 +93,7 @@ class RecoverPhraseView extends StatelessWidget { child: SingleChildScrollView( child: MnemonicTable( words: mnemonic, + isDesktop: false, ), ), ), diff --git a/lib/pages/settings_views/wallet_settings_view/wallet_backup_views/wallet_backup_view.dart b/lib/pages/settings_views/wallet_settings_view/wallet_backup_views/wallet_backup_view.dart index ad46137ba..9895fb177 100644 --- a/lib/pages/settings_views/wallet_settings_view/wallet_backup_views/wallet_backup_view.dart +++ b/lib/pages/settings_views/wallet_settings_view/wallet_backup_views/wallet_backup_view.dart @@ -123,6 +123,7 @@ class WalletBackupView extends ConsumerWidget { child: SingleChildScrollView( child: MnemonicTable( words: mnemonic, + isDesktop: false, ), ), ), diff --git a/lib/pages/settings_views/wallet_settings_view/wallet_settings_wallet_settings/delete_wallet_recovery_phrase_view.dart b/lib/pages/settings_views/wallet_settings_view/wallet_settings_wallet_settings/delete_wallet_recovery_phrase_view.dart index 2ad55ae68..699a1da90 100644 --- a/lib/pages/settings_views/wallet_settings_view/wallet_settings_wallet_settings/delete_wallet_recovery_phrase_view.dart +++ b/lib/pages/settings_views/wallet_settings_view/wallet_settings_wallet_settings/delete_wallet_recovery_phrase_view.dart @@ -140,6 +140,7 @@ class _DeleteWalletRecoveryPhraseViewState child: SingleChildScrollView( child: MnemonicTable( words: _mnemonic, + isDesktop: false, ), ), ), diff --git a/lib/pages_desktop_specific/home/my_stack_view/exit_to_my_stack_button.dart b/lib/pages_desktop_specific/home/my_stack_view/exit_to_my_stack_button.dart index daf5c22e3..876f61c35 100644 --- a/lib/pages_desktop_specific/home/my_stack_view/exit_to_my_stack_button.dart +++ b/lib/pages_desktop_specific/home/my_stack_view/exit_to_my_stack_button.dart @@ -4,7 +4,12 @@ import 'package:stackwallet/utilities/cfcolors.dart'; import 'package:stackwallet/utilities/text_styles.dart'; class ExitToMyStackButton extends StatelessWidget { - const ExitToMyStackButton({Key? key}) : super(key: key); + const ExitToMyStackButton({ + Key? key, + this.onPressed, + }) : super(key: key); + + final VoidCallback? onPressed; @override Widget build(BuildContext context) { @@ -16,11 +21,12 @@ class ExitToMyStackButton extends StatelessWidget { height: 56, child: TextButton( style: CFColors.getSmallSecondaryEnabledButtonColor(context), - onPressed: () { - Navigator.of(context).popUntil( - ModalRoute.withName(DesktopHomeView.routeName), - ); - }, + onPressed: onPressed ?? + () { + Navigator.of(context).popUntil( + ModalRoute.withName(DesktopHomeView.routeName), + ); + }, child: Padding( padding: const EdgeInsets.symmetric( horizontal: 30,