CW-148 cake pay partial redemptions (#490)
* Ionia custom redemption screen * update ionia gift card remaining amount with custom value * [NO-TASK] Fix issues with custom redeem * replace redeem * update remaining amount * fixed from code review * Add localization
Godwin Asuquo committed
Sep 2, 2022 at 16:47 UTC
bd25d047b2dc648ddc776b760eec2fd32c02433b
26 files changed
+446
-32
lib/di.dart
+18
@@ -5,10 +5,13 @@ import 'package:cake_wallet/ionia/ionia_anypay.dart';
5
import 'package:cake_wallet/ionia/ionia_category.dart';
6
import 'package:cake_wallet/ionia/ionia_gift_card.dart';
7
import 'package:cake_wallet/ionia/ionia_tip.dart';
8
+import 'package:cake_wallet/src/screens/ionia/cards/ionia_custom_redeem_page.dart';
9
import 'package:cake_wallet/src/screens/ionia/cards/ionia_gift_card_detail_page.dart';
10
+import 'package:cake_wallet/src/screens/ionia/cards/ionia_more_options_page.dart';
11
import 'package:cake_wallet/view_model/ionia/ionia_auth_view_model.dart';
12
import 'package:cake_wallet/view_model/ionia/ionia_buy_card_view_model.dart';
13
import 'package:cake_wallet/view_model/ionia/ionia_custom_tip_view_model.dart';
14
+import 'package:cake_wallet/view_model/ionia/ionia_custom_redeem_view_model.dart';
15
import 'package:cake_wallet/view_model/ionia/ionia_filter_view_model.dart';
16
import 'package:cake_wallet/ionia/ionia_service.dart';
17
import 'package:cake_wallet/ionia/ionia_api.dart';
@@ -747,6 +750,21 @@ Future setup(
750
return IoniaGiftCardDetailPage(getIt.get<IoniaGiftCardDetailsViewModel>(param1: giftCard));
751
});
752
753
+ getIt.registerFactoryParam<IoniaMoreOptionsPage, List, void>((List args, _){
754
+ final giftCard = args.first as IoniaGiftCard;
755
+
756
+ return IoniaMoreOptionsPage(giftCard);
757
+ });
758
+
759
+ getIt.registerFactoryParam<IoniaCustomRedeemViewModel, IoniaGiftCard, void>((IoniaGiftCard giftCard, _) => IoniaCustomRedeemViewModel(giftCard));
760
+
761
+ getIt.registerFactoryParam<IoniaCustomRedeemPage, List, void>((List args, _){
762
+ final giftCard = args.first as IoniaGiftCard;
763
+
764
+ return IoniaCustomRedeemPage(getIt.get<IoniaCustomRedeemViewModel>(param1: giftCard) );
765
+ });
766
+
767
+
768
getIt.registerFactoryParam<IoniaCustomTipPage, List, void>((List args, _) {
769
return IoniaCustomTipPage(getIt.get<IoniaCustomTipViewModel>(param1: args));
770
});
lib/ionia/ionia_gift_card.dart
+2
-1
@@ -60,10 +60,11 @@ class IoniaGiftCard {
60
final double actualAmount;
61
final double totalTransactionAmount;
62
final double totalDashTransactionAmount;
63
- final double remainingAmount;
63
+ double remainingAmount;
64
final String createdDateFormatted;
65
final String lastTransactionDateFormatted;
66
final bool isActive;
67
final bool isEmpty;
68
final String logoUrl;
69
+
70
}
\ No newline at end of file
lib/router.dart
+10
@@ -6,8 +6,10 @@ import 'package:cake_wallet/src/screens/buy/buy_webview_page.dart';
6
import 'package:cake_wallet/src/screens/buy/pre_order_page.dart';
7
import 'package:cake_wallet/src/screens/ionia/cards/ionia_account_cards_page.dart';
8
import 'package:cake_wallet/src/screens/ionia/cards/ionia_account_page.dart';
9
+import 'package:cake_wallet/src/screens/ionia/cards/ionia_custom_redeem_page.dart';
10
import 'package:cake_wallet/src/screens/ionia/cards/ionia_custom_tip_page.dart';
11
import 'package:cake_wallet/src/screens/ionia/cards/ionia_gift_card_detail_page.dart';
12
+import 'package:cake_wallet/src/screens/ionia/cards/ionia_more_options_page.dart';
13
import 'package:cake_wallet/src/screens/order_details/order_details_page.dart';
14
import 'package:cake_wallet/src/screens/pin_code/pin_code_widget.dart';
15
import 'package:cake_wallet/src/screens/restore/restore_from_backup_page.dart';
@@ -452,6 +454,14 @@ Route<dynamic> createRoute(RouteSettings settings) {
454
case Routes.ioniaGiftCardDetailPage:
455
final args = settings.arguments as List;
456
return CupertinoPageRoute<void>(builder: (_) => getIt.get<IoniaGiftCardDetailPage>(param1: args.first));
457
+
458
+ case Routes.ioniaCustomRedeemPage:
459
+ final args = settings.arguments as List;
460
+ return CupertinoPageRoute<void>(builder: (_) => getIt.get<IoniaCustomRedeemPage>(param1: args));
461
+
462
+ case Routes.ioniaMoreOptionsPage:
463
+ final args = settings.arguments as List;
464
+ return CupertinoPageRoute<void>(builder: (_) => getIt.get<IoniaMoreOptionsPage>(param1: args));
465
466
case Routes.ioniaPaymentStatusPage:
467
final args = settings.arguments as List;
lib/routes.dart
+2
@@ -74,4 +74,6 @@ class Routes {
74
static const ioniaCustomTipPage = 'ionia_custom_tip_page';
75
static const ioniaGiftCardDetailPage = '/ionia_gift_card_detail_page';
76
static const ioniaPaymentStatusPage = '/ionia_payment_status_page';
77
+ static const ioniaMoreOptionsPage = '/ionia_more_options_page';
78
+ static const ioniaCustomRedeemPage = '/ionia_custom_redeem_page';
79
}
lib/src/screens/ionia/cards/ionia_custom_redeem_page.dart
new
+167
@@ -0,0 +1,167 @@
1
+import 'package:cake_wallet/src/screens/base_page.dart';
2
+import 'package:cake_wallet/src/screens/ionia/widgets/card_item.dart';
3
+import 'package:cake_wallet/src/widgets/base_text_form_field.dart';
4
+import 'package:cake_wallet/src/widgets/keyboard_done_button.dart';
5
+import 'package:cake_wallet/src/widgets/primary_button.dart';
6
+import 'package:cake_wallet/src/widgets/scollable_with_bottom_section.dart';
7
+import 'package:cake_wallet/themes/theme_base.dart';
8
+import 'package:cake_wallet/view_model/ionia/ionia_custom_redeem_view_model.dart';
9
+import 'package:flutter/material.dart';
10
+import 'package:flutter/services.dart';
11
+import 'package:flutter_mobx/flutter_mobx.dart';
12
+import 'package:keyboard_actions/keyboard_actions.dart';
13
+import 'package:cake_wallet/generated/i18n.dart';
14
+
15
+class IoniaCustomRedeemPage extends BasePage {
16
+ IoniaCustomRedeemPage(
17
+ this.ioniaCustomRedeemViewModel,
18
+ ) : _amountFieldFocus = FocusNode(),
19
+ _amountController = TextEditingController() {
20
+ _amountController.addListener(() {
21
+ ioniaCustomRedeemViewModel.updateAmount(_amountController.text);
22
+ });
23
+ }
24
+
25
+ final IoniaCustomRedeemViewModel ioniaCustomRedeemViewModel;
26
+
27
+
28
+ @override
29
+ String get title => S.current.custom_redeem_amount;
30
+
31
+ @override
32
+ Color get titleColor => Colors.white;
33
+
34
+ @override
35
+ bool get extendBodyBehindAppBar => true;
36
+
37
+ @override
38
+ AppBarStyle get appBarStyle => AppBarStyle.transparent;
39
+
40
+ Color get textColor => currentTheme.type == ThemeType.dark ? Colors.white : Color(0xff393939);
41
+
42
+ final TextEditingController _amountController;
43
+ final FocusNode _amountFieldFocus;
44
+
45
+ @override
46
+ Widget body(BuildContext context) {
47
+ final _width = MediaQuery.of(context).size.width;
48
+ final giftCard = ioniaCustomRedeemViewModel.giftCard;
49
+ return KeyboardActions(
50
+ disableScroll: true,
51
+ config: KeyboardActionsConfig(
52
+ keyboardActionsPlatform: KeyboardActionsPlatform.IOS,
53
+ keyboardBarColor: Theme.of(context).accentTextTheme.body2.backgroundColor,
54
+ nextFocus: false,
55
+ actions: [
56
+ KeyboardActionsItem(
57
+ focusNode: _amountFieldFocus,
58
+ toolbarButtons: [(_) => KeyboardDoneButton()],
59
+ ),
60
+ ]),
61
+ child: Container(
62
+ color: Theme.of(context).backgroundColor,
63
+ child: ScrollableWithBottomSection(
64
+ contentPadding: EdgeInsets.zero,
65
+ content: Column(
66
+ children: [
67
+ Container(
68
+ padding: EdgeInsets.symmetric(horizontal: 25),
69
+ decoration: BoxDecoration(
70
+ borderRadius: BorderRadius.only(bottomLeft: Radius.circular(24), bottomRight: Radius.circular(24)),
71
+ gradient: LinearGradient(colors: [
72
+ Theme.of(context).primaryTextTheme.subhead.color,
73
+ Theme.of(context).primaryTextTheme.subhead.decorationColor,
74
+ ], begin: Alignment.topLeft, end: Alignment.bottomRight),
75
+ ),
76
+ child: Column(
77
+ mainAxisSize: MainAxisSize.min,
78
+ crossAxisAlignment: CrossAxisAlignment.stretch,
79
+ children: [
80
+ SizedBox(height: 150),
81
+ BaseTextFormField(
82
+ controller: _amountController,
83
+ focusNode: _amountFieldFocus,
84
+ keyboardType: TextInputType.numberWithOptions(signed: false, decimal: true),
85
+ inputFormatters: [FilteringTextInputFormatter.deny(RegExp('[\-|\ ]'))],
86
+ hintText: '1000',
87
+ placeholderTextStyle: TextStyle(
88
+ color: Theme.of(context).primaryTextTheme.headline.color,
89
+ fontWeight: FontWeight.w500,
90
+ fontSize: 36,
91
+ ),
92
+ borderColor: Theme.of(context).primaryTextTheme.headline.color,
93
+ textColor: Colors.white,
94
+ textStyle: TextStyle(
95
+ color: Colors.white,
96
+ fontSize: 36,
97
+ ),
98
+ suffixIcon: SizedBox(
99
+ width: _width / 6,
100
+ ),
101
+ prefixIcon: Padding(
102
+ padding: EdgeInsets.only(
103
+ top: 5.0,
104
+ left: _width / 4,
105
+ ),
106
+ child: Text(
107
+ 'USD: ',
108
+ style: TextStyle(
109
+ color: Colors.white,
110
+ fontWeight: FontWeight.w900,
111
+ fontSize: 36,
112
+ ),
113
+ ),
114
+ ),
115
+ ),
116
+ SizedBox(height: 8),
117
+ Observer(builder: (_)=>
118
+ !ioniaCustomRedeemViewModel.disableRedeem ?
119
+ Center(
120
+ child: Text('\$${giftCard.remainingAmount} - \$${ioniaCustomRedeemViewModel.amount} = \$${ioniaCustomRedeemViewModel.remaining} ${S.of(context).remaining}',
121
+ style: TextStyle(
122
+ color: Theme.of(context).primaryTextTheme.headline.color,
123
+ ),),
124
+ ) : SizedBox.shrink(),
125
+ ),
126
+ SizedBox(height: 24),
127
+ ],
128
+ ),
129
+ ),
130
+ Padding(
131
+ padding: const EdgeInsets.all(24.0),
132
+ child: CardItem(
133
+ title: giftCard.legalName,
134
+ backgroundColor: Theme.of(context).accentTextTheme.display4.backgroundColor.withOpacity(0.1),
135
+ discount: giftCard.remainingAmount,
136
+ isAmount: true,
137
+ discountBackground: AssetImage('assets/images/red_badge_discount.png'),
138
+ titleColor: Theme.of(context).accentTextTheme.display4.backgroundColor,
139
+ subtitleColor: Theme.of(context).hintColor,
140
+ subTitle: S.of(context).online,
141
+ logoUrl: giftCard.logoUrl,
142
+ ),
143
+ ),
144
+ ],
145
+ ),
146
+ bottomSection: Column(
147
+ children: [
148
+ Padding(
149
+ padding: EdgeInsets.only(bottom: 12),
150
+ child: PrimaryButton(
151
+ onPressed: () {
152
+ Navigator.of(context).pop(_amountController.text);
153
+ },
154
+ isDisabled: ioniaCustomRedeemViewModel.disableRedeem,
155
+ text: S.of(context).add_custom_redemption,
156
+ color: Theme.of(context).accentTextTheme.body2.color,
157
+ textColor: Colors.white,
158
+ ),
159
+ ),
160
+ SizedBox(height: 30),
161
+ ],
162
+ ),
163
+ ),
164
+ ),
165
+ );
166
+ }
167
+}
lib/src/screens/ionia/cards/ionia_gift_card_detail_page.dart
+39
-15
@@ -117,7 +117,7 @@ class IoniaGiftCardDetailPage extends BasePage {
117
buildIoniaTile(
118
context,
119
title: S.of(context).amount,
120
- subTitle: viewModel.giftCard.remainingAmount.toStringAsFixed(2) ?? '0.00',
120
+ subTitle: viewModel.remainingAmount.toStringAsFixed(2) ?? '0.00',
121
)),
122
Divider(height: 50),
123
TextIconButton(
@@ -127,21 +127,45 @@ class IoniaGiftCardDetailPage extends BasePage {
127
],
128
),
129
bottomSection: Padding(
130
- padding: EdgeInsets.only(bottom: 12),
131
- child: Observer(builder: (_) {
132
- if (!viewModel.giftCard.isEmpty) {
133
- return LoadingPrimaryButton(
134
- isLoading: viewModel.redeemState is IsExecutingState,
135
- onPressed: () => viewModel.redeem().then((_){
136
- Navigator.of(context).pushNamedAndRemoveUntil(Routes.ioniaManageCardsPage, (route) => route.isFirst);
137
- }),
138
- text: S.of(context).mark_as_redeemed,
139
- color: Theme.of(context).accentTextTheme.body2.color,
140
- textColor: Colors.white);
141
- }
130
+ padding: EdgeInsets.only(bottom: 12),
131
+ child: Observer(
132
+ builder: (_) {
133
+ if (!viewModel.giftCard.isEmpty) {
134
+ return Column(
135
+ children: [
136
+ PrimaryButton(
137
+ onPressed: () async {
138
+ final amount = await Navigator.of(context)
139
+ .pushNamed(Routes.ioniaMoreOptionsPage, arguments: [viewModel.giftCard]) as String;
140
+ if (amount != null) {
141
+ viewModel.updateRemaining(double.parse(amount));
142
+ }
143
+ },
144
+ text: S.of(context).more_options,
145
+ color: Theme.of(context).accentTextTheme.caption.color,
146
+ textColor: Theme.of(context).primaryTextTheme.title.color,
147
+ ),
148
+ SizedBox(height: 12),
149
+ LoadingPrimaryButton(
150
+ isLoading: viewModel.redeemState is IsExecutingState,
151
+ onPressed: () => viewModel.redeem().then(
152
+ (_) {
153
+ Navigator.of(context)
154
+ .pushNamedAndRemoveUntil(Routes.ioniaManageCardsPage, (route) => route.isFirst);
155
+ },
156
+ ),
157
+ text: S.of(context).mark_as_redeemed,
158
+ color: Theme.of(context).accentTextTheme.body2.color,
159
+ textColor: Colors.white,
160
+ ),
161
+ ],
162
+ );
163
+ }
164
143
- return Container();
144
- })),
165
+ return Container();
166
+ },
167
+ ),
168
+ ),
169
);
170
}
171
lib/src/screens/ionia/cards/ionia_more_options_page.dart
new
+90
@@ -0,0 +1,90 @@
1
+import 'package:cake_wallet/ionia/ionia_gift_card.dart';
2
+import 'package:cake_wallet/routes.dart';
3
+import 'package:cake_wallet/src/screens/base_page.dart';
4
+import 'package:cake_wallet/generated/i18n.dart';
5
+import 'package:cake_wallet/typography.dart';
6
+import 'package:flutter/material.dart';
7
+
8
+
9
+class IoniaMoreOptionsPage extends BasePage {
10
+ IoniaMoreOptionsPage(this.giftCard);
11
+
12
+ final IoniaGiftCard giftCard;
13
+
14
+ @override
15
+ Widget middle(BuildContext context) {
16
+ return Text(
17
+ S.current.more_options,
18
+ style: textMediumSemiBold(
19
+ color: Theme.of(context).accentTextTheme.display4.backgroundColor,
20
+ ),
21
+ );
22
+ }
23
+
24
+ @override
25
+ Widget body(BuildContext context) {
26
+ return Padding(
27
+ padding: const EdgeInsets.all(16.0),
28
+ child: Column(
29
+ crossAxisAlignment: CrossAxisAlignment.stretch,
30
+ children: [
31
+ SizedBox(height: 10,),
32
+ Center(child: Text(S.of(context).choose_from_available_options, style: textMedium(
33
+ color: Theme.of(context).primaryTextTheme.title.color,
34
+ ),)),
35
+ SizedBox(height: 40,),
36
+ InkWell(
37
+ onTap: () async {
38
+ final amount = await Navigator.of(context).pushNamed(Routes.ioniaCustomRedeemPage, arguments: [giftCard]) as String;
39
+ if(amount.isNotEmpty){
40
+ Navigator.pop(context, amount);
41
+ }
42
+ },
43
+ child: _GradiantContainer(
44
+ content: Padding(
45
+ padding: const EdgeInsets.only(top: 24, left: 20, right: 24, bottom: 50),
46
+ child: Text(
47
+ S.of(context).custom_redeem_amount,
48
+ style: textXLargeSemiBold(),
49
+ ),
50
+ ),
51
+ ),
52
+ )
53
+ ],
54
+ ),
55
+ );
56
+ }
57
+}
58
+
59
+class _GradiantContainer extends StatelessWidget {
60
+ const _GradiantContainer({
61
+ Key key,
62
+ @required this.content,
63
+ this.padding,
64
+ this.width,
65
+ }) : super(key: key);
66
+
67
+ final Widget content;
68
+ final EdgeInsets padding;
69
+ final double width;
70
+
71
+ @override
72
+ Widget build(BuildContext context) {
73
+ return Container(
74
+ child: content,
75
+ width: width,
76
+ padding: padding ?? EdgeInsets.all(24),
77
+ decoration: BoxDecoration(
78
+ borderRadius: BorderRadius.circular(15),
79
+ gradient: LinearGradient(
80
+ colors: [
81
+ Theme.of(context).scaffoldBackgroundColor,
82
+ Theme.of(context).accentColor,
83
+ ],
84
+ begin: Alignment.topRight,
85
+ end: Alignment.bottomLeft,
86
+ ),
87
+ ),
88
+ );
89
+ }
90
+}
lib/src/screens/ionia/widgets/card_item.dart
+3
@@ -12,6 +12,7 @@ class CardItem extends StatelessWidget {
12
this.onTap,
13
this.logoUrl,
14
this.discount,
15
+ this.isAmount = false,
16
});
17
18
final VoidCallback onTap;
@@ -19,6 +20,7 @@ class CardItem extends StatelessWidget {
20
final String subTitle;
21
final String logoUrl;
22
final double discount;
23
+ final bool isAmount;
24
final Color backgroundColor;
25
final Color titleColor;
26
final Color subtitleColor;
@@ -100,6 +102,7 @@ class CardItem extends StatelessWidget {
102
padding: const EdgeInsets.only(top: 20.0),
103
child: DiscountBadge(
104
percentage: discount,
105
+ isAmount: isAmount,
106
discountBackground: discountBackground,
107
),
108
),
lib/src/widgets/discount_badge.dart
+3
-1
@@ -4,11 +4,13 @@ import 'package:cake_wallet/generated/i18n.dart';
4
class DiscountBadge extends StatelessWidget {
5
const DiscountBadge({
6
Key key,
7
+ this.isAmount = false,
8
@required this.percentage,
9
this.discountBackground,
10
}) : super(key: key);
11
12
final double percentage;
13
+ final bool isAmount;
14
final AssetImage discountBackground;
15
16
@override
@@ -16,7 +18,7 @@ class DiscountBadge extends StatelessWidget {
18
return Container(
19
padding: EdgeInsets.symmetric(horizontal: 8, vertical: 4),
20
child: Text(
19
- S.of(context).discount(percentage.toStringAsFixed(2)),
21
+ isAmount ? '\$${percentage.toStringAsFixed(2)}' : S.of(context).discount(percentage.toStringAsFixed(2)),
22
style: TextStyle(
23
color: Colors.white,
24
fontSize: 12,
lib/view_model/ionia/ionia_custom_redeem_view_model.dart
new
+27
@@ -0,0 +1,27 @@
1
+import 'package:cake_wallet/ionia/ionia_gift_card.dart';
2
+import 'package:mobx/mobx.dart';
3
+part 'ionia_custom_redeem_view_model.g.dart';
4
+class IoniaCustomRedeemViewModel = IoniaCustomRedeemViewModelBase with _$IoniaCustomRedeemViewModel;
5
+
6
+abstract class IoniaCustomRedeemViewModelBase with Store {
7
+ IoniaCustomRedeemViewModelBase(this.giftCard){
8
+ amount = 0;
9
+ }
10
+
11
+ final IoniaGiftCard giftCard;
12
+
13
+ @observable
14
+ double amount;
15
+
16
+ @computed
17
+ double get remaining => amount <= giftCard.remainingAmount ? giftCard.remainingAmount - amount : 0;
18
+
19
+ @computed
20
+ bool get disableRedeem => amount > giftCard.remainingAmount;
21
+
22
+ @action
23
+ void updateAmount(String text){
24
+ amount = text.isEmpty ? 0 : (double.parse(text.replaceAll(',', '.')) ?? 0);
25
+ }
26
+
27
+}
\ No newline at end of file
lib/view_model/ionia/ionia_gift_card_details_view_model.dart
+10
@@ -12,6 +12,7 @@ abstract class IoniaGiftCardDetailsViewModelBase with Store {
12
13
IoniaGiftCardDetailsViewModelBase({this.ioniaService, this.giftCard}) {
14
redeemState = InitialExecutionState();
15
+ remainingAmount = giftCard.remainingAmount;
16
}
17
18
final IoniaService ioniaService;
@@ -20,11 +21,15 @@ abstract class IoniaGiftCardDetailsViewModelBase with Store {
21
@observable
22
IoniaGiftCard giftCard;
23
24
+ @observable
25
+ double remainingAmount;
26
+
27
@observable
28
ExecutionState redeemState;
29
30
@action
31
Future<void> redeem() async {
32
+ giftCard.remainingAmount = remainingAmount;
33
try {
34
redeemState = IsExecutingState();
35
await ioniaService.redeem(giftCard);
@@ -35,6 +40,11 @@ abstract class IoniaGiftCardDetailsViewModelBase with Store {
40
}
41
}
42
43
+ @action
44
+ void updateRemaining(double amount){
45
+ remainingAmount = amount;
46
+ }
47
+
48
void increaseBrightness() async {
49
brightness = await DeviceDisplayBrightness.getBrightness();
50
await DeviceDisplayBrightness.setBrightness(1.0);
res/values/strings_de.arb
+5
-1
@@ -639,5 +639,9 @@
639
"fixed_pair_not_supported": "Dieses feste Paar wird von den ausgewählten Vermittlungsstellen nicht unterstützt",
640
"variable_pair_not_supported": "Dieses Variablenpaar wird von den ausgewählten Börsen nicht unterstützt",
641
"none_of_selected_providers_can_exchange": "Keiner der ausgewählten Anbieter kann diesen Austausch vornehmen",
642
- "choose_one": "Wähle ein"
642
+ "choose_one": "Wähle ein",
643
+ "choose_from_available_options": "Wähle aus verfügbaren Optionen:",
644
+ "custom_redeem_amount": "Benutzerdefinierter Einlösungsbetrag",
645
+ "add_custom_redemption": "Benutzerdefinierte Einlösung hinzufügen",
646
+ "remaining": "Rest"
647
}
res/values/strings_en.arb
+5
-1
@@ -639,5 +639,9 @@
639
"fixed_pair_not_supported": "This fixed pair is not supported with the selected exchanges",
640
"variable_pair_not_supported": "This variable pair is not supported with the selected exchanges",
641
"none_of_selected_providers_can_exchange": "None of the selected providers can make this exchange",
642
- "choose_one": "Choose one"
642
+ "choose_one": "Choose one",
643
+ "choose_from_available_options": "Choose from the available options:",
644
+ "custom_redeem_amount": "Custom Redeem Amount",
645
+ "add_custom_redemption": "Add Custom Redemption",
646
+ "remaining": "remaining"
647
}
res/values/strings_es.arb
+5
-1
@@ -639,5 +639,9 @@
639
"fixed_pair_not_supported": "Este par fijo no es compatible con los intercambios seleccionados",
640
"variable_pair_not_supported": "Este par de variables no es compatible con los intercambios seleccionados",
641
"none_of_selected_providers_can_exchange": "Ninguno de los proveedores seleccionados puede realizar este intercambio",
642
- "choose_one": "Elige uno"
642
+ "choose_one": "Elige uno",
643
+ "choose_from_available_options": "Elija entre las opciones disponibles:",
644
+ "custom_redeem_amount": "Cantidad de canje personalizada",
645
+ "add_custom_redemption": "Agregar redención personalizada",
646
+ "remaining": "restante"
647
}
res/values/strings_fr.arb
+5
-1
@@ -637,5 +637,9 @@
637
"fixed_pair_not_supported": "Cette paire fixe n'est pas prise en charge avec les échanges sélectionnés",
638
"variable_pair_not_supported": "Cette paire de variables n'est pas prise en charge avec les échanges sélectionnés",
639
"none_of_selected_providers_can_exchange": "Aucun des prestataires sélectionnés ne peut effectuer cet échange",
640
- "choose_one": "Choisissez-en un"
640
+ "choose_one": "Choisissez-en un",
641
+ "choose_from_available_options": "Choisissez parmi les options disponibles :",
642
+ "custom_redeem_amount": "Montant d'échange personnalisé",
643
+ "add_custom_redemption": "Ajouter un remboursement personnalisé",
644
+ "remaining": "restant"
645
}
res/values/strings_hi.arb
+5
-1
@@ -639,5 +639,9 @@
639
"fixed_pair_not_supported": "यह निश्चित जोड़ी चयनित एक्सचेंजों के साथ समर्थित नहीं है",
640
"variable_pair_not_supported": "यह परिवर्तनीय जोड़ी चयनित एक्सचेंजों के साथ समर्थित नहीं है",
641
"none_of_selected_providers_can_exchange": "चयनित प्रदाताओं में से कोई भी इस एक्सचेंज को नहीं बना सकता",
642
- "choose_one": "एक का चयन"
642
+ "choose_one": "एक का चयन",
643
+ "choose_from_available_options": "उपलब्ध विकल्पों में से चुनें:",
644
+ "custom_redeem_amount": "कस्टम रिडीम राशि",
645
+ "add_custom_redemption": "कस्टम रिडेम्पशन जोड़ें",
646
+ "remaining": "शेष"
647
}
res/values/strings_hr.arb
+5
-1
@@ -639,5 +639,9 @@
639
"fixed_pair_not_supported": "Ovaj fiksni par nije podržan s odabranim burzama",
640
"variable_pair_not_supported": "Ovaj par varijabli nije podržan s odabranim burzama",
641
"none_of_selected_providers_can_exchange": "Niti jedan od odabranih pružatelja usluga ne može izvršiti ovu razmjenu",
642
- "choose_one": "Izaberi jedan"
642
+ "choose_one": "Izaberi jedan",
643
+ "choose_from_available_options": "Odaberite neku od dostupnih opcija:",
644
+ "custom_redeem_amount": "Prilagođeni iznos otkupa",
645
+ "add_custom_redemption": "Dodaj prilagođeni otkup",
646
+ "remaining": "preostalo"
647
}
res/values/strings_it.arb
+5
-1
@@ -639,5 +639,9 @@
639
"fixed_pair_not_supported": "Questa coppia fissa non è supportata con gli scambi selezionati",
640
"variable_pair_not_supported": "Questa coppia di variabili non è supportata con gli scambi selezionati",
641
"none_of_selected_providers_can_exchange": "Nessuno dei fornitori selezionati può effettuare questo scambio",
642
- "choose_one": "Scegline uno"
642
+ "choose_one": "Scegline uno",
643
+ "choose_from_available_options": "Scegli tra le opzioni disponibili:",
644
+ "custom_redeem_amount": "Importo di riscatto personalizzato",
645
+ "add_custom_redemption": "Aggiungi riscatto personalizzato",
646
+ "remaining": "rimanente"
647
}
res/values/strings_ja.arb
+5
-1
@@ -639,5 +639,9 @@
639
"fixed_pair_not_supported": "この固定ペアは、選択したエクスチェンジではサポートされていません",
640
"variable_pair_not_supported": "この変数ペアは、選択した取引所ではサポートされていません",
641
"none_of_selected_providers_can_exchange": "選択したプロバイダーはいずれもこの交換を行うことができません",
642
- "choose_one": "1 つ選択してください"
642
+ "choose_one": "1 つ選択してください",
643
+ "choose_from_available_options": "利用可能なオプションから選択してください:",
644
+ "custom_redeem_amount": "カスタム交換金額",
645
+ "add_custom_redemption": "カスタム引き換えを追加",
646
+ "remaining": "残り"
647
}
res/values/strings_ko.arb
+5
-1
@@ -639,5 +639,9 @@
639
"fixed_pair_not_supported": "이 고정 쌍은 선택한 교환에서 지원되지 않습니다.",
640
"variable_pair_not_supported": "이 변수 쌍은 선택한 교환에서 지원되지 않습니다.",
641
"none_of_selected_providers_can_exchange": "선택한 공급자 중 누구도 이 교환을 할 수 없습니다.",
642
- "choose_one": "하나 선택"
642
+ "choose_one": "하나 선택",
643
+ "choose_from_available_options": "사용 가능한 옵션에서 선택:",
644
+ "custom_redeem_amount": "사용자 지정 상환 금액",
645
+ "add_custom_redemption": "사용자 지정 상환 추가",
646
+ "remaining": "남은"
647
}
res/values/strings_nl.arb
+5
-1
@@ -639,5 +639,9 @@
639
"fixed_pair_not_supported": "Dit vaste paar wordt niet ondersteund bij de geselecteerde exchanges",
640
"variable_pair_not_supported": "Dit variabelenpaar wordt niet ondersteund met de geselecteerde uitwisselingen",
641
"none_of_selected_providers_can_exchange": "Geen van de geselecteerde providers kan deze uitwisseling maken",
642
- "choose_one": "Kies er een"
642
+ "choose_one": "Kies er een",
643
+ "choose_from_available_options": "Kies uit de beschikbare opties:",
644
+ "custom_redeem_amount": "Aangepast inwisselbedrag",
645
+ "add_custom_redemption": "Voeg aangepaste inwisseling toe",
646
+ "remaining": "resterende"
647
}
res/values/strings_pl.arb
+5
-1
@@ -639,5 +639,9 @@
639
"fixed_pair_not_supported": "Ta stała para nie jest obsługiwana na wybranych giełdach",
640
"variable_pair_not_supported": "Ta para zmiennych nie jest obsługiwana na wybranych giełdach",
641
"none_of_selected_providers_can_exchange": "Żaden z wybranych dostawców nie może dokonać tej wymiany",
642
- "choose_one": "Wybierz jeden"
642
+ "choose_one": "Wybierz jeden",
643
+ "choose_from_available_options": "Wybierz z dostępnych opcji:",
644
+ "custom_redeem_amount": "Niestandardowa kwota wykorzystania",
645
+ "add_custom_redemption": "Dodaj niestandardowe wykorzystanie",
646
+ "remaining": "pozostałe"
647
}
res/values/strings_pt.arb
+5
-1
@@ -639,5 +639,9 @@
639
"fixed_pair_not_supported": "Este par fixo não é compatível com as exchanges selecionadas",
640
"variable_pair_not_supported": "Este par de variáveis não é compatível com as trocas selecionadas",
641
"none_of_selected_providers_can_exchange": "Nenhum dos provedores selecionados pode fazer esta troca",
642
- "choose_one": "Escolha um"
642
+ "choose_one": "Escolha um",
643
+ "choose_from_available_options": "Escolha entre as opções disponíveis:",
644
+ "custom_redeem_amount": "Valor de resgate personalizado",
645
+ "add_custom_redemption": "Adicionar resgate personalizado",
646
+ "remaining": "restante"
647
}
res/values/strings_ru.arb
+5
-1
@@ -639,5 +639,9 @@
639
"fixed_pair_not_supported": "Эта фиксированная пара не поддерживается выбранными биржами.",
640
"variable_pair_not_supported": "Эта пара переменных не поддерживается выбранными биржами.",
641
"none_of_selected_providers_can_exchange": "Ни один из выбранных провайдеров не может совершить этот обмен",
642
- "choose_one": "Выбери один"
642
+ "choose_one": "Выбери один",
643
+ "choose_from_available_options": "Выберите из доступных вариантов:",
644
+ "custom_redeem_amount": "Пользовательская сумма погашения",
645
+ "add_custom_redemption": "Добавить пользовательское погашение",
646
+ "remaining": "осталось"
647
}
res/values/strings_uk.arb
+5
-1
@@ -638,5 +638,9 @@
638
"fixed_pair_not_supported": "Ця фіксована пара не підтримується вибраними біржами",
639
"variable_pair_not_supported": "Ця пара змінних не підтримується вибраними біржами",
640
"none_of_selected_providers_can_exchange": "Жоден із вибраних провайдерів не може здійснити цей обмін",
641
- "choose_one": "Вибери один"
641
+ "choose_one": "Вибери один",
642
+ "choose_from_available_options": "Виберіть із доступних варіантів:",
643
+ "custom_redeem_amount": "Власна сума викупу",
644
+ "add_custom_redemption": "Додати спеціальне погашення",
645
+ "remaining": "залишилося"
646
}
res/values/strings_zh.arb
+5
-1
@@ -637,5 +637,9 @@
637
"fixed_pair_not_supported": "所选交易所不支持此固定货币对",
638
"variable_pair_not_supported": "所选交易所不支持此变量对",
639
"none_of_selected_providers_can_exchange": "选定的供应商都不能进行此交换",
640
- "choose_one": "选一个"
640
+ "choose_one": "选一个",
641
+ "choose_from_available_options": "从可用选项中选择:",
642
+ "custom_redeem_amount": "自定义兑换金额",
643
+ "add_custom_redemption": "添加自定义兑换",
644
+ "remaining": "剩余"
645
}