From d99aac9d98085d1c449c3ab1844755a3fac12c38 Mon Sep 17 00:00:00 2001 From: mkyq <53115730+mkyq@users.noreply.github.com> Date: Tue, 8 Nov 2022 15:57:33 -0500 Subject: [PATCH 01/12] Cast rateId as optional String for calculateAmount for ChangeNow api. (#612) --- lib/exchange/changenow/changenow_exchange_provider.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/exchange/changenow/changenow_exchange_provider.dart b/lib/exchange/changenow/changenow_exchange_provider.dart index b663b697c..20f529733 100644 --- a/lib/exchange/changenow/changenow_exchange_provider.dart +++ b/lib/exchange/changenow/changenow_exchange_provider.dart @@ -232,7 +232,7 @@ class ChangeNowExchangeProvider extends ExchangeProvider { final responseJSON = json.decode(response.body) as Map; final fromAmount = double.parse(responseJSON['fromAmount'].toString()); final toAmount = double.parse(responseJSON['toAmount'].toString()); - final rateId = responseJSON['rateId'] as String ?? ''; + final rateId = responseJSON['rateId'] as String? ?? ''; if (rateId.isNotEmpty) { _lastUsedRateId = rateId; From 7d49dc47616559b8e94f72c54abd50a6eb9ea341 Mon Sep 17 00:00:00 2001 From: Serhii Date: Thu, 10 Nov 2022 20:08:52 +0200 Subject: [PATCH 02/12] rework confirm sending screen for cake pay (#603) * rework confirm sending allert * remove confirm_modal.dart * fix text color and buttons size --- lib/di.dart | 1 + .../cards/ionia_buy_card_detail_page.dart | 84 +++------- .../screens/ionia/widgets/confirm_modal.dart | 149 ------------------ .../send/widgets/confirm_sending_alert.dart | 86 +++++++++- lib/src/widgets/base_alert_dialog.dart | 98 +++++++----- .../ionia_purchase_merch_view_model.dart | 4 + 6 files changed, 169 insertions(+), 253 deletions(-) delete mode 100644 lib/src/screens/ionia/widgets/confirm_modal.dart diff --git a/lib/di.dart b/lib/di.dart index 7ce2ff6d9..90549cf6f 100644 --- a/lib/di.dart +++ b/lib/di.dart @@ -701,6 +701,7 @@ Future setup( ioniaAnyPayService: getIt.get(), amount: amount, ioniaMerchant: merchant, + sendViewModel: getIt.get() ); }); diff --git a/lib/src/screens/ionia/cards/ionia_buy_card_detail_page.dart b/lib/src/screens/ionia/cards/ionia_buy_card_detail_page.dart index f3b12e65b..4b9f0a220 100644 --- a/lib/src/screens/ionia/cards/ionia_buy_card_detail_page.dart +++ b/lib/src/screens/ionia/cards/ionia_buy_card_detail_page.dart @@ -3,7 +3,6 @@ import 'package:cake_wallet/ionia/ionia_merchant.dart'; import 'package:cake_wallet/ionia/ionia_tip.dart'; import 'package:cake_wallet/palette.dart'; import 'package:cake_wallet/routes.dart'; -import 'package:cake_wallet/src/screens/ionia/widgets/confirm_modal.dart'; import 'package:cake_wallet/src/screens/ionia/widgets/ionia_alert_model.dart'; import 'package:cake_wallet/src/screens/ionia/widgets/text_icon_button.dart'; import 'package:cake_wallet/src/widgets/alert_with_one_action.dart'; @@ -18,6 +17,7 @@ import 'package:cake_wallet/generated/i18n.dart'; import 'package:flutter_mobx/flutter_mobx.dart'; import 'package:mobx/mobx.dart'; import 'package:cake_wallet/src/screens/base_page.dart'; +import 'package:cake_wallet/src/screens/send/widgets/confirm_sending_alert.dart'; class IoniaBuyGiftCardDetailPage extends BasePage { IoniaBuyGiftCardDetailPage(this.ioniaPurchaseViewModel); @@ -295,73 +295,35 @@ class IoniaBuyGiftCardDetailPage extends BasePage { final amount = ioniaPurchaseViewModel.invoice!.totalAmount; final addresses = ioniaPurchaseViewModel.invoice!.outAddresses; + ioniaPurchaseViewModel.sendViewModel.outputs.first.setCryptoAmount(amount); + ioniaPurchaseViewModel.sendViewModel.outputs.first.address = addresses.first; await showPopUp( context: context, builder: (_) { - return IoniaConfirmModal( + return ConfirmSendingAlert( alertTitle: S.of(context).confirm_sending, - alertContent: Container( - height: 200, - padding: EdgeInsets.all(15), - child: Column(children: [ - Row(children: [ - Text(S.of(context).payment_id, - textAlign: TextAlign.center, - style: TextStyle( - fontSize: 16, - fontWeight: FontWeight.w400, - color: PaletteDark.pigeonBlue, - decoration: TextDecoration.none)), - Text(ioniaPurchaseViewModel.invoice!.paymentId, - style: TextStyle( - fontSize: 16, - fontWeight: FontWeight.w400, - color: PaletteDark.pigeonBlue, - decoration: TextDecoration.none)) - ], mainAxisAlignment: MainAxisAlignment.spaceBetween), - SizedBox(height: 10), - Row(children: [ - Text(S.of(context).amount, - textAlign: TextAlign.center, - style: TextStyle( - fontSize: 16, - fontWeight: FontWeight.w400, - color: PaletteDark.pigeonBlue, - decoration: TextDecoration.none)), - Text('$amount ${ioniaPurchaseViewModel.invoice!.chain}', - style: TextStyle( - fontSize: 16, - fontWeight: FontWeight.w400, - color: PaletteDark.pigeonBlue, - decoration: TextDecoration.none)) - ], mainAxisAlignment: MainAxisAlignment.spaceBetween), - SizedBox(height: 25), - Row(children: [ - Text(S.of(context).recipient_address, - style: TextStyle( - fontSize: 16, - fontWeight: FontWeight.w400, - color: PaletteDark.pigeonBlue, - decoration: TextDecoration.none)) - ], mainAxisAlignment: MainAxisAlignment.center), - Expanded( - child: ListView.builder( - itemBuilder: (_, int index) { - return Text(addresses[index], - style: TextStyle( - fontSize: 14, - fontWeight: FontWeight.w400, - color: PaletteDark.pigeonBlue, - decoration: TextDecoration.none)); - }, - itemCount: addresses.length, - physics: NeverScrollableScrollPhysics())) - ])), + paymentId: S.of(context).payment_id, + paymentIdValue: ioniaPurchaseViewModel.invoice!.paymentId, + amount: S.of(context).send_amount, + amountValue: '$amount ${ioniaPurchaseViewModel.invoice!.chain}', + fiatAmountValue: + '~ ${ioniaPurchaseViewModel.sendViewModel.outputs.first.fiatAmount} ' + '${ioniaPurchaseViewModel.sendViewModel.fiat.title}', + fee: S.of(context).send_fee, + feeValue: + '${ioniaPurchaseViewModel.sendViewModel.outputs.first.estimatedFee} ' + '${ioniaPurchaseViewModel.invoice!.chain}', + feeFiatAmount: + '${ioniaPurchaseViewModel.sendViewModel.outputs.first.estimatedFeeFiatAmount} ' + '${ioniaPurchaseViewModel.sendViewModel.fiat.title}', + outputs: ioniaPurchaseViewModel.sendViewModel.outputs, rightButtonText: S.of(context).ok, leftButtonText: S.of(context).cancel, - leftActionColor: Color(0xffFF6600), - rightActionColor: Theme.of(context).accentTextTheme!.bodyText1!.color!, + alertLeftActionButtonTextColor: Colors.white, + alertRightActionButtonTextColor: Colors.white, + alertLeftActionButtonColor: Palette.brightOrange, + alertRightActionButtonColor: Theme.of(context).textTheme!.subtitle2!.color, actionRightButton: () async { Navigator.of(context).pop(); await ioniaPurchaseViewModel.commitPaymentInvoice(); diff --git a/lib/src/screens/ionia/widgets/confirm_modal.dart b/lib/src/screens/ionia/widgets/confirm_modal.dart deleted file mode 100644 index cfc9a1cf1..000000000 --- a/lib/src/screens/ionia/widgets/confirm_modal.dart +++ /dev/null @@ -1,149 +0,0 @@ -import 'dart:ui'; - -import 'package:cake_wallet/palette.dart'; -import 'package:flutter/material.dart'; - -class IoniaConfirmModal extends StatelessWidget { - IoniaConfirmModal({ - required this.alertTitle, - required this.alertContent, - required this.leftButtonText, - required this.rightButtonText, - required this.actionLeftButton, - required this.actionRightButton, - required this.leftActionColor, - required this.rightActionColor, - this.hideActions = false, - }); - - final String alertTitle; - final Widget alertContent; - final String leftButtonText; - final String rightButtonText; - final VoidCallback actionLeftButton; - final VoidCallback actionRightButton; - final Color leftActionColor; - final Color rightActionColor; - final bool hideActions; - - Widget actionButtons(BuildContext context) { - return Row( - mainAxisSize: MainAxisSize.max, - children: [ - IoniaActionButton( - buttonText: leftButtonText, - action: actionLeftButton, - backgoundColor: leftActionColor, - ), - Container( - width: 1, - height: 52, - color: Theme.of(context).dividerColor, - ), - IoniaActionButton( - buttonText: rightButtonText, - action: actionRightButton, - backgoundColor: rightActionColor, - ), - ], - ); - } - - Widget title(BuildContext context) { - return Text( - alertTitle, - textAlign: TextAlign.center, - style: TextStyle( - fontSize: 20, - fontFamily: 'Lato', - fontWeight: FontWeight.w600, - color: Theme.of(context).primaryTextTheme!.headline6!.color!, - decoration: TextDecoration.none, - ), - ); - } - - @override - Widget build(BuildContext context) { - return Container( - color: Colors.transparent, - child: BackdropFilter( - filter: ImageFilter.blur(sigmaX: 3.0, sigmaY: 3.0), - child: Container( - decoration: BoxDecoration(color: PaletteDark.darkNightBlue.withOpacity(0.75)), - child: Center( - child: GestureDetector( - onTap: () => null, - child: ClipRRect( - borderRadius: BorderRadius.all(Radius.circular(30)), - child: Container( - width: 327, - color: Theme.of(context).accentTextTheme!.headline6!.decorationColor!, - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - Padding( - padding: EdgeInsets.fromLTRB(24, 20, 24, 0), - child: title(context), - ), - Padding( - padding: EdgeInsets.only(top: 16, bottom: 8), - child: Container( - height: 1, - color: Theme.of(context).dividerColor, - ), - ), - alertContent, - actionButtons(context), - ], - ), - ), - ), - ), - ), - ), - ), - ); - } -} - -class IoniaActionButton extends StatelessWidget { - const IoniaActionButton({ - required this.buttonText, - required this.action, - required this.backgoundColor, - }); - - final String buttonText; - final VoidCallback action; - final Color backgoundColor; - - @override - Widget build(BuildContext context) { - return Flexible( - child: Container( - height: 52, - padding: EdgeInsets.only(left: 6, right: 6), - color: backgoundColor, - child: ButtonTheme( - minWidth: double.infinity, - child: TextButton( - onPressed: action, - // FIX-ME: ignored highlightColor and splashColor - //highlightColor: Colors.transparent, - //splashColor: Colors.transparent, - child: Text( - buttonText, - textAlign: TextAlign.center, - style: TextStyle( - fontSize: 15, - fontFamily: 'Lato', - fontWeight: FontWeight.w600, - color: backgoundColor != null ? Colors.white : Theme.of(context).primaryTextTheme!.bodyText2!.backgroundColor!, - decoration: TextDecoration.none, - ), - )), - ), - )); - } -} diff --git a/lib/src/screens/send/widgets/confirm_sending_alert.dart b/lib/src/screens/send/widgets/confirm_sending_alert.dart index 317303442..a034d801e 100644 --- a/lib/src/screens/send/widgets/confirm_sending_alert.dart +++ b/lib/src/screens/send/widgets/confirm_sending_alert.dart @@ -4,10 +4,13 @@ import 'package:flutter/material.dart'; import 'package:cake_wallet/src/widgets/base_alert_dialog.dart'; import 'package:cake_wallet/generated/i18n.dart'; import 'package:cake_wallet/src/widgets/cake_scrollbar.dart'; +import 'package:flutter/scheduler.dart'; class ConfirmSendingAlert extends BaseAlertDialog { ConfirmSendingAlert({ required this.alertTitle, + this.paymentId, + this.paymentIdValue, required this.amount, required this.amountValue, required this.fiatAmountValue, @@ -19,9 +22,15 @@ class ConfirmSendingAlert extends BaseAlertDialog { required this.rightButtonText, required this.actionLeftButton, required this.actionRightButton, - this.alertBarrierDismissible = true}); + this.alertBarrierDismissible = true, + this.alertLeftActionButtonTextColor, + this.alertRightActionButtonTextColor, + this.alertLeftActionButtonColor, + this.alertRightActionButtonColor}); final String alertTitle; + final String? paymentId; + final String? paymentIdValue; final String amount; final String amountValue; final String fiatAmountValue; @@ -34,6 +43,10 @@ class ConfirmSendingAlert extends BaseAlertDialog { final VoidCallback actionLeftButton; final VoidCallback actionRightButton; final bool alertBarrierDismissible; + final Color? alertLeftActionButtonTextColor; + final Color? alertRightActionButtonTextColor; + final Color? alertLeftActionButtonColor; + final Color? alertRightActionButtonColor; @override String get titleText => alertTitle; @@ -56,8 +69,22 @@ class ConfirmSendingAlert extends BaseAlertDialog { @override bool get barrierDismissible => alertBarrierDismissible; + @override + Color? get leftActionButtonTextColor => alertLeftActionButtonTextColor; + + @override + Color? get rightActionButtonTextColor => alertRightActionButtonTextColor; + + @override + Color? get leftActionButtonColor => alertLeftActionButtonColor; + + @override + Color? get rightActionButtonColor => alertRightActionButtonColor; + @override Widget content(BuildContext context) => ConfirmSendingAlertContent( + paymentId: paymentId, + paymentIdValue: paymentIdValue, amount: amount, amountValue: amountValue, fiatAmountValue: fiatAmountValue, @@ -70,6 +97,8 @@ class ConfirmSendingAlert extends BaseAlertDialog { class ConfirmSendingAlertContent extends StatefulWidget { ConfirmSendingAlertContent({ + this.paymentId, + this.paymentIdValue, required this.amount, required this.amountValue, required this.fiatAmountValue, @@ -78,6 +107,8 @@ class ConfirmSendingAlertContent extends StatefulWidget { required this.feeFiatAmount, required this.outputs}); + final String? paymentId; + final String? paymentIdValue; final String amount; final String amountValue; final String fiatAmountValue; @@ -88,6 +119,8 @@ class ConfirmSendingAlertContent extends StatefulWidget { @override ConfirmSendingAlertContentState createState() => ConfirmSendingAlertContentState( + paymentId: paymentId, + paymentIdValue: paymentIdValue, amount: amount, amountValue: amountValue, fiatAmountValue: fiatAmountValue, @@ -100,6 +133,8 @@ class ConfirmSendingAlertContent extends StatefulWidget { class ConfirmSendingAlertContentState extends State { ConfirmSendingAlertContentState({ + this.paymentId, + this.paymentIdValue, required this.amount, required this.amountValue, required this.fiatAmountValue, @@ -115,6 +150,8 @@ class ConfirmSendingAlertContentState extends State : S.current.recipient_address; } + final String? paymentId; + final String? paymentIdValue; final String amount; final String amountValue; final String fiatAmountValue; @@ -129,6 +166,7 @@ class ConfirmSendingAlertContentState extends State double fromTop = 0; String recipientTitle; int itemCount; + bool showScrollbar = false; @override Widget build(BuildContext context) { @@ -140,6 +178,12 @@ class ConfirmSendingAlertContentState extends State setState(() {}); }); + SchedulerBinding.instance.addPostFrameCallback((_) { + setState(() { + showScrollbar = controller.position.maxScrollExtent > 0; + }); + }); + return Stack( alignment: Alignment.center, clipBehavior: Clip.none, @@ -150,6 +194,44 @@ class ConfirmSendingAlertContentState extends State controller: controller, child: Column( children: [ + if (paymentIdValue != null && paymentId != null) + Padding( + padding: EdgeInsets.only(bottom: 32), + child: Row( + mainAxisSize: MainAxisSize.max, + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + paymentId!, + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.normal, + fontFamily: 'Lato', + color: Theme.of(context).primaryTextTheme! + .headline6!.color!, + decoration: TextDecoration.none, + ), + ), + Column( + crossAxisAlignment: CrossAxisAlignment.end, + children: [ + Text( + paymentIdValue!, + style: TextStyle( + fontSize: 18, + fontWeight: FontWeight.w600, + fontFamily: 'Lato', + color: Theme.of(context).primaryTextTheme! + .headline6!.color!, + decoration: TextDecoration.none, + ), + ), + ], + ) + ], + ), + ), Row( mainAxisSize: MainAxisSize.max, mainAxisAlignment: MainAxisAlignment.spaceBetween, @@ -365,7 +447,7 @@ class ConfirmSendingAlertContentState extends State ) ) ), - if (itemCount > 1) CakeScrollbar( + if (showScrollbar) CakeScrollbar( backgroundHeight: backgroundHeight, thumbHeight: thumbHeight, fromTop: fromTop, diff --git a/lib/src/widgets/base_alert_dialog.dart b/lib/src/widgets/base_alert_dialog.dart index 7713284f2..70370e227 100644 --- a/lib/src/widgets/base_alert_dialog.dart +++ b/lib/src/widgets/base_alert_dialog.dart @@ -11,6 +11,10 @@ class BaseAlertDialog extends StatelessWidget { VoidCallback get actionLeft => () {}; VoidCallback get actionRight => () {}; bool get barrierDismissible => true; + Color? get leftActionButtonTextColor => null; + Color? get rightActionButtonTextColor => null; + Color? get leftActionButtonColor => null; + Color? get rightActionButtonColor => null; Widget title(BuildContext context) { return Text( @@ -45,52 +49,64 @@ class BaseAlertDialog extends StatelessWidget { height: 52, child: Row( mainAxisSize: MainAxisSize.max, - mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.stretch, children: [ - Flexible( - child: Container( - width: double.infinity, - color: Theme.of(context).accentTextTheme!.bodyText1!.decorationColor!, - child: TextButton( - onPressed: actionLeft, - child: Text( - leftActionButtonText, - textAlign: TextAlign.center, - style: TextStyle( - fontSize: 15, - fontFamily: 'Lato', - fontWeight: FontWeight.w600, - color: Theme.of(context).primaryTextTheme!.bodyText1!.backgroundColor!, - decoration: TextDecoration.none, - ), - )), - ), - ), + Expanded( + child: TextButton( + onPressed: actionLeft, + style: TextButton.styleFrom( + backgroundColor: leftActionButtonColor ?? + Theme.of(context) + .accentTextTheme! + .bodyText1! + .decorationColor!, + shape: const RoundedRectangleBorder( + borderRadius: BorderRadius.all(Radius.zero))), + child: Text( + leftActionButtonText, + textAlign: TextAlign.center, + style: TextStyle( + fontSize: 15, + fontFamily: 'Lato', + fontWeight: FontWeight.w600, + color: leftActionButtonTextColor ?? + Theme.of(context).primaryTextTheme! + .bodyText1!.backgroundColor!, + decoration: TextDecoration.none, + ), + )), + ), Container( width: 1, color: Theme.of(context).dividerColor, ), - Flexible( - child: Container( - width: double.infinity, - color: Theme.of(context).accentTextTheme!.bodyText2!.backgroundColor!, - child: TextButton( - onPressed: actionRight, - child: Text( - rightActionButtonText, - textAlign: TextAlign.center, - style: TextStyle( - fontSize: 15, - fontFamily: 'Lato', - fontWeight: FontWeight.w600, - color: Theme.of(context).primaryTextTheme!.bodyText2!.backgroundColor!, - decoration: TextDecoration.none, - ), - )), - ), - ), - ], - )); + Expanded( + child: TextButton( + onPressed: actionRight, + style: TextButton.styleFrom( + backgroundColor: rightActionButtonColor ?? + Theme.of(context).accentTextTheme! + .bodyText2!.backgroundColor!, + shape: const RoundedRectangleBorder( + borderRadius: BorderRadius.all(Radius.zero))), + child: Text( + rightActionButtonText, + textAlign: TextAlign.center, + style: TextStyle( + fontSize: 15, + fontFamily: 'Lato', + fontWeight: FontWeight.w600, + color: rightActionButtonTextColor ?? + Theme.of(context) + .primaryTextTheme! + .bodyText2! + .backgroundColor!, + decoration: TextDecoration.none, + ), + )), + ), + ], + )); } @override diff --git a/lib/view_model/ionia/ionia_purchase_merch_view_model.dart b/lib/view_model/ionia/ionia_purchase_merch_view_model.dart index da71f31fa..df6a23718 100644 --- a/lib/view_model/ionia/ionia_purchase_merch_view_model.dart +++ b/lib/view_model/ionia/ionia_purchase_merch_view_model.dart @@ -7,6 +7,7 @@ import 'package:cake_wallet/ionia/ionia_anypay.dart'; import 'package:cake_wallet/ionia/ionia_merchant.dart'; import 'package:cake_wallet/ionia/ionia_tip.dart'; import 'package:cake_wallet/ionia/ionia_any_pay_payment_info.dart'; +import 'package:cake_wallet/view_model/send/send_view_model.dart'; part 'ionia_purchase_merch_view_model.g.dart'; @@ -17,6 +18,7 @@ abstract class IoniaMerchPurchaseViewModelBase with Store { required this.ioniaAnyPayService, required this.amount, required this.ioniaMerchant, + required this.sendViewModel, }) : tipAmount = 0.0, percentage = 0.0, invoiceCreationState = InitialExecutionState(), @@ -40,6 +42,8 @@ abstract class IoniaMerchPurchaseViewModelBase with Store { final IoniaMerchant ioniaMerchant; + final SendViewModel sendViewModel; + final IoniaAnyPay ioniaAnyPayService; IoniaAnyPayPaymentInfo? paymentInfo; From 1efced7607dea0679971ec95877cfdd7847121a4 Mon Sep 17 00:00:00 2001 From: M Date: Thu, 10 Nov 2022 13:11:10 -0500 Subject: [PATCH 03/12] Update build version for cake wallet to 132; monero.com 28 --- scripts/android/app_env.sh | 4 ++-- scripts/ios/app_env.sh | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/scripts/android/app_env.sh b/scripts/android/app_env.sh index b9ca9f98b..54ad0b4d4 100644 --- a/scripts/android/app_env.sh +++ b/scripts/android/app_env.sh @@ -15,13 +15,13 @@ APP_ANDROID_TYPE=$1 MONERO_COM_NAME="Monero.com" MONERO_COM_VERSION="1.2.0" -MONERO_COM_BUILD_NUMBER=26 +MONERO_COM_BUILD_NUMBER=28 MONERO_COM_BUNDLE_ID="com.monero.app" MONERO_COM_PACKAGE="com.monero.app" CAKEWALLET_NAME="Cake Wallet" CAKEWALLET_VERSION="4.5.0" -CAKEWALLET_BUILD_NUMBER=130 +CAKEWALLET_BUILD_NUMBER=132 CAKEWALLET_BUNDLE_ID="com.cakewallet.cake_wallet" CAKEWALLET_PACKAGE="com.cakewallet.cake_wallet" diff --git a/scripts/ios/app_env.sh b/scripts/ios/app_env.sh index bab932345..c7ecaa60b 100644 --- a/scripts/ios/app_env.sh +++ b/scripts/ios/app_env.sh @@ -14,12 +14,12 @@ APP_IOS_TYPE=$1 MONERO_COM_NAME="Monero.com" MONERO_COM_VERSION="1.2.0" -MONERO_COM_BUILD_NUMBER=26 +MONERO_COM_BUILD_NUMBER=28 MONERO_COM_BUNDLE_ID="com.cakewallet.monero" CAKEWALLET_NAME="Cake Wallet" CAKEWALLET_VERSION="4.5.0" -CAKEWALLET_BUILD_NUMBER=130 +CAKEWALLET_BUILD_NUMBER=132 CAKEWALLET_BUNDLE_ID="com.fotolockr.cakewallet" HAVEN_NAME="Haven" From ab305e22a23c9f2930a538a1110ca1c9eb3ee24a Mon Sep 17 00:00:00 2001 From: mkyq <53115730+mkyq@users.noreply.github.com> Date: Wed, 16 Nov 2022 18:30:35 -0500 Subject: [PATCH 04/12] Remove duplication for qr codes. (#628) --- lib/src/screens/receive/widgets/qr_painter.dart | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/src/screens/receive/widgets/qr_painter.dart b/lib/src/screens/receive/widgets/qr_painter.dart index 90dba73ac..e4af59f1a 100644 --- a/lib/src/screens/receive/widgets/qr_painter.dart +++ b/lib/src/screens/receive/widgets/qr_painter.dart @@ -9,7 +9,6 @@ class QrPainter extends CustomPainter { this.errorCorrectionLevel, ) : this._qr = QrCode(version, errorCorrectionLevel)..addData(data) { _p.color = this.color; - _qr.addData(data); _qrImage = QrImage(_qr); } From 35007fcf3ecc3dbac44ae8b2e9e3bb904bef653e Mon Sep 17 00:00:00 2001 From: mkyq <53115730+mkyq@users.noreply.github.com> Date: Wed, 16 Nov 2022 18:33:12 -0500 Subject: [PATCH 05/12] Update version to 4.5.1 for cakewallet; 1.2.1 for monero.com. (#629) --- scripts/android/app_env.sh | 8 ++++---- scripts/ios/app_env.sh | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/scripts/android/app_env.sh b/scripts/android/app_env.sh index 54ad0b4d4..e57d3a97c 100644 --- a/scripts/android/app_env.sh +++ b/scripts/android/app_env.sh @@ -14,14 +14,14 @@ TYPES=($MONERO_COM $CAKEWALLET $HAVEN) APP_ANDROID_TYPE=$1 MONERO_COM_NAME="Monero.com" -MONERO_COM_VERSION="1.2.0" -MONERO_COM_BUILD_NUMBER=28 +MONERO_COM_VERSION="1.2.1" +MONERO_COM_BUILD_NUMBER=29 MONERO_COM_BUNDLE_ID="com.monero.app" MONERO_COM_PACKAGE="com.monero.app" CAKEWALLET_NAME="Cake Wallet" -CAKEWALLET_VERSION="4.5.0" -CAKEWALLET_BUILD_NUMBER=132 +CAKEWALLET_VERSION="4.5.1" +CAKEWALLET_BUILD_NUMBER=133 CAKEWALLET_BUNDLE_ID="com.cakewallet.cake_wallet" CAKEWALLET_PACKAGE="com.cakewallet.cake_wallet" diff --git a/scripts/ios/app_env.sh b/scripts/ios/app_env.sh index c7ecaa60b..8bb945680 100644 --- a/scripts/ios/app_env.sh +++ b/scripts/ios/app_env.sh @@ -13,13 +13,13 @@ TYPES=($MONERO_COM $CAKEWALLET $HAVEN) APP_IOS_TYPE=$1 MONERO_COM_NAME="Monero.com" -MONERO_COM_VERSION="1.2.0" -MONERO_COM_BUILD_NUMBER=28 +MONERO_COM_VERSION="1.2.1" +MONERO_COM_BUILD_NUMBER=29 MONERO_COM_BUNDLE_ID="com.cakewallet.monero" CAKEWALLET_NAME="Cake Wallet" -CAKEWALLET_VERSION="4.5.0" -CAKEWALLET_BUILD_NUMBER=132 +CAKEWALLET_VERSION="4.5.1" +CAKEWALLET_BUILD_NUMBER=133 CAKEWALLET_BUNDLE_ID="com.fotolockr.cakewallet" HAVEN_NAME="Haven" From 3dbdb8fceaa77c33dbc0ff58484c411ee5ee4a77 Mon Sep 17 00:00:00 2001 From: mkyq <53115730+mkyq@users.noreply.github.com> Date: Wed, 16 Nov 2022 20:15:30 -0500 Subject: [PATCH 06/12] Update targetSdkVersion to 31. (#630) --- android/app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/android/app/build.gradle b/android/app/build.gradle index 74cd0f8f7..00cef6393 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -46,7 +46,7 @@ android { defaultConfig { applicationId appProperties['id'] minSdkVersion 21 - targetSdkVersion 30 + targetSdkVersion 31 versionCode flutterVersionCode.toInteger() versionName flutterVersionName testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" From 91941e7c80fc01141b7215afe3f918ed92cfdaf4 Mon Sep 17 00:00:00 2001 From: mkyq <53115730+mkyq@users.noreply.github.com> Date: Wed, 16 Nov 2022 20:19:23 -0500 Subject: [PATCH 07/12] Update build number for android cakewallet to 134; monero.com to 30. (#631) --- scripts/android/app_env.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/android/app_env.sh b/scripts/android/app_env.sh index e57d3a97c..1cb3084cf 100644 --- a/scripts/android/app_env.sh +++ b/scripts/android/app_env.sh @@ -15,13 +15,13 @@ APP_ANDROID_TYPE=$1 MONERO_COM_NAME="Monero.com" MONERO_COM_VERSION="1.2.1" -MONERO_COM_BUILD_NUMBER=29 +MONERO_COM_BUILD_NUMBER=30 MONERO_COM_BUNDLE_ID="com.monero.app" MONERO_COM_PACKAGE="com.monero.app" CAKEWALLET_NAME="Cake Wallet" CAKEWALLET_VERSION="4.5.1" -CAKEWALLET_BUILD_NUMBER=133 +CAKEWALLET_BUILD_NUMBER=134 CAKEWALLET_BUNDLE_ID="com.cakewallet.cake_wallet" CAKEWALLET_PACKAGE="com.cakewallet.cake_wallet" From 841b69aef743b8d984ff81de817735072104de31 Mon Sep 17 00:00:00 2001 From: mkyq <53115730+mkyq@users.noreply.github.com> Date: Wed, 16 Nov 2022 21:55:26 -0500 Subject: [PATCH 08/12] Android exported (#632) * Add android:exported="true" to android activity. * Update build version for android for cakewallet to 135; monero.com 31. --- android/app/src/main/AndroidManifestBase.xml | 3 ++- scripts/android/app_env.sh | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/android/app/src/main/AndroidManifestBase.xml b/android/app/src/main/AndroidManifestBase.xml index f43b0369b..22278d5f1 100644 --- a/android/app/src/main/AndroidManifestBase.xml +++ b/android/app/src/main/AndroidManifestBase.xml @@ -21,7 +21,8 @@ android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode" android:hardwareAccelerated="true" android:windowSoftInputMode="adjustResize" - android:screenOrientation="portrait"> + android:screenOrientation="portrait" + android:exported="true"> Date: Wed, 16 Nov 2022 22:00:59 -0500 Subject: [PATCH 09/12] Update android build version for cakewallet to 136; monero.com 32. (#633) --- scripts/android/app_env.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/android/app_env.sh b/scripts/android/app_env.sh index 51e9fcdec..d361c8dfa 100644 --- a/scripts/android/app_env.sh +++ b/scripts/android/app_env.sh @@ -15,13 +15,13 @@ APP_ANDROID_TYPE=$1 MONERO_COM_NAME="Monero.com" MONERO_COM_VERSION="1.2.1" -MONERO_COM_BUILD_NUMBER=31 +MONERO_COM_BUILD_NUMBER=32 MONERO_COM_BUNDLE_ID="com.monero.app" MONERO_COM_PACKAGE="com.monero.app" CAKEWALLET_NAME="Cake Wallet" CAKEWALLET_VERSION="4.5.1" -CAKEWALLET_BUILD_NUMBER=135 +CAKEWALLET_BUILD_NUMBER=136 CAKEWALLET_BUNDLE_ID="com.cakewallet.cake_wallet" CAKEWALLET_PACKAGE="com.cakewallet.cake_wallet" From bcf09b048c635206e978ea1628ecb23201228c99 Mon Sep 17 00:00:00 2001 From: Omar Hatem Date: Tue, 22 Nov 2022 03:52:03 +0200 Subject: [PATCH 10/12] Cw 220 fix grey exchange screen (#641) * Fix nullability issue for ChangeNow rateId * Handle concurrent modification error from Splay Tree --- .../exchange/exchange_view_model.dart | 158 +++++++++--------- 1 file changed, 83 insertions(+), 75 deletions(-) diff --git a/lib/view_model/exchange/exchange_view_model.dart b/lib/view_model/exchange/exchange_view_model.dart index e7e73855b..725208324 100644 --- a/lib/view_model/exchange/exchange_view_model.dart +++ b/lib/view_model/exchange/exchange_view_model.dart @@ -7,7 +7,6 @@ import 'package:cake_wallet/exchange/sideshift/sideshift_exchange_provider.dart' import 'package:cake_wallet/exchange/sideshift/sideshift_request.dart'; import 'package:cake_wallet/exchange/simpleswap/simpleswap_exchange_provider.dart'; import 'package:cake_wallet/view_model/settings/settings_view_model.dart'; -import 'package:cw_core/transaction_priority.dart'; import 'package:cake_wallet/exchange/simpleswap/simpleswap_request.dart'; import 'package:cw_core/wallet_base.dart'; import 'package:cw_core/crypto_currency.dart'; @@ -375,96 +374,105 @@ abstract class ExchangeViewModelBase with Store { TradeRequest? request; String amount = ''; - for (var provider in _sortedAvailableProviders.values) { - if (!(await provider.checkIsAvailable())) { - continue; - } + try { + for (var provider in _sortedAvailableProviders.values) { + if (!(await provider.checkIsAvailable())) { + continue; + } - if (provider is SideShiftExchangeProvider) { - request = SideShiftRequest( - depositMethod: depositCurrency, - settleMethod: receiveCurrency, - depositAmount: depositAmount.replaceAll(',', '.'), - settleAddress: receiveAddress, - refundAddress: depositAddress, - ); - amount = depositAmount; - } + if (provider is SideShiftExchangeProvider) { + request = SideShiftRequest( + depositMethod: depositCurrency, + settleMethod: receiveCurrency, + depositAmount: depositAmount.replaceAll(',', '.'), + settleAddress: receiveAddress, + refundAddress: depositAddress, + ); + amount = depositAmount; + } - if (provider is SimpleSwapExchangeProvider) { - request = SimpleSwapRequest( - from: depositCurrency, - to: receiveCurrency, - amount: depositAmount.replaceAll(',', '.'), - address: receiveAddress, - refundAddress: depositAddress, - ); - amount = depositAmount; - } - - if (provider is XMRTOExchangeProvider) { - request = XMRTOTradeRequest( + if (provider is SimpleSwapExchangeProvider) { + request = SimpleSwapRequest( from: depositCurrency, to: receiveCurrency, amount: depositAmount.replaceAll(',', '.'), - receiveAmount: receiveAmount.replaceAll(',', '.'), address: receiveAddress, refundAddress: depositAddress, - isBTCRequest: isReceiveAmountEntered); - amount = depositAmount; - } + ); + amount = depositAmount; + } - if (provider is ChangeNowExchangeProvider) { - request = ChangeNowRequest( - from: depositCurrency, - to: receiveCurrency, - fromAmount: depositAmount.replaceAll(',', '.'), - toAmount: receiveAmount.replaceAll(',', '.'), - refundAddress: depositAddress, - address: receiveAddress, - isReverse: isReverse); - amount = isReverse ? receiveAmount : depositAmount; - } + if (provider is XMRTOExchangeProvider) { + request = XMRTOTradeRequest( + from: depositCurrency, + to: receiveCurrency, + amount: depositAmount.replaceAll(',', '.'), + receiveAmount: receiveAmount.replaceAll(',', '.'), + address: receiveAddress, + refundAddress: depositAddress, + isBTCRequest: isReceiveAmountEntered); + amount = depositAmount; + } - if (provider is MorphTokenExchangeProvider) { - request = MorphTokenRequest( - from: depositCurrency, - to: receiveCurrency, - amount: depositAmount.replaceAll(',', '.'), - refundAddress: depositAddress, - address: receiveAddress); - amount = depositAmount; - } + if (provider is ChangeNowExchangeProvider) { + request = ChangeNowRequest( + from: depositCurrency, + to: receiveCurrency, + fromAmount: depositAmount.replaceAll(',', '.'), + toAmount: receiveAmount.replaceAll(',', '.'), + refundAddress: depositAddress, + address: receiveAddress, + isReverse: isReverse); + amount = isReverse ? receiveAmount : depositAmount; + } - amount = amount.replaceAll(',', '.'); + if (provider is MorphTokenExchangeProvider) { + request = MorphTokenRequest( + from: depositCurrency, + to: receiveCurrency, + amount: depositAmount.replaceAll(',', '.'), + refundAddress: depositAddress, + address: receiveAddress); + amount = depositAmount; + } - if (limitsState is LimitsLoadedSuccessfully) { - if (double.parse(amount) < limits.min!) { - continue; - } else if (limits.max != null && double.parse(amount) > limits.max!) { - continue; - } else { - try { - tradeState = TradeIsCreating(); - final trade = await provider.createTrade( - request: request!, isFixedRateMode: isFixedRateMode); - trade.walletId = wallet.id; - tradesStore.setTrade(trade); - await trades.add(trade); - tradeState = TradeIsCreatedSuccessfully(trade: trade); - /// return after the first successful trade - return; - } catch (e) { + amount = amount.replaceAll(',', '.'); + + if (limitsState is LimitsLoadedSuccessfully) { + if (double.parse(amount) < limits.min!) { continue; + } else if (limits.max != null && double.parse(amount) > limits.max!) { + continue; + } else { + try { + tradeState = TradeIsCreating(); + final trade = await provider.createTrade( + request: request!, isFixedRateMode: isFixedRateMode); + trade.walletId = wallet.id; + tradesStore.setTrade(trade); + await trades.add(trade); + tradeState = TradeIsCreatedSuccessfully(trade: trade); + /// return after the first successful trade + return; + } catch (e) { + continue; + } } } } - } - /// if the code reached here then none of the providers succeeded - tradeState = TradeIsCreatedFailure( - title: S.current.trade_not_created, - error: S.current.none_of_selected_providers_can_exchange); + /// if the code reached here then none of the providers succeeded + tradeState = TradeIsCreatedFailure( + title: S.current.trade_not_created, + error: S.current.none_of_selected_providers_can_exchange); + } on ConcurrentModificationError { + /// if create trade happened at the exact same time of the scheduled rate update + /// then delay the create trade a bit and try again + /// + /// this is because the limitation of the SplayTreeMap that + /// you can't modify it while iterating through it + Future.delayed(Duration(milliseconds: 500), createTrade); + } } @action From 9b32c9c95666093841621b4753b0de40e8a19f37 Mon Sep 17 00:00:00 2001 From: Omar Hatem Date: Tue, 22 Nov 2022 04:18:18 +0200 Subject: [PATCH 11/12] CW-227 Add Disable Exchange option to settings (#642) * Add Disable Exchange option to settings --- lib/entities/preferences_key.dart | 1 + lib/src/screens/dashboard/dashboard_page.dart | 4 +++- lib/store/settings_store.dart | 8 ++++++++ lib/view_model/dashboard/dashboard_view_model.dart | 6 ++---- lib/view_model/settings/settings_view_model.dart | 6 ++++++ 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 ++- 20 files changed, 50 insertions(+), 20 deletions(-) diff --git a/lib/entities/preferences_key.dart b/lib/entities/preferences_key.dart index 6cf7e5608..a28410192 100644 --- a/lib/entities/preferences_key.dart +++ b/lib/entities/preferences_key.dart @@ -11,6 +11,7 @@ class PreferencesKey { static const shouldSaveRecipientAddressKey = 'save_recipient_address'; static const allowBiometricalAuthenticationKey = 'allow_biometrical_authentication'; + static const disableExchangeKey = 'disable_exchange'; static const currentTheme = 'current_theme'; static const isDarkThemeLegacy = 'dark_theme'; static const displayActionListModeKey = 'display_list_mode'; diff --git a/lib/src/screens/dashboard/dashboard_page.dart b/lib/src/screens/dashboard/dashboard_page.dart index f3d5a21fb..fe8414134 100644 --- a/lib/src/screens/dashboard/dashboard_page.dart +++ b/lib/src/screens/dashboard/dashboard_page.dart @@ -315,6 +315,8 @@ class DashboardPage extends BasePage { } Future _onClickExchangeButton(BuildContext context) async { - await Navigator.of(context).pushNamed(Routes.exchange); + if (walletViewModel.isEnabledExchangeAction) { + await Navigator.of(context).pushNamed(Routes.exchange); + } } } diff --git a/lib/store/settings_store.dart b/lib/store/settings_store.dart index 2b3105a34..534ea67e9 100644 --- a/lib/store/settings_store.dart +++ b/lib/store/settings_store.dart @@ -30,6 +30,7 @@ abstract class SettingsStoreBase with Store { required BalanceDisplayMode initialBalanceDisplayMode, required bool initialSaveRecipientAddress, required bool initialAllowBiometricalAuthentication, + required bool initialExchangeEnabled, required ThemeBase initialTheme, required int initialPinLength, required String initialLanguageCode, @@ -47,6 +48,7 @@ abstract class SettingsStoreBase with Store { balanceDisplayMode = initialBalanceDisplayMode, shouldSaveRecipientAddress = initialSaveRecipientAddress, allowBiometricalAuthentication = initialAllowBiometricalAuthentication, + disableExchange = initialExchangeEnabled, currentTheme = initialTheme, pinCodeLength = initialPinLength, languageCode = initialLanguageCode, @@ -143,6 +145,9 @@ abstract class SettingsStoreBase with Store { @observable bool allowBiometricalAuthentication; + @observable + bool disableExchange; + @observable ThemeBase currentTheme; @@ -221,6 +226,8 @@ abstract class SettingsStoreBase with Store { final allowBiometricalAuthentication = sharedPreferences .getBool(PreferencesKey.allowBiometricalAuthenticationKey) ?? false; + final disableExchange = sharedPreferences + .getBool(PreferencesKey.disableExchangeKey) ?? false; final legacyTheme = (sharedPreferences.getBool(PreferencesKey.isDarkThemeLegacy) ?? false) ? ThemeType.dark.index @@ -284,6 +291,7 @@ abstract class SettingsStoreBase with Store { initialBalanceDisplayMode: currentBalanceDisplayMode, initialSaveRecipientAddress: shouldSaveRecipientAddress, initialAllowBiometricalAuthentication: allowBiometricalAuthentication, + initialExchangeEnabled: disableExchange, initialTheme: savedTheme, actionlistDisplayMode: actionListDisplayMode, initialPinLength: pinLength, diff --git a/lib/view_model/dashboard/dashboard_view_model.dart b/lib/view_model/dashboard/dashboard_view_model.dart index 49dd2437a..7f11b0c2f 100644 --- a/lib/view_model/dashboard/dashboard_view_model.dart +++ b/lib/view_model/dashboard/dashboard_view_model.dart @@ -53,7 +53,6 @@ abstract class DashboardViewModelBase with Store { hasBuyAction = false, isEnabledBuyAction = false, hasExchangeAction = false, - isEnabledExchangeAction = false, isShowFirstYatIntroduction = false, isShowSecondYatIntroduction = false, isShowThirdYatIntroduction = false, @@ -249,8 +248,8 @@ abstract class DashboardViewModelBase with Store { void furtherShowYatPopup(bool shouldShow) => settingsStore.shouldShowYatPopup = shouldShow; - @observable - bool isEnabledExchangeAction; + @computed + bool get isEnabledExchangeAction => !settingsStore.disableExchange; @observable bool hasExchangeAction; @@ -365,7 +364,6 @@ abstract class DashboardViewModelBase with Store { } void updateActions() { - isEnabledExchangeAction = true; hasExchangeAction = !isHaven; isEnabledBuyAction = wallet.type != WalletType.haven && wallet.type != WalletType.monero; diff --git a/lib/view_model/settings/settings_view_model.dart b/lib/view_model/settings/settings_view_model.dart index aabe51ef1..f85d2c459 100644 --- a/lib/view_model/settings/settings_view_model.dart +++ b/lib/view_model/settings/settings_view_model.dart @@ -208,6 +208,12 @@ abstract class SettingsViewModelBase with Store { setAllowBiometricalAuthentication(value); } }), + SwitcherListItem( + title: S.current.disable_exchange, + value: () => _settingsStore.disableExchange, + onValueChange: (BuildContext context, bool value) { + _settingsStore.disableExchange = value; + }), ChoicesListItem( title: S.current.color_theme, items: ThemeList.all, diff --git a/res/values/strings_de.arb b/res/values/strings_de.arb index 685d817d5..f5170b84e 100644 --- a/res/values/strings_de.arb +++ b/res/values/strings_de.arb @@ -651,5 +651,6 @@ "ignor": "Ignorieren", "use_suggested": "Vorgeschlagen verwenden", "do_not_share_warning_text" : "Teilen Sie diese nicht mit anderen, einschließlich des Supports.\n\nSie werden Ihr Geld stehlen!", - "help": "hilfe" + "help": "hilfe", + "disable_exchange": "Exchange deaktivieren" } diff --git a/res/values/strings_en.arb b/res/values/strings_en.arb index 877d09231..b62dbd984 100644 --- a/res/values/strings_en.arb +++ b/res/values/strings_en.arb @@ -651,5 +651,6 @@ "ignor": "Ignore", "use_suggested": "Use Suggested", "do_not_share_warning_text" : "Do not share these with anyone else, including support.\n\nThey will steal your money!", - "help": "help" + "help": "help", + "disable_exchange": "Disable exchange" } diff --git a/res/values/strings_es.arb b/res/values/strings_es.arb index 505f3ffa8..beff1af8d 100644 --- a/res/values/strings_es.arb +++ b/res/values/strings_es.arb @@ -651,5 +651,6 @@ "ignor": "Pasar por alto", "use_suggested": "Usar sugerido", "do_not_share_warning_text" : "No comparta estos con nadie más, incluido el soporte.\n\n¡Te robarán tu dinero!", - "help": "ayuda" + "help": "ayuda", + "disable_exchange": "Deshabilitar intercambio" } diff --git a/res/values/strings_fr.arb b/res/values/strings_fr.arb index 941016c0b..fa1d01e22 100644 --- a/res/values/strings_fr.arb +++ b/res/values/strings_fr.arb @@ -649,5 +649,6 @@ "ignor": "Ignorer", "use_suggested": "Utilisation suggérée", "do_not_share_warning_text" : "Ne les partagez avec personne d'autre, y compris avec l'assistance.\n\nIls vont voler votre argent!", - "help": "aider" + "help": "aider", + "disable_exchange": "Désactiver l'échange" } diff --git a/res/values/strings_hi.arb b/res/values/strings_hi.arb index 7faa06f7f..c7b6ece40 100644 --- a/res/values/strings_hi.arb +++ b/res/values/strings_hi.arb @@ -651,5 +651,6 @@ "ignor": "नज़रअंदाज़ करना", "use_suggested": "सुझाए गए का प्रयोग करें", "do_not_share_warning_text" : "इन्हें समर्थन सहित किसी और के साथ साझा न करें।\n\nवे आपका पैसा चुरा लेंगे!", - "help": "मदद करना" + "help": "मदद करना", + "disable_exchange": "एक्सचेंज अक्षम करें" } diff --git a/res/values/strings_hr.arb b/res/values/strings_hr.arb index 4fa77948a..532a4d63a 100644 --- a/res/values/strings_hr.arb +++ b/res/values/strings_hr.arb @@ -651,5 +651,6 @@ "ignor": "Zanemariti", "use_suggested": "Koristite predloženo", "do_not_share_warning_text" : "Nemojte ih dijeliti ni s kim, uključujući podršku.\n\nUkrast će vam novac!", - "help": "pomozite" + "help": "pomozite", + "disable_exchange": "Onemogući exchange" } diff --git a/res/values/strings_it.arb b/res/values/strings_it.arb index 9a42a588b..cb5209fc3 100644 --- a/res/values/strings_it.arb +++ b/res/values/strings_it.arb @@ -651,5 +651,6 @@ "ignor": "Ignorare", "use_suggested": "Usa suggerito", "do_not_share_warning_text" : "Non condividerli con nessun altro, incluso il supporto.\n\nTi ruberanno i soldi!", - "help": "aiuto" + "help": "aiuto", + "disable_exchange": "Disabilita scambio" } diff --git a/res/values/strings_ja.arb b/res/values/strings_ja.arb index c1d0de4e3..2d1c291ce 100644 --- a/res/values/strings_ja.arb +++ b/res/values/strings_ja.arb @@ -651,5 +651,6 @@ "ignor": "無視", "use_suggested": "推奨を使用", "do_not_share_warning_text" : "サポートを含め、これらを他の誰とも共有しないでください。\n\n彼らはあなたのお金を盗みます!", - "help": "ヘルプ" + "help": "ヘルプ", + "disable_exchange": "交換を無効にする" } diff --git a/res/values/strings_ko.arb b/res/values/strings_ko.arb index 127aa949e..f24e736cb 100644 --- a/res/values/strings_ko.arb +++ b/res/values/strings_ko.arb @@ -651,5 +651,6 @@ "ignor": "무시하다", "use_suggested": "추천 사용", "do_not_share_warning_text" : "지원을 포함하여 다른 사람과 이러한 정보를 공유하지 마십시오.\n\n그들은 당신의 돈을 훔칠 것입니다!", - "help": "돕다" + "help": "돕다", + "disable_exchange": "교환 비활성화" } diff --git a/res/values/strings_nl.arb b/res/values/strings_nl.arb index fa748b552..5663b0357 100644 --- a/res/values/strings_nl.arb +++ b/res/values/strings_nl.arb @@ -651,5 +651,6 @@ "ignor": "Negeren", "use_suggested": "Gebruik aanbevolen", "do_not_share_warning_text" : "Deel deze met niemand anders, ook niet met support.\n\nZe zullen je geld stelen!", - "help": "helpen" + "help": "helpen", + "disable_exchange": "Uitwisseling uitschakelen" } diff --git a/res/values/strings_pl.arb b/res/values/strings_pl.arb index 454fe9717..f2a414ae2 100644 --- a/res/values/strings_pl.arb +++ b/res/values/strings_pl.arb @@ -651,5 +651,6 @@ "ignor": "Ignorować", "use_suggested": "Użyj sugerowane", "do_not_share_warning_text" : "Nie udostępniaj ich nikomu innemu, w tym wsparcia.\n\nUkradną twoje pieniądze!", - "help": "pomoc" + "help": "pomoc", + "disable_exchange": "Wyłącz wymianę" } diff --git a/res/values/strings_pt.arb b/res/values/strings_pt.arb index 04a0a3ff2..25318dc2d 100644 --- a/res/values/strings_pt.arb +++ b/res/values/strings_pt.arb @@ -651,5 +651,6 @@ "ignor": "Ignorar", "use_suggested": "Uso sugerido", "do_not_share_warning_text" : "Não os compartilhe com mais ninguém, incluindo suporte.\n\nEles vão roubar seu dinheiro!", - "help": "ajuda" + "help": "ajuda", + "disable_exchange": "Desativar troca" } diff --git a/res/values/strings_ru.arb b/res/values/strings_ru.arb index 632b0990c..a907e5765 100644 --- a/res/values/strings_ru.arb +++ b/res/values/strings_ru.arb @@ -651,5 +651,6 @@ "ignor": "Игнорировать", "use_suggested": "Использовать предложенный", "do_not_share_warning_text" : "Не делитесь ими с кем-либо еще, в том числе со службой поддержки.\n\nОни украдут ваши деньги!", - "help": "помощь" + "help": "помощь", + "disable_exchange": "Отключить обмен" } diff --git a/res/values/strings_uk.arb b/res/values/strings_uk.arb index 5e0f0d18a..91042e91b 100644 --- a/res/values/strings_uk.arb +++ b/res/values/strings_uk.arb @@ -650,5 +650,6 @@ "ignor": "Ігнорувати", "use_suggested": "Використати запропоноване", "do_not_share_warning_text" : "Не повідомляйте їх нікому, включно зі службою підтримки.\n\nВони вкрадуть ваші гроші!", - "help": "допомога" + "help": "допомога", + "disable_exchange": "Вимкнути exchange" } diff --git a/res/values/strings_zh.arb b/res/values/strings_zh.arb index c46d07d59..958e80d14 100644 --- a/res/values/strings_zh.arb +++ b/res/values/strings_zh.arb @@ -649,5 +649,6 @@ "ignor": "忽视", "use_suggested": "使用建议", "do_not_share_warning_text" : "不要與其他任何人分享這些內容,包括支持。\n\n他們會偷你的錢!", - "help": "帮助" + "help": "帮助", + "disable_exchange": "禁用交换" } From 4d91ef6af8b554f66f68239b8fde46a7be59d7f2 Mon Sep 17 00:00:00 2001 From: Omar Hatem Date: Sun, 27 Nov 2022 22:10:21 +0200 Subject: [PATCH 12/12] App Center Integration with CI/CD workflow (#644) Add Ionia client id to secrets Update how to build android instructions Change devicelocale version as it caused issues when building Add trigger for send test build to transfer.sh and notify slack channel --- .github/workflows/pr_test_build.yml | 116 ++++++++++++++++++++++++++++ howto-build-android.md | 8 +- pubspec_base.yaml | 2 +- tool/utils/secret_key.dart | 1 + 4 files changed, 124 insertions(+), 3 deletions(-) create mode 100644 .github/workflows/pr_test_build.yml diff --git a/.github/workflows/pr_test_build.yml b/.github/workflows/pr_test_build.yml new file mode 100644 index 000000000..dd2f1edeb --- /dev/null +++ b/.github/workflows/pr_test_build.yml @@ -0,0 +1,116 @@ +name: PR Test Build + +on: + pull_request: + branches: [ main ] + +jobs: + test: + + runs-on: ubuntu-18.04 + + steps: + - uses: actions/checkout@v2 + - uses: actions/setup-java@v1 + with: + java-version: '8.x' + + - name: Flutter action + uses: subosito/flutter-action@v1 + with: + flutter-version: '3.3.x' + channel: stable + + - name: Install package dependencies + run: sudo apt-get install -y curl unzip automake build-essential file pkg-config git python libtool libtinfo5 cmake clang + + - name: Execute Build and Setup Commands + run: | + sudo mkdir -p /opt/android + sudo chown $USER /opt/android + cd /opt/android + git clone https://github.com/cake-tech/cake_wallet.git --branch $GITHUB_HEAD_REF + cd cake_wallet/scripts/android/ + ./install_ndk.sh + source ./app_env.sh cakewallet + ./app_config.sh + ./build_all.sh + ./copy_monero_deps.sh + + - name: Install Flutter dependencies + run: | + cd /opt/android/cake_wallet + flutter pub get + + - name: Generate KeyStore + run: | + cd /opt/android/cake_wallet/android/app + keytool -genkey -v -keystore key.jks -keyalg RSA -keysize 2048 -validity 10000 -alias testKey -noprompt -dname "CN=CakeWallet, OU=CakeWallet, O=CakeWallet, L=Florida, S=America, C=USA" -storepass ${{ secrets.STORE_PASS }} -keypass ${{ secrets.KEY_PASS }} + + - name: Generate key properties + run: | + cd /opt/android/cake_wallet + flutter packages pub run tool/generate_android_key_properties.dart keyAlias=testKey storeFile=key.jks storePassword=${{ secrets.STORE_PASS }} keyPassword=${{ secrets.KEY_PASS }} + + - name: Generate localization + run: | + cd /opt/android/cake_wallet + flutter packages pub run tool/generate_localization.dart + + - name: Build generated code + run: | + cd /opt/android/cake_wallet + cd cw_core && flutter pub get && flutter packages pub run build_runner build --delete-conflicting-outputs && cd .. + cd cw_monero && flutter pub get && flutter packages pub run build_runner build --delete-conflicting-outputs && cd .. + cd cw_bitcoin && flutter pub get && flutter packages pub run build_runner build --delete-conflicting-outputs && cd .. + cd cw_haven && flutter pub get && flutter packages pub run build_runner build --delete-conflicting-outputs && cd .. + flutter packages pub run build_runner build --delete-conflicting-outputs + + - name: Add secrets + run: | + cd /opt/android/cake_wallet + touch lib/.secrets.g.dart + echo "const salt = '${{ secrets.SALT }}';" > lib/.secrets.g.dart + echo "const keychainSalt = '${{ secrets.KEY_CHAIN_SALT }}';" >> lib/.secrets.g.dart + echo "const key = '${{ secrets.KEY }}';" >> lib/.secrets.g.dart + echo "const walletSalt = '${{ secrets.WALLET_SALT }}';" >> lib/.secrets.g.dart + echo "const shortKey = '${{ secrets.SHORT_KEY }}';" >> lib/.secrets.g.dart + echo "const backupSalt = '${{ secrets.BACKUP_SALT }}';" >> lib/.secrets.g.dart + echo "const backupKeychainSalt = '${{ secrets.BACKUP_KEY_CHAIN_SALT }}';" >> lib/.secrets.g.dart + echo "const changeNowApiKey = '${{ secrets.CHANGE_NOW_API_KEY }}';" >> lib/.secrets.g.dart + echo "const wyreSecretKey = '${{ secrets.WYRE_SECRET_KEY }}';" >> lib/.secrets.g.dart + echo "const wyreApiKey = '${{ secrets.WYRE_API_KEY }}';" >> lib/.secrets.g.dart + echo "const wyreAccountId = '${{ secrets.WYRE_ACCOUNT_ID }}';" >> lib/.secrets.g.dart + echo "const moonPayApiKey = '${{ secrets.MOON_PAY_API_KEY }}';" >> lib/.secrets.g.dart + echo "const moonPaySecretKey = '${{ secrets.MOON_PAY_SECRET_KEY }}';" >> lib/.secrets.g.dart + echo "const sideShiftAffiliateId = '${{ secrets.SIDE_SHIFT_AFFILIATE_ID }}';" >> lib/.secrets.g.dart + echo "const sideShiftApiKey = '${{ secrets.SIDE_SHIFT_API_KEY }}';" >> lib/.secrets.g.dart + echo "const simpleSwapApiKey = '${{ secrets.SIMPLE_SWAP_API_KEY }}';" >> lib/.secrets.g.dart + echo "const onramperApiKey = '${{ secrets.ONRAMPER_API_KEY }}';" >> lib/.secrets.g.dart + echo "const anypayToken = '${{ secrets.ANY_PAY_TOKEN }}';" >> lib/.secrets.g.dart + echo "const ioniaClientId = '${{ secrets.IONIA_CLIENT_ID }}';" >> lib/.secrets.g.dart + + - name: Build + run: | + cd /opt/android/cake_wallet + flutter build apk --release + +# - name: Push to App Center +# run: | +# echo 'Installing App Center CLI tools' +# npm install -g appcenter-cli +# echo "Publishing test to App Center" +# appcenter distribute release \ +# --group "Testers" \ +# --file "/opt/android/cake_wallet/build/app/outputs/apk/release/app-release.apk" \ +# --release-notes ${GITHUB_HEAD_REF} \ +# --app Cake-Labs/Cake-Wallet \ +# --token ${{ secrets.APP_CENTER_TOKEN }} \ +# --quiet + + - name: Send Test APK + run: | + cd /opt/android/cake_wallet + var=$(curl --upload-file build/app/outputs/apk/release/app-release.apk https://transfer.sh/app-release.apk) + curl ${{ secrets.SLACK_WEB_HOOK }} -H "Content-Type: application/json" -d '{"apk_link": "'"$var"'","ticket": "'"$GITHUB_HEAD_REF"'"}' + diff --git a/howto-build-android.md b/howto-build-android.md index 28478cdd1..4ef385b9f 100644 --- a/howto-build-android.md +++ b/howto-build-android.md @@ -55,7 +55,7 @@ You may download and install the latest version of Android Studio [here](https:/ ### 3. Installing Flutter -Need to install flutter with version `2.0.4`. For this please check section [Install Flutter manually](https://docs.flutter.dev/get-started/install/linux#install-flutter-manually). When flutter repository is downloaded please open it with `cd ` and checkout version 2.0.4 by `git checkout 2.0.4`. +Need to install flutter with version `3.x.x`. For this please check section [Install Flutter manually](https://docs.flutter.dev/get-started/install/linux#install-flutter-manually). ### 4. Verify Installations @@ -66,7 +66,7 @@ Verify that the Android toolchain, Flutter, and Android Studio have been correct The output of this command will appear like this, indicating successful installations. If there are problems with your installation, they **must** be corrected before proceeding. ``` Doctor summary (to see all details, run flutter doctor -v): -[✓] Flutter (Channel stable, 2.0.4, on Linux, locale en_US.UTF-8) +[✓] Flutter (Channel stable, 3.x.x, on Linux, locale en_US.UTF-8) [✓] Android toolchain - develop for Android devices (Android SDK version 28) [✓] Android Studio (version 4.0) ``` @@ -156,6 +156,10 @@ Generate mobx models for `cw_bitcoin`: `cd cw_bitcoin && flutter pub get && flutter packages pub run build_runner build --delete-conflicting-outputs && cd ..` +Generate mobx models for `cw_haven`: + +`cd cw_haven && flutter pub get && flutter packages pub run build_runner build --delete-conflicting-outputs && cd ..` + Finally build mobx models for the app: `$ flutter packages pub run build_runner build --delete-conflicting-outputs` diff --git a/pubspec_base.yaml b/pubspec_base.yaml index 248a06de0..00e1a39b1 100644 --- a/pubspec_base.yaml +++ b/pubspec_base.yaml @@ -34,7 +34,7 @@ dependencies: local_auth: ^2.1.0 package_info: ^2.0.0 #package_info_plus: ^1.4.2 - devicelocale: ^0.5.4 + devicelocale: ^0.4.3 auto_size_text: ^3.0.0 dotted_border: ^2.0.0+2 smooth_page_indicator: ^1.0.0+2 diff --git a/tool/utils/secret_key.dart b/tool/utils/secret_key.dart index 64c7beefd..e5202a829 100644 --- a/tool/utils/secret_key.dart +++ b/tool/utils/secret_key.dart @@ -28,6 +28,7 @@ class SecretKey { SecretKey('simpleSwapApiKey', () => ''), SecretKey('anypayToken', () => ''), SecretKey('onramperApiKey', () => ''), + SecretKey('ioniaClientId', () => ''), ]; final String name;