diff --git a/lib/entities/openalias_record.dart b/lib/entities/openalias_record.dart index 842a711fe..6d8b759f5 100644 --- a/lib/entities/openalias_record.dart +++ b/lib/entities/openalias_record.dart @@ -37,7 +37,7 @@ class OpenaliasRecord { required String ticker, required List txtRecord, }) { - String address = formattedName; + String address = ''; String name = formattedName; String note = ''; diff --git a/lib/entities/parsed_address.dart b/lib/entities/parsed_address.dart index a73b44e33..67caebcb5 100644 --- a/lib/entities/parsed_address.dart +++ b/lib/entities/parsed_address.dart @@ -1,7 +1,7 @@ import 'package:cake_wallet/entities/openalias_record.dart'; import 'package:cake_wallet/entities/yat_record.dart'; -enum ParseFrom { unstoppableDomains, openAlias, yatRecord, fio, notParsed, twitter } +enum ParseFrom { unstoppableDomains, openAlias, yatRecord, fio, notParsed, twitter, contact } class ParsedAddress { ParsedAddress({ @@ -40,13 +40,17 @@ class ParsedAddress { ); } - factory ParsedAddress.fetchOpenAliasAddress({required OpenaliasRecord record, required String name}){ - return ParsedAddress( - addresses: [record.address], - name: record.name, - description: record.description, - parseFrom: ParseFrom.openAlias, - ); + factory ParsedAddress.fetchOpenAliasAddress( + {required OpenaliasRecord record, required String name}) { + if (record.address.isEmpty) { + return ParsedAddress(addresses: [name]); + } + return ParsedAddress( + addresses: [record.address], + name: record.name, + description: record.description, + parseFrom: ParseFrom.openAlias, + ); } factory ParsedAddress.fetchFioAddress({required String address, required String name}){ @@ -65,6 +69,14 @@ class ParsedAddress { ); } + factory ParsedAddress.fetchContactAddress({required String address, required String name}){ + return ParsedAddress( + addresses: [address], + name: name, + parseFrom: ParseFrom.contact, + ); + } + final List addresses; final String name; final String description; diff --git a/lib/src/screens/send/widgets/extract_address_from_parsed.dart b/lib/src/screens/send/widgets/extract_address_from_parsed.dart index a293835a3..d7e0e3d7f 100644 --- a/lib/src/screens/send/widgets/extract_address_from_parsed.dart +++ b/lib/src/screens/send/widgets/extract_address_from_parsed.dart @@ -68,6 +68,7 @@ Future extractAddressFromParsed( } return address; + case ParseFrom.contact: case ParseFrom.notParsed: address = parsedAddress.addresses.first; return address; @@ -85,4 +86,4 @@ Future extractAddressFromParsed( }); return address; -} \ No newline at end of file +} diff --git a/lib/src/screens/send/widgets/send_card.dart b/lib/src/screens/send/widgets/send_card.dart index 2b4b40fa3..d07516f79 100644 --- a/lib/src/screens/send/widgets/send_card.dart +++ b/lib/src/screens/send/widgets/send_card.dart @@ -103,7 +103,7 @@ class SendCardState extends State config: KeyboardActionsConfig( keyboardActionsPlatform: KeyboardActionsPlatform.IOS, keyboardBarColor: Theme.of(context) - .accentTextTheme! + .accentTextTheme .bodyLarge! .backgroundColor!, nextFocus: false, @@ -127,9 +127,9 @@ class SendCardState extends State bottomLeft: Radius.circular(24), bottomRight: Radius.circular(24)), gradient: LinearGradient(colors: [ - Theme.of(context).primaryTextTheme!.titleMedium!.color!, + Theme.of(context).primaryTextTheme.titleMedium!.color!, Theme.of(context) - .primaryTextTheme! + .primaryTextTheme .titleMedium! .decorationColor!, ], begin: Alignment.topLeft, end: Alignment.bottomRight), @@ -165,11 +165,11 @@ class SendCardState extends State AddressTextFieldOption.addressBook ], buttonColor: Theme.of(context) - .primaryTextTheme! + .primaryTextTheme .headlineMedium! .color!, borderColor: Theme.of(context) - .primaryTextTheme! + .primaryTextTheme .headlineSmall! .color!, textStyle: TextStyle( @@ -180,7 +180,7 @@ class SendCardState extends State fontSize: 14, fontWeight: FontWeight.w500, color: Theme.of(context) - .primaryTextTheme! + .primaryTextTheme .headlineSmall! .decorationColor!), onPushPasteButton: (context) async { @@ -189,7 +189,9 @@ class SendCardState extends State }, onPushAddressBookButton: (context) async { output.resetParsedAddress(); - await output.fetchParsedAddress(context); + }, + onSelectedContact: (contact) { + output.loadContact(contact); }, validator: validator, selectedCurrency: sendViewModel.currency, @@ -201,7 +203,7 @@ class SendCardState extends State controller: extractedAddressController, readOnly: true, borderColor: Theme.of(context) - .primaryTextTheme! + .primaryTextTheme .headlineSmall! .color!, textStyle: TextStyle( @@ -233,7 +235,7 @@ class SendCardState extends State height: 32, decoration: BoxDecoration( color: Theme.of(context) - .primaryTextTheme! + .primaryTextTheme .headlineMedium! .color!, borderRadius: @@ -246,7 +248,7 @@ class SendCardState extends State fontSize: 12, fontWeight: FontWeight.bold, color: Theme.of(context) - .primaryTextTheme! + .primaryTextTheme .headlineMedium! .decorationColor!)), ), @@ -287,7 +289,7 @@ class SendCardState extends State color: Colors.white), placeholderTextStyle: TextStyle( color: Theme.of(context) - .primaryTextTheme! + .primaryTextTheme .headlineSmall! .decorationColor!, fontWeight: FontWeight.w500, @@ -308,7 +310,7 @@ class SendCardState extends State child: Container( decoration: BoxDecoration( color: Theme.of(context) - .primaryTextTheme! + .primaryTextTheme .headlineMedium! .color!, borderRadius: @@ -325,7 +327,7 @@ class SendCardState extends State FontWeight.bold, color: Theme.of(context) - .primaryTextTheme! + .primaryTextTheme .headlineMedium! .decorationColor!))), ))))]), @@ -334,7 +336,7 @@ class SendCardState extends State ) )), Divider(height: 1,color: Theme.of(context) - .primaryTextTheme! + .primaryTextTheme .headlineSmall! .decorationColor!), Observer( @@ -353,7 +355,7 @@ class SendCardState extends State fontSize: 12, fontWeight: FontWeight.w600, color: Theme.of(context) - .primaryTextTheme! + .primaryTextTheme .headlineSmall! .decorationColor!), )), @@ -363,7 +365,7 @@ class SendCardState extends State fontSize: 12, fontWeight: FontWeight.w600, color: Theme.of(context) - .primaryTextTheme! + .primaryTextTheme .headlineSmall! .decorationColor!), ) @@ -394,7 +396,7 @@ class SendCardState extends State ), hintText: '0.00', borderColor: Theme.of(context) - .primaryTextTheme! + .primaryTextTheme .headlineSmall! .color!, textStyle: TextStyle( @@ -403,7 +405,7 @@ class SendCardState extends State color: Colors.white), placeholderTextStyle: TextStyle( color: Theme.of(context) - .primaryTextTheme!.headlineSmall!.decorationColor!, + .primaryTextTheme.headlineSmall!.decorationColor!, fontWeight: FontWeight.w500, fontSize: 14), )), @@ -414,7 +416,7 @@ class SendCardState extends State keyboardType: TextInputType.multiline, maxLines: null, borderColor: Theme.of(context) - .primaryTextTheme! + .primaryTextTheme .headlineSmall! .color!, textStyle: TextStyle( @@ -426,7 +428,7 @@ class SendCardState extends State fontSize: 14, fontWeight: FontWeight.w500, color: Theme.of(context) - .primaryTextTheme! + .primaryTextTheme .headlineSmall! .decorationColor!), ), @@ -490,7 +492,7 @@ class SendCardState extends State FontWeight.w600, color: Theme .of(context) - .primaryTextTheme! + .primaryTextTheme .headlineSmall! .decorationColor!)) ), @@ -586,7 +588,7 @@ class SendCardState extends State }); noteController.addListener(() { - final note = noteController.text ?? ''; + final note = noteController.text; if (note != output.note) { output.note = note; @@ -676,4 +678,4 @@ class SendCardState extends State @override bool get wantKeepAlive => true; -} \ No newline at end of file +} diff --git a/lib/src/widgets/address_text_field.dart b/lib/src/widgets/address_text_field.dart index 9017aa8b1..3462c7ed4 100644 --- a/lib/src/widgets/address_text_field.dart +++ b/lib/src/widgets/address_text_field.dart @@ -1,4 +1,3 @@ - import 'package:cake_wallet/utils/device_info.dart'; import 'package:cake_wallet/utils/responsive_layout_util.dart'; import 'package:flutter/services.dart'; @@ -16,10 +15,7 @@ class AddressTextField extends StatelessWidget { {required this.controller, this.isActive = true, this.placeholder, - this.options = const [ - AddressTextFieldOption.qrCode, - AddressTextFieldOption.addressBook - ], + this.options = const [AddressTextFieldOption.qrCode, AddressTextFieldOption.addressBook], this.onURIScanned, this.focusNode, this.isBorderExist = true, @@ -31,6 +27,7 @@ class AddressTextField extends StatelessWidget { this.validator, this.onPushPasteButton, this.onPushAddressBookButton, + this.onSelectedContact, this.selectedCurrency}); static const prefixIconWidth = 34.0; @@ -52,6 +49,7 @@ class AddressTextField extends StatelessWidget { final FocusNode? focusNode; final Function(BuildContext context)? onPushPasteButton; final Function(BuildContext context)? onPushAddressBookButton; + final Function(ContactBase contact)? onSelectedContact; final CryptoCurrency? selectedCurrency; @override @@ -66,34 +64,27 @@ class AddressTextField extends StatelessWidget { controller: controller, focusNode: focusNode, style: textStyle ?? - TextStyle( - fontSize: 16, - color: Theme.of(context).primaryTextTheme!.titleLarge!.color!), + TextStyle(fontSize: 16, color: Theme.of(context).primaryTextTheme.titleLarge!.color!), decoration: InputDecoration( suffixIcon: SizedBox( - width: prefixIconWidth * options.length + - (spaceBetweenPrefixIcons * options.length), + width: prefixIconWidth * options.length + (spaceBetweenPrefixIcons * options.length), ), - hintStyle: hintStyle ?? - TextStyle(fontSize: 16, color: Theme.of(context).hintColor), + hintStyle: hintStyle ?? TextStyle(fontSize: 16, color: Theme.of(context).hintColor), hintText: placeholder ?? S.current.widgets_address, focusedBorder: isBorderExist ? UnderlineInputBorder( borderSide: BorderSide( - color: borderColor ?? Theme.of(context).dividerColor, - width: 1.0)) + color: borderColor ?? Theme.of(context).dividerColor, width: 1.0)) : InputBorder.none, disabledBorder: isBorderExist ? UnderlineInputBorder( borderSide: BorderSide( - color: borderColor ?? Theme.of(context).dividerColor, - width: 1.0)) + color: borderColor ?? Theme.of(context).dividerColor, width: 1.0)) : InputBorder.none, enabledBorder: isBorderExist ? UnderlineInputBorder( borderSide: BorderSide( - color: borderColor ?? Theme.of(context).dividerColor, - width: 1.0)) + color: borderColor ?? Theme.of(context).dividerColor, width: 1.0)) : InputBorder.none, ), validator: validator, @@ -102,11 +93,11 @@ class AddressTextField extends StatelessWidget { top: 2, right: 0, child: SizedBox( - width: prefixIconWidth * options.length + - (spaceBetweenPrefixIcons * options.length), + width: prefixIconWidth * options.length + (spaceBetweenPrefixIcons * options.length), child: Row( - mainAxisAlignment: ResponsiveLayoutUtil.instance.isMobile - ? MainAxisAlignment.spaceBetween : MainAxisAlignment.end, + mainAxisAlignment: ResponsiveLayoutUtil.instance.isMobile + ? MainAxisAlignment.spaceBetween + : MainAxisAlignment.end, children: [ SizedBox(width: 5), if (this.options.contains(AddressTextFieldOption.paste)) ...[ @@ -122,20 +113,14 @@ class AddressTextField extends StatelessWidget { padding: EdgeInsets.all(8), decoration: BoxDecoration( color: buttonColor ?? - Theme.of(context) - .accentTextTheme - ! - .titleLarge! - .color!, - borderRadius: - BorderRadius.all(Radius.circular(6))), + Theme.of(context).accentTextTheme.titleLarge!.color!, + borderRadius: BorderRadius.all(Radius.circular(6))), child: Image.asset( 'assets/images/paste_ios.png', color: iconColor ?? Theme.of(context) .primaryTextTheme - ! - .headlineMedium! + .headlineMedium! .decorationColor!, )), ), @@ -155,28 +140,21 @@ class AddressTextField extends StatelessWidget { padding: EdgeInsets.all(8), decoration: BoxDecoration( color: buttonColor ?? - Theme.of(context) - .accentTextTheme - - .titleLarge! - .color!, - borderRadius: - BorderRadius.all(Radius.circular(6))), + Theme.of(context).accentTextTheme.titleLarge!.color!, + borderRadius: BorderRadius.all(Radius.circular(6))), child: Image.asset( 'assets/images/qr_code_icon.png', color: iconColor ?? Theme.of(context) .primaryTextTheme - !.headlineMedium! + .headlineMedium! .decorationColor!, )), ), )) ] else SizedBox(width: 5), - if (this - .options - .contains(AddressTextFieldOption.addressBook)) ...[ + if (this.options.contains(AddressTextFieldOption.addressBook)) ...[ Container( width: prefixIconWidth, height: prefixIconHeight, @@ -184,26 +162,19 @@ class AddressTextField extends StatelessWidget { child: Semantics( label: S.of(context).address_book, child: InkWell( - onTap: () async => - _presetAddressBookPicker(context), + onTap: () async => _presetAddressBookPicker(context), child: Container( padding: EdgeInsets.all(8), decoration: BoxDecoration( color: buttonColor ?? - Theme.of(context) - .accentTextTheme - ! - .titleLarge! - .color!, - borderRadius: - BorderRadius.all(Radius.circular(6))), + Theme.of(context).accentTextTheme.titleLarge!.color!, + borderRadius: BorderRadius.all(Radius.circular(6))), child: Image.asset( 'assets/images/open_book.png', color: iconColor ?? Theme.of(context) .primaryTextTheme - ! - .headlineMedium! + .headlineMedium! .decorationColor!, )), ), @@ -221,30 +192,31 @@ class AddressTextField extends StatelessWidget { if (code.isEmpty) { return; } - + try { final uri = Uri.parse(code); controller?.text = uri.path; onURIScanned?.call(uri); - } catch(_){ + } catch (_) { controller?.text = code; } } Future _presetAddressBookPicker(BuildContext context) async { final contact = await Navigator.of(context) - .pushNamed(Routes.pickerAddressBook,arguments: selectedCurrency); + .pushNamed(Routes.pickerAddressBook, arguments: selectedCurrency); - if (contact is ContactBase && contact.address != null) { + if (contact is ContactBase) { controller?.text = contact.address; onPushAddressBookButton?.call(context); + onSelectedContact?.call(contact); } } Future _pasteAddress(BuildContext context) async { final clipboard = await Clipboard.getData('text/plain'); final address = clipboard?.text ?? ''; - + if (address.isNotEmpty) { controller?.text = address; } diff --git a/lib/view_model/send/output.dart b/lib/view_model/send/output.dart index 74628f24e..f9ec749ab 100644 --- a/lib/view_model/send/output.dart +++ b/lib/view_model/send/output.dart @@ -17,6 +17,8 @@ import 'package:cake_wallet/store/settings_store.dart'; import 'package:cake_wallet/generated/i18n.dart'; import 'package:cake_wallet/bitcoin/bitcoin.dart'; +import 'package:cake_wallet/entities/contact_base.dart'; + part 'output.g.dart'; const String cryptoNumberPattern = '0.0'; @@ -70,7 +72,7 @@ abstract class OutputBase with Store { int amount = 0; try { - if (cryptoAmount?.isNotEmpty ?? false) { + if (cryptoAmount.isNotEmpty) { final _cryptoAmount = cryptoAmount.replaceAll(',', '.'); int _amount = 0; switch (walletType) { @@ -240,4 +242,11 @@ abstract class OutputBase with Store { extractedAddress = await extractAddressFromParsed(context, parsedAddress); note = parsedAddress.description; } + + void loadContact(ContactBase contact) { + address = contact.name; + parsedAddress = ParsedAddress.fetchContactAddress(address: contact.address, name: contact.name); + extractedAddress = parsedAddress.addresses.first; + note = parsedAddress.description; + } } diff --git a/pubspec_base.yaml b/pubspec_base.yaml index 2c8908aea..9355dc739 100644 --- a/pubspec_base.yaml +++ b/pubspec_base.yaml @@ -3,7 +3,6 @@ dependencies: sdk: flutter flutter_localizations: sdk: flutter - flutter_cupertino_localizations: ^1.0.1 intl: ^0.17.0 url_launcher: ^6.1.4 qr_flutter: @@ -128,4 +127,4 @@ flutter: - asset: assets/fonts/Lato-Regular.ttf - asset: assets/fonts/Lato-Medium.ttf - asset: assets/fonts/Lato-Semibold.ttf - - asset: assets/fonts/Lato-Bold.ttf \ No newline at end of file + - asset: assets/fonts/Lato-Bold.ttf