From 41d9c8ca0cc3355cd2dd969718edf9a7f7d83ca9 Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Mon, 27 Mar 2023 14:29:55 -0600 Subject: [PATCH] select wallet for token view --- .../select_wallet_for_token_view.dart | 205 ++++++++++++++++++ lib/route_generator.dart | 16 ++ 2 files changed, 221 insertions(+) create mode 100644 lib/pages/add_wallet_views/select_wallet_for_token_view.dart diff --git a/lib/pages/add_wallet_views/select_wallet_for_token_view.dart b/lib/pages/add_wallet_views/select_wallet_for_token_view.dart new file mode 100644 index 000000000..e376d3202 --- /dev/null +++ b/lib/pages/add_wallet_views/select_wallet_for_token_view.dart @@ -0,0 +1,205 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:stackwallet/db/hive/db.dart'; +import 'package:stackwallet/models/add_wallet_list_entity/sub_classes/coin_entity.dart'; +import 'package:stackwallet/models/add_wallet_list_entity/sub_classes/eth_token_entity.dart'; +import 'package:stackwallet/pages/add_wallet_views/create_or_restore_wallet_view/create_or_restore_wallet_view.dart'; +import 'package:stackwallet/pages/add_wallet_views/verify_recovery_phrase_view/verify_recovery_phrase_view.dart'; +import 'package:stackwallet/providers/global/wallets_service_provider.dart'; +import 'package:stackwallet/utilities/text_styles.dart'; +import 'package:stackwallet/utilities/theme/stack_colors.dart'; +import 'package:stackwallet/utilities/util.dart'; +import 'package:stackwallet/widgets/background.dart'; +import 'package:stackwallet/widgets/conditional_parent.dart'; +import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart'; +import 'package:stackwallet/widgets/desktop/primary_button.dart'; +import 'package:stackwallet/widgets/rounded_container.dart'; +import 'package:stackwallet/widgets/rounded_white_container.dart'; +import 'package:stackwallet/widgets/wallet_info_row/wallet_info_row.dart'; + +class SelectWalletForTokenView extends ConsumerStatefulWidget { + const SelectWalletForTokenView({ + Key? key, + required this.entity, + }) : super(key: key); + + static const String routeName = "/selectWalletForTokenView"; + + final EthTokenEntity entity; + + @override + ConsumerState<SelectWalletForTokenView> createState() => + _SelectWalletForTokenViewState(); +} + +class _SelectWalletForTokenViewState + extends ConsumerState<SelectWalletForTokenView> { + final isDesktop = Util.isDesktop; + late final List<String> ethWalletIds; + + String? _selectedWalletId; + + void _onContinue() { + // + } + + void _onAddNewEthWallet() { + ref.read(createSpecialEthWalletRoutingFlag.notifier).state = true; + Navigator.of(context).pushNamed( + CreateOrRestoreWalletView.routeName, + arguments: CoinEntity(widget.entity.coin), + ); + } + + @override + void initState() { + final walletsData = + ref.read(walletsServiceChangeNotifierProvider).fetchWalletsData(); + walletsData.removeWhere((key, value) => value.coin != widget.entity.coin); + ethWalletIds = []; + + // TODO: proper wallet data class instead of this Hive silliness + for (final walletId in walletsData.values.map((e) => e.walletId).toList()) { + final walletContracts = DB.instance.get<dynamic>( + boxName: walletId, + key: DBKeys.ethTokenContracts, + ) as List<String>? ?? + []; + if (!walletContracts.contains(widget.entity.token.address)) { + ethWalletIds.add(walletId); + } + } + + super.initState(); + } + + @override + Widget build(BuildContext context) { + return WillPopScope( + onWillPop: () async { + ref.read(createSpecialEthWalletRoutingFlag.notifier).state = false; + return true; + }, + child: ConditionalParent( + condition: !isDesktop, + builder: (child) => Background( + child: Scaffold( + backgroundColor: + Theme.of(context).extension<StackColors>()!.background, + appBar: AppBar( + leading: AppBarBackButton( + onPressed: () { + Navigator.of(context).pop(); + }, + ), + ), + body: SafeArea( + child: Padding( + padding: const EdgeInsets.all(16), + child: child, + ), + + // child: LayoutBuilder( + // builder: (ctx, constraints) { + // return SingleChildScrollView( + // child: ConstrainedBox( + // constraints: + // BoxConstraints(minHeight: constraints.maxHeight), + // child: IntrinsicHeight( + // child: child, + // ), + // ), + // ); + // }, + // ), + ), + ), + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + Text( + "Select Ethereum wallet", + textAlign: TextAlign.center, + style: STextStyles.pageTitleH1(context), + ), + const SizedBox( + height: 8, + ), + Text( + "You are adding an ETH token.", + textAlign: TextAlign.center, + style: STextStyles.subtitle(context), + ), + const SizedBox( + height: 8, + ), + Text( + "You must choose an Ethereum wallet in order to use ${widget.entity.name}", + textAlign: TextAlign.center, + style: STextStyles.subtitle(context), + ), + const SizedBox( + height: 16, + ), + ethWalletIds.isEmpty + ? RoundedWhiteContainer( + child: Text( + "You do not have any Ethereum wallets", + style: STextStyles.label(context), + ), + ) + : Expanded( + child: Column( + children: [ + RoundedWhiteContainer( + padding: const EdgeInsets.all(8), + child: ListView.separated( + itemCount: ethWalletIds.length, + shrinkWrap: true, + separatorBuilder: (_, __) => const SizedBox( + height: 6, + ), + itemBuilder: (_, index) { + return RoundedContainer( + padding: const EdgeInsets.all(8), + onPressed: () { + setState(() { + _selectedWalletId = ethWalletIds[index]; + }); + }, + color: _selectedWalletId == ethWalletIds[index] + ? Theme.of(context) + .extension<StackColors>()! + .highlight + : Colors.transparent, + child: WalletInfoRow( + walletId: ethWalletIds[index], + ), + ); + }, + ), + ), + ], + ), + ), + if (ethWalletIds.isEmpty) + const SizedBox( + height: 16, + ), + ethWalletIds.isEmpty + ? PrimaryButton( + label: "Add new Ethereum wallet", + onPressed: _onAddNewEthWallet, + ) + : PrimaryButton( + label: "Continue", + enabled: _selectedWalletId != null, + onPressed: _onContinue, + ), + ], + ), + ), + ); + } +} diff --git a/lib/route_generator.dart b/lib/route_generator.dart index 7903b1796..9ee9e85ad 100644 --- a/lib/route_generator.dart +++ b/lib/route_generator.dart @@ -4,6 +4,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:isar/isar.dart'; import 'package:stackwallet/models/add_wallet_list_entity/add_wallet_list_entity.dart'; +import 'package:stackwallet/models/add_wallet_list_entity/sub_classes/eth_token_entity.dart'; import 'package:stackwallet/models/buy/response_objects/quote.dart'; import 'package:stackwallet/models/contact_address_entry.dart'; import 'package:stackwallet/models/exchange/incomplete_exchange.dart'; @@ -20,6 +21,7 @@ import 'package:stackwallet/pages/add_wallet_views/new_wallet_recovery_phrase_vi 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/restore_wallet_view/restore_options_view/restore_options_view.dart'; import 'package:stackwallet/pages/add_wallet_views/restore_wallet_view/restore_wallet_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/verify_recovery_phrase_view.dart'; import 'package:stackwallet/pages/address_book_views/address_book_view.dart'; import 'package:stackwallet/pages/address_book_views/subviews/add_address_book_entry_view.dart'; @@ -225,6 +227,20 @@ class RouteGenerator { } return _routeError("${settings.name} invalid args: ${args.toString()}"); + case SelectWalletForTokenView.routeName: + if (args is EthTokenEntity) { + return getRoute( + shouldUseMaterialRoute: useMaterialPageRoute, + builder: (_) => SelectWalletForTokenView( + entity: args, + ), + settings: RouteSettings( + name: settings.name, + ), + ); + } + return _routeError("${settings.name} invalid args: ${args.toString()}"); + case AddCustomTokenView.routeName: return getRoute( shouldUseMaterialRoute: useMaterialPageRoute,