Merge branch 'ionia' of github.com:cake-tech/cake_wallet into ionia

This commit is contained in:
M 2022-06-21 09:49:10 +01:00
commit aab6d89afa
10 changed files with 133 additions and 63 deletions

View file

@ -3,6 +3,7 @@ import 'package:cake_wallet/entities/parse_address_from_domain.dart';
import 'package:cake_wallet/entities/wake_lock.dart'; import 'package:cake_wallet/entities/wake_lock.dart';
import 'package:cake_wallet/ionia/ionia_service.dart'; import 'package:cake_wallet/ionia/ionia_service.dart';
import 'package:cake_wallet/ionia/ionia_api.dart'; import 'package:cake_wallet/ionia/ionia_api.dart';
import 'package:cake_wallet/ionia/ionia_merchant.dart';
import 'package:cake_wallet/monero/monero.dart'; import 'package:cake_wallet/monero/monero.dart';
import 'package:cake_wallet/haven/haven.dart'; import 'package:cake_wallet/haven/haven.dart';
import 'package:cake_wallet/haven/haven.dart'; import 'package:cake_wallet/haven/haven.dart';
@ -652,8 +653,9 @@ Future setup(
getIt.registerFactory<IoniaService>( getIt.registerFactory<IoniaService>(
() => IoniaService(getIt.get<FlutterSecureStorage>(), getIt.get<IoniaApi>())); () => IoniaService(getIt.get<FlutterSecureStorage>(), getIt.get<IoniaApi>()));
getIt.registerFactory(() => IoniaViewModel(ioniaService: getIt.get<IoniaService>())); getIt.registerFactory(
() => IoniaViewModel(ioniaService: getIt.get<IoniaService>(), ioniaMerchantService: getIt.get<IoniaMerchantService>()));
getIt.registerFactory(() => IoniaCreateAccountPage(getIt.get<IoniaViewModel>())); getIt.registerFactory(() => IoniaCreateAccountPage(getIt.get<IoniaViewModel>()));
@ -668,9 +670,17 @@ Future setup(
getIt.registerFactory(() => IoniaWelcomePage(getIt.get<IoniaViewModel>())); getIt.registerFactory(() => IoniaWelcomePage(getIt.get<IoniaViewModel>()));
getIt.registerFactory(() => IoniaBuyGiftCardPage()); getIt.registerFactoryParam<IoniaBuyGiftCardPage, List, void>((List args, _) {
final merchant = args.first as IoniaMerchant;
getIt.registerFactory(() => IoniaBuyGiftCardDetailPage()); return IoniaBuyGiftCardPage(merchant);
});
getIt.registerFactoryParam<IoniaBuyGiftCardDetailPage, List, void>((List args, _) {
final merchant = args.first as IoniaMerchant;
return IoniaBuyGiftCardDetailPage(merchant);
});
getIt.registerFactory(() => IoniaManageCardsPage(getIt.get<IoniaViewModel>())); getIt.registerFactory(() => IoniaManageCardsPage(getIt.get<IoniaViewModel>()));

View file

@ -416,13 +416,15 @@ Route<dynamic> createRoute(RouteSettings settings) {
return CupertinoPageRoute<void>(builder: (_) => getIt.get<IoniaManageCardsPage>()); return CupertinoPageRoute<void>(builder: (_) => getIt.get<IoniaManageCardsPage>());
case Routes.ioniaBuyGiftCardPage: case Routes.ioniaBuyGiftCardPage:
return CupertinoPageRoute<void>(builder: (_) => getIt.get<IoniaBuyGiftCardPage>()); final args = settings.arguments as List;
return CupertinoPageRoute<void>(builder: (_) => getIt.get<IoniaBuyGiftCardPage>(param1: args));
case Routes.ioniaBuyGiftCardDetailPage: case Routes.ioniaBuyGiftCardDetailPage:
return CupertinoPageRoute<void>(builder: (_) => getIt.get<IoniaBuyGiftCardDetailPage>()); final args = settings.arguments as List;
return CupertinoPageRoute<void>(builder: (_) => getIt.get<IoniaBuyGiftCardDetailPage>(param1: args));
case Routes.ioniaVerifyIoniaOtpPage: case Routes.ioniaVerifyIoniaOtpPage:
final args = settings.arguments as List; final args = settings.arguments as List;
return CupertinoPageRoute<void>(builder: (_) =>getIt.get<IoniaVerifyIoniaOtp>(param1: args)); return CupertinoPageRoute<void>(builder: (_) =>getIt.get<IoniaVerifyIoniaOtp>(param1: args));
case Routes.ioniaDebitCardPage: case Routes.ioniaDebitCardPage:

View file

@ -30,7 +30,7 @@ class IoniaWelcomePage extends BasePage {
Widget body(BuildContext context) { Widget body(BuildContext context) {
reaction((_) => _ioniaViewModel.isLoggedIn, (bool state) { reaction((_) => _ioniaViewModel.isLoggedIn, (bool state) {
if (state) { if (state) {
Navigator.pushReplacementNamed(context, Routes.ioniaDebitCardPage); Navigator.pushReplacementNamed(context, Routes.ioniaManageCardsPage);
} }
}); });
return Padding( return Padding(

View file

@ -1,8 +1,8 @@
import 'package:cake_wallet/di.dart'; import 'package:cake_wallet/di.dart';
import 'package:cake_wallet/ionia/ionia_merchant.dart';
import 'package:cake_wallet/palette.dart'; import 'package:cake_wallet/palette.dart';
import 'package:cake_wallet/src/screens/ionia/widgets/confirm_modal.dart'; import 'package:cake_wallet/src/screens/ionia/widgets/confirm_modal.dart';
import 'package:cake_wallet/src/screens/ionia/widgets/text_icon_button.dart'; import 'package:cake_wallet/src/screens/ionia/widgets/text_icon_button.dart';
import 'package:cake_wallet/src/widgets/alert_with_two_actions.dart';
import 'package:cake_wallet/src/widgets/discount_badge.dart'; import 'package:cake_wallet/src/widgets/discount_badge.dart';
import 'package:cake_wallet/src/widgets/primary_button.dart'; import 'package:cake_wallet/src/widgets/primary_button.dart';
import 'package:cake_wallet/src/widgets/scollable_with_bottom_section.dart'; import 'package:cake_wallet/src/widgets/scollable_with_bottom_section.dart';
@ -14,6 +14,11 @@ import 'package:flutter/material.dart';
import 'package:cake_wallet/generated/i18n.dart'; import 'package:cake_wallet/generated/i18n.dart';
class IoniaBuyGiftCardDetailPage extends StatelessWidget { class IoniaBuyGiftCardDetailPage extends StatelessWidget {
const IoniaBuyGiftCardDetailPage(this.merchant);
final IoniaMerchant merchant;
ThemeBase get currentTheme => getIt.get<SettingsStore>().currentTheme; ThemeBase get currentTheme => getIt.get<SettingsStore>().currentTheme;
Color get backgroundLightColor => Colors.white; Color get backgroundLightColor => Colors.white;
@ -52,7 +57,7 @@ class IoniaBuyGiftCardDetailPage extends StatelessWidget {
Widget middle(BuildContext context) { Widget middle(BuildContext context) {
return Text( return Text(
'AppleBees', merchant.legalName,
style: TextStyle( style: TextStyle(
fontSize: 22, fontSize: 22,
fontFamily: 'Lato', fontFamily: 'Lato',
@ -74,7 +79,7 @@ class IoniaBuyGiftCardDetailPage extends StatelessWidget {
SizedBox(height: 60), SizedBox(height: 60),
Row( Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [leading(context), middle(context), DiscountBadge()], children: [leading(context), middle(context), DiscountBadge(percentage: merchant.minimumDiscount,)],
), ),
SizedBox(height: 36), SizedBox(height: 36),
Container( Container(

View file

@ -1,3 +1,4 @@
import 'package:cake_wallet/ionia/ionia_merchant.dart';
import 'package:cake_wallet/routes.dart'; import 'package:cake_wallet/routes.dart';
import 'package:cake_wallet/src/screens/base_page.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/screens/ionia/widgets/card_item.dart';
@ -12,9 +13,12 @@ import 'package:keyboard_actions/keyboard_actions.dart';
import 'package:cake_wallet/generated/i18n.dart'; import 'package:cake_wallet/generated/i18n.dart';
class IoniaBuyGiftCardPage extends BasePage { class IoniaBuyGiftCardPage extends BasePage {
IoniaBuyGiftCardPage() IoniaBuyGiftCardPage(this.merchant)
: _amountFieldFocus = FocusNode(), : _amountFieldFocus = FocusNode(),
_amountController = TextEditingController(); _amountController = TextEditingController();
final IoniaMerchant merchant;
@override @override
String get title => S.current.enter_amount; String get title => S.current.enter_amount;
@ -93,7 +97,7 @@ class IoniaBuyGiftCardPage extends BasePage {
left: _width / 4, left: _width / 4,
), ),
child: Text( child: Text(
'USD: ', '${merchant.acceptedCurrency}: ',
style: TextStyle( style: TextStyle(
color: Colors.white, color: Colors.white,
fontWeight: FontWeight.w900, fontWeight: FontWeight.w900,
@ -107,13 +111,13 @@ class IoniaBuyGiftCardPage extends BasePage {
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
Text( Text(
S.of(context).min_amount('5'), S.of(context).min_amount(merchant.minimumCardPurchase.toString()),
style: TextStyle( style: TextStyle(
color: Theme.of(context).primaryTextTheme.headline.color, color: Theme.of(context).primaryTextTheme.headline.color,
), ),
), ),
Text( Text(
S.of(context).max_amount('20000'), S.of(context).max_amount(merchant.maximumCardPurchase.toString()),
style: TextStyle( style: TextStyle(
color: Theme.of(context).primaryTextTheme.headline.color, color: Theme.of(context).primaryTextTheme.headline.color,
), ),
@ -127,11 +131,13 @@ class IoniaBuyGiftCardPage extends BasePage {
Padding( Padding(
padding: const EdgeInsets.all(24.0), padding: const EdgeInsets.all(24.0),
child: CardItem( child: CardItem(
onTap: () {}, title: merchant.legalName,
title: 'Applebees', backgroundColor: Theme.of(context).accentTextTheme.display4.backgroundColor.withOpacity(0.1),
hasDiscount: true, discount: 0.0,
subTitle: 'subTitle', titleColor: Theme.of(context).accentTextTheme.display4.backgroundColor,
logoUrl: '', subtitleColor: Theme.of(context).hintColor,
subTitle: merchant.isOnline ? S.of(context).online : S.of(context).offline,
logoUrl: merchant.logoUrl,
), ),
) )
], ],
@ -141,10 +147,10 @@ class IoniaBuyGiftCardPage extends BasePage {
Padding( Padding(
padding: EdgeInsets.only(bottom: 12), padding: EdgeInsets.only(bottom: 12),
child: PrimaryButton( child: PrimaryButton(
onPressed: () => Navigator.of(context).pushNamed(Routes.ioniaBuyGiftCardDetailPage), onPressed: () => Navigator.of(context).pushNamed(Routes.ioniaBuyGiftCardDetailPage, arguments: [merchant] ),
text: S.of(context).continue_text, text: S.of(context).continue_text,
color: Theme.of(context).accentTextTheme.body2.color, color: Theme.of(context).accentTextTheme.body2.color,
textColor: Colors.white, textColor: Theme.of(context).primaryTextTheme.body1.color,
), ),
), ),
SizedBox(height: 30), SizedBox(height: 30),

View file

@ -8,6 +8,8 @@ import 'package:cake_wallet/view_model/ionia/ionia_view_model.dart';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:cake_wallet/generated/i18n.dart'; import 'package:cake_wallet/generated/i18n.dart';
import 'package:flutter_mobx/flutter_mobx.dart';
import 'package:mobx/mobx.dart';
class IoniaManageCardsPage extends BasePage { class IoniaManageCardsPage extends BasePage {
IoniaManageCardsPage(this._ioniaViewModel); IoniaManageCardsPage(this._ioniaViewModel);
@ -49,7 +51,7 @@ class IoniaManageCardsPage extends BasePage {
Widget leading(BuildContext context) { Widget leading(BuildContext context) {
final _backButton = Icon( final _backButton = Icon(
Icons.arrow_back_ios, Icons.arrow_back_ios,
color: titleColor ?? Theme.of(context).primaryTextTheme.title.color, color: Theme.of(context).accentTextTheme.display3.backgroundColor,
size: 16, size: 16,
); );
@ -141,27 +143,43 @@ class IoniaManageCardsPage extends BasePage {
), ),
SizedBox(height: 8), SizedBox(height: 8),
Expanded( Expanded(
child: RawScrollbar( child: Observer(
thumbColor: Colors.white.withOpacity(0.15), builder: (_) {
radius: Radius.circular(20), final merchantsList = _ioniaViewModel.ioniaMerchants;
isAlwaysShown: true, return RawScrollbar(
thickness: 2, thumbColor: Colors.white.withOpacity(0.15),
controller: _scrollController, radius: Radius.circular(20),
child: ListView.separated( isAlwaysShown: true,
padding: EdgeInsets.only(left: 2, right: 22), thickness: 2,
controller: _scrollController, controller: _scrollController,
itemCount: 20, child: ListView.separated(
separatorBuilder: (_, __) => SizedBox(height: 4), padding: EdgeInsets.only(left: 2, right: 22),
itemBuilder: (_, index) { controller: _scrollController,
return CardItem( itemCount: merchantsList.length,
logoUrl: '', separatorBuilder: (_, __) => SizedBox(height: 4),
onTap: () => Navigator.of(context).pushNamed(Routes.ioniaBuyGiftCardPage), itemBuilder: (_, index) {
title: 'Amazon', final merchant = merchantsList[index];
subTitle: 'Onlin', return CardItem(
hasDiscount: true, logoUrl: merchant.logoUrl,
); onTap: () => Navigator.of(context).pushNamed(Routes.ioniaBuyGiftCardPage,
}, arguments: [merchant]),
), title: merchant.legalName,
subTitle: merchant.isOnline ? S.of(context).online : S.of(context).offline,
backgroundColor: Theme.of(context).textTheme.title.backgroundColor,
titleColor: Theme.of(context)
.accentTextTheme
.display3
.backgroundColor,
subtitleColor: Theme.of(context)
.accentTextTheme
.display2
.backgroundColor,
discount: merchant.minimumDiscount,
);
},
),
);
}
), ),
), ),
], ],

View file

@ -1,22 +1,28 @@
import 'package:cake_wallet/palette.dart';
import 'package:cake_wallet/src/widgets/discount_badge.dart'; import 'package:cake_wallet/src/widgets/discount_badge.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
class CardItem extends StatelessWidget { class CardItem extends StatelessWidget {
CardItem({ CardItem({
@required this.onTap,
@required this.title, @required this.title,
@required this.subTitle, @required this.subTitle,
@required this.backgroundColor,
@required this.titleColor,
@required this.subtitleColor,
this.onTap,
this.logoUrl, this.logoUrl,
this.hasDiscount = false, this.discount,
}); });
final VoidCallback onTap; final VoidCallback onTap;
final String title; final String title;
final String subTitle; final String subTitle;
final String logoUrl; final String logoUrl;
final bool hasDiscount; final double discount;
final Color backgroundColor;
final Color titleColor;
final Color subtitleColor;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -28,7 +34,7 @@ class CardItem extends StatelessWidget {
padding: EdgeInsets.all(12), padding: EdgeInsets.all(12),
width: double.infinity, width: double.infinity,
decoration: BoxDecoration( decoration: BoxDecoration(
color: Colors.black.withOpacity(0.1), color: backgroundColor,
borderRadius: BorderRadius.circular(20), borderRadius: BorderRadius.circular(20),
border: Border.all( border: Border.all(
color: Colors.white.withOpacity(0.20), color: Colors.white.withOpacity(0.20),
@ -57,19 +63,23 @@ class CardItem extends StatelessWidget {
Column( Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Text( SizedBox(
title, width: 200,
style: TextStyle( child: Text(
color: Palette.stateGray, title,
fontSize: 24, overflow: TextOverflow.ellipsis,
fontWeight: FontWeight.w900, style: TextStyle(
color: titleColor,
fontSize: 20,
fontWeight: FontWeight.w900,
),
), ),
), ),
SizedBox(height: 5), SizedBox(height: 5),
Text( Text(
subTitle, subTitle,
style: TextStyle( style: TextStyle(
color: Palette.niagara , color: subtitleColor,
fontWeight: FontWeight.w500, fontWeight: FontWeight.w500,
fontFamily: 'Lato'), fontFamily: 'Lato'),
) )
@ -78,12 +88,12 @@ class CardItem extends StatelessWidget {
], ],
), ),
), ),
if (hasDiscount) if (discount != 0.0)
Align( Align(
alignment: Alignment.topRight, alignment: Alignment.topRight,
child: Padding( child: Padding(
padding: const EdgeInsets.only(top: 20.0), padding: const EdgeInsets.only(top: 20.0),
child: DiscountBadge(), child: DiscountBadge(percentage: discount),
), ),
), ),
], ],

View file

@ -5,8 +5,11 @@ import 'package:cake_wallet/generated/i18n.dart';
class DiscountBadge extends StatelessWidget { class DiscountBadge extends StatelessWidget {
const DiscountBadge({ const DiscountBadge({
Key key, Key key,
@required this.percentage,
}) : super(key: key); }) : super(key: key);
final double percentage;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Stack( return Stack(
@ -16,7 +19,7 @@ class DiscountBadge extends StatelessWidget {
Padding( Padding(
padding: const EdgeInsets.only(right: 10.0), padding: const EdgeInsets.only(right: 10.0),
child: Text( child: Text(
S.of(context).discount('20'), S.of(context).discount(percentage.toString()),
style: TextStyle( style: TextStyle(
color: Colors.white, color: Colors.white,
fontSize: 12, fontSize: 12,

View file

@ -1,5 +1,7 @@
import 'package:cake_wallet/ionia/ionia_service.dart'; import 'package:cake_wallet/ionia/ionia_service.dart';
import 'package:cake_wallet/ionia/ionia_create_state.dart'; import 'package:cake_wallet/ionia/ionia_create_state.dart';
import 'package:cake_wallet/ionia/ionia_merchant.dart';
import 'package:cake_wallet/ionia/ionia_merchant_service.dart';
import 'package:cake_wallet/ionia/ionia_virtual_card.dart'; import 'package:cake_wallet/ionia/ionia_virtual_card.dart';
import 'package:mobx/mobx.dart'; import 'package:mobx/mobx.dart';
part 'ionia_view_model.g.dart'; part 'ionia_view_model.g.dart';
@ -7,14 +9,19 @@ part 'ionia_view_model.g.dart';
class IoniaViewModel = IoniaViewModelBase with _$IoniaViewModel; class IoniaViewModel = IoniaViewModelBase with _$IoniaViewModel;
abstract class IoniaViewModelBase with Store { abstract class IoniaViewModelBase with Store {
IoniaViewModelBase({this.ioniaService})
IoniaViewModelBase({this.ioniaService, this.ioniaMerchantService})
: createUserState = IoniaCreateStateSuccess(), : createUserState = IoniaCreateStateSuccess(),
otpState = IoniaOtpSendDisabled(), otpState = IoniaOtpSendDisabled(),
cardState = IoniaNoCardState() { cardState = IoniaNoCardState(), ioniaMerchants = [] {
_getCard(); _getMerchants().then((value){
ioniaMerchants = value;
});
_getAuthStatus().then((value) => isLoggedIn = value); _getAuthStatus().then((value) => isLoggedIn = value);
} }
final IoniaMerchantService ioniaMerchantService;
final IoniaService ioniaService; final IoniaService ioniaService;
@observable @observable
@ -29,6 +36,9 @@ abstract class IoniaViewModelBase with Store {
@observable @observable
IoniaFetchCardState cardState; IoniaFetchCardState cardState;
@observable
List<IoniaMerchant> ioniaMerchants;
@observable @observable
String email; String email;
@ -88,4 +98,8 @@ abstract class IoniaViewModelBase with Store {
cardState = IoniaFetchCardFailure(); cardState = IoniaFetchCardFailure();
} }
} }
Future<List<IoniaMerchant>> _getMerchants()async{
return await ioniaMerchantService.getMerchants();
}
} }

View file

@ -594,5 +594,7 @@
"by_cake_pay": "by CakePay", "by_cake_pay": "by CakePay",
"expires": "Expires", "expires": "Expires",
"mm": "MM", "mm": "MM",
"yy": "YY" "yy": "YY",
"online": "Online",
"offline": "Offline"
} }