CAKE-359 | added text field for extracted (from Yat, Unstoppable Domains, OpenAlias) address to send_card.dart; added extractedAddress and isParsedAddress parameters to output.dart; applied extractedAddress to monero_wallet.dart and electrum_wallet.dart; added TextValidator to send_view_model.dart

This commit is contained in:
OleksandrSobol 2021-09-22 16:47:10 +03:00
parent 9958f6c2e0
commit 3b649ef682
7 changed files with 116 additions and 69 deletions

View file

@ -280,8 +280,12 @@ abstract class ElectrumWalletBase extends WalletBase<ElectrumBalance,
? item.formattedCryptoAmount ? item.formattedCryptoAmount
: amount; : amount;
final outputAddress = item.isParsedAddress
? item.extractedAddress
: item.address;
txb.addOutput( txb.addOutput(
addressToOutputScript(item.address, networkType), addressToOutputScript(outputAddress, networkType),
outputAmount); outputAmount);
}); });

View file

@ -175,11 +175,15 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
throw MoneroTransactionCreationException('Wrong balance. Not enough XMR on your balance.'); throw MoneroTransactionCreationException('Wrong balance. Not enough XMR on your balance.');
} }
final moneroOutputs = outputs.map((output) => final moneroOutputs = outputs.map((output) {
MoneroOutput( final outputAddress = output.isParsedAddress
address: output.address, ? output.extractedAddress
amount: output.cryptoAmount.replaceAll(',', '.'))) : output.address;
.toList();
return MoneroOutput(
address: outputAddress,
amount: output.cryptoAmount.replaceAll(',', '.'));
}).toList();
pendingTransactionDescription = pendingTransactionDescription =
await transaction_history.createTransactionMultDest( await transaction_history.createTransactionMultDest(
@ -188,7 +192,9 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
accountIndex: walletAddresses.account.id); accountIndex: walletAddresses.account.id);
} else { } else {
final output = outputs.first; final output = outputs.first;
final address = output.address; final address = output.isParsedAddress
? output.extractedAddress
: output.address;
final amount = output.sendAll final amount = output.sendAll
? null ? null
: output.cryptoAmount.replaceAll(',', '.'); : output.cryptoAmount.replaceAll(',', '.');

View file

@ -1,5 +1,4 @@
import 'dart:ui'; import 'dart:ui';
import 'package:cake_wallet/src/screens/send/widgets/parse_address_from_domain_alert.dart';
import 'package:cake_wallet/src/screens/send/widgets/send_card.dart'; import 'package:cake_wallet/src/screens/send/widgets/send_card.dart';
import 'package:cake_wallet/src/widgets/alert_with_two_actions.dart'; import 'package:cake_wallet/src/widgets/alert_with_two_actions.dart';
import 'package:cake_wallet/src/widgets/template_tile.dart'; import 'package:cake_wallet/src/widgets/template_tile.dart';

View file

@ -1,4 +1,3 @@
import 'package:cake_wallet/entities/parsed_address.dart';
import 'package:cake_wallet/palette.dart'; import 'package:cake_wallet/palette.dart';
import 'package:cake_wallet/view_model/send/output.dart'; import 'package:cake_wallet/view_model/send/output.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
@ -274,16 +273,15 @@ class ConfirmSendingAlertContentState extends State<ConfirmSendingAlertContent>
itemCount: itemCount, itemCount: itemCount,
itemBuilder: (context, index) { itemBuilder: (context, index) {
final item = outputs[index]; final item = outputs[index];
final _address = item.address; final _address = item.isParsedAddress
? item.extractedAddress
: item.address;
final _amount = final _amount =
item.cryptoAmount.replaceAll(',', '.'); item.cryptoAmount.replaceAll(',', '.');
final isParsedAddress =
item.parsedAddress.parseFrom !=
ParseFrom.notParsed;
return Column( return Column(
children: [ children: [
if (isParsedAddress) Padding( if (item.isParsedAddress) Padding(
padding: EdgeInsets.only(top: 8), padding: EdgeInsets.only(top: 8),
child: Text( child: Text(
item.parsedAddress.name, item.parsedAddress.name,
@ -334,8 +332,7 @@ class ConfirmSendingAlertContentState extends State<ConfirmSendingAlertContent>
}) })
: Column( : Column(
children: [ children: [
if (outputs.first.parsedAddress.parseFrom != if (outputs.first.isParsedAddress) Padding(
ParseFrom.notParsed) Padding(
padding: EdgeInsets.only(top: 8), padding: EdgeInsets.only(top: 8),
child: Text( child: Text(
outputs.first.parsedAddress.name, outputs.first.parsedAddress.name,
@ -352,7 +349,9 @@ class ConfirmSendingAlertContentState extends State<ConfirmSendingAlertContent>
Padding( Padding(
padding: EdgeInsets.only(top: 8), padding: EdgeInsets.only(top: 8),
child: Text( child: Text(
outputs.first.address, outputs.first.isParsedAddress
? outputs.first.extractedAddress
: outputs.first.address,
style: TextStyle( style: TextStyle(
fontSize: 10, fontSize: 10,
fontWeight: FontWeight.w600, fontWeight: FontWeight.w600,

View file

@ -1,7 +1,6 @@
import 'dart:ui'; import 'dart:ui';
import 'package:cake_wallet/entities/transaction_priority.dart'; import 'package:cake_wallet/entities/transaction_priority.dart';
import 'package:cake_wallet/routes.dart'; import 'package:cake_wallet/routes.dart';
import 'package:cake_wallet/src/screens/send/widgets/parse_address_from_domain_alert.dart';
import 'package:cake_wallet/src/widgets/keyboard_done_button.dart'; import 'package:cake_wallet/src/widgets/keyboard_done_button.dart';
import 'package:cake_wallet/src/widgets/picker.dart'; import 'package:cake_wallet/src/widgets/picker.dart';
import 'package:cake_wallet/view_model/send/output.dart'; import 'package:cake_wallet/view_model/send/output.dart';
@ -38,6 +37,7 @@ class SendCardState extends State<SendCard>
cryptoAmountController = TextEditingController(), cryptoAmountController = TextEditingController(),
fiatAmountController = TextEditingController(), fiatAmountController = TextEditingController(),
noteController = TextEditingController(), noteController = TextEditingController(),
extractedAddressController = TextEditingController(),
cryptoAmountFocus = FocusNode(), cryptoAmountFocus = FocusNode(),
fiatAmountFocus = FocusNode(), fiatAmountFocus = FocusNode(),
addressFocusNode = FocusNode(); addressFocusNode = FocusNode();
@ -52,6 +52,7 @@ class SendCardState extends State<SendCard>
final TextEditingController cryptoAmountController; final TextEditingController cryptoAmountController;
final TextEditingController fiatAmountController; final TextEditingController fiatAmountController;
final TextEditingController noteController; final TextEditingController noteController;
final TextEditingController extractedAddressController;
final FocusNode cryptoAmountFocus; final FocusNode cryptoAmountFocus;
final FocusNode fiatAmountFocus; final FocusNode fiatAmountFocus;
final FocusNode addressFocusNode; final FocusNode addressFocusNode;
@ -101,58 +102,80 @@ class SendCardState extends State<SendCard>
child: Padding( child: Padding(
padding: EdgeInsets.fromLTRB(24, 100, 24, 32), padding: EdgeInsets.fromLTRB(24, 100, 24, 32),
child: SingleChildScrollView( child: SingleChildScrollView(
child: Column( child: Observer(builder: (_) => Column(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: <Widget>[ children: <Widget>[
AddressTextField( Observer(builder: (_) {
focusNode: addressFocusNode, final validator = output.isParsedAddress
controller: addressController, ? sendViewModel.textValidator
onURIScanned: (uri) { : sendViewModel.addressValidator;
var address = '';
var amount = '';
if (uri != null) { return AddressTextField(
address = uri.path; focusNode: addressFocusNode,
amount = uri.queryParameters['tx_amount'] ?? controller: addressController,
uri.queryParameters['amount']; onURIScanned: (uri) {
} else { var address = '';
address = uri.toString(); var amount = '';
}
addressController.text = address; if (uri != null) {
cryptoAmountController.text = amount; address = uri.path;
}, amount = uri.queryParameters['tx_amount'] ??
options: [ uri.queryParameters['amount'];
AddressTextFieldOption.paste, } else {
AddressTextFieldOption.qrCode, address = uri.toString();
AddressTextFieldOption.addressBook }
],
buttonColor: Theme.of(context) addressController.text = address;
.primaryTextTheme cryptoAmountController.text = amount;
.display1 },
.color, options: [
borderColor: Theme.of(context) AddressTextFieldOption.paste,
.primaryTextTheme AddressTextFieldOption.qrCode,
.headline AddressTextFieldOption.addressBook
.color, ],
textStyle: TextStyle( buttonColor: Theme.of(context)
fontSize: 14, .primaryTextTheme
fontWeight: FontWeight.w500, .display1
color: Colors.white), .color,
hintStyle: TextStyle( borderColor: Theme.of(context)
fontSize: 14, .primaryTextTheme
fontWeight: FontWeight.w500, .headline
color: Theme.of(context) .color,
.primaryTextTheme textStyle: TextStyle(
.headline fontSize: 14,
.decorationColor), fontWeight: FontWeight.w500,
onPushPasteButton: (context) async { color: Colors.white),
output.resetParsedAddress(); hintStyle: TextStyle(
await output.fetchParsedAddress(context); fontSize: 14,
}, fontWeight: FontWeight.w500,
onPushAddressBookButton: (context) => color: Theme.of(context)
output.resetParsedAddress(), .primaryTextTheme
validator: sendViewModel.addressValidator, .headline
.decorationColor),
onPushPasteButton: (context) async {
output.resetParsedAddress();
await output.fetchParsedAddress(context);
},
onPushAddressBookButton: (context) =>
output.resetParsedAddress(),
validator: validator,
);
}),
if (output.isParsedAddress) Padding(
padding: const EdgeInsets.only(top: 20),
child: BaseTextFormField(
controller: extractedAddressController,
readOnly: true,
borderColor: Theme.of(context)
.primaryTextTheme
.headline
.color,
textStyle: TextStyle(
fontSize: 14,
fontWeight: FontWeight.w500,
color: Colors.white),
validator: sendViewModel.addressValidator
)
), ),
Observer( Observer(
builder: (_) => Padding( builder: (_) => Padding(
@ -440,7 +463,7 @@ class SendCardState extends State<SendCard>
) )
) )
], ],
) ))
), ),
), ),
) )
@ -453,6 +476,7 @@ class SendCardState extends State<SendCard>
cryptoAmountController.text = output.cryptoAmount; cryptoAmountController.text = output.cryptoAmount;
fiatAmountController.text = output.fiatAmount; fiatAmountController.text = output.fiatAmount;
noteController.text = output.note; noteController.text = output.note;
extractedAddressController.text = output.extractedAddress;
if (_effectsInstalled) { if (_effectsInstalled) {
return; return;
@ -520,6 +544,7 @@ class SendCardState extends State<SendCard>
final address = addressController.text; final address = addressController.text;
if (output.address != address) { if (output.address != address) {
output.resetParsedAddress();
output.address = address; output.address = address;
} }
}); });
@ -532,11 +557,14 @@ class SendCardState extends State<SendCard>
addressFocusNode.addListener(() async { addressFocusNode.addListener(() async {
if (!addressFocusNode.hasFocus && addressController.text.isNotEmpty) { if (!addressFocusNode.hasFocus && addressController.text.isNotEmpty) {
output.resetParsedAddress();
await output.fetchParsedAddress(context); await output.fetchParsedAddress(context);
} }
}); });
reaction((_) => output.extractedAddress, (String extractedAddress) {
extractedAddressController.text = extractedAddress;
});
_effectsInstalled = true; _effectsInstalled = true;
} }

View file

@ -47,8 +47,16 @@ abstract class OutputBase with Store {
@observable @observable
bool sendAll; bool sendAll;
@observable
ParsedAddress parsedAddress; ParsedAddress parsedAddress;
@observable
String extractedAddress;
@computed
bool get isParsedAddress => parsedAddress.parseFrom != ParseFrom.notParsed
&& parsedAddress.name.isNotEmpty;
@computed @computed
int get formattedCryptoAmount { int get formattedCryptoAmount {
int amount = 0; int amount = 0;
@ -134,6 +142,7 @@ abstract class OutputBase with Store {
} }
void resetParsedAddress() { void resetParsedAddress() {
extractedAddress = '';
parsedAddress = ParsedAddress(addresses: []); parsedAddress = ParsedAddress(addresses: []);
} }
@ -206,6 +215,6 @@ abstract class OutputBase with Store {
final domain = address; final domain = address;
final ticker = _wallet.currency.title.toLowerCase(); final ticker = _wallet.currency.title.toLowerCase();
parsedAddress = await parseAddressFromDomain(domain, ticker); parsedAddress = await parseAddressFromDomain(domain, ticker);
address = await defineAddress(context, parsedAddress); extractedAddress = await defineAddress(context, parsedAddress);
} }
} }

View file

@ -117,6 +117,8 @@ abstract class SendViewModelBase with Store {
Validator get addressValidator => AddressValidator(type: _wallet.currency); Validator get addressValidator => AddressValidator(type: _wallet.currency);
Validator get textValidator => TextValidator();
@observable @observable
PendingTransaction pendingTransaction; PendingTransaction pendingTransaction;