From 01adf863d06a179332136a3fd80210a38b146265 Mon Sep 17 00:00:00 2001 From: OmarHatem28 Date: Tue, 9 Aug 2022 13:34:40 +0200 Subject: [PATCH 01/12] Add the ability to launch app from Crypto QR codes --- android/app/src/main/AndroidManifestBase.xml | 9 +++++ lib/main.dart | 37 ++++++++++++++++++++ 2 files changed, 46 insertions(+) diff --git a/android/app/src/main/AndroidManifestBase.xml b/android/app/src/main/AndroidManifestBase.xml index f43b0369b..f4023f532 100644 --- a/android/app/src/main/AndroidManifestBase.xml +++ b/android/app/src/main/AndroidManifestBase.xml @@ -38,6 +38,15 @@ android:scheme="cakewallet" android:host="y.at" /> + + + + + + + + + with SingleTickerProviderStateMixin { super.initState(); //_handleIncomingLinks(); //_handleInitialUri(); + + initUniLinks(); } @override @@ -210,6 +212,41 @@ class AppState extends State with SingleTickerProviderStateMixin { super.dispose(); } + /// handle app links while the app is already started - be it in + /// the foreground or in the background. + Future initUniLinks() async { + try { + stream = getLinksStream().listen((String link) { + handleDeepLinking(link); + }); + + final String initialLink = await getInitialLink(); + + handleDeepLinking(initialLink); + } catch (e) { + print(e); + } + } + + void handleDeepLinking(String link) async { + if (link == null || !mounted) return; + + final List urlComponents = link.split(":"); + + switch (urlComponents.first) { + case "bitcoin": + print("@@@@@@@@@@@@@@@@@@@@@@@@@@"); + print("Bitcoin QR Code: \n${link}"); + break; + case "litecoin": + case "haven": + case "monero": + default: + print("@@@@@@@@@@@@@@@@@@@@@@@@@@"); + print(link); + } + } + Future _handleInitialUri() async { try { final uri = await getInitialUri(); From 7bccf468323fe40f8cde19a86d436669f68c81d1 Mon Sep 17 00:00:00 2001 From: OmarHatem28 Date: Tue, 9 Aug 2022 15:47:41 +0200 Subject: [PATCH 02/12] Send data from URI to send screen --- lib/di.dart | 10 ++++-- lib/main.dart | 27 ++++++++------- lib/router.dart | 7 +++- lib/src/screens/send/send_page.dart | 11 ++++-- lib/src/screens/send/widgets/send_card.dart | 37 ++++++++++++++++----- 5 files changed, 64 insertions(+), 28 deletions(-) diff --git a/lib/di.dart b/lib/di.dart index bd911335d..bc02b3466 100644 --- a/lib/di.dart +++ b/lib/di.dart @@ -5,6 +5,7 @@ import 'package:cake_wallet/ionia/ionia_anypay.dart'; import 'package:cake_wallet/ionia/ionia_category.dart'; import 'package:cake_wallet/ionia/ionia_gift_card.dart'; import 'package:cake_wallet/src/screens/ionia/cards/ionia_gift_card_detail_page.dart'; +import 'package:cake_wallet/utils/payment_request.dart'; import 'package:cake_wallet/view_model/ionia/ionia_auth_view_model.dart'; import 'package:cake_wallet/view_model/ionia/ionia_buy_card_view_model.dart'; import 'package:cake_wallet/view_model/ionia/ionia_filter_view_model.dart'; @@ -372,9 +373,12 @@ Future setup( getIt.get(), _transactionDescriptionBox)); - getIt.registerFactory( - () => SendPage(sendViewModel: getIt.get(), - settingsViewModel: getIt.get())); + getIt.registerFactoryParam( + (PaymentRequest initialPaymentRequest, _) => SendPage( + sendViewModel: getIt.get(), + settingsViewModel: getIt.get(), + initialPaymentRequest: initialPaymentRequest, + )); getIt.registerFactory(() => SendTemplatePage( sendTemplateViewModel: getIt.get())); diff --git a/lib/main.dart b/lib/main.dart index 901773072..cfd242dbf 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -5,6 +5,7 @@ import 'package:cake_wallet/buy/order.dart'; import 'package:cake_wallet/ionia/ionia_category.dart'; import 'package:cake_wallet/ionia/ionia_merchant.dart'; import 'package:cake_wallet/store/yat/yat_store.dart'; +import 'package:cake_wallet/utils/payment_request.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; @@ -216,34 +217,32 @@ class AppState extends State with SingleTickerProviderStateMixin { /// the foreground or in the background. Future initUniLinks() async { try { - stream = getLinksStream().listen((String link) { - handleDeepLinking(link); + stream = getUriLinksStream().listen((Uri uri) { + handleDeepLinking(uri); }); - final String initialLink = await getInitialLink(); + final Uri initialUri = await getInitialUri(); - handleDeepLinking(initialLink); + handleDeepLinking(initialUri); } catch (e) { print(e); } } - void handleDeepLinking(String link) async { - if (link == null || !mounted) return; + void handleDeepLinking(Uri uri) { + if (uri == null || !mounted) return; - final List urlComponents = link.split(":"); - - switch (urlComponents.first) { + switch (uri.scheme) { case "bitcoin": - print("@@@@@@@@@@@@@@@@@@@@@@@@@@"); - print("Bitcoin QR Code: \n${link}"); - break; case "litecoin": case "haven": case "monero": default: - print("@@@@@@@@@@@@@@@@@@@@@@@@@@"); - print(link); + Navigator.pushNamed( + navigatorKey.currentContext, + Routes.send, + arguments: PaymentRequest.fromUri(uri), + ); } } diff --git a/lib/router.dart b/lib/router.dart index 1a9c3c2d5..c5079f078 100644 --- a/lib/router.dart +++ b/lib/router.dart @@ -16,6 +16,7 @@ import 'package:cake_wallet/src/screens/seed/pre_seed_page.dart'; import 'package:cake_wallet/src/screens/support/support_page.dart'; import 'package:cake_wallet/src/screens/unspent_coins/unspent_coins_details_page.dart'; import 'package:cake_wallet/src/screens/unspent_coins/unspent_coins_list_page.dart'; +import 'package:cake_wallet/utils/payment_request.dart'; import 'package:cake_wallet/view_model/monero_account_list/account_list_item.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; @@ -207,8 +208,12 @@ Route createRoute(RouteSettings settings) { builder: (_) => getIt.get()); case Routes.send: + final initialPaymentRequest = settings.arguments as PaymentRequest; + return CupertinoPageRoute( - fullscreenDialog: true, builder: (_) => getIt.get()); + fullscreenDialog: true, builder: (_) => getIt.get( + param1: initialPaymentRequest, + )); case Routes.sendTemplate: return CupertinoPageRoute( diff --git a/lib/src/screens/send/send_page.dart b/lib/src/screens/send/send_page.dart index 791548f3d..64e564501 100644 --- a/lib/src/screens/send/send_page.dart +++ b/lib/src/screens/send/send_page.dart @@ -5,6 +5,7 @@ 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/picker.dart'; import 'package:cake_wallet/src/widgets/template_tile.dart'; +import 'package:cake_wallet/utils/payment_request.dart'; import 'package:cake_wallet/view_model/send/output.dart'; import 'package:cake_wallet/view_model/settings/settings_view_model.dart'; import 'package:flutter/cupertino.dart'; @@ -28,13 +29,18 @@ import 'package:smooth_page_indicator/smooth_page_indicator.dart'; import 'package:cw_core/crypto_currency.dart'; class SendPage extends BasePage { - SendPage({@required this.sendViewModel,@required this.settingsViewModel }) : _formKey = GlobalKey(),fiatFromSettings = settingsViewModel.fiatCurrency; + SendPage({ + @required this.sendViewModel, + @required this.settingsViewModel, + this.initialPaymentRequest, + }) : _formKey = GlobalKey(),fiatFromSettings = settingsViewModel.fiatCurrency; final SendViewModel sendViewModel; final SettingsViewModel settingsViewModel; final GlobalKey _formKey; final controller = PageController(initialPage: 0); - final FiatCurrency fiatFromSettings ; + final FiatCurrency fiatFromSettings; + final PaymentRequest initialPaymentRequest; bool _effectsInstalled = false; @@ -116,6 +122,7 @@ class SendPage extends BasePage { key: output.key, output: output, sendViewModel: sendViewModel, + initialPaymentRequest: initialPaymentRequest, ); }); }, diff --git a/lib/src/screens/send/widgets/send_card.dart b/lib/src/screens/send/widgets/send_card.dart index 69858a3ac..27b3f49dc 100644 --- a/lib/src/screens/send/widgets/send_card.dart +++ b/lib/src/screens/send/widgets/send_card.dart @@ -19,23 +19,35 @@ import 'package:cake_wallet/generated/i18n.dart'; import 'package:cake_wallet/src/widgets/base_text_form_field.dart'; class SendCard extends StatefulWidget { - SendCard({Key key, @required this.output, @required this.sendViewModel}) : super(key: key); + SendCard({ + Key key, + @required this.output, + @required this.sendViewModel, + this.initialPaymentRequest, + }) : super(key: key); final Output output; final SendViewModel sendViewModel; + final PaymentRequest initialPaymentRequest; @override - SendCardState createState() => SendCardState( + SendCardState createState() { + return SendCardState( output: output, - sendViewModel: sendViewModel + sendViewModel: sendViewModel, + initialPaymentRequest: initialPaymentRequest, ); + } } class SendCardState extends State with AutomaticKeepAliveClientMixin { - SendCardState({@required this.output, @required this.sendViewModel}) - : addressController = TextEditingController(), - cryptoAmountController = TextEditingController(), + SendCardState({ + @required this.output, + @required this.sendViewModel, + PaymentRequest initialPaymentRequest}) + : addressController = TextEditingController(text: initialPaymentRequest?.address), + cryptoAmountController = TextEditingController(text: initialPaymentRequest?.amount), fiatAmountController = TextEditingController(), noteController = TextEditingController(), extractedAddressController = TextEditingController(), @@ -111,6 +123,11 @@ class SendCardState extends State ? sendViewModel.textValidator : sendViewModel.addressValidator; + print("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); + print("444444444444444444444444444444"); + print(addressController.text); + print(cryptoAmountController.text); + return AddressTextField( focusNode: addressFocusNode, controller: addressController, @@ -509,8 +526,12 @@ class SendCardState extends State } void _setEffects(BuildContext context) { - addressController.text = output.address; - cryptoAmountController.text = output.cryptoAmount; + if (output.address.isNotEmpty) { + addressController.text = output.address; + } + if (output.cryptoAmount.isNotEmpty) { + cryptoAmountController.text = output.cryptoAmount; + } fiatAmountController.text = output.fiatAmount; noteController.text = output.note; extractedAddressController.text = output.extractedAddress; From e5fac16ef77ec032b768762913dfcae62802267d Mon Sep 17 00:00:00 2001 From: OmarHatem28 Date: Tue, 9 Aug 2022 17:06:21 +0200 Subject: [PATCH 03/12] Notify user when a different currency is scanned --- lib/main.dart | 17 +++------- lib/src/screens/send/widgets/send_card.dart | 35 ++++++++++++++++----- lib/utils/payment_request.dart | 7 +++-- lib/view_model/send/send_view_model.dart | 2 ++ res/values/strings_de.arb | 3 +- res/values/strings_en.arb | 3 +- res/values/strings_es.arb | 3 +- res/values/strings_fr.arb | 3 +- res/values/strings_hi.arb | 3 +- res/values/strings_hr.arb | 3 +- res/values/strings_it.arb | 3 +- res/values/strings_ja.arb | 3 +- res/values/strings_ko.arb | 3 +- res/values/strings_nl.arb | 3 +- res/values/strings_pl.arb | 3 +- res/values/strings_pt.arb | 3 +- res/values/strings_ru.arb | 3 +- res/values/strings_uk.arb | 3 +- res/values/strings_zh.arb | 3 +- 19 files changed, 69 insertions(+), 37 deletions(-) diff --git a/lib/main.dart b/lib/main.dart index cfd242dbf..120871fbd 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -232,18 +232,11 @@ class AppState extends State with SingleTickerProviderStateMixin { void handleDeepLinking(Uri uri) { if (uri == null || !mounted) return; - switch (uri.scheme) { - case "bitcoin": - case "litecoin": - case "haven": - case "monero": - default: - Navigator.pushNamed( - navigatorKey.currentContext, - Routes.send, - arguments: PaymentRequest.fromUri(uri), - ); - } + Navigator.pushNamed( + navigatorKey.currentContext, + Routes.send, + arguments: PaymentRequest.fromUri(uri), + ); } Future _handleInitialUri() async { diff --git a/lib/src/screens/send/widgets/send_card.dart b/lib/src/screens/send/widgets/send_card.dart index 27b3f49dc..063b9d57a 100644 --- a/lib/src/screens/send/widgets/send_card.dart +++ b/lib/src/screens/send/widgets/send_card.dart @@ -1,4 +1,5 @@ import 'dart:ui'; +import 'package:cake_wallet/src/widgets/alert_with_one_action.dart'; import 'package:cake_wallet/utils/payment_request.dart'; import 'package:cw_core/transaction_priority.dart'; import 'package:cake_wallet/routes.dart'; @@ -45,8 +46,8 @@ class SendCardState extends State SendCardState({ @required this.output, @required this.sendViewModel, - PaymentRequest initialPaymentRequest}) - : addressController = TextEditingController(text: initialPaymentRequest?.address), + this.initialPaymentRequest}) + : addressController = TextEditingController(text: initialPaymentRequest?.address?.toLowerCase()), cryptoAmountController = TextEditingController(text: initialPaymentRequest?.amount), fiatAmountController = TextEditingController(), noteController = TextEditingController(), @@ -60,6 +61,7 @@ class SendCardState extends State final Output output; final SendViewModel sendViewModel; + final PaymentRequest initialPaymentRequest; final TextEditingController addressController; final TextEditingController cryptoAmountController; @@ -72,6 +74,27 @@ class SendCardState extends State bool _effectsInstalled = false; + @override + void initState() { + super.initState(); + + /// if the current wallet doesn't match the one in the qr code + if (initialPaymentRequest != null && + sendViewModel.walletCurrencyName != initialPaymentRequest.scheme?.toLowerCase()) { + WidgetsBinding.instance?.addPostFrameCallback((timeStamp) { + showPopUp( + context: context, + builder: (BuildContext context) { + return AlertWithOneAction( + alertTitle: S.of(context).error, + alertContent: S.of(context).unmatched_currencies, + buttonText: S.of(context).ok, + buttonAction: () => Navigator.of(context).pop()); + }); + }); + } + } + @override Widget build(BuildContext context) { super.build(context); @@ -123,11 +146,6 @@ class SendCardState extends State ? sendViewModel.textValidator : sendViewModel.addressValidator; - print("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); - print("444444444444444444444444444444"); - print(addressController.text); - print(cryptoAmountController.text); - return AddressTextField( focusNode: addressFocusNode, controller: addressController, @@ -529,7 +547,8 @@ class SendCardState extends State if (output.address.isNotEmpty) { addressController.text = output.address; } - if (output.cryptoAmount.isNotEmpty) { + if (output.cryptoAmount.isNotEmpty || + sendViewModel.walletCurrencyName != initialPaymentRequest?.scheme?.toLowerCase()) { cryptoAmountController.text = output.cryptoAmount; } fiatAmountController.text = output.fiatAmount; diff --git a/lib/utils/payment_request.dart b/lib/utils/payment_request.dart index d4338a39a..3830c69cb 100644 --- a/lib/utils/payment_request.dart +++ b/lib/utils/payment_request.dart @@ -1,18 +1,21 @@ class PaymentRequest { - PaymentRequest(this.address, this.amount); + PaymentRequest(this.address, this.amount, {this.scheme}); factory PaymentRequest.fromUri(Uri uri) { var address = ""; var amount = ""; + var scheme = ""; if (uri != null) { address = uri.path; amount = uri.queryParameters['tx_amount'] ?? uri.queryParameters['amount'] ?? ""; + scheme = uri.scheme; } - return PaymentRequest(address, amount); + return PaymentRequest(address, amount, scheme: scheme); } final String address; final String amount; + final String scheme; } \ No newline at end of file diff --git a/lib/view_model/send/send_view_model.dart b/lib/view_model/send/send_view_model.dart index b615c00c4..1b06d2421 100644 --- a/lib/view_model/send/send_view_model.dart +++ b/lib/view_model/send/send_view_model.dart @@ -157,6 +157,8 @@ abstract class SendViewModelBase with Store { WalletType get walletType => _wallet.type; + String get walletCurrencyName => _wallet.currency.name.toLowerCase(); + bool get hasCurrecyChanger => walletType == WalletType.haven; final WalletBase _wallet; diff --git a/res/values/strings_de.arb b/res/values/strings_de.arb index d9687bc36..7791563f9 100644 --- a/res/values/strings_de.arb +++ b/res/values/strings_de.arb @@ -632,5 +632,6 @@ "gift_card_is_generated": "Geschenkkarte wird generiert", "open_gift_card": "Geschenkkarte öffnen", "contact_support": "Support kontaktieren", - "gift_cards_unavailable": "Geschenkkarten können derzeit nur über Monero, Bitcoin und Litecoin erworben werden" + "gift_cards_unavailable": "Geschenkkarten können derzeit nur über Monero, Bitcoin und Litecoin erworben werden", + "unmatched_currencies": "Die Währung Ihres aktuellen Wallets stimmt nicht mit der des gescannten QR überein" } diff --git a/res/values/strings_en.arb b/res/values/strings_en.arb index 9fc0b743e..ff88286ac 100644 --- a/res/values/strings_en.arb +++ b/res/values/strings_en.arb @@ -632,5 +632,6 @@ "gift_card_is_generated": "Gift Card is generated", "open_gift_card": "Open Gift Card", "contact_support": "Contact Support", - "gift_cards_unavailable": "Gift cards are available for purchase only with Monero, Bitcoin, and Litecoin at this time" + "gift_cards_unavailable": "Gift cards are available for purchase only with Monero, Bitcoin, and Litecoin at this time", + "unmatched_currencies": "Your current wallet's currency does not match that of the scanned QR" } diff --git a/res/values/strings_es.arb b/res/values/strings_es.arb index 084658081..685770f13 100644 --- a/res/values/strings_es.arb +++ b/res/values/strings_es.arb @@ -632,5 +632,6 @@ "gift_card_is_generated": "Se genera la tarjeta de regalo", "open_gift_card": "Abrir tarjeta de regalo", "contact_support": "Contactar con Soporte", - "gift_cards_unavailable": "Las tarjetas de regalo están disponibles para comprar solo a través de Monero, Bitcoin y Litecoin en este momento" + "gift_cards_unavailable": "Las tarjetas de regalo están disponibles para comprar solo a través de Monero, Bitcoin y Litecoin en este momento", + "unmatched_currencies": "La moneda de su billetera actual no coincide con la del QR escaneado" } diff --git a/res/values/strings_fr.arb b/res/values/strings_fr.arb index 9817e7bef..e348912df 100644 --- a/res/values/strings_fr.arb +++ b/res/values/strings_fr.arb @@ -630,5 +630,6 @@ "gift_card_is_generated": "La carte-cadeau est générée", "open_gift_card": "Ouvrir la carte-cadeau", "contact_support": "Contacter l'assistance", - "gift_cards_unavailable": "Les cartes-cadeaux ne sont disponibles à l'achat que via Monero, Bitcoin et Litecoin pour le moment" + "gift_cards_unavailable": "Les cartes-cadeaux ne sont disponibles à l'achat que via Monero, Bitcoin et Litecoin pour le moment", + "unmatched_currencies": "La devise de votre portefeuille actuel ne correspond pas à celle du QR scanné" } diff --git a/res/values/strings_hi.arb b/res/values/strings_hi.arb index 03a891169..22e429b7e 100644 --- a/res/values/strings_hi.arb +++ b/res/values/strings_hi.arb @@ -632,5 +632,6 @@ "gift_card_is_generated": "गिफ्ट कार्ड जनरेट हुआ", "open_gift_card": "गिफ्ट कार्ड खोलें", "contact_support": "सहायता से संपर्क करें", - "gift_cards_unavailable": "उपहार कार्ड इस समय केवल मोनेरो, बिटकॉइन और लिटकोइन के माध्यम से खरीदने के लिए उपलब्ध हैं" + "gift_cards_unavailable": "उपहार कार्ड इस समय केवल मोनेरो, बिटकॉइन और लिटकोइन के माध्यम से खरीदने के लिए उपलब्ध हैं", + "unmatched_currencies": "आपके वर्तमान वॉलेट की मुद्रा स्कैन किए गए क्यूआर से मेल नहीं खाती" } diff --git a/res/values/strings_hr.arb b/res/values/strings_hr.arb index c25b54eb8..ea29a7491 100644 --- a/res/values/strings_hr.arb +++ b/res/values/strings_hr.arb @@ -632,5 +632,6 @@ "gift_card_is_generated": "Poklon kartica je generirana", "open_gift_card": "Otvori darovnu karticu", "contact_support": "Kontaktirajte podršku", - "gift_cards_unavailable": "Poklon kartice trenutno su dostupne za kupnju samo putem Monera, Bitcoina i Litecoina" + "gift_cards_unavailable": "Poklon kartice trenutno su dostupne za kupnju samo putem Monera, Bitcoina i Litecoina", + "unmatched_currencies": "Valuta vašeg trenutnog novčanika ne odgovara onoj na skeniranom QR-u" } diff --git a/res/values/strings_it.arb b/res/values/strings_it.arb index 8383c9ad9..2e0793283 100644 --- a/res/values/strings_it.arb +++ b/res/values/strings_it.arb @@ -632,5 +632,6 @@ "gift_card_is_generated": "Il buono regalo è stato generato", "open_gift_card": "Apri carta regalo", "contact_support": "Contatta l'assistenza", - "gift_cards_unavailable": "Le carte regalo sono disponibili per l'acquisto solo tramite Monero, Bitcoin e Litecoin in questo momento" + "gift_cards_unavailable": "Le carte regalo sono disponibili per l'acquisto solo tramite Monero, Bitcoin e Litecoin in questo momento", + "unmatched_currencies": "La valuta del tuo portafoglio attuale non corrisponde a quella del QR scansionato" } diff --git a/res/values/strings_ja.arb b/res/values/strings_ja.arb index 0ee7b5f29..e0bd967e9 100644 --- a/res/values/strings_ja.arb +++ b/res/values/strings_ja.arb @@ -632,5 +632,6 @@ "gift_card_is_generated": "ギフトカードが生成されます", "open_gift_card": "オープンギフトカード", "contact_support": "サポートに連絡する", - "gift_cards_unavailable": "現時点では、ギフトカードはMonero、Bitcoin、Litecoinからのみ購入できます。" + "gift_cards_unavailable": "現時点では、ギフトカードはMonero、Bitcoin、Litecoinからのみ購入できます。", + "unmatched_currencies": "現在のウォレットの通貨がスキャンされたQRの通貨と一致しません" } diff --git a/res/values/strings_ko.arb b/res/values/strings_ko.arb index d7ee849aa..5f60de560 100644 --- a/res/values/strings_ko.arb +++ b/res/values/strings_ko.arb @@ -632,5 +632,6 @@ "gift_card_is_generated": "기프트 카드가 생성되었습니다", "open_gift_card": "기프트 카드 열기", "contact_support": "지원팀에 문의", - "gift_cards_unavailable": "기프트 카드는 현재 Monero, Bitcoin 및 Litecoin을 통해서만 구매할 수 있습니다." + "gift_cards_unavailable": "기프트 카드는 현재 Monero, Bitcoin 및 Litecoin을 통해서만 구매할 수 있습니다.", + "unmatched_currencies": "현재 지갑의 통화가 스캔한 QR의 통화와 일치하지 않습니다." } diff --git a/res/values/strings_nl.arb b/res/values/strings_nl.arb index 967cf1e38..e9c43fc01 100644 --- a/res/values/strings_nl.arb +++ b/res/values/strings_nl.arb @@ -632,5 +632,6 @@ "gift_card_is_generated": "Cadeaukaart is gegenereerd", "open_gift_card": "Geschenkkaart openen", "contact_support": "Contact opnemen met ondersteuning", - "gift_cards_unavailable": "Cadeaubonnen kunnen momenteel alleen worden gekocht via Monero, Bitcoin en Litecoin" + "gift_cards_unavailable": "Cadeaubonnen kunnen momenteel alleen worden gekocht via Monero, Bitcoin en Litecoin", + "unmatched_currencies": "De valuta van uw huidige portemonnee komt niet overeen met die van de gescande QR" } diff --git a/res/values/strings_pl.arb b/res/values/strings_pl.arb index be58b6a17..42bdcde86 100644 --- a/res/values/strings_pl.arb +++ b/res/values/strings_pl.arb @@ -632,5 +632,6 @@ "gift_card_is_generated": "Karta podarunkowa jest generowana", "open_gift_card": "Otwórz kartę podarunkową", "contact_support": "Skontaktuj się z pomocą techniczną", - "gift_cards_unavailable": "Karty podarunkowe można obecnie kupić tylko za pośrednictwem Monero, Bitcoin i Litecoin" + "gift_cards_unavailable": "Karty podarunkowe można obecnie kupić tylko za pośrednictwem Monero, Bitcoin i Litecoin", + "unmatched_currencies": "Waluta Twojego obecnego portfela nie odpowiada walucie zeskanowanego kodu QR" } diff --git a/res/values/strings_pt.arb b/res/values/strings_pt.arb index 50aa25100..8d2d52ded 100644 --- a/res/values/strings_pt.arb +++ b/res/values/strings_pt.arb @@ -632,5 +632,6 @@ "gift_card_is_generated": "Cartão presente é gerado", "open_gift_card": "Abrir vale-presente", "contact_support": "Contatar Suporte", - "gift_cards_unavailable": "Os cartões-presente estão disponíveis para compra apenas através do Monero, Bitcoin e Litecoin no momento" + "gift_cards_unavailable": "Os cartões-presente estão disponíveis para compra apenas através do Monero, Bitcoin e Litecoin no momento", + "unmatched_currencies": "A moeda da sua carteira atual não corresponde à do QR digitalizado" } diff --git a/res/values/strings_ru.arb b/res/values/strings_ru.arb index ce8109512..0cd899be4 100644 --- a/res/values/strings_ru.arb +++ b/res/values/strings_ru.arb @@ -632,5 +632,6 @@ "gift_card_is_generated": "Подарочная карта сгенерирована", "open_gift_card": "Открыть подарочную карту", "contact_support": "Связаться со службой поддержки", - "gift_cards_unavailable": "В настоящее время подарочные карты можно приобрести только через Monero, Bitcoin и Litecoin." + "gift_cards_unavailable": "В настоящее время подарочные карты можно приобрести только через Monero, Bitcoin и Litecoin.", + "unmatched_currencies": "Валюта вашего текущего кошелька не соответствует валюте отсканированного QR-кода." } diff --git a/res/values/strings_uk.arb b/res/values/strings_uk.arb index 04e270d57..8ca95cae4 100644 --- a/res/values/strings_uk.arb +++ b/res/values/strings_uk.arb @@ -631,5 +631,6 @@ "gift_card_is_generated": "Подарункова картка створена", "open_gift_card": "Відкрити подарункову картку", "contact_support": "Звернутися до служби підтримки", - "gift_cards_unavailable": "Наразі подарункові картки можна придбати лише через Monero, Bitcoin і Litecoin" + "gift_cards_unavailable": "Наразі подарункові картки можна придбати лише через Monero, Bitcoin і Litecoin", + "unmatched_currencies": "Валюта вашого гаманця не збігається з валютою сканованого QR-коду" } diff --git a/res/values/strings_zh.arb b/res/values/strings_zh.arb index 14af48137..2c5eb6dfc 100644 --- a/res/values/strings_zh.arb +++ b/res/values/strings_zh.arb @@ -630,5 +630,6 @@ "gift_card_is_generated": "礼品卡生成", "open_gift_card": "打开礼品卡", "contact_support": "联系支持", - "gift_cards_unavailable": "目前只能通过门罗币、比特币和莱特币购买礼品卡" + "gift_cards_unavailable": "目前只能通过门罗币、比特币和莱特币购买礼品卡", + "unmatched_currencies": "您当前钱包的货币与扫描的 QR 的货币不匹配" } From 13a95ab11f6205f312d101e47f6e4d4aa6c1aee6 Mon Sep 17 00:00:00 2001 From: Godwin Asuquo Date: Tue, 6 Sep 2022 09:09:44 +0300 Subject: [PATCH 04/12] fix color for login back button --- lib/src/screens/ionia/auth/ionia_login_page.dart | 3 --- 1 file changed, 3 deletions(-) diff --git a/lib/src/screens/ionia/auth/ionia_login_page.dart b/lib/src/screens/ionia/auth/ionia_login_page.dart index bcbc0fee3..44df933b5 100644 --- a/lib/src/screens/ionia/auth/ionia_login_page.dart +++ b/lib/src/screens/ionia/auth/ionia_login_page.dart @@ -26,9 +26,6 @@ class IoniaLoginPage extends BasePage { final IoniaAuthViewModel _authViewModel; - @override - Color get titleColor => Colors.black; - final TextEditingController _emailController; @override From 406707fa5862cdb5de832ccd5378ad9b1c283fd1 Mon Sep 17 00:00:00 2001 From: Godwin Asuquo Date: Tue, 13 Sep 2022 08:13:20 +0300 Subject: [PATCH 05/12] fix partial redemption --- lib/src/screens/ionia/cards/ionia_custom_redeem_page.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/src/screens/ionia/cards/ionia_custom_redeem_page.dart b/lib/src/screens/ionia/cards/ionia_custom_redeem_page.dart index 4bb76848f..c85108be4 100644 --- a/lib/src/screens/ionia/cards/ionia_custom_redeem_page.dart +++ b/lib/src/screens/ionia/cards/ionia_custom_redeem_page.dart @@ -149,7 +149,7 @@ class IoniaCustomRedeemPage extends BasePage { padding: EdgeInsets.only(bottom: 12), child: PrimaryButton( onPressed: () { - Navigator.of(context).pop(_amountController.text); + Navigator.of(context).pop(ioniaCustomRedeemViewModel.remaining.toString()); }, isDisabled: ioniaCustomRedeemViewModel.disableRedeem, text: S.of(context).add_custom_redemption, From f078457c7b6eab9cb8977b777727e366e090f636 Mon Sep 17 00:00:00 2001 From: OmarHatem Date: Tue, 8 Nov 2022 16:56:27 +0200 Subject: [PATCH 06/12] Update Branch to null safety Add deep linking to iOS --- android/app/src/main/AndroidManifestBase.xml | 2 +- ios/Runner/InfoBase.plist | 54 +++++++++++++++----- lib/di.dart | 4 +- lib/main.dart | 29 +++++++---- lib/router.dart | 2 +- lib/src/screens/send/widgets/send_card.dart | 9 ++-- lib/utils/payment_request.dart | 6 +-- lib/view_model/send/send_view_model.dart | 4 +- 8 files changed, 74 insertions(+), 36 deletions(-) diff --git a/android/app/src/main/AndroidManifestBase.xml b/android/app/src/main/AndroidManifestBase.xml index f4023f532..8d94ba24f 100644 --- a/android/app/src/main/AndroidManifestBase.xml +++ b/android/app/src/main/AndroidManifestBase.xml @@ -38,7 +38,7 @@ android:scheme="cakewallet" android:host="y.at" /> - + diff --git a/ios/Runner/InfoBase.plist b/ios/Runner/InfoBase.plist index ad8816ca3..794391665 100644 --- a/ios/Runner/InfoBase.plist +++ b/ios/Runner/InfoBase.plist @@ -21,18 +21,48 @@ CFBundleSignature ???? CFBundleURLTypes - - - CFBundleTypeRole - Editor - CFBundleURLName - y.at - CFBundleURLSchemes - - cakewallet - - - + + + CFBundleTypeRole + Editor + CFBundleURLName + y.at + CFBundleURLSchemes + + cakewallet + + + + CFBundleTypeRole + Editor + CFBundleURLName + bitcoin + CFBundleURLSchemes + + bitcoin + + + + CFBundleTypeRole + Editor + CFBundleURLName + monero + CFBundleURLSchemes + + monero + + + + CFBundleTypeRole + Editor + CFBundleURLName + litecoin + CFBundleURLSchemes + + litecoin + + + CFBundleVersion $(CURRENT_PROJECT_VERSION) LSRequiresIPhoneOS diff --git a/lib/di.dart b/lib/di.dart index 9a554b25a..3481d783e 100644 --- a/lib/di.dart +++ b/lib/di.dart @@ -377,8 +377,8 @@ Future setup( getIt.get(), _transactionDescriptionBox)); - getIt.registerFactoryParam( - (PaymentRequest initialPaymentRequest, _) => SendPage( + getIt.registerFactoryParam( + (PaymentRequest? initialPaymentRequest, _) => SendPage( sendViewModel: getIt.get(), settingsViewModel: getIt.get(), initialPaymentRequest: initialPaymentRequest, diff --git a/lib/main.dart b/lib/main.dart index 7a3cc5ffe..8e971ec4b 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -39,6 +39,8 @@ import 'package:cw_core/unspent_coins_info.dart'; import 'package:cake_wallet/monero/monero.dart'; import 'package:cake_wallet/wallet_type_utils.dart'; +import 'src/screens/auth/auth_page.dart'; + final navigatorKey = GlobalKey(); final rootKey = GlobalKey(); @@ -213,15 +215,15 @@ class AppState extends State with SingleTickerProviderStateMixin { super.dispose(); } - /// handle app links while the app is already started - be it in - /// the foreground or in the background. + /// handle app links while the app is already started + /// whether its in the foreground or in the background. Future initUniLinks() async { try { - stream = getUriLinksStream().listen((Uri uri) { + stream = uriLinkStream.listen((Uri? uri) { handleDeepLinking(uri); }); - final Uri initialUri = await getInitialUri(); + final Uri? initialUri = await getInitialUri(); handleDeepLinking(initialUri); } catch (e) { @@ -229,14 +231,21 @@ class AppState extends State with SingleTickerProviderStateMixin { } } - void handleDeepLinking(Uri uri) { + void handleDeepLinking(Uri? uri) { if (uri == null || !mounted) return; - Navigator.pushNamed( - navigatorKey.currentContext, - Routes.send, - arguments: PaymentRequest.fromUri(uri), - ); + Navigator.of(navigatorKey.currentContext!).pushNamed(Routes.auth, + arguments: (bool isAuthenticatedSuccessfully, AuthPageState auth) { + if (isAuthenticatedSuccessfully) { + auth.close(route: Routes.send, arguments: PaymentRequest.fromUri(uri)); + } + }); + + // Navigator.pushNamed( + // navigatorKey.currentContext!, + // Routes.send, + // arguments: PaymentRequest.fromUri(uri), + // ); } Future _handleInitialUri() async { diff --git a/lib/router.dart b/lib/router.dart index 08c91db22..065e91a31 100644 --- a/lib/router.dart +++ b/lib/router.dart @@ -210,7 +210,7 @@ Route createRoute(RouteSettings settings) { builder: (_) => getIt.get()); case Routes.send: - final initialPaymentRequest = settings.arguments as PaymentRequest; + final initialPaymentRequest = settings.arguments as PaymentRequest?; return CupertinoPageRoute( fullscreenDialog: true, builder: (_) => getIt.get( diff --git a/lib/src/screens/send/widgets/send_card.dart b/lib/src/screens/send/widgets/send_card.dart index acc53e782..07b33843a 100644 --- a/lib/src/screens/send/widgets/send_card.dart +++ b/lib/src/screens/send/widgets/send_card.dart @@ -1,4 +1,3 @@ -import 'dart:ui'; import 'package:cake_wallet/src/widgets/alert_with_one_action.dart'; import 'package:cake_wallet/utils/payment_request.dart'; import 'package:cw_core/transaction_priority.dart'; @@ -44,7 +43,7 @@ class SendCardState extends State required this.output, required this.sendViewModel, this.initialPaymentRequest}) - : addressController = TextEditingController(text: initialPaymentRequest?.address?.toLowerCase()), + : addressController = TextEditingController(text: initialPaymentRequest?.address.toLowerCase()), cryptoAmountController = TextEditingController(text: initialPaymentRequest?.amount), fiatAmountController = TextEditingController(), noteController = TextEditingController(), @@ -77,8 +76,8 @@ class SendCardState extends State /// if the current wallet doesn't match the one in the qr code if (initialPaymentRequest != null && - sendViewModel.walletCurrencyName != initialPaymentRequest.scheme?.toLowerCase()) { - WidgetsBinding.instance?.addPostFrameCallback((timeStamp) { + sendViewModel.walletCurrencyName != initialPaymentRequest!.scheme.toLowerCase()) { + WidgetsBinding.instance.addPostFrameCallback((timeStamp) { showPopUp( context: context, builder: (BuildContext context) { @@ -544,7 +543,7 @@ class SendCardState extends State addressController.text = output.address; } if (output.cryptoAmount.isNotEmpty || - sendViewModel.walletCurrencyName != initialPaymentRequest?.scheme?.toLowerCase()) { + sendViewModel.walletCurrencyName != initialPaymentRequest?.scheme.toLowerCase()) { cryptoAmountController.text = output.cryptoAmount; } fiatAmountController.text = output.fiatAmount; diff --git a/lib/utils/payment_request.dart b/lib/utils/payment_request.dart index 0a6306cd8..88730f037 100644 --- a/lib/utils/payment_request.dart +++ b/lib/utils/payment_request.dart @@ -1,7 +1,7 @@ class PaymentRequest { - PaymentRequest(this.address, this.amount, this.note, {this.scheme}); + PaymentRequest(this.address, this.amount, this.note, this.scheme); - factory PaymentRequest.fromUri(Uri uri) { + factory PaymentRequest.fromUri(Uri? uri) { var address = ""; var amount = ""; var note = ""; @@ -15,7 +15,7 @@ class PaymentRequest { scheme = uri.scheme; } - return PaymentRequest(address, amount, note, scheme: scheme); + return PaymentRequest(address, amount, note, scheme); } final String address; diff --git a/lib/view_model/send/send_view_model.dart b/lib/view_model/send/send_view_model.dart index a17635a89..5632f8855 100644 --- a/lib/view_model/send/send_view_model.dart +++ b/lib/view_model/send/send_view_model.dart @@ -137,7 +137,7 @@ abstract class SendViewModelBase with Store { PendingTransaction? pendingTransaction; @computed - String get balance => balanceViewModel.availableBalance ?? '0.0'; + String get balance => balanceViewModel.availableBalance; @computed bool get isReadyForSend => _wallet.syncStatus is SyncedSyncStatus; @@ -164,7 +164,7 @@ abstract class SendViewModelBase with Store { WalletType get walletType => _wallet.type; - String get walletCurrencyName => _wallet.currency.name.toLowerCase(); + String? get walletCurrencyName => _wallet.currency.name?.toLowerCase(); bool get hasCurrecyChanger => walletType == WalletType.haven; From f68798dd197b3a09ac3b23f59c45fef959785562 Mon Sep 17 00:00:00 2001 From: OmarHatem Date: Tue, 8 Nov 2022 18:12:01 +0200 Subject: [PATCH 07/12] Move handling deep links to app root --- lib/main.dart | 44 ---------------------------------- lib/src/screens/root/root.dart | 39 +++++++++++++++++++++++++++++- 2 files changed, 38 insertions(+), 45 deletions(-) diff --git a/lib/main.dart b/lib/main.dart index 8e971ec4b..6431d2f6e 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -5,7 +5,6 @@ import 'package:cake_wallet/buy/order.dart'; import 'package:cake_wallet/ionia/ionia_category.dart'; import 'package:cake_wallet/ionia/ionia_merchant.dart'; import 'package:cake_wallet/store/yat/yat_store.dart'; -import 'package:cake_wallet/utils/payment_request.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; @@ -39,8 +38,6 @@ import 'package:cw_core/unspent_coins_info.dart'; import 'package:cake_wallet/monero/monero.dart'; import 'package:cake_wallet/wallet_type_utils.dart'; -import 'src/screens/auth/auth_page.dart'; - final navigatorKey = GlobalKey(); final rootKey = GlobalKey(); @@ -205,47 +202,6 @@ class AppState extends State with SingleTickerProviderStateMixin { super.initState(); //_handleIncomingLinks(); //_handleInitialUri(); - - initUniLinks(); - } - - @override - void dispose() { - stream?.cancel(); - super.dispose(); - } - - /// handle app links while the app is already started - /// whether its in the foreground or in the background. - Future initUniLinks() async { - try { - stream = uriLinkStream.listen((Uri? uri) { - handleDeepLinking(uri); - }); - - final Uri? initialUri = await getInitialUri(); - - handleDeepLinking(initialUri); - } catch (e) { - print(e); - } - } - - void handleDeepLinking(Uri? uri) { - if (uri == null || !mounted) return; - - Navigator.of(navigatorKey.currentContext!).pushNamed(Routes.auth, - arguments: (bool isAuthenticatedSuccessfully, AuthPageState auth) { - if (isAuthenticatedSuccessfully) { - auth.close(route: Routes.send, arguments: PaymentRequest.fromUri(uri)); - } - }); - - // Navigator.pushNamed( - // navigatorKey.currentContext!, - // Routes.send, - // arguments: PaymentRequest.fromUri(uri), - // ); } Future _handleInitialUri() async { diff --git a/lib/src/screens/root/root.dart b/lib/src/screens/root/root.dart index c507f6e1f..014dd0451 100644 --- a/lib/src/screens/root/root.dart +++ b/lib/src/screens/root/root.dart @@ -1,10 +1,12 @@ import 'dart:async'; +import 'package:cake_wallet/utils/payment_request.dart'; import 'package:flutter/material.dart'; import 'package:cake_wallet/routes.dart'; import 'package:cake_wallet/src/screens/auth/auth_page.dart'; import 'package:cake_wallet/store/app_store.dart'; import 'package:cake_wallet/store/authentication_store.dart'; import 'package:cake_wallet/entities/qr_scanner.dart'; +import 'package:uni_links/uni_links.dart'; class Root extends StatefulWidget { Root( @@ -35,6 +37,9 @@ class RootState extends State with WidgetsBindingObserver { bool _isInactive; bool _postFrameCallback; + StreamSubscription? stream; + Uri? launchUri; + @override void initState() { _isInactiveController = StreamController.broadcast(); @@ -42,6 +47,34 @@ class RootState extends State with WidgetsBindingObserver { _postFrameCallback = false; WidgetsBinding.instance.addObserver(this); super.initState(); + + initUniLinks(); + } + + @override + void dispose() { + stream?.cancel(); + super.dispose(); + } + + /// handle app links while the app is already started + /// whether its in the foreground or in the background. + Future initUniLinks() async { + try { + stream = uriLinkStream.listen((Uri? uri) { + handleDeepLinking(uri); + }); + + handleDeepLinking(await getInitialUri()); + } catch (e) { + print(e); + } + } + + void handleDeepLinking(Uri? uri) { + if (uri == null || !mounted) return; + + launchUri = uri; } @override @@ -75,7 +108,11 @@ class RootState extends State with WidgetsBindingObserver { } _reset(); - auth.close(); + auth.close( + route: launchUri != null ? Routes.send : null, + arguments: PaymentRequest.fromUri(launchUri), + ); + launchUri = null; }); }); } From 8511805ee35fca9ddbf5818fb50622dc305c180b Mon Sep 17 00:00:00 2001 From: Godwin Asuquo Date: Wed, 30 Nov 2022 10:00:05 +0200 Subject: [PATCH 08/12] Fix correct adjusted amount for custom redeem --- lib/ionia/ionia_gift_card.dart | 2 +- lib/ionia/ionia_service.dart | 4 +-- .../ionia/cards/ionia_custom_redeem_page.dart | 2 +- .../cards/ionia_gift_card_detail_page.dart | 28 +++++++++---------- .../ionia/cards/ionia_more_options_page.dart | 6 ++-- .../ionia/widgets/ionia_filter_modal.dart | 2 +- .../ionia_gift_card_details_view_model.dart | 10 +++++-- 7 files changed, 29 insertions(+), 25 deletions(-) diff --git a/lib/ionia/ionia_gift_card.dart b/lib/ionia/ionia_gift_card.dart index b729e261f..04b45b907 100644 --- a/lib/ionia/ionia_gift_card.dart +++ b/lib/ionia/ionia_gift_card.dart @@ -37,7 +37,7 @@ class IoniaGiftCard { purchaseAmount: element['PurchaseAmount'] as double, actualAmount: element['ActualAmount'] as double, totalTransactionAmount: element['TotalTransactionAmount'] as double, - totalDashTransactionAmount: element['TotalDashTransactionAmount'] as double, + totalDashTransactionAmount: element['TotalDashTransactionAmount'] != null ? element['TotalDashTransactionAmount'] as double : 0.0, remainingAmount: element['RemainingAmount'] as double, isActive: element['IsActive'] as bool, isEmpty: element['IsEmpty'] as bool, diff --git a/lib/ionia/ionia_service.dart b/lib/ionia/ionia_service.dart index 942bc25b5..51e23ad28 100644 --- a/lib/ionia/ionia_service.dart +++ b/lib/ionia/ionia_service.dart @@ -148,8 +148,8 @@ class IoniaService { // Redeem - Future redeem(IoniaGiftCard giftCard) async { - await chargeGiftCard(giftCardId: giftCard.id, amount: giftCard.remainingAmount); + Future redeem({required int giftCardId, required double amount}) async { + await chargeGiftCard(giftCardId: giftCardId, amount: amount); } // Get Gift Card diff --git a/lib/src/screens/ionia/cards/ionia_custom_redeem_page.dart b/lib/src/screens/ionia/cards/ionia_custom_redeem_page.dart index 53e41ff22..f9ce0ae88 100644 --- a/lib/src/screens/ionia/cards/ionia_custom_redeem_page.dart +++ b/lib/src/screens/ionia/cards/ionia_custom_redeem_page.dart @@ -149,7 +149,7 @@ class IoniaCustomRedeemPage extends BasePage { padding: EdgeInsets.only(bottom: 12), child: PrimaryButton( onPressed: () { - Navigator.of(context).pop(ioniaCustomRedeemViewModel.remaining.toString()); + Navigator.of(context).pop([ioniaCustomRedeemViewModel.remaining.toString(), ioniaCustomRedeemViewModel.amount.toString()]); }, isDisabled: ioniaCustomRedeemViewModel.disableRedeem, text: S.of(context).add_custom_redemption, diff --git a/lib/src/screens/ionia/cards/ionia_gift_card_detail_page.dart b/lib/src/screens/ionia/cards/ionia_gift_card_detail_page.dart index 1c768fa17..2e7162e40 100644 --- a/lib/src/screens/ionia/cards/ionia_gift_card_detail_page.dart +++ b/lib/src/screens/ionia/cards/ionia_gift_card_detail_page.dart @@ -130,19 +130,19 @@ class IoniaGiftCardDetailPage extends BasePage { if (!viewModel.giftCard.isEmpty) { return Column( children: [ - //PrimaryButton( - // onPressed: () async { - // final amount = await Navigator.of(context) - // .pushNamed(Routes.ioniaMoreOptionsPage, arguments: [viewModel.giftCard]) as String; - // if (amount != null) { - // viewModel.updateRemaining(double.parse(amount)); - // } - // }, - // text: S.of(context).more_options, - // color: Theme.of(context).accentTextTheme!.caption!.color!, - // textColor: Theme.of(context).primaryTextTheme!.headline6!.color!, - //), - //SizedBox(height: 12), + PrimaryButton( + onPressed: () async { + final amount = await Navigator.of(context) + .pushNamed(Routes.ioniaMoreOptionsPage, arguments: [viewModel.giftCard]) as List?; + if (amount != null) { + viewModel.updateRemaining( balance: double.parse(amount.first), customAmount: double.parse(amount.last)); + } + }, + text: S.of(context).more_options, + color: Theme.of(context).accentTextTheme.caption!.color!, + textColor: Theme.of(context).primaryTextTheme.headline6!.color!, + ), + SizedBox(height: 12), LoadingPrimaryButton( isLoading: viewModel.redeemState is IsExecutingState, onPressed: () => viewModel.redeem().then( @@ -152,7 +152,7 @@ class IoniaGiftCardDetailPage extends BasePage { }, ), text: S.of(context).mark_as_redeemed, - color: Theme.of(context).accentTextTheme!.bodyText1!.color!, + color: Theme.of(context).accentTextTheme.bodyText1!.color!, textColor: Colors.white, ), ], diff --git a/lib/src/screens/ionia/cards/ionia_more_options_page.dart b/lib/src/screens/ionia/cards/ionia_more_options_page.dart index 84f0bed30..d4e378f84 100644 --- a/lib/src/screens/ionia/cards/ionia_more_options_page.dart +++ b/lib/src/screens/ionia/cards/ionia_more_options_page.dart @@ -35,9 +35,9 @@ class IoniaMoreOptionsPage extends BasePage { SizedBox(height: 40,), InkWell( onTap: () async { - final amount = await Navigator.of(context).pushNamed(Routes.ioniaCustomRedeemPage, arguments: [giftCard]) as String; - if(amount.isNotEmpty){ - Navigator.pop(context, amount); + final amounts = await Navigator.of(context).pushNamed(Routes.ioniaCustomRedeemPage, arguments: [giftCard]) as List; + if(amounts.first.isNotEmpty){ + Navigator.pop(context, amounts); } }, child: _GradiantContainer( diff --git a/lib/src/screens/ionia/widgets/ionia_filter_modal.dart b/lib/src/screens/ionia/widgets/ionia_filter_modal.dart index ec6e84cc0..b6bcac070 100644 --- a/lib/src/screens/ionia/widgets/ionia_filter_modal.dart +++ b/lib/src/screens/ionia/widgets/ionia_filter_modal.dart @@ -53,7 +53,7 @@ class IoniaFilterModal extends StatelessWidget { prefixIcon: searchIcon, hintText: S.of(context).search_category, contentPadding: EdgeInsets.only(bottom: 5), - fillColor: Theme.of(context).textTheme!.subtitle1!.backgroundColor!, + fillColor: Theme.of(context).textTheme.subtitle1?.backgroundColor, border: OutlineInputBorder( borderSide: BorderSide.none, borderRadius: BorderRadius.circular(8), diff --git a/lib/view_model/ionia/ionia_gift_card_details_view_model.dart b/lib/view_model/ionia/ionia_gift_card_details_view_model.dart index 8e0a2795b..745f2d530 100644 --- a/lib/view_model/ionia/ionia_gift_card_details_view_model.dart +++ b/lib/view_model/ionia/ionia_gift_card_details_view_model.dart @@ -15,6 +15,7 @@ abstract class IoniaGiftCardDetailsViewModelBase with Store { required this.giftCard}) : redeemState = InitialExecutionState(), remainingAmount = giftCard.remainingAmount, + adjustedAmount = 0, brightness = 0; final IoniaService ioniaService; @@ -27,6 +28,8 @@ abstract class IoniaGiftCardDetailsViewModelBase with Store { @observable double remainingAmount; + double adjustedAmount; + @observable ExecutionState redeemState; @@ -35,7 +38,7 @@ abstract class IoniaGiftCardDetailsViewModelBase with Store { giftCard.remainingAmount = remainingAmount; try { redeemState = IsExecutingState(); - await ioniaService.redeem(giftCard); + await ioniaService.redeem(giftCardId: giftCard.id, amount : adjustedAmount > 0 ? adjustedAmount : giftCard.remainingAmount); giftCard = await ioniaService.getGiftCard(id: giftCard.id); redeemState = ExecutedSuccessfullyState(); } catch(e) { @@ -44,8 +47,9 @@ abstract class IoniaGiftCardDetailsViewModelBase with Store { } @action - void updateRemaining(double amount){ - remainingAmount = amount; + void updateRemaining({required double balance, required double customAmount}) { + remainingAmount = balance; + adjustedAmount = customAmount; } void increaseBrightness() async { From 0203f686c555581308c6bf25c05622606782d56f Mon Sep 17 00:00:00 2001 From: Godwin Asuquo Date: Wed, 7 Dec 2022 18:12:45 +0100 Subject: [PATCH 09/12] fix issue with custom redeem amount remaining --- lib/di.dart | 3 +- .../ionia/cards/ionia_custom_redeem_page.dart | 69 ++++++++++-------- .../cards/ionia_gift_card_detail_page.dart | 70 +++++++++---------- .../ionia/cards/ionia_more_options_page.dart | 67 ++++++++++-------- .../ionia/ionia_custom_redeem_view_model.dart | 36 ++++++++-- .../ionia_gift_card_details_view_model.dart | 33 ++++----- 6 files changed, 156 insertions(+), 122 deletions(-) diff --git a/lib/di.dart b/lib/di.dart index 90549cf6f..910feae4a 100644 --- a/lib/di.dart +++ b/lib/di.dart @@ -760,7 +760,8 @@ Future setup( return IoniaMoreOptionsPage(giftCard); }); - getIt.registerFactoryParam((IoniaGiftCard giftCard, _) => IoniaCustomRedeemViewModel(giftCard)); + getIt.registerFactoryParam((IoniaGiftCard giftCard, _) + => IoniaCustomRedeemViewModel(giftCard: giftCard, ioniaService: getIt.get())); getIt.registerFactoryParam((List args, _){ final giftCard = args.first as IoniaGiftCard; diff --git a/lib/src/screens/ionia/cards/ionia_custom_redeem_page.dart b/lib/src/screens/ionia/cards/ionia_custom_redeem_page.dart index f9ce0ae88..f2702d791 100644 --- a/lib/src/screens/ionia/cards/ionia_custom_redeem_page.dart +++ b/lib/src/screens/ionia/cards/ionia_custom_redeem_page.dart @@ -1,3 +1,4 @@ +import 'package:cake_wallet/core/execution_state.dart'; import 'package:cake_wallet/src/screens/base_page.dart'; import 'package:cake_wallet/src/screens/ionia/widgets/card_item.dart'; import 'package:cake_wallet/src/widgets/base_text_form_field.dart'; @@ -18,12 +19,11 @@ class IoniaCustomRedeemPage extends BasePage { ) : _amountFieldFocus = FocusNode(), _amountController = TextEditingController() { _amountController.addListener(() { - ioniaCustomRedeemViewModel.updateAmount(_amountController.text); + ioniaCustomRedeemViewModel.updateAmount(_amountController.text); }); } final IoniaCustomRedeemViewModel ioniaCustomRedeemViewModel; - @override String get title => S.current.custom_redeem_amount; @@ -50,7 +50,7 @@ class IoniaCustomRedeemPage extends BasePage { disableScroll: true, config: KeyboardActionsConfig( keyboardActionsPlatform: KeyboardActionsPlatform.IOS, - keyboardBarColor: Theme.of(context).accentTextTheme!.bodyText1!.backgroundColor!, + keyboardBarColor: Theme.of(context).accentTextTheme.bodyText1!.backgroundColor!, nextFocus: false, actions: [ KeyboardActionsItem( @@ -67,10 +67,11 @@ class IoniaCustomRedeemPage extends BasePage { Container( padding: EdgeInsets.symmetric(horizontal: 25), decoration: BoxDecoration( - borderRadius: BorderRadius.only(bottomLeft: Radius.circular(24), bottomRight: Radius.circular(24)), + borderRadius: BorderRadius.only( + bottomLeft: Radius.circular(24), bottomRight: Radius.circular(24)), gradient: LinearGradient(colors: [ - Theme.of(context).primaryTextTheme!.subtitle1!.color!, - Theme.of(context).primaryTextTheme!.subtitle1!.decorationColor!, + Theme.of(context).primaryTextTheme.subtitle1!.color!, + Theme.of(context).primaryTextTheme.subtitle1!.decorationColor!, ], begin: Alignment.topLeft, end: Alignment.bottomRight), ), child: Column( @@ -85,11 +86,11 @@ class IoniaCustomRedeemPage extends BasePage { inputFormatters: [FilteringTextInputFormatter.deny(RegExp('[\-|\ ]'))], hintText: '1000', placeholderTextStyle: TextStyle( - color: Theme.of(context).primaryTextTheme!.headline5!.color!, + color: Theme.of(context).primaryTextTheme.headline5!.color!, fontWeight: FontWeight.w500, fontSize: 36, ), - borderColor: Theme.of(context).primaryTextTheme!.headline5!.color!, + borderColor: Theme.of(context).primaryTextTheme.headline5!.color!, textColor: Colors.white, textStyle: TextStyle( color: Colors.white, @@ -114,14 +115,17 @@ class IoniaCustomRedeemPage extends BasePage { ), ), SizedBox(height: 8), - Observer(builder: (_)=> - !ioniaCustomRedeemViewModel.disableRedeem ? - Center( - child: Text('\$${giftCard.remainingAmount} - \$${ioniaCustomRedeemViewModel.amount} = \$${ioniaCustomRedeemViewModel.formattedRemaining} ${S.of(context).remaining}', - style: TextStyle( - color: Theme.of(context).primaryTextTheme!.headline5!.color!, - ),), - ) : SizedBox.shrink(), + Observer( + builder: (_) => !ioniaCustomRedeemViewModel.disableRedeem + ? Center( + child: Text( + '\$${giftCard.remainingAmount} - \$${ioniaCustomRedeemViewModel.amount} = \$${ioniaCustomRedeemViewModel.formattedRemaining} ${S.of(context).remaining}', + style: TextStyle( + color: Theme.of(context).primaryTextTheme.headline5!.color!, + ), + ), + ) + : SizedBox.shrink(), ), SizedBox(height: 24), ], @@ -131,30 +135,37 @@ class IoniaCustomRedeemPage extends BasePage { padding: const EdgeInsets.all(24.0), child: CardItem( title: giftCard.legalName, - backgroundColor: Theme.of(context).accentTextTheme!.headline1!.backgroundColor!.withOpacity(0.1), + backgroundColor: Theme.of(context) + .accentTextTheme + .headline1! + .backgroundColor! + .withOpacity(0.1), discount: giftCard.remainingAmount, isAmount: true, discountBackground: AssetImage('assets/images/red_badge_discount.png'), - titleColor: Theme.of(context).accentTextTheme!.headline1!.backgroundColor!, + titleColor: Theme.of(context).accentTextTheme.headline1!.backgroundColor!, subtitleColor: Theme.of(context).hintColor, subTitle: S.of(context).online, logoUrl: giftCard.logoUrl, ), - ), + ), ], ), bottomSection: Column( children: [ - Padding( - padding: EdgeInsets.only(bottom: 12), - child: PrimaryButton( - onPressed: () { - Navigator.of(context).pop([ioniaCustomRedeemViewModel.remaining.toString(), ioniaCustomRedeemViewModel.amount.toString()]); - }, - isDisabled: ioniaCustomRedeemViewModel.disableRedeem, - text: S.of(context).add_custom_redemption, - color: Theme.of(context).accentTextTheme!.bodyText1!.color!, - textColor: Colors.white, + Observer( + builder: (_) => Padding( + padding: EdgeInsets.only(bottom: 12), + child: LoadingPrimaryButton( + isLoading: ioniaCustomRedeemViewModel.redeemState is IsExecutingState, + isDisabled: ioniaCustomRedeemViewModel.disableRedeem, + text: S.of(context).add_custom_redemption, + color: Theme.of(context).accentTextTheme.bodyText1!.color!, + textColor: Colors.white, + onPressed: () => ioniaCustomRedeemViewModel.addCustomRedeem().then((value) { + Navigator.of(context).pop(ioniaCustomRedeemViewModel.remaining.toString()); + }), + ), ), ), SizedBox(height: 30), diff --git a/lib/src/screens/ionia/cards/ionia_gift_card_detail_page.dart b/lib/src/screens/ionia/cards/ionia_gift_card_detail_page.dart index 2e7162e40..5b3c980ec 100644 --- a/lib/src/screens/ionia/cards/ionia_gift_card_detail_page.dart +++ b/lib/src/screens/ionia/cards/ionia_gift_card_detail_page.dart @@ -32,7 +32,7 @@ class IoniaGiftCardDetailPage extends BasePage { final _backButton = Icon( Icons.arrow_back_ios, - color: Theme.of(context).primaryTextTheme!.headline6!.color!, + color: Theme.of(context).primaryTextTheme.headline6!.color!, size: 16, ); return Padding( @@ -43,7 +43,7 @@ class IoniaGiftCardDetailPage extends BasePage { child: ButtonTheme( minWidth: double.minPositive, child: TextButton( - // FIX-ME: Style + // FIX-ME: Style //highlightColor: Colors.transparent, //splashColor: Colors.transparent, //padding: EdgeInsets.all(0), @@ -61,7 +61,8 @@ class IoniaGiftCardDetailPage extends BasePage { Widget middle(BuildContext context) { return Text( viewModel.giftCard.legalName, - style: textMediumSemiBold(color: Theme.of(context).accentTextTheme!.headline1!.backgroundColor!), + style: + textMediumSemiBold(color: Theme.of(context).accentTextTheme.headline1!.backgroundColor!), ); } @@ -102,20 +103,21 @@ class IoniaGiftCardDetailPage extends BasePage { title: S.of(context).gift_card_number, subTitle: viewModel.giftCard.cardNumber, ), - if (viewModel.giftCard.cardPin?.isNotEmpty ?? false) - ...[Divider(height: 30), + if (viewModel.giftCard.cardPin.isNotEmpty) ...[ + Divider(height: 30), buildIoniaTile( context, title: S.of(context).pin_number, subTitle: viewModel.giftCard.cardPin, - )], + ) + ], Divider(height: 30), - Observer(builder: (_) => - buildIoniaTile( - context, - title: S.of(context).amount, - subTitle: viewModel.remainingAmount.toStringAsFixed(2) ?? '0.00', - )), + Observer( + builder: (_) => buildIoniaTile( + context, + title: S.of(context).amount, + subTitle: viewModel.remainingAmount.toStringAsFixed(2), + )), Divider(height: 50), TextIconButton( label: S.of(context).how_to_use_card, @@ -131,24 +133,23 @@ class IoniaGiftCardDetailPage extends BasePage { return Column( children: [ PrimaryButton( - onPressed: () async { - final amount = await Navigator.of(context) - .pushNamed(Routes.ioniaMoreOptionsPage, arguments: [viewModel.giftCard]) as List?; - if (amount != null) { - viewModel.updateRemaining( balance: double.parse(amount.first), customAmount: double.parse(amount.last)); - } - }, - text: S.of(context).more_options, - color: Theme.of(context).accentTextTheme.caption!.color!, - textColor: Theme.of(context).primaryTextTheme.headline6!.color!, + onPressed: () async { + await Navigator.of(context).pushNamed( + Routes.ioniaMoreOptionsPage, + arguments: [viewModel.giftCard]) as String?; + viewModel.refeshCard(); + }, + text: S.of(context).more_options, + color: Theme.of(context).accentTextTheme.caption!.color!, + textColor: Theme.of(context).primaryTextTheme.headline6!.color!, ), SizedBox(height: 12), LoadingPrimaryButton( isLoading: viewModel.redeemState is IsExecutingState, onPressed: () => viewModel.redeem().then( (_) { - Navigator.of(context) - .pushNamedAndRemoveUntil(Routes.ioniaManageCardsPage, (route) => route.isFirst); + Navigator.of(context).pushNamedAndRemoveUntil( + Routes.ioniaManageCardsPage, (route) => route.isFirst); }, ), text: S.of(context).mark_as_redeemed, @@ -168,12 +169,11 @@ class IoniaGiftCardDetailPage extends BasePage { Widget buildIoniaTile(BuildContext context, {required String title, required String subTitle}) { return IoniaTile( - title: title, - subTitle: subTitle, - onTap: () { - Clipboard.setData(ClipboardData(text: subTitle)); - showBar(context, - S.of(context).transaction_details_copied(title)); + title: title, + subTitle: subTitle, + onTap: () { + Clipboard.setData(ClipboardData(text: subTitle)); + showBar(context, S.of(context).transaction_details_copied(title)); }); } @@ -184,10 +184,10 @@ class IoniaGiftCardDetailPage extends BasePage { showPopUp( context: context, builder: (BuildContext context) { - return IoniaAlertModal( + return IoniaAlertModal( title: S.of(context).how_to_use_card, content: Column( - crossAxisAlignment: CrossAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, children: viewModel.giftCard.instructions .map((instruction) { return [ @@ -196,13 +196,13 @@ class IoniaGiftCardDetailPage extends BasePage { child: Text( instruction.header, style: textLargeSemiBold( - color: Theme.of(context).textTheme!.headline3!.color!, + color: Theme.of(context).textTheme.headline3!.color!, ), )), Text( instruction.body, style: textMedium( - color: Theme.of(context).textTheme!.headline3!.color!, + color: Theme.of(context).textTheme.headline3!.color!, ), ) ]; @@ -210,7 +210,7 @@ class IoniaGiftCardDetailPage extends BasePage { .expand((e) => e) .toList()), actionTitle: S.of(context).send_got_it, - ); + ); }); } } diff --git a/lib/src/screens/ionia/cards/ionia_more_options_page.dart b/lib/src/screens/ionia/cards/ionia_more_options_page.dart index d4e378f84..facdfaf32 100644 --- a/lib/src/screens/ionia/cards/ionia_more_options_page.dart +++ b/lib/src/screens/ionia/cards/ionia_more_options_page.dart @@ -5,7 +5,6 @@ import 'package:cake_wallet/generated/i18n.dart'; import 'package:cake_wallet/typography.dart'; import 'package:flutter/material.dart'; - class IoniaMoreOptionsPage extends BasePage { IoniaMoreOptionsPage(this.giftCard); @@ -16,7 +15,7 @@ class IoniaMoreOptionsPage extends BasePage { return Text( S.current.more_options, style: textMediumSemiBold( - color: Theme.of(context).accentTextTheme!.headline1!.backgroundColor!, + color: Theme.of(context).accentTextTheme.headline1!.backgroundColor!, ), ); } @@ -27,40 +26,46 @@ class IoniaMoreOptionsPage extends BasePage { padding: const EdgeInsets.all(16.0), child: Column( crossAxisAlignment: CrossAxisAlignment.stretch, - children: [ - SizedBox(height: 10,), - Center(child: Text(S.of(context).choose_from_available_options, style: textMedium( - color: Theme.of(context).primaryTextTheme!.headline6!.color!, - ),)), - SizedBox(height: 40,), - InkWell( - onTap: () async { - final amounts = await Navigator.of(context).pushNamed(Routes.ioniaCustomRedeemPage, arguments: [giftCard]) as List; - if(amounts.first.isNotEmpty){ - Navigator.pop(context, amounts); - } - }, - child: _GradiantContainer( - content: Padding( - padding: const EdgeInsets.only(top: 24, left: 20, right: 24, bottom: 50), - child: Text( - S.of(context).custom_redeem_amount, - style: textXLargeSemiBold(), - ), - ), - ), - ) - ], - ), + children: [ + SizedBox( + height: 10, + ), + Center( + child: Text( + S.of(context).choose_from_available_options, + style: textMedium( + color: Theme.of(context).primaryTextTheme.headline6!.color!, + ), + )), + SizedBox( + height: 40, + ), + InkWell( + onTap: () async { + final amount = await Navigator.of(context) + .pushNamed(Routes.ioniaCustomRedeemPage, arguments: [giftCard]) as String?; + if (amount != null && amount.isNotEmpty) { + Navigator.pop(context); + } + }, + child: _GradiantContainer( + content: Padding( + padding: const EdgeInsets.only(top: 24, left: 20, right: 24, bottom: 50), + child: Text( + S.of(context).custom_redeem_amount, + style: textXLargeSemiBold(), + ), + ), + ), + ) + ], + ), ); } } class _GradiantContainer extends StatelessWidget { - const _GradiantContainer({ - Key? key, - required this.content - }) : super(key: key); + const _GradiantContainer({Key? key, required this.content}) : super(key: key); final Widget content; diff --git a/lib/view_model/ionia/ionia_custom_redeem_view_model.dart b/lib/view_model/ionia/ionia_custom_redeem_view_model.dart index 963604c15..6471c7378 100644 --- a/lib/view_model/ionia/ionia_custom_redeem_view_model.dart +++ b/lib/view_model/ionia/ionia_custom_redeem_view_model.dart @@ -1,29 +1,51 @@ +import 'package:cake_wallet/core/execution_state.dart'; import 'package:cake_wallet/ionia/ionia_gift_card.dart'; +import 'package:cake_wallet/ionia/ionia_service.dart'; import 'package:mobx/mobx.dart'; part 'ionia_custom_redeem_view_model.g.dart'; + class IoniaCustomRedeemViewModel = IoniaCustomRedeemViewModelBase with _$IoniaCustomRedeemViewModel; abstract class IoniaCustomRedeemViewModelBase with Store { - IoniaCustomRedeemViewModelBase(this.giftCard) - : amount = 0; + IoniaCustomRedeemViewModelBase({ + required this.giftCard, + required this.ioniaService, + }) : amount = 0, + redeemState = InitialExecutionState(); final IoniaGiftCard giftCard; + final IoniaService ioniaService; + + @observable + ExecutionState redeemState; + @observable double amount; @computed - double get remaining => amount <= giftCard.remainingAmount ? giftCard.remainingAmount - amount : 0; + double get remaining => + amount <= giftCard.remainingAmount ? giftCard.remainingAmount - amount : 0; @computed - String get formattedRemaining => remaining.toStringAsFixed(2); + String get formattedRemaining => remaining.toStringAsFixed(2); @computed bool get disableRedeem => amount > giftCard.remainingAmount; @action - void updateAmount(String text){ - amount = text.isEmpty ? 0 : (double.parse(text.replaceAll(',', '.')) ?? 0); + void updateAmount(String text) { + amount = text.isEmpty ? 0 : (double.parse(text.replaceAll(',', '.'))); } -} \ No newline at end of file + @action + Future addCustomRedeem() async { + try { + redeemState = IsExecutingState(); + await ioniaService.redeem(giftCardId: giftCard.id, amount: amount); + redeemState = ExecutedSuccessfullyState(); + } catch (e) { + redeemState = FailureState(e.toString()); + } + } +} diff --git a/lib/view_model/ionia/ionia_gift_card_details_view_model.dart b/lib/view_model/ionia/ionia_gift_card_details_view_model.dart index 745f2d530..cbf5ebc78 100644 --- a/lib/view_model/ionia/ionia_gift_card_details_view_model.dart +++ b/lib/view_model/ionia/ionia_gift_card_details_view_model.dart @@ -6,30 +6,25 @@ import 'package:device_display_brightness/device_display_brightness.dart'; part 'ionia_gift_card_details_view_model.g.dart'; -class IoniaGiftCardDetailsViewModel = IoniaGiftCardDetailsViewModelBase with _$IoniaGiftCardDetailsViewModel; +class IoniaGiftCardDetailsViewModel = IoniaGiftCardDetailsViewModelBase + with _$IoniaGiftCardDetailsViewModel; abstract class IoniaGiftCardDetailsViewModelBase with Store { - - IoniaGiftCardDetailsViewModelBase({ - required this.ioniaService, - required this.giftCard}) - : redeemState = InitialExecutionState(), - remainingAmount = giftCard.remainingAmount, - adjustedAmount = 0, - brightness = 0; + IoniaGiftCardDetailsViewModelBase({required this.ioniaService, required this.giftCard}) + : redeemState = InitialExecutionState(), + remainingAmount = giftCard.remainingAmount, + brightness = 0; final IoniaService ioniaService; - + double brightness; - + @observable IoniaGiftCard giftCard; @observable double remainingAmount; - double adjustedAmount; - @observable ExecutionState redeemState; @@ -38,22 +33,22 @@ abstract class IoniaGiftCardDetailsViewModelBase with Store { giftCard.remainingAmount = remainingAmount; try { redeemState = IsExecutingState(); - await ioniaService.redeem(giftCardId: giftCard.id, amount : adjustedAmount > 0 ? adjustedAmount : giftCard.remainingAmount); + await ioniaService.redeem(giftCardId: giftCard.id, amount: giftCard.remainingAmount); giftCard = await ioniaService.getGiftCard(id: giftCard.id); redeemState = ExecutedSuccessfullyState(); - } catch(e) { + } catch (e) { redeemState = FailureState(e.toString()); } } @action - void updateRemaining({required double balance, required double customAmount}) { - remainingAmount = balance; - adjustedAmount = customAmount; + Future refeshCard() async { + giftCard = await ioniaService.getGiftCard(id: giftCard.id); + remainingAmount = giftCard.remainingAmount; } void increaseBrightness() async { brightness = await DeviceDisplayBrightness.getBrightness(); await DeviceDisplayBrightness.setBrightness(1.0); } -} \ No newline at end of file +} From 826ae46b072cde306e6f1f88287cc98c8a5e09a2 Mon Sep 17 00:00:00 2001 From: OmarHatem Date: Mon, 12 Dec 2022 18:01:42 +0200 Subject: [PATCH 10/12] - Fix not filling fiat amount - Fix conflicts with master --- lib/src/screens/send/send_page.dart | 3 +-- lib/src/screens/send/widgets/send_card.dart | 14 ++++++++++---- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/lib/src/screens/send/send_page.dart b/lib/src/screens/send/send_page.dart index c3f5f24c4..2cd849f34 100644 --- a/lib/src/screens/send/send_page.dart +++ b/lib/src/screens/send/send_page.dart @@ -29,12 +29,11 @@ class SendPage extends BasePage { SendPage({ required this.sendViewModel, this.initialPaymentRequest, - }) : _formKey = GlobalKey(),fiatFromSettings = settingsViewModel.fiatCurrency; + }) : _formKey = GlobalKey(); final SendViewModel sendViewModel; final GlobalKey _formKey; final controller = PageController(initialPage: 0); - final FiatCurrency fiatFromSettings; final PaymentRequest? initialPaymentRequest; bool _effectsInstalled = false; diff --git a/lib/src/screens/send/widgets/send_card.dart b/lib/src/screens/send/widgets/send_card.dart index 41045b451..3be56d409 100644 --- a/lib/src/screens/send/widgets/send_card.dart +++ b/lib/src/screens/send/widgets/send_card.dart @@ -43,8 +43,8 @@ class SendCardState extends State required this.output, required this.sendViewModel, this.initialPaymentRequest}) - : addressController = TextEditingController(text: initialPaymentRequest?.address.toLowerCase()), - cryptoAmountController = TextEditingController(text: initialPaymentRequest?.amount), + : addressController = TextEditingController(), + cryptoAmountController = TextEditingController(), fiatAmountController = TextEditingController(), noteController = TextEditingController(), extractedAddressController = TextEditingController(), @@ -545,8 +545,7 @@ class SendCardState extends State if (output.address.isNotEmpty) { addressController.text = output.address; } - if (output.cryptoAmount.isNotEmpty || - sendViewModel.walletCurrencyName != initialPaymentRequest?.scheme.toLowerCase()) { + if (output.cryptoAmount.isNotEmpty) { cryptoAmountController.text = output.cryptoAmount; } fiatAmountController.text = output.fiatAmount; @@ -640,6 +639,13 @@ class SendCardState extends State extractedAddressController.text = extractedAddress; }); + if (initialPaymentRequest != null && + sendViewModel.walletCurrencyName != initialPaymentRequest!.scheme.toLowerCase()) { + addressController.text = initialPaymentRequest!.address; + cryptoAmountController.text = initialPaymentRequest!.amount; + noteController.text = initialPaymentRequest!.note; + } + _effectsInstalled = true; } From 30ef231d247f17deae5ded2d55968cf7072930df Mon Sep 17 00:00:00 2001 From: OmarHatem Date: Mon, 12 Dec 2022 22:16:46 +0200 Subject: [PATCH 11/12] Fix fill data condition --- lib/src/screens/send/widgets/send_card.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/src/screens/send/widgets/send_card.dart b/lib/src/screens/send/widgets/send_card.dart index 3be56d409..082067d95 100644 --- a/lib/src/screens/send/widgets/send_card.dart +++ b/lib/src/screens/send/widgets/send_card.dart @@ -640,7 +640,7 @@ class SendCardState extends State }); if (initialPaymentRequest != null && - sendViewModel.walletCurrencyName != initialPaymentRequest!.scheme.toLowerCase()) { + sendViewModel.walletCurrencyName == initialPaymentRequest!.scheme.toLowerCase()) { addressController.text = initialPaymentRequest!.address; cryptoAmountController.text = initialPaymentRequest!.amount; noteController.text = initialPaymentRequest!.note; From dbf214ee1bd7fc32f744eee24f142d5eb1598ea6 Mon Sep 17 00:00:00 2001 From: Godwin Asuquo Date: Tue, 13 Dec 2022 18:26:25 +0100 Subject: [PATCH 12/12] [skip ci] fix issues from code review --- lib/ionia/ionia_gift_card.dart | 2 +- .../ionia/cards/ionia_more_options_page.dart | 13 ++++++------- .../ionia/ionia_custom_redeem_view_model.dart | 2 +- 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/lib/ionia/ionia_gift_card.dart b/lib/ionia/ionia_gift_card.dart index 04b45b907..2ba0fd136 100644 --- a/lib/ionia/ionia_gift_card.dart +++ b/lib/ionia/ionia_gift_card.dart @@ -37,7 +37,7 @@ class IoniaGiftCard { purchaseAmount: element['PurchaseAmount'] as double, actualAmount: element['ActualAmount'] as double, totalTransactionAmount: element['TotalTransactionAmount'] as double, - totalDashTransactionAmount: element['TotalDashTransactionAmount'] != null ? element['TotalDashTransactionAmount'] as double : 0.0, + totalDashTransactionAmount: (element['TotalDashTransactionAmount'] as double?) ?? 0.0, remainingAmount: element['RemainingAmount'] as double, isActive: element['IsActive'] as bool, isEmpty: element['IsEmpty'] as bool, diff --git a/lib/src/screens/ionia/cards/ionia_more_options_page.dart b/lib/src/screens/ionia/cards/ionia_more_options_page.dart index facdfaf32..7d38c5e1e 100644 --- a/lib/src/screens/ionia/cards/ionia_more_options_page.dart +++ b/lib/src/screens/ionia/cards/ionia_more_options_page.dart @@ -31,15 +31,14 @@ class IoniaMoreOptionsPage extends BasePage { height: 10, ), Center( - child: Text( - S.of(context).choose_from_available_options, - style: textMedium( - color: Theme.of(context).primaryTextTheme.headline6!.color!, + child: Text( + S.of(context).choose_from_available_options, + style: textMedium( + color: Theme.of(context).primaryTextTheme.headline6!.color!, + ), ), - )), - SizedBox( - height: 40, ), + SizedBox(height: 40), InkWell( onTap: () async { final amount = await Navigator.of(context) diff --git a/lib/view_model/ionia/ionia_custom_redeem_view_model.dart b/lib/view_model/ionia/ionia_custom_redeem_view_model.dart index 6471c7378..5776443ee 100644 --- a/lib/view_model/ionia/ionia_custom_redeem_view_model.dart +++ b/lib/view_model/ionia/ionia_custom_redeem_view_model.dart @@ -35,7 +35,7 @@ abstract class IoniaCustomRedeemViewModelBase with Store { @action void updateAmount(String text) { - amount = text.isEmpty ? 0 : (double.parse(text.replaceAll(',', '.'))); + amount = double.tryParse(text.replaceAll(',', '.')) ?? 0; } @action