Cw 150 cake pay introduction card (#486)

* create introducing card * add ability to close the card * update walletInfo class * update localization * fix intro text * fix card size * show card for existing and new wallet types * disable card for haven wallets * fixes to PR * fixes to PR * fix PR

Serhii committed Aug 30, 2022 at 21:03 UTC 7fae9cf9bb1cee6f1e84fb31a595c5baf150b0cc
21 files changed +189 -19
cw_core/lib/wallet_info.dart
+14 -3
@@ -9,7 +9,7 @@ part 'wallet_info.g.dart';
9 class WalletInfo extends HiveObject {
10 WalletInfo(this.id, this.name, this.type, this.isRecovery, this.restoreHeight,
11 this.timestamp, this.dirPath, this.path, this.address, this.yatEid,
12 - this.yatLastUsedAddressRaw)
12 + this.yatLastUsedAddressRaw, this.showIntroCakePayCard)
13 : _yatLastUsedAddressController = StreamController<String>.broadcast();
14
15 factory WalletInfo.external(
@@ -23,10 +23,11 @@ class WalletInfo extends HiveObject {
23 @required String path,
24 @required String address,
25 String yatEid ='',
26 - String yatLastUsedAddressRaw = ''}) {
26 + String yatLastUsedAddressRaw = '',
27 + bool showIntroCakePayCard}) {
28 return WalletInfo(id, name, type, isRecovery, restoreHeight,
29 date.millisecondsSinceEpoch ?? 0, dirPath, path, address,
29 - yatEid, yatLastUsedAddressRaw);
30 + yatEid, yatLastUsedAddressRaw, showIntroCakePayCard);
31 }
32
33 static const typeId = 4;
@@ -68,6 +69,9 @@ class WalletInfo extends HiveObject {
69 @HiveField(12)
70 String yatLastUsedAddressRaw;
71
72 + @HiveField(13)
73 + bool showIntroCakePayCard;
74 +
75 String get yatLastUsedAddress => yatLastUsedAddressRaw;
76
77 set yatLastUsedAddress(String address) {
@@ -77,6 +81,13 @@ class WalletInfo extends HiveObject {
81
82 String get yatEmojiId => yatEid ?? '';
83
84 + bool get isShowIntroCakePayCard {
85 + if(showIntroCakePayCard == null) {
86 + return type != WalletType.haven;
87 + }
88 + return showIntroCakePayCard;
89 + }
90 +
91 DateTime get date => DateTime.fromMillisecondsSinceEpoch(timestamp);
92
93 Stream<String> get yatLastUsedAddressStream => _yatLastUsedAddressController.stream;
lib/core/wallet_creation_service.dart
+6
@@ -46,6 +46,12 @@ class WalletCreationService {
46 .any((walletInfo) => walletInfo.name.toLowerCase() == walletName);
47 }
48
49 + bool typeExists(WalletType type) {
50 + return walletInfoSource
51 + .values
52 + .any((walletInfo) => walletInfo.type == type);
53 + }
54 +
55 void checkIfExists(String name) {
56 if (exists(name)) {
57 throw Exception('Wallet with name ${name} already exists!');
lib/src/screens/dashboard/widgets/balance_page.dart
+17
@@ -7,6 +7,9 @@ import 'package:cake_wallet/view_model/dashboard/dashboard_view_model.dart';
7 import 'package:flutter/scheduler.dart';
8 import 'package:flutter_mobx/flutter_mobx.dart';
9 import 'package:auto_size_text/auto_size_text.dart';
10 +import 'package:cake_wallet/src/widgets/introducing_card.dart';
11 +import 'package:cake_wallet/generated/i18n.dart';
12 +
13
14 class BalancePage extends StatelessWidget{
15 BalancePage({@required this.dashboardViewModel, @required this.settingsStore});
@@ -44,6 +47,19 @@ class BalancePage extends StatelessWidget{
47 maxLines: 1,
48 textAlign: TextAlign.center);
49 })),
50 + Observer(builder: (_) {
51 + if (dashboardViewModel.balanceViewModel.isShowCard){
52 + return IntroducingCard(
53 + title: S.of(context).introducing_cake_pay,
54 + subTitle: S.of(context).cake_pay_learn_more,
55 + borderColor: settingsStore.currentTheme.type == ThemeType.bright
56 + ? Color.fromRGBO(255, 255, 255, 0.2)
57 + : Colors.transparent,
58 + closeCard: dashboardViewModel.balanceViewModel.disableIntroCakePayCard
59 + );
60 + }
61 + return Container ();
62 + }),
63 Observer(builder: (_) {
64 return ListView.separated(
65 physics: NeverScrollableScrollPhysics(),
@@ -180,3 +196,4 @@ class BalancePage extends StatelessWidget{
196 );
197 }
198 }
199 +
lib/src/widgets/introducing_card.dart new
+89
@@ -0,0 +1,89 @@
1 +import 'package:auto_size_text/auto_size_text.dart';
2 +import 'package:flutter/material.dart';
3 +import 'package:cake_wallet/palette.dart';
4 +
5 +class IntroducingCard extends StatelessWidget {
6 + IntroducingCard(
7 + {this.borderColor, this.closeCard, this.title, this.subTitle});
8 +
9 + final String title;
10 + final String subTitle;
11 + final Color borderColor;
12 + final Function() closeCard;
13 +
14 + @override
15 + Widget build(BuildContext context) {
16 + return Padding(
17 + padding: const EdgeInsets.fromLTRB(16,0,16,16),
18 + child: Container(
19 + width: double.infinity,
20 + decoration: BoxDecoration(
21 + borderRadius: BorderRadius.circular(30.0),
22 + border: Border.all(
23 + color: borderColor,
24 + width: 1,
25 + ),
26 + color: Theme.of(context).textTheme.title.backgroundColor),
27 + child: Row(
28 + mainAxisAlignment: MainAxisAlignment.spaceBetween,
29 + crossAxisAlignment: CrossAxisAlignment.start,
30 + children: [
31 + Expanded(
32 + flex: 1,
33 + child: Padding(
34 + padding: const EdgeInsets.all(24),
35 + child: Column(
36 + crossAxisAlignment: CrossAxisAlignment.start,
37 + children: [
38 + AutoSizeText(title ?? '',
39 + style: TextStyle(
40 + fontSize: 24,
41 + fontFamily: 'Lato',
42 + fontWeight: FontWeight.bold,
43 + color: Theme.of(context)
44 + .accentTextTheme
45 + .display3
46 + .backgroundColor,
47 + height: 1),
48 + maxLines: 1,
49 + textAlign: TextAlign.center),
50 + SizedBox(height: 14),
51 + Text(subTitle ?? '',
52 + textAlign: TextAlign.left,
53 + style: TextStyle(
54 + fontSize: 12,
55 + fontFamily: 'Lato',
56 + color: Theme.of(context)
57 + .accentTextTheme
58 + .display3
59 + .backgroundColor,
60 + height: 1)),
61 + ],
62 + ),
63 + ),
64 + ),
65 + Padding(
66 + padding: const EdgeInsets.fromLTRB(0,16,16,0),
67 + child: GestureDetector(
68 + onTap: closeCard,
69 + child: Container(
70 + height: 23,
71 + width: 23,
72 + decoration: BoxDecoration(
73 + color: Colors.white, shape: BoxShape.circle),
74 + child: Center(
75 + child: Image.asset(
76 + 'assets/images/x.png',
77 + color: Palette.darkBlueCraiola,
78 + height: 15,
79 + width: 15,
80 + )),
81 + ),
82 + ),
83 + )
84 + ],
85 + ),
86 + ),
87 + );
88 + }
89 +}
lib/view_model/dashboard/balance_view_model.dart
+13
@@ -39,6 +39,7 @@ abstract class BalanceViewModelBase with Store {
39 @required this.fiatConvertationStore}) {
40 isReversing = false;
41 wallet ??= appStore.wallet;
42 + isShowCard = wallet.walletInfo.isShowIntroCakePayCard;
43 reaction((_) => appStore.wallet, _onWalletChange);
44 }
45
@@ -235,6 +236,9 @@ abstract class BalanceViewModelBase with Store {
236 @computed
237 CryptoCurrency get currency => appStore.wallet.currency;
238
239 + @observable
240 + bool isShowCard;
241 +
242 ReactionDisposer _onCurrentWalletChangeReaction;
243
244 @action
@@ -244,6 +248,15 @@ abstract class BalanceViewModelBase with Store {
248 wallet) {
249 this.wallet = wallet;
250 _onCurrentWalletChangeReaction?.reaction?.dispose();
251 + isShowCard = wallet.walletInfo.isShowIntroCakePayCard;
252 + }
253 +
254 + @action
255 + Future<void> disableIntroCakePayCard () async {
256 + const cardDisplayStatus = false;
257 + wallet.walletInfo.showIntroCakePayCard = cardDisplayStatus;
258 + await wallet.walletInfo.save();
259 + isShowCard = cardDisplayStatus;
260 }
261
262 String _getFiatBalance({double price, String cryptoAmount}) {
lib/view_model/wallet_creation_vm.dart
+5 -1
@@ -37,6 +37,9 @@ abstract class WalletCreationVMBase with Store {
37 bool nameExists(String name)
38 => walletCreationService.exists(name);
39
40 + bool typeExists(WalletType type)
41 + => walletCreationService.typeExists(type);
42 +
43 Future<void> create({dynamic options}) async {
44 try {
45 state = IsExecutingState();
@@ -56,7 +59,8 @@ abstract class WalletCreationVMBase with Store {
59 restoreHeight: credentials.height ?? 0,
60 date: DateTime.now(),
61 path: path,
59 - dirPath: dirPath);
62 + dirPath: dirPath,
63 + showIntroCakePayCard: (!walletCreationService.typeExists(type)) && type != WalletType.haven);
64 credentials.walletInfo = walletInfo;
65 final wallet = await process(credentials);
66 walletInfo.address = wallet.walletAddresses.address;
res/values/strings_de.arb
+3 -1
@@ -632,5 +632,7 @@
632 "gift_card_is_generated": "Geschenkkarte wird generiert",
633 "open_gift_card": "Geschenkkarte öffnen",
634 "contact_support": "Support kontaktieren",
635 - "gift_cards_unavailable": "Geschenkkarten können derzeit nur über Monero, Bitcoin und Litecoin erworben werden"
635 + "gift_cards_unavailable": "Geschenkkarten können derzeit nur über Monero, Bitcoin und Litecoin erworben werden",
636 + "introducing_cake_pay": "Einführung von Cake Pay!",
637 + "cake_pay_learn_more": "Karten sofort in der App kaufen und einlösen!\nWischen Sie nach rechts, um mehr zu erfahren!"
638 }
res/values/strings_en.arb
+3 -1
@@ -632,5 +632,7 @@
632 "gift_card_is_generated": "Gift Card is generated",
633 "open_gift_card": "Open Gift Card",
634 "contact_support": "Contact Support",
635 - "gift_cards_unavailable": "Gift cards are available for purchase only with Monero, Bitcoin, and Litecoin at this time"
635 + "gift_cards_unavailable": "Gift cards are available for purchase only with Monero, Bitcoin, and Litecoin at this time",
636 + "introducing_cake_pay": "Introducing Cake Pay!",
637 + "cake_pay_learn_more": "Instantly purchase and redeem cards in the app!\nSwipe right to learn more!"
638 }
res/values/strings_es.arb
+3 -1
@@ -632,5 +632,7 @@
632 "gift_card_is_generated": "Se genera la tarjeta de regalo",
633 "open_gift_card": "Abrir tarjeta de regalo",
634 "contact_support": "Contactar con Soporte",
635 - "gift_cards_unavailable": "Las tarjetas de regalo están disponibles para comprar solo a través de Monero, Bitcoin y Litecoin en este momento"
635 + "gift_cards_unavailable": "Las tarjetas de regalo están disponibles para comprar solo a través de Monero, Bitcoin y Litecoin en este momento",
636 + "introducing_cake_pay": "¡Presentamos Cake Pay!",
637 + "cake_pay_learn_more": "¡Compre y canjee tarjetas al instante en la aplicación!\n¡Desliza hacia la derecha para obtener más información!"
638 }
res/values/strings_fr.arb
+3 -1
@@ -630,5 +630,7 @@
630 "gift_card_is_generated": "La carte-cadeau est générée",
631 "open_gift_card": "Ouvrir la carte-cadeau",
632 "contact_support": "Contacter l'assistance",
633 - "gift_cards_unavailable": "Les cartes-cadeaux ne sont disponibles à l'achat que via Monero, Bitcoin et Litecoin pour le moment"
633 + "gift_cards_unavailable": "Les cartes-cadeaux ne sont disponibles à l'achat que via Monero, Bitcoin et Litecoin pour le moment",
634 + "introducing_cake_pay": "Présentation de Cake Pay!",
635 + "cake_pay_learn_more": "Achetez et échangez instantanément des cartes dans l'application !\nBalayez vers la droite pour en savoir plus !"
636 }
res/values/strings_hi.arb
+3 -1
@@ -632,5 +632,7 @@
632 "gift_card_is_generated": "गिफ्ट कार्ड जनरेट हुआ",
633 "open_gift_card": "गिफ्ट कार्ड खोलें",
634 "contact_support": "सहायता से संपर्क करें",
635 - "gift_cards_unavailable": "उपहार कार्ड इस समय केवल मोनेरो, बिटकॉइन और लिटकोइन के माध्यम से खरीदने के लिए उपलब्ध हैं"
635 + "gift_cards_unavailable": "उपहार कार्ड इस समय केवल मोनेरो, बिटकॉइन और लिटकोइन के माध्यम से खरीदने के लिए उपलब्ध हैं",
636 + "introducing_cake_pay": "परिचय Cake Pay!",
637 + "cake_pay_learn_more": "ऐप में तुरंत कार्ड खरीदें और रिडीम करें!\nअधिक जानने के लिए दाएं स्वाइप करें!"
638 }
res/values/strings_hr.arb
+3 -1
@@ -632,5 +632,7 @@
632 "gift_card_is_generated": "Poklon kartica je generirana",
633 "open_gift_card": "Otvori darovnu karticu",
634 "contact_support": "Kontaktirajte podršku",
635 - "gift_cards_unavailable": "Poklon kartice trenutno su dostupne za kupnju samo putem Monera, Bitcoina i Litecoina"
635 + "gift_cards_unavailable": "Poklon kartice trenutno su dostupne za kupnju samo putem Monera, Bitcoina i Litecoina",
636 + "introducing_cake_pay": "Predstavljamo Cake Pay!",
637 + "cake_pay_learn_more": "Odmah kupite i iskoristite kartice u aplikaciji!\nPrijeđite prstom udesno da biste saznali više!"
638 }
res/values/strings_it.arb
+3 -1
@@ -632,5 +632,7 @@
632 "gift_card_is_generated": "Il buono regalo è stato generato",
633 "open_gift_card": "Apri carta regalo",
634 "contact_support": "Contatta l'assistenza",
635 - "gift_cards_unavailable": "Le carte regalo sono disponibili per l'acquisto solo tramite Monero, Bitcoin e Litecoin in questo momento"
635 + "gift_cards_unavailable": "Le carte regalo sono disponibili per l'acquisto solo tramite Monero, Bitcoin e Litecoin in questo momento",
636 + "introducing_cake_pay": "Presentazione di Cake Pay!",
637 + "cake_pay_learn_more": "Acquista e riscatta istantaneamente le carte nell'app!\nScorri verso destra per saperne di più!"
638 }
res/values/strings_ja.arb
+3 -1
@@ -632,5 +632,7 @@
632 "gift_card_is_generated": "ギフトカードが生成されます",
633 "open_gift_card": "オープンギフトカード",
634 "contact_support": "サポートに連絡する",
635 - "gift_cards_unavailable": "現時点では、ギフトカードはMonero、Bitcoin、Litecoinからのみ購入できます。"
635 + "gift_cards_unavailable": "現時点では、ギフトカードはMonero、Bitcoin、Litecoinからのみ購入できます。",
636 + "introducing_cake_pay": "序章Cake Pay!",
637 + "cake_pay_learn_more": "アプリですぐにカードを購入して引き換えましょう!\n右にスワイプして詳細をご覧ください。"
638 }
res/values/strings_ko.arb
+3 -1
@@ -632,5 +632,7 @@
632 "gift_card_is_generated": "기프트 카드가 생성되었습니다",
633 "open_gift_card": "기프트 카드 열기",
634 "contact_support": "지원팀에 문의",
635 - "gift_cards_unavailable": "기프트 카드는 현재 Monero, Bitcoin 및 Litecoin을 통해서만 구매할 수 있습니다."
635 + "gift_cards_unavailable": "기프트 카드는 현재 Monero, Bitcoin 및 Litecoin을 통해서만 구매할 수 있습니다.",
636 + "introducing_cake_pay": "소개 Cake Pay!",
637 + "cake_pay_learn_more": "앱에서 즉시 카드를 구매하고 사용하세요!\n자세히 알아보려면 오른쪽으로 스와이프하세요!"
638 }
res/values/strings_nl.arb
+3 -1
@@ -632,5 +632,7 @@
632 "gift_card_is_generated": "Cadeaukaart is gegenereerd",
633 "open_gift_card": "Geschenkkaart openen",
634 "contact_support": "Contact opnemen met ondersteuning",
635 - "gift_cards_unavailable": "Cadeaubonnen kunnen momenteel alleen worden gekocht via Monero, Bitcoin en Litecoin"
635 + "gift_cards_unavailable": "Cadeaubonnen kunnen momenteel alleen worden gekocht via Monero, Bitcoin en Litecoin",
636 + "introducing_cake_pay": "Introductie van Cake Pay!",
637 + "cake_pay_learn_more": "Koop en wissel direct kaarten in de app!\nSwipe naar rechts voor meer informatie!"
638 }
res/values/strings_pl.arb
+3 -1
@@ -632,5 +632,7 @@
632 "gift_card_is_generated": "Karta podarunkowa jest generowana",
633 "open_gift_card": "Otwórz kartę podarunkową",
634 "contact_support": "Skontaktuj się z pomocą techniczną",
635 - "gift_cards_unavailable": "Karty podarunkowe można obecnie kupić tylko za pośrednictwem Monero, Bitcoin i Litecoin"
635 + "gift_cards_unavailable": "Karty podarunkowe można obecnie kupić tylko za pośrednictwem Monero, Bitcoin i Litecoin",
636 + "introducing_cake_pay": "Przedstawiamy Ciasto Pay!",
637 + "cake_pay_learn_more": "Natychmiast kupuj i realizuj karty w aplikacji!\nPrzesuń w prawo, aby dowiedzieć się więcej!"
638 }
res/values/strings_pt.arb
+3 -1
@@ -632,5 +632,7 @@
632 "gift_card_is_generated": "Cartão presente é gerado",
633 "open_gift_card": "Abrir vale-presente",
634 "contact_support": "Contatar Suporte",
635 - "gift_cards_unavailable": "Os cartões-presente estão disponíveis para compra apenas através do Monero, Bitcoin e Litecoin no momento"
635 + "gift_cards_unavailable": "Os cartões-presente estão disponíveis para compra apenas através do Monero, Bitcoin e Litecoin no momento",
636 + "introducing_cake_pay": "Apresentando o Cake Pay!",
637 + "cake_pay_learn_more": "Compre e resgate cartões instantaneamente no aplicativo!\nDeslize para a direita para saber mais!"
638 }
res/values/strings_ru.arb
+3 -1
@@ -632,5 +632,7 @@
632 "gift_card_is_generated": "Подарочная карта сгенерирована",
633 "open_gift_card": "Открыть подарочную карту",
634 "contact_support": "Связаться со службой поддержки",
635 - "gift_cards_unavailable": "В настоящее время подарочные карты можно приобрести только через Monero, Bitcoin и Litecoin."
635 + "gift_cards_unavailable": "В настоящее время подарочные карты можно приобрести только через Monero, Bitcoin и Litecoin.",
636 + "introducing_cake_pay": "Представляем Cake Pay!",
637 + "cake_pay_learn_more": "Мгновенно покупайте и погашайте карты в приложении!\nПроведите вправо, чтобы узнать больше!"
638 }
res/values/strings_uk.arb
+3 -1
@@ -631,5 +631,7 @@
631 "gift_card_is_generated": "Подарункова картка створена",
632 "open_gift_card": "Відкрити подарункову картку",
633 "contact_support": "Звернутися до служби підтримки",
634 - "gift_cards_unavailable": "Наразі подарункові картки можна придбати лише через Monero, Bitcoin і Litecoin"
634 + "gift_cards_unavailable": "Наразі подарункові картки можна придбати лише через Monero, Bitcoin і Litecoin",
635 + "introducing_cake_pay": "Представляємо Cake Pay!",
636 + "cake_pay_learn_more": "Миттєва купівля та погашення карток в додатку!\nПроведіть праворуч, щоб дізнатися більше!"
637 }
res/values/strings_zh.arb
+3 -1
@@ -630,5 +630,7 @@
630 "gift_card_is_generated": "礼品卡生成",
631 "open_gift_card": "打开礼品卡",
632 "contact_support": "联系支持",
633 - "gift_cards_unavailable": "目前只能通过门罗币、比特币和莱特币购买礼品卡"
633 + "gift_cards_unavailable": "目前只能通过门罗币、比特币和莱特币购买礼品卡",
634 + "introducing_cake_pay": "介绍 Cake Pay!",
635 + "cake_pay_learn_more": "立即在应用程序中购买和兑换卡!\n向右滑动了解更多!"
636 }