// ignore_for_file: use_build_context_synchronously import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:gecko/globals.dart'; import 'package:gecko/models/wallet_data.dart'; import 'package:gecko/models/widgets_keys.dart'; import 'package:gecko/providers/my_wallets.dart'; import 'package:gecko/providers/substrate_sdk.dart'; import 'package:gecko/providers/wallet_options.dart'; import 'package:gecko/providers/wallets_profiles.dart'; import 'package:gecko/screens/myWallets/unlocking_wallet.dart'; import 'package:gecko/screens/transaction_in_progress.dart'; import 'package:gecko/widgets/balance.dart'; import 'package:gecko/widgets/name_by_address.dart'; import 'package:provider/provider.dart'; import 'package:url_launcher/url_launcher.dart'; void paymentPopup(BuildContext context, String toAddress, String? username) { final walletViewProvider = Provider.of(context, listen: false); final myWalletProvider = Provider.of(context, listen: false); double fees = 0; const double shapeSize = 20; var defaultWallet = myWalletProvider.getDefaultWallet(); bool canValidate = false; final amountFocus = FocusNode(); walletViewProvider.payAmount.text = ''; Future executeTransfert() async { String? pin; if (myWalletProvider.pinCode == '') { pin = await Navigator.push( context, MaterialPageRoute( builder: (homeContext) { return UnlockingWallet(wallet: defaultWallet); }, ), ); } log.d(pin); if (pin != null || myWalletProvider.pinCode != '') { // Payment workflow ! final sub = Provider.of(context, listen: false); final acc = sub.getCurrentWallet(); log.d( "fromAddress: ${acc.address!},destAddress: $toAddress, amount: ${double.parse(walletViewProvider.payAmount.text)}, password: $pin"); sub.pay( fromAddress: acc.address!, destAddress: toAddress, amount: double.parse(walletViewProvider.payAmount.text), password: pin ?? myWalletProvider.pinCode); Navigator.push( context, MaterialPageRoute(builder: (context) { return TransactionInProgress( toAddress: toAddress, toUsername: username); }), ); } } myWalletProvider.readAllWallets().then((value) => myWalletProvider.listWallets .sort((a, b) => a.derivation!.compareTo(b.derivation!))); showModalBottomSheet( shape: const RoundedRectangleBorder( borderRadius: BorderRadius.only( topRight: Radius.circular(shapeSize), topLeft: Radius.circular(shapeSize), ), ), isScrollControlled: true, context: context, builder: (BuildContext context) { final sub = Provider.of(homeContext, listen: false); final walletOptions = Provider.of(context, listen: false); return StatefulBuilder( builder: (BuildContext context, StateSetter setState) { if (walletViewProvider.payAmount.text != '' && (double.parse(walletViewProvider.payAmount.text) + 2 / balanceRatio) <= (walletOptions.balanceCache[defaultWallet.address] ?? 0) && toAddress != defaultWallet.address) { if ((walletOptions.balanceCache[toAddress] == 0 || walletOptions.balanceCache[toAddress] == null) && double.parse(walletViewProvider.payAmount.text) < 5 / balanceRatio) { canValidate = false; } else { canValidate = true; } } else { canValidate = false; } final bool isUdUnit = configBox.get('isUdUnit') ?? false; return Padding( padding: EdgeInsets.only( bottom: MediaQuery.of(context).viewInsets.bottom), child: Container( height: 420, decoration: const ShapeDecoration( color: Color(0xffffeed1), shape: RoundedRectangleBorder( borderRadius: BorderRadius.only( topRight: Radius.circular(shapeSize), topLeft: Radius.circular(shapeSize), ), ), ), child: Padding( padding: const EdgeInsets.only( top: 15, bottom: 0, left: 17, right: 17), child: Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( 'executeATransfer'.tr(), style: const TextStyle( fontSize: 24, fontWeight: FontWeight.w700), ), IconButton( key: keyPopButton, iconSize: 35, icon: const Icon(Icons.cancel_outlined), onPressed: () { Navigator.pop(context); }, ), ]), const SizedBox(height: 5), Text( 'from'.tr(args: ['']), style: TextStyle( fontSize: 19, fontWeight: FontWeight.w500, color: Colors.grey[600]), ), const SizedBox(height: 5), Consumer(builder: (context, sub, _) { return Container( decoration: BoxDecoration( border: Border.all( color: Colors.blueAccent.shade200, width: 2), borderRadius: const BorderRadius.all(Radius.circular(10.0)), ), padding: const EdgeInsets.all(0), child: DropdownButton( dropdownColor: const Color(0xffffeed1), elevation: 12, key: keyDropdownWallets, value: defaultWallet, menuMaxHeight: 300, onTap: () { FocusScope.of(context) .requestFocus(amountFocus); }, selectedItemBuilder: (_) { return myWalletProvider.listWallets .map((WalletData wallet) { return Container( width: 330, padding: const EdgeInsets.all(8), child: Visibility( visible: wallet.address == defaultWallet.address, child: Row(children: [ NameByAddress( wallet: wallet, fontStyle: FontStyle.normal), const Spacer(), Balance( address: wallet.address, size: 20), ]), ), ); }).toList(); }, onChanged: (WalletData? newSelectedWallet) async { defaultWallet = newSelectedWallet!; await sub.setCurrentWallet(newSelectedWallet); sub.reload(); amountFocus.requestFocus(); setState(() {}); }, items: myWalletProvider.listWallets .map((WalletData wallet) { return DropdownMenuItem( value: wallet, key: keySelectThisWallet(wallet.address), child: Container( color: const Color(0xffffeed1), width: 332, height: 80, padding: const EdgeInsets.all(7), child: Row(children: [ NameByAddress( wallet: wallet, fontStyle: FontStyle.normal), const Spacer(), Balance( address: wallet.address, size: 20), ]), ), ); }).toList()), ); }), const SizedBox(height: 12), Row( children: [ Text( 'to'.tr(args: ['']), style: TextStyle( fontSize: 19, fontWeight: FontWeight.w500, color: Colors.grey[600]), ), const SizedBox(width: 10), Text( username ?? getShortPubkey(toAddress), style: const TextStyle( fontSize: 21, fontWeight: FontWeight.w600, ), ), ], ), const SizedBox(height: 7), Row( children: [ Text( 'amount'.tr(), style: TextStyle( fontSize: 19, fontWeight: FontWeight.w500, color: Colors.grey[600]), ), const Spacer(), InkWell( onTap: () => infoFeesPopup(context), child: Row( children: [ const Icon(Icons.info_outlined, color: orangeC), const SizedBox(width: 5), Text( 'fees'.tr( args: [fees.toString(), currencyName]), style: const TextStyle( color: orangeC, fontSize: 17, fontWeight: FontWeight.w500, ), ), ], ), ), const SizedBox(width: 10), ], ), const SizedBox(height: 10), Focus( onFocusChange: (focused) { setState(() { FocusScope.of(context).requestFocus(amountFocus); }); }, child: TextField( textInputAction: TextInputAction.done, onEditingComplete: () async => canValidate ? await executeTransfert() : null, key: keyAmountField, controller: walletViewProvider.payAmount, autofocus: true, focusNode: amountFocus, maxLines: 1, textAlign: TextAlign.center, autocorrect: false, keyboardType: const TextInputType.numberWithOptions( decimal: true), onChanged: (_) async { fees = await sub.txFees( defaultWallet.address, toAddress, double.parse( walletViewProvider.payAmount.text == '' ? '0' : walletViewProvider.payAmount.text)); log.d(fees); setState(() {}); }, inputFormatters: [ FilteringTextInputFormatter.deny(',', replacementString: '.'), FilteringTextInputFormatter.allow( RegExp(r'(^\d+\.?\d{0,2})')), ], decoration: InputDecoration( hintText: '0.00', suffix: Text(isUdUnit ? 'ud'.tr(args: ['']) : currencyName), // udUnitDisplay(40), filled: true, fillColor: Colors.transparent, focusedBorder: OutlineInputBorder( borderSide: BorderSide( color: Colors.grey[500]!, width: 2), borderRadius: BorderRadius.circular(8), ), contentPadding: const EdgeInsets.all(10), ), style: const TextStyle( fontSize: 30, color: Colors.black, fontWeight: FontWeight.w600, ), ), ), const Spacer(), SizedBox( width: double.infinity, height: 60, child: ElevatedButton( key: keyConfirmPayment, style: ElevatedButton.styleFrom( foregroundColor: Colors.white, elevation: 4, backgroundColor: orangeC, // foreground ), onPressed: canValidate ? () async { Navigator.pop(context); await executeTransfert(); } : null, child: Text( 'executeTheTransfer'.tr(), style: const TextStyle( fontSize: 20, fontWeight: FontWeight.w600), ), ), ), const Spacer(), ]), ), ), ); }); }); } //).then((value) => walletViewProvider.payAmount.text = '' Future infoFeesPopup(BuildContext context) async { return showDialog( context: context, barrierDismissible: true, builder: (BuildContext context) { return AlertDialog( backgroundColor: backgroundColor, content: Column( mainAxisSize: MainAxisSize.min, children: [ const Icon(Icons.info_outlined, color: orangeC, size: 40), const SizedBox(height: 20), Text( 'feesExplanation'.tr(), textAlign: TextAlign.center, style: const TextStyle(fontSize: 20, fontWeight: FontWeight.w500), ), const SizedBox(height: 30), Text( 'feesExplanationDetails'.tr(), textAlign: TextAlign.center, style: const TextStyle(fontSize: 18, fontWeight: FontWeight.w300), ), const SizedBox(height: 5), InkWell( onTap: () async => await _launchUrl('https://duniter.org'), child: Container( padding: const EdgeInsets.only( bottom: 2, ), decoration: const BoxDecoration( border: Border( bottom: BorderSide( color: Colors.blueAccent, width: 1, ))), child: Text( 'moreInfo'.tr(), textAlign: TextAlign.center, style: const TextStyle( fontSize: 18, fontWeight: FontWeight.w300, color: Colors.blueAccent, // decoration: TextDecoration.underline, ), ), ), ), ], ), actions: [ Row( mainAxisAlignment: MainAxisAlignment.center, children: [ TextButton( key: keyInfoPopup, child: Padding( padding: const EdgeInsets.all(8), child: Text( 'gotit'.tr(), style: const TextStyle( fontSize: 21, color: Color(0xffD80000), ), ), ), onPressed: () { Navigator.pop(context, true); }, ), ], ) ], ); }, ); } Future _launchUrl(String url) async { if (!await launchUrl(Uri.parse(url))) { throw Exception('Could not launch $url'); } }