From 738cb55a40e519c86ffd00d0d103f8accd37eed2 Mon Sep 17 00:00:00 2001 From: julian Date: Tue, 14 May 2024 09:49:20 -0600 Subject: [PATCH 1/5] fix delete frost wallet on mobile --- .../delete_wallet_recovery_phrase_view.dart | 375 +++++++++++++----- .../delete_wallet_warning_view.dart | 47 ++- .../wallet_settings_wallet_settings_view.dart | 10 +- lib/route_generator.dart | 21 + 4 files changed, 338 insertions(+), 115 deletions(-) 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 420002c83..8c7d94fe9 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 @@ -17,6 +17,7 @@ import 'package:flutter_svg/svg.dart'; 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/home_view/home_view.dart'; +import 'package:stackwallet/pages/wallet_view/transaction_views/tx_v2/transaction_v2_details_view.dart'; import 'package:stackwallet/providers/global/secure_store_provider.dart'; import 'package:stackwallet/providers/global/wallets_provider.dart'; import 'package:stackwallet/themes/stack_colors.dart'; @@ -24,23 +25,35 @@ import 'package:stackwallet/utilities/assets.dart'; import 'package:stackwallet/utilities/clipboard_interface.dart'; import 'package:stackwallet/utilities/constants.dart'; import 'package:stackwallet/utilities/text_styles.dart'; +import 'package:stackwallet/utilities/util.dart'; import 'package:stackwallet/wallets/isar/providers/wallet_info_provider.dart'; import 'package:stackwallet/widgets/background.dart'; import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart'; +import 'package:stackwallet/widgets/custom_buttons/simple_copy_button.dart'; +import 'package:stackwallet/widgets/desktop/primary_button.dart'; +import 'package:stackwallet/widgets/detail_item.dart'; +import 'package:stackwallet/widgets/rounded_white_container.dart'; import 'package:stackwallet/widgets/stack_dialog.dart'; class DeleteWalletRecoveryPhraseView extends ConsumerStatefulWidget { const DeleteWalletRecoveryPhraseView({ - Key? key, + super.key, required this.walletId, required this.mnemonic, + this.frostWalletData, this.clipboardInterface = const ClipboardWrapper(), - }) : super(key: key); + }); static const routeName = "/deleteWalletRecoveryPhrase"; final String walletId; final List mnemonic; + final ({ + String myName, + String config, + String keys, + ({String config, String keys})? prevGen, + })? frostWalletData; final ClipboardInterface clipboardInterface; @@ -54,6 +67,62 @@ class _DeleteWalletRecoveryPhraseViewState late List _mnemonic; late ClipboardInterface _clipboardInterface; + bool _lock = false; + + void _continuePressed() { + if (_lock) { + return; + } + _lock = true; + try { + showDialog( + barrierDismissible: true, + context: context, + builder: (_) => StackDialog( + title: "Thanks! Your wallet will be deleted.", + leftButton: TextButton( + style: Theme.of(context) + .extension()! + .getSecondaryEnabledButtonStyle(context), + onPressed: () { + Navigator.pop(context); + }, + child: Text( + "Cancel", + style: STextStyles.button(context).copyWith( + color: + Theme.of(context).extension()!.accentColorDark, + ), + ), + ), + rightButton: TextButton( + style: Theme.of(context) + .extension()! + .getPrimaryEnabledButtonStyle(context), + onPressed: () async { + await ref.read(pWallets).deleteWallet( + ref.read(pWalletInfo(widget.walletId)), + ref.read(secureStoreProvider), + ); + + if (mounted) { + Navigator.of(context).popUntil( + ModalRoute.withName(HomeView.routeName), + ); + } + }, + child: Text( + "Ok", + style: STextStyles.button(context), + ), + ), + ), + ); + } finally { + _lock = false; + } + } + @override void initState() { _mnemonic = widget.mnemonic; @@ -65,6 +134,9 @@ class _DeleteWalletRecoveryPhraseViewState Widget build(BuildContext context) { debugPrint("BUILD: $runtimeType"); + final bool frost = widget.frostWalletData != null; + final prevGen = widget.frostWalletData?.prevGen != null; + return Background( child: Scaffold( backgroundColor: Theme.of(context).extension()!.background, @@ -93,7 +165,7 @@ class _DeleteWalletRecoveryPhraseViewState onPressed: () async { await _clipboardInterface .setData(ClipboardData(text: _mnemonic.join(" "))); - if (mounted) { + if (context.mounted) { unawaited( showFloatingFlushBar( type: FlushBarType.info, @@ -111,116 +183,207 @@ class _DeleteWalletRecoveryPhraseViewState ), body: Padding( padding: const EdgeInsets.all(16), - child: Column( - crossAxisAlignment: CrossAxisAlignment.stretch, - children: [ - const SizedBox( - height: 4, - ), - Text( - ref.watch(pWalletName(widget.walletId)), - textAlign: TextAlign.center, - style: STextStyles.label(context).copyWith( - fontSize: 12, - ), - ), - const SizedBox( - height: 4, - ), - Text( - "Recovery Phrase", - textAlign: TextAlign.center, - style: STextStyles.pageTitleH1(context), - ), - const SizedBox( - height: 16, - ), - Container( - decoration: BoxDecoration( - color: Theme.of(context).extension()!.popupBG, - 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(context).copyWith( - color: Theme.of(context) - .extension()! - .accentColorDark), - ), - ), - ), - const SizedBox( - height: 8, - ), - Expanded( - child: SingleChildScrollView( - child: MnemonicTable( - words: _mnemonic, - isDesktop: false, - ), - ), - ), - const SizedBox( - height: 16, - ), - TextButton( - style: Theme.of(context) - .extension()! - .getPrimaryEnabledButtonStyle(context), - onPressed: () { - showDialog( - barrierDismissible: true, - context: context, - builder: (_) => StackDialog( - title: "Thanks! Your wallet will be deleted.", - leftButton: TextButton( - style: Theme.of(context) - .extension()! - .getSecondaryEnabledButtonStyle(context), - onPressed: () { - Navigator.pop(context); - }, - child: Text( - "Cancel", - style: STextStyles.button(context).copyWith( - color: Theme.of(context) - .extension()! - .accentColorDark), + child: frost + ? LayoutBuilder( + builder: (builderContext, constraints) { + return SingleChildScrollView( + child: ConstrainedBox( + constraints: BoxConstraints( + minHeight: constraints.maxHeight, + ), + child: IntrinsicHeight( + child: Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + RoundedWhiteContainer( + child: Text( + "Please write down your backup data. Keep it safe and " + "never share it with anyone. " + "Your backup data is the only way you can access your " + "funds if you forget your PIN, lose your phone, etc." + "\n\n" + "Stack Wallet does not keep nor is able to restore " + "your backup data. " + "Only you have access to your wallet.", + style: STextStyles.label(context), + ), + ), + const SizedBox( + height: 24, + ), + // DetailItem( + // title: "My name", + // detail: frostWalletData!.myName, + // button: Util.isDesktop + // ? IconCopyButton( + // data: frostWalletData!.myName, + // ) + // : SimpleCopyButton( + // data: frostWalletData!.myName, + // ), + // ), + // const SizedBox( + // height: 16, + // ), + DetailItem( + title: "Multisig config", + detail: widget.frostWalletData!.config, + button: Util.isDesktop + ? IconCopyButton( + data: widget.frostWalletData!.config, + ) + : SimpleCopyButton( + data: widget.frostWalletData!.config, + ), + ), + const SizedBox( + height: 16, + ), + DetailItem( + title: "Keys", + detail: widget.frostWalletData!.keys, + button: Util.isDesktop + ? IconCopyButton( + data: widget.frostWalletData!.keys, + ) + : SimpleCopyButton( + data: widget.frostWalletData!.keys, + ), + ), + if (prevGen) + const SizedBox( + height: 24, + ), + if (prevGen) + RoundedWhiteContainer( + child: Text( + "Previous generation info", + style: STextStyles.label(context), + ), + ), + if (prevGen) + const SizedBox( + height: 12, + ), + if (prevGen) + DetailItem( + title: "Previous multisig config", + detail: + widget.frostWalletData!.prevGen!.config, + button: Util.isDesktop + ? IconCopyButton( + data: widget + .frostWalletData!.prevGen!.config, + ) + : SimpleCopyButton( + data: widget + .frostWalletData!.prevGen!.config, + ), + ), + if (prevGen) + const SizedBox( + height: 16, + ), + if (prevGen) + DetailItem( + title: "Previous keys", + detail: widget.frostWalletData!.prevGen!.keys, + button: Util.isDesktop + ? IconCopyButton( + data: widget + .frostWalletData!.prevGen!.keys, + ) + : SimpleCopyButton( + data: widget + .frostWalletData!.prevGen!.keys, + ), + ), + + const Spacer(), + const SizedBox( + height: 16, + ), + PrimaryButton( + label: "Continue", + onPressed: _continuePressed, + ), + ], + ), + ), + ), + ); + }, + ) + : Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + const SizedBox( + height: 4, + ), + Text( + ref.watch(pWalletName(widget.walletId)), + textAlign: TextAlign.center, + style: STextStyles.label(context).copyWith( + fontSize: 12, + ), + ), + const SizedBox( + height: 4, + ), + Text( + "Recovery Phrase", + textAlign: TextAlign.center, + style: STextStyles.pageTitleH1(context), + ), + const SizedBox( + height: 16, + ), + Container( + decoration: BoxDecoration( + color: + Theme.of(context).extension()!.popupBG, + borderRadius: BorderRadius.circular( + Constants.size.circularBorderRadius, ), ), - rightButton: TextButton( - style: Theme.of(context) - .extension()! - .getPrimaryEnabledButtonStyle(context), - onPressed: () async { - await ref.read(pWallets).deleteWallet( - ref.read(pWalletInfo(widget.walletId)), - ref.read(secureStoreProvider), - ); - - if (mounted) { - Navigator.of(context).popUntil( - ModalRoute.withName(HomeView.routeName)); - } - }, + child: Padding( + padding: const EdgeInsets.all(12), child: Text( - "Ok", - style: STextStyles.button(context), + "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(context).copyWith( + color: Theme.of(context) + .extension()! + .accentColorDark, + ), ), ), ), - ); - }, - child: Text( - "Continue", - style: STextStyles.button(context), + const SizedBox( + height: 8, + ), + Expanded( + child: SingleChildScrollView( + child: MnemonicTable( + words: _mnemonic, + isDesktop: false, + ), + ), + ), + const SizedBox( + height: 16, + ), + TextButton( + style: Theme.of(context) + .extension()! + .getPrimaryEnabledButtonStyle(context), + onPressed: _continuePressed, + child: Text( + "Continue", + style: STextStyles.button(context), + ), + ), + ], ), - ), - ], - ), ), ), ); diff --git a/lib/pages/settings_views/wallet_settings_view/wallet_settings_wallet_settings/delete_wallet_warning_view.dart b/lib/pages/settings_views/wallet_settings_view/wallet_settings_wallet_settings/delete_wallet_warning_view.dart index 2a44ef1f8..84c4f817b 100644 --- a/lib/pages/settings_views/wallet_settings_view/wallet_settings_wallet_settings/delete_wallet_warning_view.dart +++ b/lib/pages/settings_views/wallet_settings_view/wallet_settings_wallet_settings/delete_wallet_warning_view.dart @@ -14,6 +14,7 @@ import 'package:stackwallet/pages/settings_views/wallet_settings_view/wallet_set import 'package:stackwallet/providers/providers.dart'; import 'package:stackwallet/themes/stack_colors.dart'; import 'package:stackwallet/utilities/text_styles.dart'; +import 'package:stackwallet/wallets/wallet/impl/bitcoin_frost_wallet.dart'; import 'package:stackwallet/wallets/wallet/wallet_mixin_interfaces/mnemonic_interface.dart'; import 'package:stackwallet/widgets/background.dart'; import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart'; @@ -21,9 +22,9 @@ import 'package:stackwallet/widgets/rounded_container.dart'; class DeleteWalletWarningView extends ConsumerWidget { const DeleteWalletWarningView({ - Key? key, + super.key, required this.walletId, - }) : super(key: key); + }); static const String routeName = "/deleteWalletWarning"; @@ -100,14 +101,50 @@ class DeleteWalletWarningView extends ConsumerWidget { .getPrimaryEnabledButtonStyle(context), onPressed: () async { final wallet = ref.read(pWallets).getWallet(walletId); - final mnemonic = - await (wallet as MnemonicInterface).getMnemonicAsWords(); + + // TODO: [prio=med] take wallets that don't have a mnemonic into account + + List? mnemonic; + ({ + String myName, + String config, + String keys, + ({String config, String keys})? prevGen, + })? frostWalletData; + + if (wallet is BitcoinFrostWallet) { + final futures = [ + wallet.getSerializedKeys(), + wallet.getMultisigConfig(), + wallet.getSerializedKeysPrevGen(), + wallet.getMultisigConfigPrevGen(), + ]; + + final results = await Future.wait(futures); + + if (results.length == 4) { + frostWalletData = ( + myName: wallet.frostInfo.myName, + config: results[1]!, + keys: results[0]!, + prevGen: results[2] == null || results[3] == null + ? null + : ( + config: results[3]!, + keys: results[2]!, + ), + ); + } + } else if (wallet is MnemonicInterface) { + mnemonic = await wallet.getMnemonicAsWords(); + } if (context.mounted) { await Navigator.of(context).pushNamed( DeleteWalletRecoveryPhraseView.routeName, arguments: ( walletId: walletId, - mnemonicWords: mnemonic, + mnemonicWords: mnemonic ?? [], + frostWalletData: frostWalletData, ), ); } diff --git a/lib/pages/settings_views/wallet_settings_view/wallet_settings_wallet_settings/wallet_settings_wallet_settings_view.dart b/lib/pages/settings_views/wallet_settings_view/wallet_settings_wallet_settings/wallet_settings_wallet_settings_view.dart index 8ead8cd35..e426c576b 100644 --- a/lib/pages/settings_views/wallet_settings_view/wallet_settings_wallet_settings/wallet_settings_wallet_settings_view.dart +++ b/lib/pages/settings_views/wallet_settings_view/wallet_settings_wallet_settings/wallet_settings_wallet_settings_view.dart @@ -122,9 +122,10 @@ class WalletSettingsWalletSettingsView extends ConsumerWidget { child: Text( "Cancel", style: STextStyles.button(context).copyWith( - color: Theme.of(context) - .extension()! - .accentColorDark), + color: Theme.of(context) + .extension()! + .accentColorDark, + ), ), ), rightButton: TextButton( @@ -150,7 +151,8 @@ class WalletSettingsWalletSettingsView extends ConsumerWidget { "Delete wallet", ), settings: const RouteSettings( - name: "/deleteWalletLockscreen"), + name: "/deleteWalletLockscreen", + ), ), ); }, diff --git a/lib/route_generator.dart b/lib/route_generator.dart index f6dcaa6da..62bae2bbd 100644 --- a/lib/route_generator.dart +++ b/lib/route_generator.dart @@ -1745,6 +1745,27 @@ class RouteGenerator { name: settings.name, ), ); + } else if (args is ({ + String walletId, + List mnemonicWords, + ({ + String myName, + String config, + String keys, + ({String config, String keys})? prevGen, + })? frostWalletData, + })) { + return getRoute( + shouldUseMaterialRoute: useMaterialPageRoute, + builder: (_) => DeleteWalletRecoveryPhraseView( + mnemonic: args.mnemonicWords, + walletId: args.walletId, + frostWalletData: args.frostWalletData, + ), + settings: RouteSettings( + name: settings.name, + ), + ); } return _routeError("${settings.name} invalid args: ${args.toString()}"); From 37cb83a2d4be40280a0260b4e9866fca1223c376 Mon Sep 17 00:00:00 2001 From: julian Date: Tue, 14 May 2024 10:26:03 -0600 Subject: [PATCH 2/5] fix coin card color --- lib/models/isar/stack_theme.dart | 451 +++++++++--------- .../sub_widgets/wallet_summary.dart | 4 +- .../sub_widgets/wallet_summary_info.dart | 13 +- lib/pages/wallet_view/wallet_view.dart | 4 +- lib/themes/theme_providers.dart | 10 + lib/themes/theme_service.dart | 2 +- lib/widgets/coin_card.dart | 6 +- 7 files changed, 252 insertions(+), 238 deletions(-) diff --git a/lib/models/isar/stack_theme.dart b/lib/models/isar/stack_theme.dart index 01e32bb2d..09f42b1b6 100644 --- a/lib/models/isar/stack_theme.dart +++ b/lib/models/isar/stack_theme.dart @@ -13,11 +13,11 @@ import 'dart:io'; import 'package:flutter/material.dart'; import 'package:isar/isar.dart'; -import 'package:stackwallet/themes/color_theme.dart'; import 'package:stackwallet/utilities/enums/coin_enum.dart'; import 'package:stackwallet/utilities/extensions/impl/box_shadow.dart'; import 'package:stackwallet/utilities/extensions/impl/gradient.dart'; import 'package:stackwallet/utilities/extensions/impl/string.dart'; +import 'package:stackwallet/utilities/logger.dart'; import 'package:stackwallet/utilities/stack_file_system.dart'; part 'stack_theme.g.dart'; @@ -45,7 +45,7 @@ class StackTheme { case "dark": return Brightness.dark; default: - // just return light instead of a possible crash causing error + // just return light instead of a possible crash causing error return Brightness.light; } } @@ -131,8 +131,8 @@ class StackTheme { @ignore Color get accentColorBlue => _accentColorBlue ??= Color( - accentColorBlueInt, - ); + accentColorBlueInt, + ); @ignore Color? _accentColorBlue; late final int accentColorBlueInt; @@ -141,8 +141,8 @@ class StackTheme { @ignore Color get accentColorGreen => _accentColorGreen ??= Color( - accentColorGreenInt, - ); + accentColorGreenInt, + ); @ignore Color? _accentColorGreen; late final int accentColorGreenInt; @@ -151,8 +151,8 @@ class StackTheme { @ignore Color get accentColorYellow => _accentColorYellow ??= Color( - accentColorYellowInt, - ); + accentColorYellowInt, + ); @ignore Color? _accentColorYellow; late final int accentColorYellowInt; @@ -161,8 +161,8 @@ class StackTheme { @ignore Color get accentColorRed => _accentColorRed ??= Color( - accentColorRedInt, - ); + accentColorRedInt, + ); @ignore Color? _accentColorRed; late final int accentColorRedInt; @@ -171,8 +171,8 @@ class StackTheme { @ignore Color get accentColorOrange => _accentColorOrange ??= Color( - accentColorOrangeInt, - ); + accentColorOrangeInt, + ); @ignore Color? _accentColorOrange; late final int accentColorOrangeInt; @@ -181,8 +181,8 @@ class StackTheme { @ignore Color get accentColorDark => _accentColorDark ??= Color( - accentColorDarkInt, - ); + accentColorDarkInt, + ); @ignore Color? _accentColorDark; late final int accentColorDarkInt; @@ -191,8 +191,8 @@ class StackTheme { @ignore Color get shadow => _shadow ??= Color( - shadowInt, - ); + shadowInt, + ); @ignore Color? _shadow; late final int shadowInt; @@ -201,8 +201,8 @@ class StackTheme { @ignore Color get textDark => _textDark ??= Color( - textDarkInt, - ); + textDarkInt, + ); @ignore Color? _textDark; late final int textDarkInt; @@ -211,8 +211,8 @@ class StackTheme { @ignore Color get textDark2 => _textDark2 ??= Color( - textDark2Int, - ); + textDark2Int, + ); @ignore Color? _textDark2; late final int textDark2Int; @@ -221,8 +221,8 @@ class StackTheme { @ignore Color get textDark3 => _textDark3 ??= Color( - textDark3Int, - ); + textDark3Int, + ); @ignore Color? _textDark3; late final int textDark3Int; @@ -231,8 +231,8 @@ class StackTheme { @ignore Color get textSubtitle1 => _textSubtitle1 ??= Color( - textSubtitle1Int, - ); + textSubtitle1Int, + ); @ignore Color? _textSubtitle1; late final int textSubtitle1Int; @@ -241,8 +241,8 @@ class StackTheme { @ignore Color get textSubtitle2 => _textSubtitle2 ??= Color( - textSubtitle2Int, - ); + textSubtitle2Int, + ); @ignore Color? _textSubtitle2; late final int textSubtitle2Int; @@ -251,8 +251,8 @@ class StackTheme { @ignore Color get textSubtitle3 => _textSubtitle3 ??= Color( - textSubtitle3Int, - ); + textSubtitle3Int, + ); @ignore Color? _textSubtitle3; late final int textSubtitle3Int; @@ -261,8 +261,8 @@ class StackTheme { @ignore Color get textSubtitle4 => _textSubtitle4 ??= Color( - textSubtitle4Int, - ); + textSubtitle4Int, + ); @ignore Color? _textSubtitle4; late final int textSubtitle4Int; @@ -271,8 +271,8 @@ class StackTheme { @ignore Color get textSubtitle5 => _textSubtitle5 ??= Color( - textSubtitle5Int, - ); + textSubtitle5Int, + ); @ignore Color? _textSubtitle5; late final int textSubtitle5Int; @@ -281,8 +281,8 @@ class StackTheme { @ignore Color get textSubtitle6 => _textSubtitle6 ??= Color( - textSubtitle6Int, - ); + textSubtitle6Int, + ); @ignore Color? _textSubtitle6; late final int textSubtitle6Int; @@ -291,8 +291,8 @@ class StackTheme { @ignore Color get textWhite => _textWhite ??= Color( - textWhiteInt, - ); + textWhiteInt, + ); @ignore Color? _textWhite; late final int textWhiteInt; @@ -301,8 +301,8 @@ class StackTheme { @ignore Color get textFavoriteCard => _textFavoriteCard ??= Color( - textFavoriteCardInt, - ); + textFavoriteCardInt, + ); @ignore Color? _textFavoriteCard; late final int textFavoriteCardInt; @@ -311,8 +311,8 @@ class StackTheme { @ignore Color get textError => _textError ??= Color( - textErrorInt, - ); + textErrorInt, + ); @ignore Color? _textError; late final int textErrorInt; @@ -321,8 +321,8 @@ class StackTheme { @ignore Color get textRestore => _textRestore ??= Color( - textRestoreInt, - ); + textRestoreInt, + ); @ignore Color? _textRestore; late final int textRestoreInt; @@ -331,8 +331,8 @@ class StackTheme { @ignore Color get buttonBackPrimary => _buttonBackPrimary ??= Color( - buttonBackPrimaryInt, - ); + buttonBackPrimaryInt, + ); @ignore Color? _buttonBackPrimary; late final int buttonBackPrimaryInt; @@ -341,8 +341,8 @@ class StackTheme { @ignore Color get buttonBackSecondary => _buttonBackSecondary ??= Color( - buttonBackSecondaryInt, - ); + buttonBackSecondaryInt, + ); @ignore Color? _buttonBackSecondary; late final int buttonBackSecondaryInt; @@ -351,8 +351,8 @@ class StackTheme { @ignore Color get buttonBackPrimaryDisabled => _buttonBackPrimaryDisabled ??= Color( - buttonBackPrimaryDisabledInt, - ); + buttonBackPrimaryDisabledInt, + ); @ignore Color? _buttonBackPrimaryDisabled; late final int buttonBackPrimaryDisabledInt; @@ -372,8 +372,8 @@ class StackTheme { @ignore Color get buttonBackBorder => _buttonBackBorder ??= Color( - buttonBackBorderInt, - ); + buttonBackBorderInt, + ); @ignore Color? _buttonBackBorder; late final int buttonBackBorderInt; @@ -382,8 +382,8 @@ class StackTheme { @ignore Color get buttonBackBorderDisabled => _buttonBackBorderDisabled ??= Color( - buttonBackBorderDisabledInt, - ); + buttonBackBorderDisabledInt, + ); @ignore Color? _buttonBackBorderDisabled; late final int buttonBackBorderDisabledInt; @@ -392,8 +392,8 @@ class StackTheme { @ignore Color get buttonBackBorderSecondary => _buttonBackBorderSecondary ??= Color( - buttonBackBorderSecondaryInt, - ); + buttonBackBorderSecondaryInt, + ); @ignore Color? _buttonBackBorderSecondary; late final int buttonBackBorderSecondaryInt; @@ -413,8 +413,8 @@ class StackTheme { @ignore Color get numberBackDefault => _numberBackDefault ??= Color( - numberBackDefaultInt, - ); + numberBackDefaultInt, + ); @ignore Color? _numberBackDefault; late final int numberBackDefaultInt; @@ -423,8 +423,8 @@ class StackTheme { @ignore Color get numpadBackDefault => _numpadBackDefault ??= Color( - numpadBackDefaultInt, - ); + numpadBackDefaultInt, + ); @ignore Color? _numpadBackDefault; late final int numpadBackDefaultInt; @@ -433,8 +433,8 @@ class StackTheme { @ignore Color get bottomNavBack => _bottomNavBack ??= Color( - bottomNavBackInt, - ); + bottomNavBackInt, + ); @ignore Color? _bottomNavBack; late final int bottomNavBackInt; @@ -443,8 +443,8 @@ class StackTheme { @ignore Color get buttonTextPrimary => _buttonTextPrimary ??= Color( - buttonTextPrimaryInt, - ); + buttonTextPrimaryInt, + ); @ignore Color? _buttonTextPrimary; late final int buttonTextPrimaryInt; @@ -453,8 +453,8 @@ class StackTheme { @ignore Color get buttonTextSecondary => _buttonTextSecondary ??= Color( - buttonTextSecondaryInt, - ); + buttonTextSecondaryInt, + ); @ignore Color? _buttonTextSecondary; late final int buttonTextSecondaryInt; @@ -463,8 +463,8 @@ class StackTheme { @ignore Color get buttonTextPrimaryDisabled => _buttonTextPrimaryDisabled ??= Color( - buttonTextPrimaryDisabledInt, - ); + buttonTextPrimaryDisabledInt, + ); @ignore Color? _buttonTextPrimaryDisabled; late final int buttonTextPrimaryDisabledInt; @@ -1517,117 +1517,117 @@ class StackTheme { ..version = version ..assetsV1 = version == 1 ? ThemeAssets.fromJson( - json: Map.from(json["assets"] as Map), - themeId: json["id"] as String, - ) + json: Map.from(json["assets"] as Map), + themeId: json["id"] as String, + ) : null ..assetsV2 = version == 2 ? ThemeAssetsV2.fromJson( - json: Map.from(json["assets"] as Map), - themeId: json["id"] as String, - ) + json: Map.from(json["assets"] as Map), + themeId: json["id"] as String, + ) : null ..assetsV3 = version >= 3 ? ThemeAssetsV3.fromJson( - json: Map.from(json["assets"] as Map), - themeId: json["id"] as String, - ) + json: Map.from(json["assets"] as Map), + themeId: json["id"] as String, + ) : null ..themeId = json["id"] as String ..name = json["name"] as String ..brightnessString = json["brightness"] as String ..backgroundInt = parseColor(json["colors"]["background"] as String) ..backgroundAppBarInt = - parseColor(json["colors"]["background_app_bar"] as String) + parseColor(json["colors"]["background_app_bar"] as String) ..gradientBackgroundString = json["colors"]["gradients"] != null ? jsonEncode(json["colors"]["gradients"]) : null ..standardBoxShadowString = - jsonEncode(json["colors"]["box_shadows"]["standard"] as Map) + jsonEncode(json["colors"]["box_shadows"]["standard"] as Map) ..homeViewButtonBarBoxShadowString = - json["colors"]["box_shadows"]["home_view_button_bar"] == null - ? null - : jsonEncode( - json["colors"]["box_shadows"]["home_view_button_bar"] as Map) + json["colors"]["box_shadows"]["home_view_button_bar"] == null + ? null + : jsonEncode( + json["colors"]["box_shadows"]["home_view_button_bar"] as Map) ..coinColorsJsonString = jsonEncode(json["colors"]['coin'] as Map) ..overlayInt = parseColor(json["colors"]["overlay"] as String) ..accentColorBlueInt = - parseColor(json["colors"]["accent_color_blue"] as String) + parseColor(json["colors"]["accent_color_blue"] as String) ..accentColorGreenInt = - parseColor(json["colors"]["accent_color_green"] as String) + parseColor(json["colors"]["accent_color_green"] as String) ..accentColorYellowInt = - parseColor(json["colors"]["accent_color_yellow"] as String) + parseColor(json["colors"]["accent_color_yellow"] as String) ..accentColorRedInt = - parseColor(json["colors"]["accent_color_red"] as String) + parseColor(json["colors"]["accent_color_red"] as String) ..accentColorOrangeInt = - parseColor(json["colors"]["accent_color_orange"] as String) + parseColor(json["colors"]["accent_color_orange"] as String) ..accentColorDarkInt = - parseColor(json["colors"]["accent_color_dark"] as String) + parseColor(json["colors"]["accent_color_dark"] as String) ..shadowInt = parseColor(json["colors"]["shadow"] as String) ..textDarkInt = parseColor(json["colors"]["text_dark_one"] as String) ..textDark2Int = parseColor(json["colors"]["text_dark_two"] as String) ..textDark3Int = parseColor(json["colors"]["text_dark_three"] as String) ..textWhiteInt = parseColor(json["colors"]["text_white"] as String) ..textFavoriteCardInt = - parseColor(json["colors"]["text_favorite"] as String) + parseColor(json["colors"]["text_favorite"] as String) ..textErrorInt = parseColor(json["colors"]["text_error"] as String) ..textRestoreInt = parseColor(json["colors"]["text_restore"] as String) ..buttonBackPrimaryInt = - parseColor(json["colors"]["button_back_primary"] as String) + parseColor(json["colors"]["button_back_primary"] as String) ..buttonBackSecondaryInt = - parseColor(json["colors"]["button_back_secondary"] as String) + parseColor(json["colors"]["button_back_secondary"] as String) ..buttonBackPrimaryDisabledInt = - parseColor(json["colors"]["button_back_primary_disabled"] as String) + parseColor(json["colors"]["button_back_primary_disabled"] as String) ..buttonBackSecondaryDisabledInt = - parseColor(json["colors"]["button_back_secondary_disabled"] as String) + parseColor(json["colors"]["button_back_secondary_disabled"] as String) ..buttonBackBorderInt = - parseColor(json["colors"]["button_back_border"] as String) + parseColor(json["colors"]["button_back_border"] as String) ..buttonBackBorderDisabledInt = - parseColor(json["colors"]["button_back_border_disabled"] as String) + parseColor(json["colors"]["button_back_border_disabled"] as String) ..buttonBackBorderSecondaryInt = - parseColor(json["colors"]["button_back_border_secondary"] as String) + parseColor(json["colors"]["button_back_border_secondary"] as String) ..buttonBackBorderSecondaryDisabledInt = parseColor( json["colors"]["button_back_border_secondary_disabled"] as String) ..numberBackDefaultInt = - parseColor(json["colors"]["number_back_default"] as String) + parseColor(json["colors"]["number_back_default"] as String) ..numpadBackDefaultInt = - parseColor(json["colors"]["numpad_back_default"] as String) + parseColor(json["colors"]["numpad_back_default"] as String) ..bottomNavBackInt = - parseColor(json["colors"]["bottom_nav_back"] as String) + parseColor(json["colors"]["bottom_nav_back"] as String) ..textSubtitle1Int = - parseColor(json["colors"]["text_subtitle_one"] as String) + parseColor(json["colors"]["text_subtitle_one"] as String) ..textSubtitle2Int = - parseColor(json["colors"]["text_subtitle_two"] as String) + parseColor(json["colors"]["text_subtitle_two"] as String) ..textSubtitle3Int = - parseColor(json["colors"]["text_subtitle_three"] as String) + parseColor(json["colors"]["text_subtitle_three"] as String) ..textSubtitle4Int = - parseColor(json["colors"]["text_subtitle_four"] as String) + parseColor(json["colors"]["text_subtitle_four"] as String) ..textSubtitle5Int = - parseColor(json["colors"]["text_subtitle_five"] as String) + parseColor(json["colors"]["text_subtitle_five"] as String) ..textSubtitle6Int = - parseColor(json["colors"]["text_subtitle_six"] as String) + parseColor(json["colors"]["text_subtitle_six"] as String) ..buttonTextPrimaryInt = - parseColor(json["colors"]["button_text_primary"] as String) + parseColor(json["colors"]["button_text_primary"] as String) ..buttonTextSecondaryInt = - parseColor(json["colors"]["button_text_secondary"] as String) + parseColor(json["colors"]["button_text_secondary"] as String) ..buttonTextPrimaryDisabledInt = - parseColor(json["colors"]["button_text_primary_disabled"] as String) + parseColor(json["colors"]["button_text_primary_disabled"] as String) ..buttonTextSecondaryDisabledInt = - parseColor(json["colors"]["button_text_secondary_disabled"] as String) + parseColor(json["colors"]["button_text_secondary_disabled"] as String) ..buttonTextBorderInt = - parseColor(json["colors"]["button_text_border"] as String) + parseColor(json["colors"]["button_text_border"] as String) ..buttonTextDisabledInt = - parseColor(json["colors"]["button_text_disabled"] as String) + parseColor(json["colors"]["button_text_disabled"] as String) ..buttonTextBorderlessInt = - parseColor(json["colors"]["button_text_borderless"] as String) + parseColor(json["colors"]["button_text_borderless"] as String) ..buttonTextBorderlessDisabledInt = parseColor( json["colors"]["button_text_borderless_disabled"] as String) ..numberTextDefaultInt = - parseColor(json["colors"]["number_text_default"] as String) + parseColor(json["colors"]["number_text_default"] as String) ..numpadTextDefaultInt = - parseColor(json["colors"]["numpad_text_default"] as String) + parseColor(json["colors"]["numpad_text_default"] as String) ..bottomNavTextInt = - parseColor(json["colors"]["bottom_nav_text"] as String) + parseColor(json["colors"]["bottom_nav_text"] as String) ..customTextButtonEnabledTextInt = parseColor( json["colors"]["custom_text_button_enabled_text"] as String) ..customTextButtonDisabledTextInt = parseColor( @@ -1635,87 +1635,87 @@ class StackTheme { ..switchBGOnInt = parseColor(json["colors"]["switch_bg_on"] as String) ..switchBGOffInt = parseColor(json["colors"]["switch_bg_off"] as String) ..switchBGDisabledInt = - parseColor(json["colors"]["switch_bg_disabled"] as String) + parseColor(json["colors"]["switch_bg_disabled"] as String) ..switchCircleOnInt = - parseColor(json["colors"]["switch_circle_on"] as String) + parseColor(json["colors"]["switch_circle_on"] as String) ..switchCircleOffInt = - parseColor(json["colors"]["switch_circle_off"] as String) + parseColor(json["colors"]["switch_circle_off"] as String) ..switchCircleDisabledInt = - parseColor(json["colors"]["switch_circle_disabled"] as String) + parseColor(json["colors"]["switch_circle_disabled"] as String) ..stepIndicatorBGCheckInt = - parseColor(json["colors"]["step_indicator_bg_check"] as String) + parseColor(json["colors"]["step_indicator_bg_check"] as String) ..stepIndicatorBGNumberInt = - parseColor(json["colors"]["step_indicator_bg_number"] as String) + parseColor(json["colors"]["step_indicator_bg_number"] as String) ..stepIndicatorBGInactiveInt = - parseColor(json["colors"]["step_indicator_bg_inactive"] as String) + parseColor(json["colors"]["step_indicator_bg_inactive"] as String) ..stepIndicatorBGLinesInt = - parseColor(json["colors"]["step_indicator_bg_lines"] as String) + parseColor(json["colors"]["step_indicator_bg_lines"] as String) ..stepIndicatorBGLinesInactiveInt = parseColor( json["colors"]["step_indicator_bg_lines_inactive"] as String) ..stepIndicatorIconTextInt = - parseColor(json["colors"]["step_indicator_icon_text"] as String) + parseColor(json["colors"]["step_indicator_icon_text"] as String) ..stepIndicatorIconNumberInt = - parseColor(json["colors"]["step_indicator_icon_number"] as String) + parseColor(json["colors"]["step_indicator_icon_number"] as String) ..stepIndicatorIconInactiveInt = - parseColor(json["colors"]["step_indicator_icon_inactive"] as String) + parseColor(json["colors"]["step_indicator_icon_inactive"] as String) ..checkboxBGCheckedInt = - parseColor(json["colors"]["checkbox_bg_checked"] as String) + parseColor(json["colors"]["checkbox_bg_checked"] as String) ..checkboxBorderEmptyInt = - parseColor(json["colors"]["checkbox_border_empty"] as String) + parseColor(json["colors"]["checkbox_border_empty"] as String) ..checkboxBGDisabledInt = - parseColor(json["colors"]["checkbox_bg_disabled"] as String) + parseColor(json["colors"]["checkbox_bg_disabled"] as String) ..checkboxIconCheckedInt = - parseColor(json["colors"]["checkbox_icon_checked"] as String) + parseColor(json["colors"]["checkbox_icon_checked"] as String) ..checkboxIconDisabledInt = - parseColor(json["colors"]["checkbox_icon_disabled"] as String) + parseColor(json["colors"]["checkbox_icon_disabled"] as String) ..checkboxTextLabelInt = - parseColor(json["colors"]["checkbox_text_label"] as String) + parseColor(json["colors"]["checkbox_text_label"] as String) ..snackBarBackSuccessInt = - parseColor(json["colors"]["snack_bar_back_success"] as String) + parseColor(json["colors"]["snack_bar_back_success"] as String) ..snackBarBackErrorInt = - parseColor(json["colors"]["snack_bar_back_error"] as String) + parseColor(json["colors"]["snack_bar_back_error"] as String) ..snackBarBackInfoInt = - parseColor(json["colors"]["snack_bar_back_info"] as String) + parseColor(json["colors"]["snack_bar_back_info"] as String) ..snackBarTextSuccessInt = - parseColor(json["colors"]["snack_bar_text_success"] as String) + parseColor(json["colors"]["snack_bar_text_success"] as String) ..snackBarTextErrorInt = - parseColor(json["colors"]["snack_bar_text_error"] as String) + parseColor(json["colors"]["snack_bar_text_error"] as String) ..snackBarTextInfoInt = - parseColor(json["colors"]["snack_bar_text_info"] as String) + parseColor(json["colors"]["snack_bar_text_info"] as String) ..bottomNavIconBackInt = - parseColor(json["colors"]["bottom_nav_icon_back"] as String) + parseColor(json["colors"]["bottom_nav_icon_back"] as String) ..bottomNavIconIconInt = - parseColor(json["colors"]["bottom_nav_icon_icon"] as String) + parseColor(json["colors"]["bottom_nav_icon_icon"] as String) ..bottomNavIconIconHighlightedInt = parseColor( json["colors"]["bottom_nav_icon_icon_highlighted"] as String) ..topNavIconPrimaryInt = - parseColor(json["colors"]["top_nav_icon_primary"] as String) + parseColor(json["colors"]["top_nav_icon_primary"] as String) ..topNavIconGreenInt = - parseColor(json["colors"]["top_nav_icon_green"] as String) + parseColor(json["colors"]["top_nav_icon_green"] as String) ..topNavIconYellowInt = - parseColor(json["colors"]["top_nav_icon_yellow"] as String) + parseColor(json["colors"]["top_nav_icon_yellow"] as String) ..topNavIconRedInt = - parseColor(json["colors"]["top_nav_icon_red"] as String) + parseColor(json["colors"]["top_nav_icon_red"] as String) ..settingsIconBackInt = - parseColor(json["colors"]["settings_icon_back"] as String) + parseColor(json["colors"]["settings_icon_back"] as String) ..settingsIconIconInt = - parseColor(json["colors"]["settings_icon_icon"] as String) + parseColor(json["colors"]["settings_icon_icon"] as String) ..settingsIconBack2Int = - parseColor(json["colors"]["settings_icon_back_two"] as String) + parseColor(json["colors"]["settings_icon_back_two"] as String) ..settingsIconElementInt = - parseColor(json["colors"]["settings_icon_element"] as String) + parseColor(json["colors"]["settings_icon_element"] as String) ..textFieldActiveBGInt = - parseColor(json["colors"]["text_field_active_bg"] as String) + parseColor(json["colors"]["text_field_active_bg"] as String) ..textFieldDefaultBGInt = - parseColor(json["colors"]["text_field_default_bg"] as String) + parseColor(json["colors"]["text_field_default_bg"] as String) ..textFieldErrorBGInt = - parseColor(json["colors"]["text_field_error_bg"] as String) + parseColor(json["colors"]["text_field_error_bg"] as String) ..textFieldSuccessBGInt = - parseColor(json["colors"]["text_field_success_bg"] as String) + parseColor(json["colors"]["text_field_success_bg"] as String) ..textFieldErrorBorderInt = - parseColor(json["colors"]["text_field_error_border"] as String) + parseColor(json["colors"]["text_field_error_border"] as String) ..textFieldSuccessBorderInt = - parseColor(json["colors"]["text_field_success_border"] as String) + parseColor(json["colors"]["text_field_success_border"] as String) ..textFieldActiveSearchIconLeftInt = parseColor( json["colors"]["text_field_active_search_icon_left"] as String) ..textFieldDefaultSearchIconLeftInt = parseColor( @@ -1725,19 +1725,19 @@ class StackTheme { ..textFieldSuccessSearchIconLeftInt = parseColor( json["colors"]["text_field_success_search_icon_left"] as String) ..textFieldActiveTextInt = - parseColor(json["colors"]["text_field_active_text"] as String) + parseColor(json["colors"]["text_field_active_text"] as String) ..textFieldDefaultTextInt = - parseColor(json["colors"]["text_field_default_text"] as String) + parseColor(json["colors"]["text_field_default_text"] as String) ..textFieldErrorTextInt = - parseColor(json["colors"]["text_field_error_text"] as String) + parseColor(json["colors"]["text_field_error_text"] as String) ..textFieldSuccessTextInt = - parseColor(json["colors"]["text_field_success_text"] as String) + parseColor(json["colors"]["text_field_success_text"] as String) ..textFieldActiveLabelInt = - parseColor(json["colors"]["text_field_active_label"] as String) + parseColor(json["colors"]["text_field_active_label"] as String) ..textFieldErrorLabelInt = - parseColor(json["colors"]["text_field_error_label"] as String) + parseColor(json["colors"]["text_field_error_label"] as String) ..textFieldSuccessLabelInt = - parseColor(json["colors"]["text_field_success_label"] as String) + parseColor(json["colors"]["text_field_success_label"] as String) ..textFieldActiveSearchIconRightInt = parseColor( json["colors"]["text_field_active_search_icon_right"] as String) ..textFieldDefaultSearchIconRightInt = parseColor( @@ -1753,61 +1753,61 @@ class StackTheme { ..settingsItem2ActiveSubInt = parseColor( json["colors"]["settings_item_level_two_active_sub"] as String) ..radioButtonIconBorderInt = - parseColor(json["colors"]["radio_button_icon_border"] as String) + parseColor(json["colors"]["radio_button_icon_border"] as String) ..radioButtonIconBorderDisabledInt = parseColor( json["colors"]["radio_button_icon_border_disabled"] as String) ..radioButtonBorderEnabledInt = - parseColor(json["colors"]["radio_button_border_enabled"] as String) + parseColor(json["colors"]["radio_button_border_enabled"] as String) ..radioButtonBorderDisabledInt = - parseColor(json["colors"]["radio_button_border_disabled"] as String) + parseColor(json["colors"]["radio_button_border_disabled"] as String) ..radioButtonIconCircleInt = - parseColor(json["colors"]["radio_button_icon_circle"] as String) + parseColor(json["colors"]["radio_button_icon_circle"] as String) ..radioButtonIconEnabledInt = - parseColor(json["colors"]["radio_button_icon_enabled"] as String) + parseColor(json["colors"]["radio_button_icon_enabled"] as String) ..radioButtonTextEnabledInt = - parseColor(json["colors"]["radio_button_text_enabled"] as String) + parseColor(json["colors"]["radio_button_text_enabled"] as String) ..radioButtonTextDisabledInt = - parseColor(json["colors"]["radio_button_text_disabled"] as String) + parseColor(json["colors"]["radio_button_text_disabled"] as String) ..radioButtonLabelEnabledInt = - parseColor(json["colors"]["radio_button_label_enabled"] as String) + parseColor(json["colors"]["radio_button_label_enabled"] as String) ..radioButtonLabelDisabledInt = - parseColor(json["colors"]["radio_button_label_disabled"] as String) + parseColor(json["colors"]["radio_button_label_disabled"] as String) ..infoItemBGInt = parseColor(json["colors"]["info_item_bg"] as String) ..infoItemLabelInt = - parseColor(json["colors"]["info_item_label"] as String) + parseColor(json["colors"]["info_item_label"] as String) ..infoItemTextInt = parseColor(json["colors"]["info_item_text"] as String) ..infoItemIconsInt = - parseColor(json["colors"]["info_item_icons"] as String) + parseColor(json["colors"]["info_item_icons"] as String) ..popupBGInt = parseColor(json["colors"]["popup_bg"] as String) ..currencyListItemBGInt = - parseColor(json["colors"]["currency_list_item_bg"] as String) + parseColor(json["colors"]["currency_list_item_bg"] as String) ..stackWalletBGInt = parseColor(json["colors"]["sw_bg"] as String) ..stackWalletMidInt = parseColor(json["colors"]["sw_mid"] as String) ..stackWalletBottomInt = parseColor(json["colors"]["sw_bottom"] as String) ..bottomNavShadowInt = - parseColor(json["colors"]["bottom_nav_shadow"] as String) + parseColor(json["colors"]["bottom_nav_shadow"] as String) ..splashInt = parseColor(json["colors"]["splash"] as String) ..highlightInt = parseColor(json["colors"]["highlight"] as String) ..warningForegroundInt = - parseColor(json["colors"]["warning_foreground"] as String) + parseColor(json["colors"]["warning_foreground"] as String) ..warningBackgroundInt = - parseColor(json["colors"]["warning_background"] as String) + parseColor(json["colors"]["warning_background"] as String) ..loadingOverlayTextColorInt = - parseColor(json["colors"]["loading_overlay_text_color"] as String) + parseColor(json["colors"]["loading_overlay_text_color"] as String) ..myStackContactIconBGInt = - parseColor(json["colors"]["my_stack_contact_icon_bg"] as String) + parseColor(json["colors"]["my_stack_contact_icon_bg"] as String) ..textConfirmTotalAmountInt = - parseColor(json["colors"]["text_confirm_total_amount"] as String) + parseColor(json["colors"]["text_confirm_total_amount"] as String) ..textSelectedWordTableItemInt = - parseColor(json["colors"]["text_selected_word_table_iterm"] as String) + parseColor(json["colors"]["text_selected_word_table_iterm"] as String) ..favoriteStarActiveInt = - parseColor(json["colors"]["favorite_star_active"] as String) + parseColor(json["colors"]["favorite_star_active"] as String) ..favoriteStarInactiveInt = - parseColor(json["colors"]["favorite_star_inactive"] as String) + parseColor(json["colors"]["favorite_star_inactive"] as String) ..rateTypeToggleColorOnInt = - parseColor(json["colors"]["rate_type_toggle_color_on"] as String) + parseColor(json["colors"]["rate_type_toggle_color_on"] as String) ..rateTypeToggleColorOffInt = - parseColor(json["colors"]["rate_type_toggle_color_off"] as String) + parseColor(json["colors"]["rate_type_toggle_color_off"] as String) ..rateTypeToggleDesktopColorOnInt = parseColor( json["colors"]["rate_type_toggle_desktop_color_on"] as String) ..rateTypeToggleDesktopColorOffInt = parseColor( @@ -1815,19 +1815,19 @@ class StackTheme { ..ethTagTextInt = parseColor(json["colors"]["eth_tag_text"] as String) ..ethTagBGInt = parseColor(json["colors"]["eth_tag_bg"] as String) ..ethWalletTagTextInt = - parseColor(json["colors"]["eth_wallet_tag_text"] as String) + parseColor(json["colors"]["eth_wallet_tag_text"] as String) ..ethWalletTagBGInt = - parseColor(json["colors"]["eth_wallet_tag_bg"] as String) + parseColor(json["colors"]["eth_wallet_tag_bg"] as String) ..tokenSummaryTextPrimaryInt = - parseColor(json["colors"]["token_summary_text_primary"] as String) + parseColor(json["colors"]["token_summary_text_primary"] as String) ..tokenSummaryTextSecondaryInt = - parseColor(json["colors"]["token_summary_text_secondary"] as String) + parseColor(json["colors"]["token_summary_text_secondary"] as String) ..tokenSummaryBGInt = - parseColor(json["colors"]["token_summary_bg"] as String) + parseColor(json["colors"]["token_summary_bg"] as String) ..tokenSummaryButtonBGInt = - parseColor(json["colors"]["token_summary_button_bg"] as String) + parseColor(json["colors"]["token_summary_button_bg"] as String) ..tokenSummaryIconInt = - parseColor(json["colors"]["token_summary_icon"] as String); + parseColor(json["colors"]["token_summary_icon"] as String); } /// Grab the int value of the hex color string. @@ -1840,7 +1840,7 @@ class StackTheme { } else { throw ArgumentError( '"$colorHex" and corresponding int ' - 'value "$colorValue" is not a valid color.', + 'value "$colorValue" is not a valid color.', ); } } catch (_) { @@ -1857,13 +1857,16 @@ class StackTheme { final Map result = {}; - for (final coin in Coin.values) { + for (final coin in Coin.values.map((e) => e.mainNetVersion)) { if (map[coin.name] is String) { result[coin] = Color( (map[coin.name] as String).toBigIntFromHex.toInt(), ); } else { - result[coin] = kCoinThemeColorDefaults.forCoin(coin); + Logging.instance.log( + "Color not found in theme for $coin", + level: LogLevel.Error, + ); } } @@ -2078,18 +2081,18 @@ class ThemeAssetsV2 implements IThemeAssets { @ignore Map get coinIcons => _coinIcons ??= parseCoinAssetsString( - coinIconsString, - placeHolder: coinPlaceholder, - ); + coinIconsString, + placeHolder: coinPlaceholder, + ); @ignore Map? _coinIcons; late final String coinIconsString; @ignore Map get coinImages => _coinImages ??= parseCoinAssetsString( - coinImagesString, - placeHolder: coinPlaceholder, - ); + coinImagesString, + placeHolder: coinPlaceholder, + ); @ignore Map? _coinImages; late final String coinImagesString; @@ -2164,9 +2167,9 @@ class ThemeAssetsV2 implements IThemeAssets { } static Map parseCoinAssetsString( - String jsonString, { - required String placeHolder, - }) { + String jsonString, { + required String placeHolder, + }) { final json = jsonDecode(jsonString) as Map; final map = Map.from(json); @@ -2348,18 +2351,18 @@ class ThemeAssetsV3 implements IThemeAssets { @ignore Map get coinIcons => _coinIcons ??= parseCoinAssetsString( - coinIconsString, - placeHolder: coinPlaceholder, - ); + coinIconsString, + placeHolder: coinPlaceholder, + ); @ignore Map? _coinIcons; late final String coinIconsString; @ignore Map get coinImages => _coinImages ??= parseCoinAssetsString( - coinImagesString, - placeHolder: coinPlaceholder, - ); + coinImagesString, + placeHolder: coinPlaceholder, + ); @ignore Map? _coinImages; late final String coinImagesString; @@ -2379,9 +2382,9 @@ class ThemeAssetsV3 implements IThemeAssets { _coinCardImages ??= coinCardImagesString == null ? null : parseCoinAssetsString( - coinCardImagesString!, - placeHolder: coinPlaceholder, - ); + coinCardImagesString!, + placeHolder: coinPlaceholder, + ); @ignore Map? _coinCardImages; late final String? coinCardImagesString; @@ -2391,9 +2394,9 @@ class ThemeAssetsV3 implements IThemeAssets { _coinCardFavoritesImages ??= coinCardFavoritesImagesString == null ? null : parseCoinAssetsString( - coinCardFavoritesImagesString!, - placeHolder: coinPlaceholder, - ); + coinCardFavoritesImagesString!, + placeHolder: coinPlaceholder, + ); @ignore Map? _coinCardFavoritesImages; @Name("otherStringParam1") @@ -2450,15 +2453,15 @@ class ThemeAssetsV3 implements IThemeAssets { ) ..coinCardImagesString = json["coins"]["cards"] is Map ? createCoinAssetsString( - "$themeId/assets", - Map.from(json["coins"]["cards"] as Map), - ) + "$themeId/assets", + Map.from(json["coins"]["cards"] as Map), + ) : null ..coinCardFavoritesImagesString = json["coins"]["favoriteCards"] is Map ? createCoinAssetsString( - "$themeId/assets", - Map.from(json["coins"]["favoriteCards"] as Map), - ) + "$themeId/assets", + Map.from(json["coins"]["favoriteCards"] as Map), + ) : null ..loadingGifRelative = json["loading_gif"] is String ? "$themeId/assets/${json["loading_gif"] as String}" @@ -2499,9 +2502,9 @@ class ThemeAssetsV3 implements IThemeAssets { } static Map parseCoinAssetsString( - String jsonString, { - required String placeHolder, - }) { + String jsonString, { + required String placeHolder, + }) { final json = jsonDecode(jsonString) as Map; final map = Map.from(json); @@ -2571,4 +2574,4 @@ abstract class IThemeAssets { String? get loadingGif; String? get background; -} \ No newline at end of file +} diff --git a/lib/pages/wallet_view/sub_widgets/wallet_summary.dart b/lib/pages/wallet_view/sub_widgets/wallet_summary.dart index 08f5f22c8..a33bf7622 100644 --- a/lib/pages/wallet_view/sub_widgets/wallet_summary.dart +++ b/lib/pages/wallet_view/sub_widgets/wallet_summary.dart @@ -15,7 +15,7 @@ import 'package:stackwallet/widgets/coin_card.dart'; class WalletSummary extends StatelessWidget { const WalletSummary({ - Key? key, + super.key, required this.walletId, required this.initialSyncStatus, this.aspectRatio = 2.0, @@ -23,7 +23,7 @@ class WalletSummary extends StatelessWidget { this.minWidth = 200.0, this.maxHeight = 250.0, this.maxWidth = 400.0, - }) : super(key: key); + }); final String walletId; final WalletSyncStatus initialSyncStatus; diff --git a/lib/pages/wallet_view/sub_widgets/wallet_summary_info.dart b/lib/pages/wallet_view/sub_widgets/wallet_summary_info.dart index aeadd6a7a..fa01d1ac6 100644 --- a/lib/pages/wallet_view/sub_widgets/wallet_summary_info.dart +++ b/lib/pages/wallet_view/sub_widgets/wallet_summary_info.dart @@ -63,18 +63,21 @@ class WalletSummaryInfo extends ConsumerWidget { debugPrint("BUILD: $runtimeType"); final externalCalls = ref.watch( - prefsChangeNotifierProvider.select((value) => value.externalCalls)); + prefsChangeNotifierProvider.select((value) => value.externalCalls), + ); final coin = ref.watch(pWalletCoin(walletId)); final balance = ref.watch(pWalletBalance(walletId)); final locale = ref.watch( - localeServiceChangeNotifierProvider.select((value) => value.locale)); + localeServiceChangeNotifierProvider.select((value) => value.locale), + ); final baseCurrency = ref .watch(prefsChangeNotifierProvider.select((value) => value.currency)); - final priceTuple = ref.watch(priceAnd24hChangeNotifierProvider - .select((value) => value.getPrice(coin))); + final priceTuple = ref.watch( + priceAnd24hChangeNotifierProvider.select((value) => value.getPrice(coin)), + ); final _showAvailable = ref.watch(walletBalanceToggleStateProvider.state).state == @@ -206,7 +209,7 @@ class WalletSummaryInfo extends ConsumerWidget { initialSyncStatus: initialSyncStatus, ), ], - ) + ), ], ), ); diff --git a/lib/pages/wallet_view/wallet_view.dart b/lib/pages/wallet_view/wallet_view.dart index f00751425..8abbd4d16 100644 --- a/lib/pages/wallet_view/wallet_view.dart +++ b/lib/pages/wallet_view/wallet_view.dart @@ -99,11 +99,11 @@ import 'package:tuple/tuple.dart'; /// [eventBus] should only be set during testing class WalletView extends ConsumerStatefulWidget { const WalletView({ - Key? key, + super.key, required this.walletId, this.eventBus, this.clipboardInterface = const ClipboardWrapper(), - }) : super(key: key); + }); static const String routeName = "/wallet"; static const double navBarHeight = 65.0; diff --git a/lib/themes/theme_providers.dart b/lib/themes/theme_providers.dart index 1219079a5..eb622e8cc 100644 --- a/lib/themes/theme_providers.dart +++ b/lib/themes/theme_providers.dart @@ -8,10 +8,12 @@ * */ +import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:stackwallet/models/isar/stack_theme.dart'; import 'package:stackwallet/themes/stack_colors.dart'; import 'package:stackwallet/themes/theme_service.dart'; +import 'package:stackwallet/utilities/enums/coin_enum.dart'; final applicationThemesDirectoryPathProvider = StateProvider((ref) => ""); @@ -38,3 +40,11 @@ final themeAssetsProvider = StateProvider( ), ), ); + +final pCoinColor = StateProvider.family( + (ref, coin) => + ref.watch( + themeProvider.select((value) => value.coinColors[coin.mainNetVersion]), + ) ?? + Colors.deepOrangeAccent, +); diff --git a/lib/themes/theme_service.dart b/lib/themes/theme_service.dart index b5882ecc5..c71a336a4 100644 --- a/lib/themes/theme_service.dart +++ b/lib/themes/theme_service.dart @@ -29,7 +29,7 @@ final pThemeService = Provider((ref) { }); class ThemeService { - static const _currentDefaultThemeVersion = 9; + static const _currentDefaultThemeVersion = 10; ThemeService._(); static ThemeService? _instance; static ThemeService get instance => _instance ??= ThemeService._(); diff --git a/lib/widgets/coin_card.dart b/lib/widgets/coin_card.dart index 9ceb13543..b4a88e80d 100644 --- a/lib/widgets/coin_card.dart +++ b/lib/widgets/coin_card.dart @@ -14,7 +14,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:stackwallet/themes/coin_card_provider.dart'; -import 'package:stackwallet/themes/stack_colors.dart'; +import 'package:stackwallet/themes/theme_providers.dart'; import 'package:stackwallet/utilities/assets.dart'; import 'package:stackwallet/utilities/constants.dart'; import 'package:stackwallet/wallets/isar/providers/wallet_info_provider.dart'; @@ -68,9 +68,7 @@ class CoinCard extends ConsumerWidget { width: width, height: height, decoration: BoxDecoration( - color: Theme.of(context) - .extension()! - .colorForCoin(coin), + color: ref.watch(pCoinColor(coin)), borderRadius: BorderRadius.circular( Constants.size.circularBorderRadius, ), From 63f75bae03544698531271251005c121c4f78ea3 Mon Sep 17 00:00:00 2001 From: julian Date: Tue, 14 May 2024 10:31:18 -0600 Subject: [PATCH 3/5] fix frost steps qr code colors --- .../dialogs/frost/frost_step_qr_dialog.dart | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/lib/widgets/dialogs/frost/frost_step_qr_dialog.dart b/lib/widgets/dialogs/frost/frost_step_qr_dialog.dart index 2dd1ace26..af33383ef 100644 --- a/lib/widgets/dialogs/frost/frost_step_qr_dialog.dart +++ b/lib/widgets/dialogs/frost/frost_step_qr_dialog.dart @@ -153,12 +153,15 @@ class _FrostStepQrDialogState extends State { child: QrImageView( data: widget.data, padding: EdgeInsets.zero, - dataModuleStyle: QrDataModuleStyle( - dataModuleShape: QrDataModuleShape.square, - color: Theme.of(context) - .extension()! - .accentColorDark, - ), + foregroundColor: Theme.of(context) + .extension()! + .accentColorDark, + // dataModuleStyle: QrDataModuleStyle( + // dataModuleShape: QrDataModuleShape.square, + // color: Theme.of(context) + // .extension()! + // .accentColorDark, + // ), ), ), ), From e3c761dfb0e8857899f6f4bc027cee5c9e68986a Mon Sep 17 00:00:00 2001 From: julian Date: Tue, 14 May 2024 10:36:11 -0600 Subject: [PATCH 4/5] flip text fields on frost restore screen --- .../restore/restore_frost_ms_wallet_view.dart | 141 +++++++++--------- 1 file changed, 72 insertions(+), 69 deletions(-) diff --git a/lib/pages/add_wallet_views/frost_ms/restore/restore_frost_ms_wallet_view.dart b/lib/pages/add_wallet_views/frost_ms/restore/restore_frost_ms_wallet_view.dart index 68c220c1f..03a7ee8bf 100644 --- a/lib/pages/add_wallet_views/frost_ms/restore/restore_frost_ms_wallet_view.dart +++ b/lib/pages/add_wallet_views/frost_ms/restore/restore_frost_ms_wallet_view.dart @@ -276,21 +276,21 @@ class _RestoreFrostMsWalletViewState Constants.size.circularBorderRadius, ), child: TextField( - key: const Key("frMyNameTextFieldKey"), - controller: keysFieldController, + key: const Key("frConfigTextFieldKey"), + controller: configFieldController, onChanged: (_) { setState(() { - _keysEmpty = keysFieldController.text.isEmpty; + _configEmpty = configFieldController.text.isEmpty; }); }, - focusNode: keysFocusNode, + focusNode: configFocusNode, readOnly: false, autocorrect: false, enableSuggestions: false, style: STextStyles.field(context), decoration: standardInputDecoration( - "Keys", - keysFocusNode, + "Enter config", + configFocusNode, context, ).copyWith( contentPadding: const EdgeInsets.only( @@ -300,50 +300,83 @@ class _RestoreFrostMsWalletViewState right: 5, ), suffixIcon: Padding( - padding: _keysEmpty + padding: _configEmpty ? const EdgeInsets.only(right: 8) : const EdgeInsets.only(right: 0), child: UnconstrainedBox( child: Row( mainAxisAlignment: MainAxisAlignment.spaceAround, children: [ - !_keysEmpty + !_configEmpty ? TextFieldIconButton( semanticsLabel: - "Clear Button. Clears The Keys Field.", - key: const Key("frMyNameClearButtonKey"), + "Clear Button. Clears The Config Field.", + key: const Key("frConfigClearButtonKey"), onTap: () { - keysFieldController.text = ""; + configFieldController.text = ""; setState(() { - _keysEmpty = true; + _configEmpty = true; }); }, child: const XIcon(), ) : TextFieldIconButton( semanticsLabel: - "Paste Button. Pastes From Clipboard To Keys Field.", - key: const Key("frKeysPasteButtonKey"), + "Paste Button. Pastes From Clipboard To Config Field Input.", + key: const Key("frConfigPasteButtonKey"), onTap: () async { final ClipboardData? data = await Clipboard.getData( - Clipboard.kTextPlain); + Clipboard.kTextPlain, + ); if (data?.text != null && data!.text!.isNotEmpty) { - keysFieldController.text = + configFieldController.text = data.text!.trim(); } setState(() { - _keysEmpty = - keysFieldController.text.isEmpty; + _configEmpty = + configFieldController.text.isEmpty; }); }, - child: _keysEmpty + child: _configEmpty ? const ClipboardIcon() : const XIcon(), ), + if (_configEmpty) + TextFieldIconButton( + semanticsLabel: + "Scan QR Button. Opens Camera For Scanning QR Code.", + key: const Key("frConfigScanQrButtonKey"), + onTap: () async { + try { + if (FocusScope.of(context).hasFocus) { + FocusScope.of(context).unfocus(); + await Future.delayed( + const Duration(milliseconds: 75), + ); + } + + final qrResult = await BarcodeScanner.scan(); + + configFieldController.text = + qrResult.rawContent; + + setState(() { + _configEmpty = + configFieldController.text.isEmpty; + }); + } on PlatformException catch (e, s) { + Logging.instance.log( + "Failed to get camera permissions while trying to scan qr code: $e\n$s", + level: LogLevel.Warning, + ); + } + }, + child: const QrCodeIcon(), + ), ], ), ), @@ -359,21 +392,21 @@ class _RestoreFrostMsWalletViewState Constants.size.circularBorderRadius, ), child: TextField( - key: const Key("frConfigTextFieldKey"), - controller: configFieldController, + key: const Key("frMyNameTextFieldKey"), + controller: keysFieldController, onChanged: (_) { setState(() { - _configEmpty = configFieldController.text.isEmpty; + _keysEmpty = keysFieldController.text.isEmpty; }); }, - focusNode: configFocusNode, + focusNode: keysFocusNode, readOnly: false, autocorrect: false, enableSuggestions: false, style: STextStyles.field(context), decoration: standardInputDecoration( - "Enter config", - configFocusNode, + "Keys", + keysFocusNode, context, ).copyWith( contentPadding: const EdgeInsets.only( @@ -383,81 +416,51 @@ class _RestoreFrostMsWalletViewState right: 5, ), suffixIcon: Padding( - padding: _configEmpty + padding: _keysEmpty ? const EdgeInsets.only(right: 8) : const EdgeInsets.only(right: 0), child: UnconstrainedBox( child: Row( mainAxisAlignment: MainAxisAlignment.spaceAround, children: [ - !_configEmpty + !_keysEmpty ? TextFieldIconButton( semanticsLabel: - "Clear Button. Clears The Config Field.", - key: const Key("frConfigClearButtonKey"), + "Clear Button. Clears The Keys Field.", + key: const Key("frMyNameClearButtonKey"), onTap: () { - configFieldController.text = ""; + keysFieldController.text = ""; setState(() { - _configEmpty = true; + _keysEmpty = true; }); }, child: const XIcon(), ) : TextFieldIconButton( semanticsLabel: - "Paste Button. Pastes From Clipboard To Config Field Input.", - key: const Key("frConfigPasteButtonKey"), + "Paste Button. Pastes From Clipboard To Keys Field.", + key: const Key("frKeysPasteButtonKey"), onTap: () async { final ClipboardData? data = await Clipboard.getData( - Clipboard.kTextPlain); + Clipboard.kTextPlain, + ); if (data?.text != null && data!.text!.isNotEmpty) { - configFieldController.text = + keysFieldController.text = data.text!.trim(); } setState(() { - _configEmpty = - configFieldController.text.isEmpty; + _keysEmpty = + keysFieldController.text.isEmpty; }); }, - child: _configEmpty + child: _keysEmpty ? const ClipboardIcon() : const XIcon(), ), - if (_configEmpty) - TextFieldIconButton( - semanticsLabel: - "Scan QR Button. Opens Camera For Scanning QR Code.", - key: const Key("frConfigScanQrButtonKey"), - onTap: () async { - try { - if (FocusScope.of(context).hasFocus) { - FocusScope.of(context).unfocus(); - await Future.delayed( - const Duration(milliseconds: 75)); - } - - final qrResult = await BarcodeScanner.scan(); - - configFieldController.text = - qrResult.rawContent; - - setState(() { - _configEmpty = - configFieldController.text.isEmpty; - }); - } on PlatformException catch (e, s) { - Logging.instance.log( - "Failed to get camera permissions while trying to scan qr code: $e\n$s", - level: LogLevel.Warning, - ); - } - }, - child: const QrCodeIcon(), - ) ], ), ), From 129c46fca02725ffccc28b2bc53345877703437c Mon Sep 17 00:00:00 2001 From: julian Date: Tue, 14 May 2024 11:11:09 -0600 Subject: [PATCH 5/5] make recovery screen scrollable on desktop --- .../new_wallet_recovery_phrase_view.dart | 276 ++++++++++-------- 1 file changed, 148 insertions(+), 128 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 8a22bc8f2..bb855d757 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 @@ -31,6 +31,7 @@ import 'package:stackwallet/utilities/text_styles.dart'; import 'package:stackwallet/utilities/util.dart'; import 'package:stackwallet/wallets/isar/providers/wallet_info_provider.dart'; import 'package:stackwallet/wallets/wallet/wallet.dart'; +import 'package:stackwallet/widgets/conditional_parent.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'; @@ -180,152 +181,171 @@ class _NewWalletRecoveryPhraseViewState child: Padding( padding: isDesktop ? const EdgeInsets.all(0) : const EdgeInsets.all(16), - child: Column( - crossAxisAlignment: CrossAxisAlignment.stretch, - children: [ - if (isDesktop) - const Spacer( - flex: 10, - ), - if (!isDesktop) - const SizedBox( - height: 4, + child: ConditionalParent( + condition: Util.isDesktop, + builder: (child) => LayoutBuilder( + builder: (context, constraints) { + return SingleChildScrollView( + child: ConstrainedBox( + constraints: BoxConstraints( + minHeight: constraints.maxHeight, + ), + child: IntrinsicHeight( + child: child, + ), + ), + ); + }, + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + if (isDesktop) + const Spacer( + flex: 10, + ), + if (!isDesktop) + const SizedBox( + height: 4, + ), + if (!isDesktop) + Text( + ref.watch(pWalletName(_wallet.walletId)), + textAlign: TextAlign.center, + style: STextStyles.label(context).copyWith( + fontSize: 12, + ), + ), + SizedBox( + height: isDesktop ? 24 : 4, ), - if (!isDesktop) Text( - ref.watch(pWalletName(_wallet.walletId)), + "Recovery Phrase", textAlign: TextAlign.center, - style: STextStyles.label(context).copyWith( - fontSize: 12, - ), + style: isDesktop + ? STextStyles.desktopH2(context) + : STextStyles.pageTitleH1(context), ), - SizedBox( - height: isDesktop ? 24 : 4, - ), - Text( - "Recovery Phrase", - textAlign: TextAlign.center, - style: isDesktop - ? STextStyles.desktopH2(context) - : STextStyles.pageTitleH1(context), - ), - const SizedBox( - height: 16, - ), - Container( - decoration: BoxDecoration( - color: isDesktop - ? Theme.of(context).extension()!.background - : Theme.of(context).extension()!.popupBG, - borderRadius: BorderRadius.circular( - Constants.size.circularBorderRadius), + const SizedBox( + height: 16, ), - 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(context) - : STextStyles.label(context).copyWith( - color: Theme.of(context) - .extension()! - .accentColorDark), + Container( + decoration: BoxDecoration( + color: isDesktop + ? Theme.of(context) + .extension()! + .background + : Theme.of(context).extension()!.popupBG, + borderRadius: BorderRadius.circular( + Constants.size.circularBorderRadius), ), - ), - ), - SizedBox( - height: isDesktop ? 21 : 8, - ), - if (!isDesktop) - Expanded( - child: SingleChildScrollView( - child: MnemonicTable( - words: _mnemonic, - isDesktop: isDesktop, + 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(context) + : STextStyles.label(context).copyWith( + color: Theme.of(context) + .extension()! + .accentColorDark), ), ), ), - if (isDesktop) - MnemonicTable( - words: _mnemonic, - isDesktop: isDesktop, + SizedBox( + height: isDesktop ? 21 : 8, ), - SizedBox( - height: isDesktop ? 24 : 16, - ), - if (isDesktop) + if (!isDesktop) + Expanded( + child: SingleChildScrollView( + child: MnemonicTable( + words: _mnemonic, + isDesktop: isDesktop, + ), + ), + ), + if (isDesktop) + MnemonicTable( + words: _mnemonic, + isDesktop: isDesktop, + ), SizedBox( - height: 70, + 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, + color: Theme.of(context) + .extension()! + .buttonTextSecondary, + ), + const SizedBox( + width: 10, + ), + Text( + "Copy to clipboard", + style: STextStyles.desktopButtonSecondaryEnabled( + context), + ) + ], + ), + ), + ), + if (isDesktop) + const SizedBox( + height: 16, + ), + ConstrainedBox( + constraints: BoxConstraints( + minHeight: isDesktop ? 70 : 0, + ), child: TextButton( onPressed: () async { - await _copy(); + 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(_wallet, _mnemonic), + )); }, - child: Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - SvgPicture.asset( - Assets.svg.copy, - width: 20, - height: 20, - color: Theme.of(context) - .extension()! - .buttonTextSecondary, - ), - const SizedBox( - width: 10, - ), - Text( - "Copy to clipboard", - style: STextStyles.desktopButtonSecondaryEnabled( - context), - ) - ], + style: Theme.of(context) + .extension()! + .getPrimaryEnabledButtonStyle(context), + child: Text( + "I saved my recovery phrase", + style: isDesktop + ? STextStyles.desktopButtonEnabled(context) + : STextStyles.button(context), ), ), ), - 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(_wallet, _mnemonic), - )); - }, - style: Theme.of(context) - .extension()! - .getPrimaryEnabledButtonStyle(context), - child: Text( - "I saved my recovery phrase", - style: isDesktop - ? STextStyles.desktopButtonEnabled(context) - : STextStyles.button(context), + if (isDesktop) + const Spacer( + flex: 15, ), - ), - ), - if (isDesktop) - const Spacer( - flex: 15, - ), - ], + ], + ), ), ), ),