From f4f58b047369a4e5b67c536a261ab22672f4962c Mon Sep 17 00:00:00 2001 From: julian <julian@cypherstack.com> Date: Fri, 31 Mar 2023 11:04:11 -0600 Subject: [PATCH] desktop add global custom eth token view --- .../add_token_view/add_custom_token_view.dart | 287 ++++++++++++------ .../add_wallet_view/add_wallet_view.dart | 28 +- 2 files changed, 218 insertions(+), 97 deletions(-) diff --git a/lib/pages/add_wallet_views/add_token_view/add_custom_token_view.dart b/lib/pages/add_wallet_views/add_token_view/add_custom_token_view.dart index 01f7b6f49..76dfceb45 100644 --- a/lib/pages/add_wallet_views/add_token_view/add_custom_token_view.dart +++ b/lib/pages/add_wallet_views/add_token_view/add_custom_token_view.dart @@ -10,8 +10,11 @@ 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/desktop_dialog_close_button.dart'; import 'package:stackwallet/widgets/desktop/primary_button.dart'; +import 'package:stackwallet/widgets/desktop/secondary_button.dart'; import 'package:stackwallet/widgets/stack_dialog.dart'; class AddCustomTokenView extends ConsumerStatefulWidget { @@ -40,97 +43,183 @@ class _AddCustomTokenViewState extends ConsumerState<AddCustomTokenView> { @override Widget build(BuildContext context) { - return Background( - child: Scaffold( - backgroundColor: Theme.of(context).extension<StackColors>()!.background, - appBar: AppBar( - leading: AppBarBackButton( - onPressed: () { - Navigator.of(context).pop(); - }, + return 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: Padding( + padding: const EdgeInsets.only( + top: 10, + left: 16, + right: 16, + bottom: 16, + ), + child: child, ), ), - body: Padding( - padding: const EdgeInsets.only( - top: 10, - left: 16, - right: 16, - bottom: 16, - ), - child: Column( - children: [ + ), + child: ConditionalParent( + condition: isDesktop, + builder: (child) => Column( + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Padding( + padding: const EdgeInsets.only( + left: 32, + ), + child: Text( + "Add custom ETH token", + style: STextStyles.desktopH3(context), + ), + ), + const DesktopDialogCloseButton(), + ], + ), + Flexible( + child: Padding( + padding: const EdgeInsets.only( + left: 32, + right: 32, + bottom: 32, + top: 16, + ), + child: child, + ), + ), + ], + ), + child: Column( + children: [ + if (!isDesktop) Text( "Add custom ETH token", style: STextStyles.pageTitleH1(context), ), + if (!isDesktop) const SizedBox( height: 16, ), - TextField( - autocorrect: !isDesktop, - enableSuggestions: !isDesktop, - controller: contractController, - style: STextStyles.field(context), - decoration: InputDecoration( - hintText: "Contract address", - hintStyle: STextStyles.fieldLabel(context), - ), + TextField( + autocorrect: !isDesktop, + enableSuggestions: !isDesktop, + controller: contractController, + style: STextStyles.field(context), + decoration: InputDecoration( + hintText: "Contract address", + hintStyle: STextStyles.fieldLabel(context), ), - const SizedBox( - height: 8, - ), - PrimaryButton( - label: "Search", - onPressed: () async { - final response = await showLoading( - whileFuture: EthereumAPI.getTokenContractInfoByAddress( - contractController.text), - context: context, - message: "Looking up contract", - ); - currentToken = response.value; - if (currentToken != null) { - nameController.text = currentToken!.name; - symbolController.text = currentToken!.symbol; - decimalsController.text = currentToken!.decimals.toString(); - } else { - nameController.text = ""; - symbolController.text = ""; - decimalsController.text = ""; - if (mounted) { - unawaited( - showDialog<void>( - context: context, - builder: (context) => StackOkDialog( - title: "Failed to look up token", - message: response.exception?.message, - ), + ), + SizedBox( + height: isDesktop ? 16 : 8, + ), + PrimaryButton( + label: "Search", + onPressed: () async { + final response = await showLoading( + whileFuture: EthereumAPI.getTokenContractInfoByAddress( + contractController.text), + context: context, + message: "Looking up contract", + ); + currentToken = response.value; + if (currentToken != null) { + nameController.text = currentToken!.name; + symbolController.text = currentToken!.symbol; + decimalsController.text = currentToken!.decimals.toString(); + } else { + nameController.text = ""; + symbolController.text = ""; + decimalsController.text = ""; + if (mounted) { + unawaited( + showDialog<void>( + context: context, + builder: (context) => StackOkDialog( + title: "Failed to look up token", + message: response.exception?.message, ), - ); - } + ), + ); } - setState(() { - addTokenButtonEnabled = currentToken != null; - }); - }, + } + setState(() { + addTokenButtonEnabled = currentToken != null; + }); + }, + ), + SizedBox( + height: isDesktop ? 16 : 8, + ), + TextField( + enabled: enableSubFields, + autocorrect: !isDesktop, + enableSuggestions: !isDesktop, + controller: nameController, + style: STextStyles.field(context), + decoration: InputDecoration( + hintText: "Token name", + hintStyle: STextStyles.fieldLabel(context), ), - const SizedBox( - height: 8, - ), - TextField( - enabled: enableSubFields, - autocorrect: !isDesktop, - enableSuggestions: !isDesktop, - controller: nameController, - style: STextStyles.field(context), - decoration: InputDecoration( - hintText: "Token name", - hintStyle: STextStyles.fieldLabel(context), - ), - ), - const SizedBox( - height: 8, + ), + SizedBox( + height: isDesktop ? 16 : 8, + ), + if (isDesktop) + Row( + children: [ + Expanded( + child: TextField( + enabled: enableSubFields, + autocorrect: !isDesktop, + enableSuggestions: !isDesktop, + controller: symbolController, + style: STextStyles.field(context), + decoration: InputDecoration( + hintText: "Ticker", + hintStyle: STextStyles.fieldLabel(context), + ), + ), + ), + const SizedBox( + width: 16, + ), + Expanded( + child: TextField( + enabled: enableSubFields, + autocorrect: !isDesktop, + enableSuggestions: !isDesktop, + controller: decimalsController, + style: STextStyles.field(context), + inputFormatters: [ + TextInputFormatter.withFunction((oldValue, newValue) => + RegExp(r'^([0-9]*)$').hasMatch(newValue.text) + ? newValue + : oldValue), + ], + keyboardType: const TextInputType.numberWithOptions( + signed: false, + decimal: false, + ), + decoration: InputDecoration( + hintText: "Decimals", + hintStyle: STextStyles.fieldLabel(context), + ), + ), + ), + ], ), + if (!isDesktop) TextField( enabled: enableSubFields, autocorrect: !isDesktop, @@ -142,9 +231,11 @@ class _AddCustomTokenViewState extends ConsumerState<AddCustomTokenView> { hintStyle: STextStyles.fieldLabel(context), ), ), + if (!isDesktop) const SizedBox( height: 8, ), + if (!isDesktop) TextField( enabled: enableSubFields, autocorrect: !isDesktop, @@ -166,19 +257,35 @@ class _AddCustomTokenViewState extends ConsumerState<AddCustomTokenView> { hintStyle: STextStyles.fieldLabel(context), ), ), - const SizedBox( - height: 16, - ), - const Spacer(), - PrimaryButton( - label: "Add token", - enabled: addTokenButtonEnabled, - onPressed: () { - Navigator.of(context).pop(currentToken!); - }, - ), - ], - ), + const SizedBox( + height: 16, + ), + const Spacer(), + Row( + children: [ + if (isDesktop) + Expanded( + child: SecondaryButton( + label: "Cancel", + onPressed: Navigator.of(context).pop, + ), + ), + if (isDesktop) + const SizedBox( + width: 16, + ), + Expanded( + child: PrimaryButton( + label: "Add token", + enabled: addTokenButtonEnabled, + onPressed: () { + Navigator.of(context).pop(currentToken!); + }, + ), + ), + ], + ), + ], ), ), ); diff --git a/lib/pages/add_wallet_views/add_wallet_view/add_wallet_view.dart b/lib/pages/add_wallet_views/add_wallet_view/add_wallet_view.dart index bb90a5c18..2307d0591 100644 --- a/lib/pages/add_wallet_views/add_wallet_view/add_wallet_view.dart +++ b/lib/pages/add_wallet_views/add_wallet_view/add_wallet_view.dart @@ -26,6 +26,7 @@ import 'package:stackwallet/utilities/util.dart'; import 'package:stackwallet/widgets/background.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_dialog.dart'; import 'package:stackwallet/widgets/desktop/desktop_scaffold.dart'; import 'package:stackwallet/widgets/expandable.dart'; import 'package:stackwallet/widgets/icon_widgets/x_icon.dart'; @@ -80,17 +81,30 @@ class _AddWalletViewState extends ConsumerState<AddWalletView> { } Future<void> _addToken() async { - final token = await Navigator.of(context).pushNamed( - AddCustomTokenView.routeName, - ); - if (token is EthContract) { - await MainDB.instance.putEthContract(token); + EthContract? contract; + if (isDesktop) { + contract = await showDialog( + context: context, + builder: (context) => const DesktopDialog( + maxWidth: 580, + maxHeight: 500, + child: AddCustomTokenView(), + ), + ); + } else { + contract = await Navigator.of(context).pushNamed( + AddCustomTokenView.routeName, + ); + } + + if (contract != null) { + await MainDB.instance.putEthContract(contract); if (mounted) { setState(() { if (tokenEntities - .where((e) => e.token.address == token.address) + .where((e) => e.token.address == contract!.address) .isEmpty) { - tokenEntities.add(EthTokenEntity(token)); + tokenEntities.add(EthTokenEntity(contract!)); tokenEntities.sort((a, b) => a.token.name.compareTo(b.token.name)); } });