From 2f2a916343f73f56be317b43f22408b020ee20ca Mon Sep 17 00:00:00 2001 From: reasje Date: Tue, 26 Sep 2023 16:40:46 +0330 Subject: [PATCH 1/4] feat: Added capitalize first letter to formatter --- .../components/balance_panel/balance.dart | 2 +- lib/common/components/components.dart | 2 +- .../components/recent_transactions/utils.dart | 1 - .../widgets/recent_transaction_item.dart | 8 ++++++-- lib/common/dialogs/dialogs.dart | 2 +- lib/common/urls.dart | 2 +- lib/common/utils/formatter.dart | 8 +++++--- .../responsive_layout/card_item.dart | 2 +- .../presentation/widgets/dapp_indicator.dart | 2 +- .../widgets/allow_multiple_gestures.dart | 3 +-- .../open_dapp/widgets/bridge_params.dart | 4 +--- .../open_dapp/widgets/transaction_dialog.dart | 18 ++++++++---------- lib/features/portfolio/portfolio.dart | 2 +- .../presentation/portfolio_page_state.dart | 9 ++------- .../subfeatures/nft/nft_list/nft_list.dart | 2 +- .../choose_crypto/choose_crypto_page.dart | 12 ++++++------ ...sscode_change_enter_current_page_state.dart | 1 - lib/features/security/security.dart | 2 +- .../chain_configuration_presenter.dart | 2 +- .../delete_custom_network_presenter.dart | 2 +- .../language_page/language_page.dart | 2 +- .../theme_settings_presenter.dart | 4 +--- .../xsd_conversion_rate_state.dart | 4 +--- .../setup_wallet/setup_wallet_presenter.dart | 2 +- 24 files changed, 44 insertions(+), 54 deletions(-) diff --git a/lib/common/components/balance_panel/balance.dart b/lib/common/components/balance_panel/balance.dart index df42ec88..19c6839c 100644 --- a/lib/common/components/balance_panel/balance.dart +++ b/lib/common/components/balance_panel/balance.dart @@ -1 +1 @@ -export 'presentation/balance_panel.dart'; \ No newline at end of file +export 'presentation/balance_panel.dart'; diff --git a/lib/common/components/components.dart b/lib/common/components/components.dart index 68fccea5..51efd134 100644 --- a/lib/common/components/components.dart +++ b/lib/common/components/components.dart @@ -2,4 +2,4 @@ export 'recent_transactions/recent_transactions.dart'; export 'gradient_text.dart'; export 'grey_container.dart'; export 'balance_panel/balance.dart'; -export 'snack_bar.dart'; \ No newline at end of file +export 'snack_bar.dart'; diff --git a/lib/common/components/recent_transactions/utils.dart b/lib/common/components/recent_transactions/utils.dart index cd720913..18d54aa2 100644 --- a/lib/common/components/recent_transactions/utils.dart +++ b/lib/common/components/recent_transactions/utils.dart @@ -99,5 +99,4 @@ class RecentTransactionsUtils { ); }).toList(); } - } diff --git a/lib/common/components/recent_transactions/widgets/recent_transaction_item.dart b/lib/common/components/recent_transactions/widgets/recent_transaction_item.dart index 4850c84d..f5116b86 100644 --- a/lib/common/components/recent_transactions/widgets/recent_transaction_item.dart +++ b/lib/common/components/recent_transactions/widgets/recent_transaction_item.dart @@ -88,7 +88,10 @@ class RecentTrxListItem extends HookConsumerWidget { children: [ Text( amount, - style: FontTheme.of(context).body1.primary().copyWith( + style: FontTheme.of(context) + .body1 + .primary() + .copyWith( fontWeight: FontWeight.w500, foreground: state.hideBalance == true ? (Paint() @@ -109,7 +112,8 @@ class RecentTrxListItem extends HookConsumerWidget { style: FontTheme.of(context).h7().copyWith( fontSize: 16, fontWeight: FontWeight.w400, - color: ColorsTheme.of(context).textSecondary, + color: + ColorsTheme.of(context).textSecondary, ), textAlign: TextAlign.start, overflow: TextOverflow.ellipsis, diff --git a/lib/common/dialogs/dialogs.dart b/lib/common/dialogs/dialogs.dart index 1b5db62c..e57c5215 100644 --- a/lib/common/dialogs/dialogs.dart +++ b/lib/common/dialogs/dialogs.dart @@ -1,3 +1,3 @@ export 'alert_dialog.dart'; export 'bottom_sheet.dart'; -export 'warning_dialog.dart'; \ No newline at end of file +export 'warning_dialog.dart'; diff --git a/lib/common/urls.dart b/lib/common/urls.dart index ba977150..2d98a0af 100644 --- a/lib/common/urls.dart +++ b/lib/common/urls.dart @@ -2,7 +2,7 @@ class Urls { static const String mxcMainnetNftMarketPlace = 'https://nft.mxc.com/'; static const String mxcTestnetNftMarketPlace = 'https://wannsee-nft.mxc.com/'; static const String mxcStatus = 'https://mxc.instatus.com/'; - + static const String dappRoot = 'https://raw.githubusercontent.com/MXCzkEVM/MEP-1759-DApp-store/main'; diff --git a/lib/common/utils/formatter.dart b/lib/common/utils/formatter.dart index f539998a..6dc738a0 100644 --- a/lib/common/utils/formatter.dart +++ b/lib/common/utils/formatter.dart @@ -1,8 +1,5 @@ import 'dart:math'; import 'package:datadashwallet/common/config.dart'; -import 'package:intl/intl.dart' as intl; -import 'package:flutter/material.dart'; -import 'package:web3dart/web3dart.dart'; class Formatter { static String formatBigNumber(double number) { @@ -89,4 +86,9 @@ class Formatter { throw e.toString(); } } + + static String capitalizeFirstLetter(String text) { + if (text.isEmpty) return text; + return text[0].toUpperCase() + text.substring(1); + } } diff --git a/lib/features/dapps/presentation/responsive_layout/card_item.dart b/lib/features/dapps/presentation/responsive_layout/card_item.dart index e3ced386..790bcc36 100644 --- a/lib/features/dapps/presentation/responsive_layout/card_item.dart +++ b/lib/features/dapps/presentation/responsive_layout/card_item.dart @@ -30,4 +30,4 @@ class CardSizes { child: child, ); } -} \ No newline at end of file +} diff --git a/lib/features/dapps/presentation/widgets/dapp_indicator.dart b/lib/features/dapps/presentation/widgets/dapp_indicator.dart index 1f7fe9a8..7781c66e 100644 --- a/lib/features/dapps/presentation/widgets/dapp_indicator.dart +++ b/lib/features/dapps/presentation/widgets/dapp_indicator.dart @@ -20,7 +20,7 @@ class DAppIndicator extends StatelessWidget { width: total * 10 < 100 ? null : 100, alignment: Alignment.center, padding: const EdgeInsets.symmetric(horizontal: 10), - decoration: BoxDecoration( + decoration: BoxDecoration( borderRadius: const BorderRadius.all( Radius.circular(50), ), diff --git a/lib/features/dapps/subfeatures/open_dapp/widgets/allow_multiple_gestures.dart b/lib/features/dapps/subfeatures/open_dapp/widgets/allow_multiple_gestures.dart index aa0ac685..e6818c46 100644 --- a/lib/features/dapps/subfeatures/open_dapp/widgets/allow_multiple_gestures.dart +++ b/lib/features/dapps/subfeatures/open_dapp/widgets/allow_multiple_gestures.dart @@ -9,7 +9,6 @@ class AllowMultipleHorizontalDrag extends HorizontalDragGestureRecognizer { void rejectGesture(int pointer) { acceptGesture(pointer); } - } class AllowMultipleDoubleTap extends DoubleTapGestureRecognizer { @@ -17,4 +16,4 @@ class AllowMultipleDoubleTap extends DoubleTapGestureRecognizer { void rejectGesture(int pointer) { acceptGesture(pointer); } -} \ No newline at end of file +} diff --git a/lib/features/dapps/subfeatures/open_dapp/widgets/bridge_params.dart b/lib/features/dapps/subfeatures/open_dapp/widgets/bridge_params.dart index 5a670776..bcf0e4c0 100644 --- a/lib/features/dapps/subfeatures/open_dapp/widgets/bridge_params.dart +++ b/lib/features/dapps/subfeatures/open_dapp/widgets/bridge_params.dart @@ -1,4 +1,3 @@ - import 'package:web3_provider/web3_provider.dart'; class BridgeParams { @@ -26,8 +25,7 @@ class BridgeParams { String? jsonPrice = json['gasPrice']; gasPrice = jsonPrice == null ? null - : (int.parse(jsonPrice.replaceAll('0x', ''), radix: 16)) - .toString(); + : (int.parse(jsonPrice.replaceAll('0x', ''), radix: 16)).toString(); value = BigInt.tryParse((json['value'] ?? '0').replaceAll('0x', ''), radix: 16) ?? diff --git a/lib/features/dapps/subfeatures/open_dapp/widgets/transaction_dialog.dart b/lib/features/dapps/subfeatures/open_dapp/widgets/transaction_dialog.dart index b6da7c4d..a58f6cda 100644 --- a/lib/features/dapps/subfeatures/open_dapp/widgets/transaction_dialog.dart +++ b/lib/features/dapps/subfeatures/open_dapp/widgets/transaction_dialog.dart @@ -3,16 +3,14 @@ import 'package:mxc_ui/mxc_ui.dart'; import 'transaction_info.dart'; -Future showTransactionDialog( - BuildContext context, { - String? title, - required String amount, - required String from, - required String to, - String? estimatedFee, - VoidCallback? onTap, - required String symbol -}) { +Future showTransactionDialog(BuildContext context, + {String? title, + required String amount, + required String from, + required String to, + String? estimatedFee, + VoidCallback? onTap, + required String symbol}) { return showModalBottomSheet( context: context, useRootNavigator: true, diff --git a/lib/features/portfolio/portfolio.dart b/lib/features/portfolio/portfolio.dart index da7c2c5f..384e99dd 100644 --- a/lib/features/portfolio/portfolio.dart +++ b/lib/features/portfolio/portfolio.dart @@ -1 +1 @@ -export 'presentation/portfolio_page_presenter.dart'; \ No newline at end of file +export 'presentation/portfolio_page_presenter.dart'; diff --git a/lib/features/portfolio/presentation/portfolio_page_state.dart b/lib/features/portfolio/presentation/portfolio_page_state.dart index 35eba1dc..2e9cd483 100644 --- a/lib/features/portfolio/presentation/portfolio_page_state.dart +++ b/lib/features/portfolio/presentation/portfolio_page_state.dart @@ -17,11 +17,6 @@ class PortfolioState with EquatableMixin { bool buyEnabled = true; @override - List get props => [ - walletBalance, - tokensList, - walletAddress, - switchTokensOrNFTs, - nftList - ]; + List get props => + [walletBalance, tokensList, walletAddress, switchTokensOrNFTs, nftList]; } diff --git a/lib/features/portfolio/subfeatures/nft/nft_list/nft_list.dart b/lib/features/portfolio/subfeatures/nft/nft_list/nft_list.dart index c51289fb..ae185ce7 100644 --- a/lib/features/portfolio/subfeatures/nft/nft_list/nft_list.dart +++ b/lib/features/portfolio/subfeatures/nft/nft_list/nft_list.dart @@ -61,7 +61,7 @@ class NFTList extends HookConsumerWidget { url: launchUrl, ), )); - } + } }, title: translate('buy_x').replaceFirst('{0}', 'NFT'), iconData: Icons.add, diff --git a/lib/features/portfolio/subfeatures/token/send_token/choose_crypto/choose_crypto_page.dart b/lib/features/portfolio/subfeatures/token/send_token/choose_crypto/choose_crypto_page.dart index 09bf5a70..9c95d327 100644 --- a/lib/features/portfolio/subfeatures/token/send_token/choose_crypto/choose_crypto_page.dart +++ b/lib/features/portfolio/subfeatures/token/send_token/choose_crypto/choose_crypto_page.dart @@ -83,13 +83,13 @@ class ChooseCryptoPage extends HookConsumerWidget { ...TokensBalanceListUtils.generateTokensBalanceList( ref.watch(state).filterTokens!, onSelected: (token) => Navigator.of(context).push( - route.featureDialog( - SendCryptoPage( - token: token, - qrCode: qrCode, - ), - ), + route.featureDialog( + SendCryptoPage( + token: token, + qrCode: qrCode, ), + ), + ), ) ], )), diff --git a/lib/features/security/presentation/passcode_change/passcode_change_enter_current_page/passcode_change_enter_current_page_state.dart b/lib/features/security/presentation/passcode_change/passcode_change_enter_current_page/passcode_change_enter_current_page_state.dart index 02f0d633..339c3df1 100644 --- a/lib/features/security/presentation/passcode_change/passcode_change_enter_current_page/passcode_change_enter_current_page_state.dart +++ b/lib/features/security/presentation/passcode_change/passcode_change_enter_current_page/passcode_change_enter_current_page_state.dart @@ -1,4 +1,3 @@ - import 'package:datadashwallet/features/security/security.dart'; class PasscodeChangeEnterCurrentPageState extends PasscodeBasePageState { diff --git a/lib/features/security/security.dart b/lib/features/security/security.dart index 3b744787..6e1a2a4c 100644 --- a/lib/features/security/security.dart +++ b/lib/features/security/security.dart @@ -20,4 +20,4 @@ export 'presentation/passcode_require/passcode_require_page.dart'; export 'presentation/passcode_change/passcode_change_enter_new_page/passcode_change_enter_new_page.dart'; export 'presentation/passcode_change/passcode_change_confirm_page/passcode_change_confirm_page.dart'; -export 'presentation/passcode_change/passcode_change_confirm_page/passcode_change_confirm_page_presenter.dart'; \ No newline at end of file +export 'presentation/passcode_change/passcode_change_confirm_page/passcode_change_confirm_page_presenter.dart'; diff --git a/lib/features/settings/subfeatures/chain_configuration/chain_configuration_presenter.dart b/lib/features/settings/subfeatures/chain_configuration/chain_configuration_presenter.dart index b590edf9..a2f86204 100644 --- a/lib/features/settings/subfeatures/chain_configuration/chain_configuration_presenter.dart +++ b/lib/features/settings/subfeatures/chain_configuration/chain_configuration_presenter.dart @@ -31,7 +31,7 @@ class ChainConfigurationPresenter notify(() => state.networks = value.where((element) => element.isAdded == true).toList()); }); - + listen(_chainConfigurationUseCase.ipfsGateWayList, (newIpfsGateWayList) { if (newIpfsGateWayList.isNotEmpty) { if (state.ipfsGateWays == null) { diff --git a/lib/features/settings/subfeatures/chain_configuration/subfeatures/delete_custom_network/delete_custom_network_presenter.dart b/lib/features/settings/subfeatures/chain_configuration/subfeatures/delete_custom_network/delete_custom_network_presenter.dart index d0b678b9..05728e3a 100644 --- a/lib/features/settings/subfeatures/chain_configuration/subfeatures/delete_custom_network/delete_custom_network_presenter.dart +++ b/lib/features/settings/subfeatures/chain_configuration/subfeatures/delete_custom_network/delete_custom_network_presenter.dart @@ -28,7 +28,7 @@ class DeleteCustomNetworkPresenter late final TextEditingController symbolController = TextEditingController(); late final TextEditingController explorerController = TextEditingController(); late final _authUseCase = ref.read(authUseCaseProvider); - + Network? selectedNetwork; @override diff --git a/lib/features/settings/subfeatures/language/presentation/language_page/language_page.dart b/lib/features/settings/subfeatures/language/presentation/language_page/language_page.dart index 6136f945..cffa4893 100644 --- a/lib/features/settings/subfeatures/language/presentation/language_page/language_page.dart +++ b/lib/features/settings/subfeatures/language/presentation/language_page/language_page.dart @@ -19,7 +19,7 @@ class LanguagePage extends ConsumerWidget { final selectedLanguage = state.currentLanguage ?? state.languages.firstWhereOrNull((item) => item.code == Localizations.localeOf(context).languageCode); - + return MxcPage( appBar: AppNavBar( title: Text( diff --git a/lib/features/settings/subfeatures/theme/presentation/theme_settings/theme_settings_presenter.dart b/lib/features/settings/subfeatures/theme/presentation/theme_settings/theme_settings_presenter.dart index 7a39db97..aa6cfb30 100644 --- a/lib/features/settings/subfeatures/theme/presentation/theme_settings/theme_settings_presenter.dart +++ b/lib/features/settings/subfeatures/theme/presentation/theme_settings/theme_settings_presenter.dart @@ -1,4 +1,3 @@ - import 'package:datadashwallet/core/core.dart'; import 'package:datadashwallet/features/settings/settings.dart'; @@ -8,8 +7,7 @@ final themeSettingsContainer = PresenterContainer( () => ThemeSettingsPresenter()); -class ThemeSettingsPresenter - extends CompletePresenter { +class ThemeSettingsPresenter extends CompletePresenter { ThemeSettingsPresenter() : super(ThemeSettingsState()); late final ThemeUseCase _themeUseCase = ref.read(themeUseCaseProvider); diff --git a/lib/features/settings/subfeatures/xsd_conversion_rate/xsd_conversion_rate_state.dart b/lib/features/settings/subfeatures/xsd_conversion_rate/xsd_conversion_rate_state.dart index 3c692f88..f180ec72 100644 --- a/lib/features/settings/subfeatures/xsd_conversion_rate/xsd_conversion_rate_state.dart +++ b/lib/features/settings/subfeatures/xsd_conversion_rate/xsd_conversion_rate_state.dart @@ -1,8 +1,6 @@ import 'package:equatable/equatable.dart'; class XsdConversionRateState with EquatableMixin { - @override - List get props => [ - ]; + List get props => []; } diff --git a/lib/features/splash/setup_wallet/setup_wallet_presenter.dart b/lib/features/splash/setup_wallet/setup_wallet_presenter.dart index 8a89b834..9058c270 100644 --- a/lib/features/splash/setup_wallet/setup_wallet_presenter.dart +++ b/lib/features/splash/setup_wallet/setup_wallet_presenter.dart @@ -27,7 +27,7 @@ class SplashSetupWalletPresenter final defaultList = Network.fixedNetworks(); _chainConfigurationUseCase.addItems(defaultList); } - + _chainConfigurationUseCase.getCurrentNetwork(); _authUseCase.resetNetwork( _chainConfigurationUseCase.getCurrentNetworkWithoutRefresh()); From 975772ec3bb949e90e78afb8f832845acd066947 Mon Sep 17 00:00:00 2001 From: reasje Date: Tue, 26 Sep 2023 18:08:16 +0330 Subject: [PATCH 2/4] feat: Added signTypedMessage functionality & --- assets/flutter_i18n/en.json | 4 +- lib/common/utils/formatter.dart | 1 + .../contract/token_contract_use_case.dart | 5 ++ .../subfeatures/open_dapp/open_dapp_page.dart | 11 +++ .../open_dapp/open_dapp_presenter.dart | 73 +++++++++++++++++++ 5 files changed, 93 insertions(+), 1 deletion(-) diff --git a/assets/flutter_i18n/en.json b/assets/flutter_i18n/en.json index de3c5e4c..c06f82ba 100644 --- a/assets/flutter_i18n/en.json +++ b/assets/flutter_i18n/en.json @@ -279,5 +279,7 @@ "network_not_found": "Network not found", "checking_balance": "Checking balance...", "no_balance": "You have no balance", - "no_balance_tip": "You currently have no MXC in your wallet.\nYou can either receive tokens or choose to claim a username later." + "no_balance_tip": "You currently have no MXC in your wallet.\nYou can either receive tokens or choose to claim a username later.", + "signature_request": "Signature request", + "sign": "Sign" } \ No newline at end of file diff --git a/lib/common/utils/formatter.dart b/lib/common/utils/formatter.dart index 6dc738a0..842519f7 100644 --- a/lib/common/utils/formatter.dart +++ b/lib/common/utils/formatter.dart @@ -1,5 +1,6 @@ import 'dart:math'; import 'package:datadashwallet/common/config.dart'; +import 'package:intl/intl.dart' as intl; class Formatter { static String formatBigNumber(double number) { diff --git a/lib/features/common/contract/token_contract_use_case.dart b/lib/features/common/contract/token_contract_use_case.dart index 4f8ccf07..12602a4d 100644 --- a/lib/features/common/contract/token_contract_use_case.dart +++ b/lib/features/common/contract/token_contract_use_case.dart @@ -168,6 +168,11 @@ class TokenContractUseCase extends ReactiveUseCase { data: data, tokenAddress: tokenAddress); + String signTypedMessage({required String privateKey, required String data}) { + return _repository.tokenContract + .signTypedMessage(privateKey: privateKey, data: data); + } + Future getChainId(String rpcUrl) async { return await _repository.tokenContract.getChainId(rpcUrl); } diff --git a/lib/features/dapps/subfeatures/open_dapp/open_dapp_page.dart b/lib/features/dapps/subfeatures/open_dapp/open_dapp_page.dart index ea536235..9d4ba5fa 100644 --- a/lib/features/dapps/subfeatures/open_dapp/open_dapp_page.dart +++ b/lib/features/dapps/subfeatures/open_dapp/open_dapp_page.dart @@ -109,9 +109,20 @@ class OpenAppPage extends HookConsumerWidget { url: url); break; case EIP1193.signMessage: + break; case EIP1193.signPersonalMessage: break; case EIP1193.signTypedMessage: + Map object = params["object"]; + presenter.signTypedMessage( + object: object, + cancel: () { + controller?.cancel(id); + }, + success: (idHash) { + controller?.sendResult(idHash, id); + }, + ); break; case EIP1193.addEthereumChain: bool? result = diff --git a/lib/features/dapps/subfeatures/open_dapp/open_dapp_presenter.dart b/lib/features/dapps/subfeatures/open_dapp/open_dapp_presenter.dart index ae20abc2..a74a0e2a 100644 --- a/lib/features/dapps/subfeatures/open_dapp/open_dapp_presenter.dart +++ b/lib/features/dapps/subfeatures/open_dapp/open_dapp_presenter.dart @@ -1,6 +1,8 @@ +import 'dart:convert'; import 'package:datadashwallet/common/common.dart'; import 'package:datadashwallet/core/core.dart'; import 'package:datadashwallet/features/dapps/subfeatures/open_dapp/widgets/swtich_network_dialog.dart'; +import 'package:datadashwallet/features/dapps/subfeatures/open_dapp/widgets/typed_message_dialog.dart'; import 'package:flutter/services.dart'; import 'package:mxc_logic/mxc_logic.dart'; import 'package:web3_provider/web3_provider.dart'; @@ -103,6 +105,21 @@ class OpenDAppPresenter extends CompletePresenter { } } + String? _signTypedMessage( + String hexData, + ) { + loading = true; + try { + final res = _tokenContractUseCase.signTypedMessage( + privateKey: state.account!.privateKey, data: hexData); + return res; + } catch (e, s) { + addError(e, s); + } finally { + loading = false; + } + } + void recordTransaction(String hash) { final timeStamp = DateTime.now(); const txStatus = TransactionStatus.pending; @@ -220,6 +237,42 @@ class OpenDAppPresenter extends CompletePresenter { } } + void signPersonalMessage() {} + + void signTypedMessage({ + required Map object, + required VoidCallback cancel, + required Function(String hash) success, + }) async { + String hexData = object['raw'] as String; + Map data = + jsonDecode(object['raw'] as String) as Map; + Map domain = data['domain'] as Map; + String primaryType = data['primaryType']; + int chainId = (domain['chainId']) as int; + String name = domain['name'] as String; + + try { + final result = await showTypedMessageDialog(context!, + title: translate('signature_request')!, + message: data['message'] as Map, + networkName: '$name ($chainId)', + primaryType: primaryType); + + if (result != null && result) { + final hash = _signTypedMessage( + hexData, + ); + if (hash != null) success.call(hash); + } else { + cancel.call(); + } + } catch (e, s) { + cancel.call(); + addError(e, s); + } + } + void changeProgress(int progress) => notify(() => state.progress = progress); void setAddress(dynamic id) { @@ -275,4 +328,24 @@ class OpenDAppPresenter extends CompletePresenter { }, ); } + + void launchAddress(String address) { + final chainExplorerUrl = state.network!.explorerUrl!; + final explorerUrl = chainExplorerUrl.endsWith('/') + ? chainExplorerUrl + : '$chainExplorerUrl/'; + + final addressUrl = '$explorerUrl${Config.addressExplorer(address)}'; + state.webviewController! + .loadUrl(urlRequest: URLRequest(url: Uri.parse(addressUrl))); + } + + bool isAddress(String address) { + try { + EthereumAddress.fromHex(address); + return true; + } catch (e) { + return false; + } + } } From 746154165270e5d06e533c3893f231e4857bfdb5 Mon Sep 17 00:00:00 2001 From: reasje Date: Tue, 26 Sep 2023 18:10:20 +0330 Subject: [PATCH 3/4] feat: Added sign message bottom sheet --- .../widgets/typed_message_dialog.dart | 52 ++++++ .../open_dapp/widgets/typed_message_info.dart | 157 ++++++++++++++++++ 2 files changed, 209 insertions(+) create mode 100644 lib/features/dapps/subfeatures/open_dapp/widgets/typed_message_dialog.dart create mode 100644 lib/features/dapps/subfeatures/open_dapp/widgets/typed_message_info.dart diff --git a/lib/features/dapps/subfeatures/open_dapp/widgets/typed_message_dialog.dart b/lib/features/dapps/subfeatures/open_dapp/widgets/typed_message_dialog.dart new file mode 100644 index 00000000..819553ab --- /dev/null +++ b/lib/features/dapps/subfeatures/open_dapp/widgets/typed_message_dialog.dart @@ -0,0 +1,52 @@ +import 'package:datadashwallet/features/dapps/subfeatures/open_dapp/widgets/typed_message_info.dart'; +import 'package:flutter/material.dart'; +import 'package:mxc_ui/mxc_ui.dart'; + +Future showTypedMessageDialog( + BuildContext context, { + String? title, + required String networkName, + required String primaryType, + required Map message, + VoidCallback? onTap, +}) { + return showModalBottomSheet( + context: context, + useRootNavigator: true, + isScrollControlled: true, + isDismissible: false, + backgroundColor: Colors.transparent, + builder: (BuildContext context) => Container( + padding: const EdgeInsets.only(left: 16, right: 16, top: 0, bottom: 44), + decoration: BoxDecoration( + color: ColorsTheme.of(context).screenBackground, + borderRadius: const BorderRadius.only( + topLeft: Radius.circular(20), + topRight: Radius.circular(20), + ), + ), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + MxcAppBarEvenly.title( + titleText: title ?? '', + action: Container( + alignment: Alignment.centerRight, + child: InkWell( + child: const Icon(Icons.close), + onTap: () => Navigator.of(context).pop(false), + ), + ), + ), + TypeMessageInfo( + message: message, + networkName: networkName, + primaryType: primaryType, + onTap: onTap, + ), + const SizedBox(height: 10), + ], + ), + ), + ); +} diff --git a/lib/features/dapps/subfeatures/open_dapp/widgets/typed_message_info.dart b/lib/features/dapps/subfeatures/open_dapp/widgets/typed_message_info.dart new file mode 100644 index 00000000..0226dd15 --- /dev/null +++ b/lib/features/dapps/subfeatures/open_dapp/widgets/typed_message_info.dart @@ -0,0 +1,157 @@ +import 'package:datadashwallet/common/utils/utils.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_i18n/flutter_i18n.dart'; +import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:mxc_ui/mxc_ui.dart'; + +import '../open_dapp_presenter.dart'; + +class TypeMessageInfo extends ConsumerWidget { + const TypeMessageInfo({ + Key? key, + required this.networkName, + required this.primaryType, + required this.message, + this.onTap, + }) : super(key: key); + + final String networkName; + final String primaryType; + final Map message; + final VoidCallback? onTap; + + @override + Widget build(BuildContext context, WidgetRef ref) { + final presenter = ref.read(openDAppPageContainer.actions); + final state = ref.watch(openDAppPageContainer.state); + return Column( + children: [ + Padding( + padding: const EdgeInsets.symmetric(horizontal: 6), + child: Column( + children: [ + titleItem(context), + ...infoItems(context, presenter), + ], + ), + ), + const SizedBox(height: 8), + signButton(context), + ], + ); + } + + Widget signButton(BuildContext context) { + String titleText = 'sign'; + AxsButtonType type = AxsButtonType.primary; + + return MxcButton.primary( + key: const ValueKey('signButton'), + size: AxsButtonSize.xl, + title: FlutterI18n.translate(context, titleText), + type: type, + onTap: () { + if (onTap != null) onTap!(); + Navigator.of(context).pop(true); + }, + ); + } + + Widget titleItem(BuildContext context) { + return Column( + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text( + primaryType, + style: FontTheme.of(context).h5(), + softWrap: true, + textAlign: TextAlign.start, + ), + const Spacer(), + Text( + networkName, + style: FontTheme.of(context).body2.secondary(), + softWrap: true, + ), + const SizedBox(height: 4), + ], + ) + ], + ); + } + + List infoItems(BuildContext context, OpenDAppPresenter presenter) { + final List infoList = []; + final keyList = message.keys.toList(); + final valueList = message.values.toList(); + for (int i = 0; i < keyList.length; i++) { + final property = keyList[i]; + final value = valueList[i].toString(); + final isAddress = presenter.isAddress(value); + infoList.add(InfoItem( + label: Formatter.capitalizeFirstLetter(property), + content: InkWell( + onTap: isAddress ? () => presenter.launchAddress(value) : null, + child: Row( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + Expanded( + child: Text( + value, + style: FontTheme.of(context).body1.primary(), + softWrap: true, + textAlign: TextAlign.right, + ), + ), + if (isAddress) ...[ + const SizedBox(width: 8), + Icon( + MxcIcons.external_link, + size: 24, + color: ColorsTheme.of(context).textSecondary, + ), + ] + ], + ), + ), + )); + } + return infoList; + } +} + +class InfoItem extends StatelessWidget { + const InfoItem({ + Key? key, + required this.label, + required this.content, + }) : super(key: key); + + final String label; + final Widget content; + + @override + Widget build(BuildContext context) { + return Padding( + padding: const EdgeInsets.symmetric(vertical: 4), + child: Row( + children: [ + Row( + children: [ + Text( + FlutterI18n.translate(context, label), + style: FontTheme.of(context).body1.secondary(), + ), + const SizedBox(width: 10), + ], + ), + Expanded( + child: content, + ), + ], + ), + ); + } +} From cd4dafa3386636aee0cedb209f9a54f2da16b563 Mon Sep 17 00:00:00 2001 From: reasje Date: Tue, 26 Sep 2023 18:11:03 +0330 Subject: [PATCH 4/4] fix: Update shared --- packages/shared | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/shared b/packages/shared index 5a8ffee4..47a25516 160000 --- a/packages/shared +++ b/packages/shared @@ -1 +1 @@ -Subproject commit 5a8ffee4536121004f975a53adbd54a22054db76 +Subproject commit 47a25516b56c13e2fe742622f20da15c43b6bb63