Cw 591 in app cake pay integration (#1376)

* init commit

* buy card UI

* buy card detail page

* card filter

* dropdown button

* user auth flow

* create order

* denomination option

* fix searching

* denom option fix UI

* simulate payment

* Update pr_test_build.yml

* Update pr_test_build.yml

* Implement order expiration handling [skip ci]

* refactor code [skip ci]

* remove ionia related code [skip ci]

* change auth flow

* add currency prefix

* grid view UI

* fix country filter issue

* fix underline color

* fix fetching card list [skip ci]

* list view

* update cake pay title

* Optimize API usage by fetching CakePay vendors

* handle no cards found case

* adjust the flow of purchases

* UI fixes

* fix btc payment data

* link extractor

* fix fetch next page issue

* UI fixes

* fix text size

* revert base page changes

* Revert "revert base page changes"

* UI fixes

* fix UI

* fix link style + localization

* update cake pay title

* update cake pay subtitle

* Update cake_pay_order.dart

* revert inject_app_details update
This commit is contained in:
Serhii 2024-06-06 04:51:22 +00:00 committed by GitHub
parent 287c2d8b60
commit 30dc8f9238
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
108 changed files with 3500 additions and 5267 deletions

View file

@ -151,6 +151,10 @@ jobs:
echo "const moralisApiKey = '${{ secrets.MORALIS_API_KEY }}';" >> lib/.secrets.g.dart echo "const moralisApiKey = '${{ secrets.MORALIS_API_KEY }}';" >> lib/.secrets.g.dart
echo "const polygonScanApiKey = '${{ secrets.POLYGON_SCAN_API_KEY }}';" >> cw_evm/lib/.secrets.g.dart echo "const polygonScanApiKey = '${{ secrets.POLYGON_SCAN_API_KEY }}';" >> cw_evm/lib/.secrets.g.dart
echo "const ankrApiKey = '${{ secrets.ANKR_API_KEY }}';" >> cw_solana/lib/.secrets.g.dart echo "const ankrApiKey = '${{ secrets.ANKR_API_KEY }}';" >> cw_solana/lib/.secrets.g.dart
echo "const testCakePayApiKey = '${{ secrets.TEST_CAKE_PAY_API_KEY }}';" >> lib/.secrets.g.dart
echo "const cakePayApiKey = '${{ secrets.CAKE_PAY_API_KEY }}';" >> lib/.secrets.g.dart
echo "const authorization = '${{ secrets.CAKE_PAY_AUTHORIZATION }}';" >> lib/.secrets.g.dart
echo "const CSRFToken = '${{ secrets.CSRF_TOKEN }}';" >> lib/.secrets.g.dart
echo "const quantexExchangeMarkup = '${{ secrets.QUANTEX_EXCHANGE_MARKUP }}';" >> lib/.secrets.g.dart echo "const quantexExchangeMarkup = '${{ secrets.QUANTEX_EXCHANGE_MARKUP }}';" >> lib/.secrets.g.dart
echo "const nano2ApiKey = '${{ secrets.NANO2_API_KEY }}';" >> cw_nano/lib/.secrets.g.dart echo "const nano2ApiKey = '${{ secrets.NANO2_API_KEY }}';" >> cw_nano/lib/.secrets.g.dart
echo "const tronGridApiKey = '${{ secrets.TRON_GRID_API_KEY }}';" >> cw_tron/lib/.secrets.g.dart echo "const tronGridApiKey = '${{ secrets.TRON_GRID_API_KEY }}';" >> cw_tron/lib/.secrets.g.dart

View file

@ -0,0 +1,245 @@
import 'dart:convert';
import 'package:cake_wallet/cake_pay/cake_pay_order.dart';
import 'package:cake_wallet/cake_pay/cake_pay_user_credentials.dart';
import 'package:cake_wallet/cake_pay/cake_pay_vendor.dart';
import 'package:http/http.dart' as http;
class CakePayApi {
static const testBaseUri = false;
static const baseTestCakePayUri = 'test.cakepay.com';
static const baseProdCakePayUri = 'buy.cakepay.com';
static const baseCakePayUri = testBaseUri ? baseTestCakePayUri : baseProdCakePayUri;
static const vendorsPath = '/api/vendors';
static const countriesPath = '/api/countries';
static const authPath = '/api/auth';
static final verifyEmailPath = '/api/verify';
static final logoutPath = '/api/logout';
static final createOrderPath = '/api/order';
static final simulatePaymentPath = '/api/simulate_payment';
/// AuthenticateUser
Future<String> authenticateUser({required String email, required String apiKey}) async {
try {
final uri = Uri.https(baseCakePayUri, authPath);
final headers = {
'Accept': 'application/json',
'Content-Type': 'application/json',
'Authorization': 'Api-Key $apiKey',
};
final response = await http.post(uri, headers: headers, body: json.encode({'email': email}));
if (response.statusCode != 200) {
throw Exception('Unexpected http status: ${response.statusCode}');
}
final bodyJson = json.decode(response.body) as Map<String, dynamic>;
if (bodyJson.containsKey('user') && bodyJson['user']['email'] != null) {
return bodyJson['user']['email'] as String;
}
throw Exception('Failed to authenticate user with error: $bodyJson');
} catch (e) {
throw Exception('Failed to authenticate user with error: $e');
}
}
/// Verify email
Future<CakePayUserCredentials> verifyEmail({
required String email,
required String code,
required String apiKey,
}) async {
final uri = Uri.https(baseCakePayUri, verifyEmailPath);
final headers = {
'Accept': 'application/json',
'Content-Type': 'application/json',
'Authorization': 'Api-Key $apiKey',
};
final query = <String, String>{'email': email, 'otp': code};
final response = await http.post(uri, headers: headers, body: json.encode(query));
if (response.statusCode != 200) {
throw Exception('Unexpected http status: ${response.statusCode}');
}
final bodyJson = json.decode(response.body) as Map<String, dynamic>;
if (bodyJson.containsKey('error')) {
throw Exception(bodyJson['error'] as String);
}
if (bodyJson.containsKey('token')) {
final token = bodyJson['token'] as String;
final userEmail = bodyJson['user']['email'] as String;
return CakePayUserCredentials(userEmail, token);
} else {
throw Exception('E-mail verification failed.');
}
}
/// createOrder
Future<CakePayOrder> createOrder({
required String apiKey,
required int cardId,
required String price,
required int quantity,
required String userEmail,
required String token,
}) async {
final uri = Uri.https(baseCakePayUri, createOrderPath);
final headers = {
'Accept': 'application/json',
'Content-Type': 'application/json',
'Authorization': 'Api-Key $apiKey',
};
final query = <String, dynamic>{
'card_id': cardId,
'price': price,
'quantity': quantity,
'user_email': userEmail,
'token': token,
'send_email': true
};
try {
final response = await http.post(uri, headers: headers, body: json.encode(query));
if (response.statusCode != 201) {
final responseBody = json.decode(response.body);
if (responseBody is List) {
throw '${responseBody[0]}';
} else {
throw Exception('Unexpected error: $responseBody');
}
}
final bodyJson = json.decode(response.body) as Map<String, dynamic>;
return CakePayOrder.fromMap(bodyJson);
} catch (e) {
throw Exception('${e}');
}
}
///Simulate Payment
Future<void> simulatePayment(
{required String CSRFToken, required String authorization, required String orderId}) async {
final uri = Uri.https(baseCakePayUri, simulatePaymentPath + '/$orderId');
final headers = {
'accept': 'application/json',
'authorization': authorization,
'X-CSRFToken': CSRFToken,
};
final response = await http.get(uri, headers: headers);
print('Response: ${response.statusCode}');
if (response.statusCode != 200) {
throw Exception('Unexpected http status: ${response.statusCode}');
}
final bodyJson = json.decode(response.body) as Map<String, dynamic>;
throw Exception('You just bot a gift card with id: ${bodyJson['order_id']}');
}
/// Logout
Future<void> logoutUser({required String email, required String apiKey}) async {
final uri = Uri.https(baseCakePayUri, logoutPath);
final headers = {
'Accept': 'application/json',
'Content-Type': 'application/json',
'Authorization': 'Api-Key $apiKey',
};
try {
final response = await http.post(uri, headers: headers, body: json.encode({'email': email}));
if (response.statusCode != 200) {
throw Exception('Unexpected http status: ${response.statusCode}');
}
} catch (e) {
print('Caught exception: $e');
}
}
/// Get Countries
Future<List<String>> getCountries(
{required String CSRFToken, required String authorization}) async {
final uri = Uri.https(baseCakePayUri, countriesPath);
final headers = {
'accept': 'application/json',
'authorization': authorization,
'X-CSRFToken': CSRFToken,
};
final response = await http.get(uri, headers: headers);
if (response.statusCode != 200) {
throw Exception('Unexpected http status: ${response.statusCode}');
}
final bodyJson = json.decode(response.body) as List;
return bodyJson.map<String>((country) => country['name'] as String).toList();
}
/// Get Vendors
Future<List<CakePayVendor>> getVendors({
required String CSRFToken,
required String authorization,
int? page,
String? country,
String? countryCode,
String? search,
List<String>? vendorIds,
bool? giftCards,
bool? prepaidCards,
bool? onDemand,
bool? custom,
}) async {
var queryParams = {
'page': page?.toString(),
'country': country,
'country_code': countryCode,
'search': search,
'vendor_ids': vendorIds?.join(','),
'gift_cards': giftCards?.toString(),
'prepaid_cards': prepaidCards?.toString(),
'on_demand': onDemand?.toString(),
'custom': custom?.toString(),
};
final uri = Uri.https(baseCakePayUri, vendorsPath, queryParams);
var headers = {
'accept': 'application/json; charset=UTF-8',
'authorization': authorization,
'X-CSRFToken': CSRFToken,
};
var response = await http.get(uri, headers: headers);
if (response.statusCode != 200) {
throw Exception(response.body);
}
final bodyJson = json.decode(response.body);
if (bodyJson is List<dynamic> && bodyJson.isEmpty) {
return [];
}
return (bodyJson['results'] as List)
.map((e) => CakePayVendor.fromJson(e as Map<String, dynamic>))
.toList();
}
}

View file

@ -0,0 +1,87 @@
import 'dart:convert';
import 'package:cake_wallet/entities/fiat_currency.dart';
class CakePayCard {
final int id;
final String name;
final String? description;
final String? termsAndConditions;
final String? howToUse;
final String? expiryAndValidity;
final String? cardImageUrl;
final String? country;
final FiatCurrency fiatCurrency;
final List<String> denominationsUsd;
final List<String> denominations;
final String? minValueUsd;
final String? maxValueUsd;
final String? minValue;
final String? maxValue;
CakePayCard({
required this.id,
required this.name,
this.description,
this.termsAndConditions,
this.howToUse,
this.expiryAndValidity,
this.cardImageUrl,
this.country,
required this.fiatCurrency,
required this.denominationsUsd,
required this.denominations,
this.minValueUsd,
this.maxValueUsd,
this.minValue,
this.maxValue,
});
factory CakePayCard.fromJson(Map<String, dynamic> json) {
final name = stripHtmlIfNeeded(json['name'] as String? ?? '');
final decodedName = fixEncoding(name);
final description = stripHtmlIfNeeded(json['description'] as String? ?? '');
final decodedDescription = fixEncoding(description);
final termsAndConditions = stripHtmlIfNeeded(json['terms_and_conditions'] as String? ?? '');
final decodedTermsAndConditions = fixEncoding(termsAndConditions);
final howToUse = stripHtmlIfNeeded(json['how_to_use'] as String? ?? '');
final decodedHowToUse = fixEncoding(howToUse);
final fiatCurrency = FiatCurrency.deserialize(raw: json['currency_code'] as String? ?? '');
final List<String> denominationsUsd =
(json['denominations_usd'] as List?)?.map((e) => e.toString()).toList() ?? [];
final List<String> denominations =
(json['denominations'] as List?)?.map((e) => e.toString()).toList() ?? [];
return CakePayCard(
id: json['id'] as int? ?? 0,
name: decodedName,
description: decodedDescription,
termsAndConditions: decodedTermsAndConditions,
howToUse: decodedHowToUse,
expiryAndValidity: json['expiry_and_validity'] as String?,
cardImageUrl: json['card_image_url'] as String?,
country: json['country'] as String?,
fiatCurrency: fiatCurrency,
denominationsUsd: denominationsUsd,
denominations: denominations,
minValueUsd: json['min_value_usd'] as String?,
maxValueUsd: json['max_value_usd'] as String?,
minValue: json['min_value'] as String?,
maxValue: json['max_value'] as String?,
);
}
static String stripHtmlIfNeeded(String text) {
return text.replaceAll(RegExp(r'<[^>]*>|&[^;]+;'), ' ');
}
static String fixEncoding(String text) {
final bytes = latin1.encode(text);
return utf8.decode(bytes, allowMalformed: true);
}
}

View file

@ -0,0 +1,131 @@
class CakePayOrder {
final String orderId;
final List<OrderCard> cards;
final String? externalId;
final double amountUsd;
final String status;
final String? vouchers;
final PaymentData paymentData;
CakePayOrder({
required this.orderId,
required this.cards,
required this.externalId,
required this.amountUsd,
required this.status,
required this.vouchers,
required this.paymentData,
});
factory CakePayOrder.fromMap(Map<String, dynamic> map) {
return CakePayOrder(
orderId: map['order_id'] as String,
cards: (map['cards'] as List<dynamic>)
.map((x) => OrderCard.fromMap(x as Map<String, dynamic>))
.toList(),
externalId: map['external_id'] as String?,
amountUsd: map['amount_usd'] as double,
status: map['status'] as String,
vouchers: map['vouchers'] as String?,
paymentData: PaymentData.fromMap(map['payment_data'] as Map<String, dynamic>));
}
}
class OrderCard {
final int cardId;
final int? externalId;
final String price;
final int quantity;
final String currencyCode;
OrderCard({
required this.cardId,
required this.externalId,
required this.price,
required this.quantity,
required this.currencyCode,
});
factory OrderCard.fromMap(Map<String, dynamic> map) {
return OrderCard(
cardId: map['card_id'] as int,
externalId: map['external_id'] as int?,
price: map['price'] as String,
quantity: map['quantity'] as int,
currencyCode: map['currency_code'] as String,
);
}
}
class PaymentData {
final CryptoPaymentData btc;
final CryptoPaymentData xmr;
final DateTime invoiceTime;
final DateTime expirationTime;
final int? commission;
PaymentData({
required this.btc,
required this.xmr,
required this.invoiceTime,
required this.expirationTime,
required this.commission,
});
factory PaymentData.fromMap(Map<String, dynamic> map) {
return PaymentData(
btc: CryptoPaymentData.fromMap(map['BTC'] as Map<String, dynamic>),
xmr: CryptoPaymentData.fromMap(map['XMR'] as Map<String, dynamic>),
invoiceTime: DateTime.fromMillisecondsSinceEpoch(map['invoice_time'] as int),
expirationTime: DateTime.fromMillisecondsSinceEpoch(map['expiration_time'] as int),
commission: map['commission'] as int?,
);
}
}
class CryptoPaymentData {
final String price;
final PaymentUrl? paymentUrls;
final String address;
CryptoPaymentData({
required this.price,
this.paymentUrls,
required this.address,
});
factory CryptoPaymentData.fromMap(Map<String, dynamic> map) {
return CryptoPaymentData(
price: map['price'] as String,
paymentUrls: PaymentUrl.fromMap(map['paymentUrls'] as Map<String, dynamic>?),
address: map['address'] as String,
);
}
}
class PaymentUrl {
final String? bip21;
final String? bip72;
final String? bip72b;
final String? bip73;
final String? bolt11;
PaymentUrl({
this.bip21,
this.bip72,
this.bip72b,
this.bip73,
this.bolt11,
});
factory PaymentUrl.fromMap(Map<String, dynamic>? map) {
return PaymentUrl(
bip21: map?['BIP21'] as String?,
bip72: map?['BIP72'] as String?,
bip72b: map?['BIP72b'] as String?,
bip73: map?['BIP73'] as String?,
bolt11: map?['BOLT11'] as String?,
);
}
}

View file

@ -0,0 +1,15 @@
class PaymentCredential {
final double amount;
final int quantity;
final double totalAmount;
final String? userName;
final String fiatCurrency;
PaymentCredential({
required this.amount,
required this.quantity,
required this.totalAmount,
required this.userName,
required this.fiatCurrency,
});
}

View file

@ -0,0 +1,107 @@
import 'package:cake_wallet/.secrets.g.dart' as secrets;
import 'package:cake_wallet/cake_pay/cake_pay_api.dart';
import 'package:cake_wallet/cake_pay/cake_pay_order.dart';
import 'package:cake_wallet/cake_pay/cake_pay_vendor.dart';
import 'package:cake_wallet/core/secure_storage.dart';
class CakePayService {
CakePayService(this.secureStorage, this.cakePayApi);
static const cakePayEmailStorageKey = 'cake_pay_email';
static const cakePayUsernameStorageKey = 'cake_pay_username';
static const cakePayUserTokenKey = 'cake_pay_user_token';
static String get testCakePayApiKey => secrets.testCakePayApiKey;
static String get cakePayApiKey => secrets.cakePayApiKey;
static String get CSRFToken => secrets.CSRFToken;
static String get authorization => secrets.authorization;
final SecureStorage secureStorage;
final CakePayApi cakePayApi;
/// Get Available Countries
Future<List<String>> getCountries() async =>
await cakePayApi.getCountries(CSRFToken: CSRFToken, authorization: authorization);
/// Get Vendors
Future<List<CakePayVendor>> getVendors({
int? page,
String? country,
String? countryCode,
String? search,
List<String>? vendorIds,
bool? giftCards,
bool? prepaidCards,
bool? onDemand,
bool? custom,
}) async {
final result = await cakePayApi.getVendors(
CSRFToken: CSRFToken,
authorization: authorization,
page: page,
country: country,
countryCode: countryCode,
search: search,
vendorIds: vendorIds,
giftCards: giftCards,
prepaidCards: prepaidCards,
onDemand: onDemand,
custom: custom);
return result;
}
/// LogIn
Future<void> logIn(String email) async {
final userName = await cakePayApi.authenticateUser(email: email, apiKey: cakePayApiKey);
await secureStorage.write(key: cakePayEmailStorageKey, value: userName);
await secureStorage.write(key: cakePayUsernameStorageKey, value: userName);
}
/// Verify email
Future<void> verifyEmail(String code) async {
final email = (await secureStorage.read(key: cakePayEmailStorageKey))!;
final credentials =
await cakePayApi.verifyEmail(email: email, code: code, apiKey: cakePayApiKey);
await secureStorage.write(key: cakePayUserTokenKey, value: credentials.token);
await secureStorage.write(key: cakePayUsernameStorageKey, value: credentials.username);
}
Future<String?> getUserEmail() async {
return (await secureStorage.read(key: cakePayEmailStorageKey));
}
/// Check is user logged
Future<bool> isLogged() async {
final username = await secureStorage.read(key: cakePayUsernameStorageKey) ?? '';
final password = await secureStorage.read(key: cakePayUserTokenKey) ?? '';
return username.isNotEmpty && password.isNotEmpty;
}
/// Logout
Future<void> logout(String email) async {
await secureStorage.delete(key: cakePayUsernameStorageKey);
await secureStorage.delete(key: cakePayUserTokenKey);
await cakePayApi.logoutUser(email: email, apiKey: cakePayApiKey);
}
/// Purchase Gift Card
Future<CakePayOrder> createOrder(
{required int cardId, required String price, required int quantity}) async {
final userEmail = (await secureStorage.read(key: cakePayEmailStorageKey))!;
final token = (await secureStorage.read(key: cakePayUserTokenKey))!;
return await cakePayApi.createOrder(
apiKey: cakePayApiKey,
cardId: cardId,
price: price,
quantity: quantity,
token: token,
userEmail: userEmail);
}
///Simulate Purchase Gift Card
Future<void> simulatePayment({required String orderId}) async => await cakePayApi.simulatePayment(
CSRFToken: CSRFToken, authorization: authorization, orderId: orderId);
}

View file

@ -0,0 +1,67 @@
import 'cake_pay_card.dart';
abstract class CakePayUserVerificationState {}
class CakePayUserVerificationStateInitial extends CakePayUserVerificationState {}
class CakePayUserVerificationStateSuccess extends CakePayUserVerificationState {}
class CakePayUserVerificationStatePending extends CakePayUserVerificationState {}
class CakePayUserVerificationStateLoading extends CakePayUserVerificationState {}
class CakePayUserVerificationStateFailure extends CakePayUserVerificationState {
CakePayUserVerificationStateFailure({required this.error});
final String error;
}
abstract class CakePayOtpState {}
class CakePayOtpValidating extends CakePayOtpState {}
class CakePayOtpSuccess extends CakePayOtpState {}
class CakePayOtpSendDisabled extends CakePayOtpState {}
class CakePayOtpSendEnabled extends CakePayOtpState {}
class CakePayOtpFailure extends CakePayOtpState {
CakePayOtpFailure({required this.error});
final String error;
}
class CakePayCreateCardState {}
class CakePayCreateCardStateSuccess extends CakePayCreateCardState {}
class CakePayCreateCardStateLoading extends CakePayCreateCardState {}
class CakePayCreateCardStateFailure extends CakePayCreateCardState {
CakePayCreateCardStateFailure({required this.error});
final String error;
}
class CakePayCardsState {}
class CakePayCardsStateNoCards extends CakePayCardsState {}
class CakePayCardsStateFetching extends CakePayCardsState {}
class CakePayCardsStateFailure extends CakePayCardsState {}
class CakePayCardsStateSuccess extends CakePayCardsState {
CakePayCardsStateSuccess({required this.card});
final CakePayCard card;
}
abstract class CakePayVendorState {}
class InitialCakePayVendorLoadingState extends CakePayVendorState {}
class CakePayVendorLoadingState extends CakePayVendorState {}
class CakePayVendorLoadedState extends CakePayVendorState {}

View file

@ -0,0 +1,6 @@
class CakePayUserCredentials {
const CakePayUserCredentials(this.username, this.token);
final String username;
final String token;
}

View file

@ -0,0 +1,51 @@
import 'dart:convert';
import 'cake_pay_card.dart';
class CakePayVendor {
final int id;
final String name;
final bool unavailable;
final String? cakeWarnings;
final List<String> countries;
final CakePayCard? card;
CakePayVendor({
required this.id,
required this.name,
required this.unavailable,
this.cakeWarnings,
required this.countries,
this.card,
});
factory CakePayVendor.fromJson(Map<String, dynamic> json) {
final name = stripHtmlIfNeeded(json['name'] as String);
final decodedName = fixEncoding(name);
var cardsJson = json['cards'] as List?;
CakePayCard? firstCard;
if (cardsJson != null && cardsJson.isNotEmpty) {
firstCard = CakePayCard.fromJson(cardsJson.first as Map<String, dynamic>);
}
return CakePayVendor(
id: json['id'] as int,
name: decodedName,
unavailable: json['unavailable'] as bool? ?? false,
cakeWarnings: json['cake_warnings'] as String?,
countries: List<String>.from(json['countries'] as List? ?? []),
card: firstCard,
);
}
static String stripHtmlIfNeeded(String text) {
return text.replaceAll(RegExp(r'<[^>]*>|&[^;]+;'), ' ');
}
static String fixEncoding(String text) {
final bytes = latin1.encode(text);
return utf8.decode(bytes, allowMalformed: true);
}
}

View file

@ -2,7 +2,6 @@ import 'package:cake_wallet/.secrets.g.dart' as secrets;
import 'package:cake_wallet/anonpay/anonpay_api.dart'; import 'package:cake_wallet/anonpay/anonpay_api.dart';
import 'package:cake_wallet/anonpay/anonpay_info_base.dart'; import 'package:cake_wallet/anonpay/anonpay_info_base.dart';
import 'package:cake_wallet/anonpay/anonpay_invoice_info.dart'; import 'package:cake_wallet/anonpay/anonpay_invoice_info.dart';
import 'package:cake_wallet/anypay/any_pay_payment_committed_info.dart';
import 'package:cake_wallet/anypay/anypay_api.dart'; import 'package:cake_wallet/anypay/anypay_api.dart';
import 'package:cake_wallet/bitcoin/bitcoin.dart'; import 'package:cake_wallet/bitcoin/bitcoin.dart';
import 'package:cake_wallet/bitcoin_cash/bitcoin_cash.dart'; import 'package:cake_wallet/bitcoin_cash/bitcoin_cash.dart';
@ -33,16 +32,10 @@ import 'package:cake_wallet/entities/qr_view_data.dart';
import 'package:cake_wallet/entities/template.dart'; import 'package:cake_wallet/entities/template.dart';
import 'package:cake_wallet/entities/transaction_description.dart'; import 'package:cake_wallet/entities/transaction_description.dart';
import 'package:cake_wallet/ethereum/ethereum.dart'; import 'package:cake_wallet/ethereum/ethereum.dart';
import 'package:cake_wallet/cake_pay/cake_pay_card.dart';
import 'package:cake_wallet/exchange/exchange_template.dart'; import 'package:cake_wallet/exchange/exchange_template.dart';
import 'package:cake_wallet/exchange/trade.dart'; import 'package:cake_wallet/exchange/trade.dart';
import 'package:cake_wallet/haven/haven.dart'; import 'package:cake_wallet/haven/haven.dart';
import 'package:cake_wallet/ionia/ionia_any_pay_payment_info.dart';
import 'package:cake_wallet/ionia/ionia_anypay.dart';
import 'package:cake_wallet/ionia/ionia_api.dart';
import 'package:cake_wallet/ionia/ionia_gift_card.dart';
import 'package:cake_wallet/ionia/ionia_merchant.dart';
import 'package:cake_wallet/ionia/ionia_service.dart';
import 'package:cake_wallet/ionia/ionia_tip.dart';
import 'package:cake_wallet/monero/monero.dart'; import 'package:cake_wallet/monero/monero.dart';
import 'package:cake_wallet/nano/nano.dart'; import 'package:cake_wallet/nano/nano.dart';
import 'package:cake_wallet/polygon/polygon.dart'; import 'package:cake_wallet/polygon/polygon.dart';
@ -72,14 +65,6 @@ import 'package:cake_wallet/src/screens/exchange/exchange_template_page.dart';
import 'package:cake_wallet/src/screens/exchange_trade/exchange_confirm_page.dart'; import 'package:cake_wallet/src/screens/exchange_trade/exchange_confirm_page.dart';
import 'package:cake_wallet/src/screens/exchange_trade/exchange_trade_page.dart'; import 'package:cake_wallet/src/screens/exchange_trade/exchange_trade_page.dart';
import 'package:cake_wallet/src/screens/faq/faq_page.dart'; import 'package:cake_wallet/src/screens/faq/faq_page.dart';
import 'package:cake_wallet/src/screens/ionia/cards/ionia_account_cards_page.dart';
import 'package:cake_wallet/src/screens/ionia/cards/ionia_account_page.dart';
import 'package:cake_wallet/src/screens/ionia/cards/ionia_custom_redeem_page.dart';
import 'package:cake_wallet/src/screens/ionia/cards/ionia_custom_tip_page.dart';
import 'package:cake_wallet/src/screens/ionia/cards/ionia_gift_card_detail_page.dart';
import 'package:cake_wallet/src/screens/ionia/cards/ionia_more_options_page.dart';
import 'package:cake_wallet/src/screens/ionia/cards/ionia_payment_status_page.dart';
import 'package:cake_wallet/src/screens/ionia/ionia.dart';
import 'package:cake_wallet/src/screens/monero_accounts/monero_account_edit_or_create_page.dart'; import 'package:cake_wallet/src/screens/monero_accounts/monero_account_edit_or_create_page.dart';
import 'package:cake_wallet/src/screens/monero_accounts/monero_account_list_page.dart'; import 'package:cake_wallet/src/screens/monero_accounts/monero_account_list_page.dart';
import 'package:cake_wallet/src/screens/nano/nano_change_rep_page.dart'; import 'package:cake_wallet/src/screens/nano/nano_change_rep_page.dart';
@ -124,16 +109,57 @@ import 'package:cake_wallet/src/screens/subaddress/address_edit_or_create_page.d
import 'package:cake_wallet/src/screens/support/support_page.dart'; import 'package:cake_wallet/src/screens/support/support_page.dart';
import 'package:cake_wallet/src/screens/support_chat/support_chat_page.dart'; import 'package:cake_wallet/src/screens/support_chat/support_chat_page.dart';
import 'package:cake_wallet/src/screens/support_other_links/support_other_links_page.dart'; import 'package:cake_wallet/src/screens/support_other_links/support_other_links_page.dart';
import 'package:cake_wallet/src/screens/wallet/wallet_edit_page.dart';
import 'package:cake_wallet/src/screens/wallet_connect/wc_connections_listing_view.dart';
import 'package:cake_wallet/themes/theme_list.dart';
import 'package:cake_wallet/utils/device_info.dart';
import 'package:cake_wallet/store/anonpay/anonpay_transactions_store.dart';
import 'package:cake_wallet/utils/payment_request.dart';
import 'package:cake_wallet/utils/responsive_layout_util.dart';
import 'package:cake_wallet/view_model/dashboard/desktop_sidebar_view_model.dart';
import 'package:cake_wallet/view_model/anon_invoice_page_view_model.dart';
import 'package:cake_wallet/view_model/anonpay_details_view_model.dart';
import 'package:cake_wallet/view_model/dashboard/home_settings_view_model.dart';
import 'package:cake_wallet/view_model/dashboard/nft_view_model.dart';
import 'package:cake_wallet/view_model/dashboard/receive_option_view_model.dart';
import 'package:cake_wallet/view_model/cake_pay/cake_pay_auth_view_model.dart';
import 'package:cake_wallet/view_model/cake_pay/cake_pay_buy_card_view_model.dart';
import 'package:cake_wallet/cake_pay/cake_pay_service.dart';
import 'package:cake_wallet/cake_pay/cake_pay_api.dart';
import 'package:cake_wallet/cake_pay/cake_pay_vendor.dart';
import 'package:cake_wallet/src/screens/cake_pay/auth/cake_pay_account_page.dart';
import 'package:cake_wallet/src/screens/cake_pay/cake_pay.dart';
import 'package:cake_wallet/view_model/cake_pay/cake_pay_account_view_model.dart';
import 'package:cake_wallet/view_model/cake_pay/cake_pay_cards_list_view_model.dart';
import 'package:cake_wallet/view_model/cake_pay/cake_pay_purchase_view_model.dart';
import 'package:cake_wallet/view_model/nano_account_list/nano_account_edit_or_create_view_model.dart';
import 'package:cake_wallet/view_model/nano_account_list/nano_account_list_view_model.dart';
import 'package:cake_wallet/view_model/node_list/pow_node_list_view_model.dart';
import 'package:cake_wallet/view_model/seed_type_view_model.dart';
import 'package:cake_wallet/view_model/set_up_2fa_viewmodel.dart';
import 'package:cake_wallet/view_model/restore/restore_from_qr_vm.dart';
import 'package:cake_wallet/view_model/settings/display_settings_view_model.dart';
import 'package:cake_wallet/view_model/settings/other_settings_view_model.dart';
import 'package:cake_wallet/view_model/settings/privacy_settings_view_model.dart';
import 'package:cake_wallet/view_model/settings/security_settings_view_model.dart';
import 'package:cake_wallet/view_model/advanced_privacy_settings_view_model.dart';
import 'package:cake_wallet/view_model/settings/trocador_providers_view_model.dart';
import 'package:cake_wallet/view_model/wallet_address_list/wallet_address_list_item.dart';
import 'package:cake_wallet/view_model/wallet_list/wallet_edit_view_model.dart';
import 'package:cake_wallet/view_model/wallet_list/wallet_list_item.dart';
import 'package:cake_wallet/view_model/wallet_restore_choose_derivation_view_model.dart';
import 'package:cw_core/nano_account.dart';
import 'package:cw_core/unspent_coins_info.dart';
import 'package:cw_core/wallet_service.dart';
import 'package:cw_core/transaction_info.dart';
import 'package:cw_core/node.dart';
import 'package:cake_wallet/src/screens/trade_details/trade_details_page.dart'; import 'package:cake_wallet/src/screens/trade_details/trade_details_page.dart';
import 'package:cake_wallet/src/screens/transaction_details/rbf_details_page.dart'; import 'package:cake_wallet/src/screens/transaction_details/rbf_details_page.dart';
import 'package:cake_wallet/src/screens/transaction_details/transaction_details_page.dart'; import 'package:cake_wallet/src/screens/transaction_details/transaction_details_page.dart';
import 'package:cake_wallet/src/screens/unspent_coins/unspent_coins_details_page.dart'; import 'package:cake_wallet/src/screens/unspent_coins/unspent_coins_details_page.dart';
import 'package:cake_wallet/src/screens/unspent_coins/unspent_coins_list_page.dart'; import 'package:cake_wallet/src/screens/unspent_coins/unspent_coins_list_page.dart';
import 'package:cake_wallet/src/screens/wallet/wallet_edit_page.dart';
import 'package:cake_wallet/src/screens/wallet_connect/wc_connections_listing_view.dart';
import 'package:cake_wallet/src/screens/wallet_keys/wallet_keys_page.dart'; import 'package:cake_wallet/src/screens/wallet_keys/wallet_keys_page.dart';
import 'package:cake_wallet/src/screens/wallet_list/wallet_list_page.dart'; import 'package:cake_wallet/src/screens/wallet_list/wallet_list_page.dart';
import 'package:cake_wallet/store/anonpay/anonpay_transactions_store.dart';
import 'package:cake_wallet/store/app_store.dart'; import 'package:cake_wallet/store/app_store.dart';
import 'package:cake_wallet/store/authentication_store.dart'; import 'package:cake_wallet/store/authentication_store.dart';
import 'package:cake_wallet/store/dashboard/fiat_conversion_store.dart'; import 'package:cake_wallet/store/dashboard/fiat_conversion_store.dart';
@ -148,14 +174,7 @@ import 'package:cake_wallet/store/templates/exchange_template_store.dart';
import 'package:cake_wallet/store/templates/send_template_store.dart'; import 'package:cake_wallet/store/templates/send_template_store.dart';
import 'package:cake_wallet/store/wallet_list_store.dart'; import 'package:cake_wallet/store/wallet_list_store.dart';
import 'package:cake_wallet/store/yat/yat_store.dart'; import 'package:cake_wallet/store/yat/yat_store.dart';
import 'package:cake_wallet/themes/theme_list.dart';
import 'package:cake_wallet/tron/tron.dart'; import 'package:cake_wallet/tron/tron.dart';
import 'package:cake_wallet/utils/device_info.dart';
import 'package:cake_wallet/utils/payment_request.dart';
import 'package:cake_wallet/utils/responsive_layout_util.dart';
import 'package:cake_wallet/view_model/advanced_privacy_settings_view_model.dart';
import 'package:cake_wallet/view_model/anon_invoice_page_view_model.dart';
import 'package:cake_wallet/view_model/anonpay_details_view_model.dart';
import 'package:cake_wallet/view_model/auth_view_model.dart'; import 'package:cake_wallet/view_model/auth_view_model.dart';
import 'package:cake_wallet/view_model/backup_view_model.dart'; import 'package:cake_wallet/view_model/backup_view_model.dart';
import 'package:cake_wallet/view_model/buy/buy_amount_view_model.dart'; import 'package:cake_wallet/view_model/buy/buy_amount_view_model.dart';
@ -165,46 +184,22 @@ import 'package:cake_wallet/view_model/contact_list/contact_view_model.dart';
import 'package:cake_wallet/view_model/dashboard/balance_view_model.dart'; import 'package:cake_wallet/view_model/dashboard/balance_view_model.dart';
import 'package:cake_wallet/view_model/dashboard/cake_features_view_model.dart'; import 'package:cake_wallet/view_model/dashboard/cake_features_view_model.dart';
import 'package:cake_wallet/view_model/dashboard/dashboard_view_model.dart'; import 'package:cake_wallet/view_model/dashboard/dashboard_view_model.dart';
import 'package:cake_wallet/view_model/dashboard/desktop_sidebar_view_model.dart';
import 'package:cake_wallet/view_model/dashboard/home_settings_view_model.dart';
import 'package:cake_wallet/view_model/dashboard/nft_view_model.dart';
import 'package:cake_wallet/view_model/dashboard/receive_option_view_model.dart';
import 'package:cake_wallet/view_model/edit_backup_password_view_model.dart'; import 'package:cake_wallet/view_model/edit_backup_password_view_model.dart';
import 'package:cake_wallet/view_model/exchange/exchange_trade_view_model.dart'; import 'package:cake_wallet/view_model/exchange/exchange_trade_view_model.dart';
import 'package:cake_wallet/view_model/exchange/exchange_view_model.dart'; import 'package:cake_wallet/view_model/exchange/exchange_view_model.dart';
import 'package:cake_wallet/view_model/hardware_wallet/ledger_view_model.dart'; import 'package:cake_wallet/view_model/hardware_wallet/ledger_view_model.dart';
import 'package:cake_wallet/view_model/ionia/ionia_account_view_model.dart';
import 'package:cake_wallet/view_model/ionia/ionia_auth_view_model.dart';
import 'package:cake_wallet/view_model/ionia/ionia_buy_card_view_model.dart';
import 'package:cake_wallet/view_model/ionia/ionia_custom_redeem_view_model.dart';
import 'package:cake_wallet/view_model/ionia/ionia_custom_tip_view_model.dart';
import 'package:cake_wallet/view_model/ionia/ionia_gift_card_details_view_model.dart';
import 'package:cake_wallet/view_model/ionia/ionia_gift_cards_list_view_model.dart';
import 'package:cake_wallet/view_model/ionia/ionia_payment_status_view_model.dart';
import 'package:cake_wallet/view_model/ionia/ionia_purchase_merch_view_model.dart';
import 'package:cake_wallet/view_model/link_view_model.dart'; import 'package:cake_wallet/view_model/link_view_model.dart';
import 'package:cake_wallet/view_model/monero_account_list/account_list_item.dart'; import 'package:cake_wallet/view_model/monero_account_list/account_list_item.dart';
import 'package:cake_wallet/view_model/monero_account_list/monero_account_edit_or_create_view_model.dart'; import 'package:cake_wallet/view_model/monero_account_list/monero_account_edit_or_create_view_model.dart';
import 'package:cake_wallet/view_model/monero_account_list/monero_account_list_view_model.dart'; import 'package:cake_wallet/view_model/monero_account_list/monero_account_list_view_model.dart';
import 'package:cake_wallet/view_model/nano_account_list/nano_account_edit_or_create_view_model.dart';
import 'package:cake_wallet/view_model/nano_account_list/nano_account_list_view_model.dart';
import 'package:cake_wallet/view_model/node_list/node_create_or_edit_view_model.dart'; import 'package:cake_wallet/view_model/node_list/node_create_or_edit_view_model.dart';
import 'package:cake_wallet/view_model/node_list/node_list_view_model.dart'; import 'package:cake_wallet/view_model/node_list/node_list_view_model.dart';
import 'package:cake_wallet/view_model/node_list/pow_node_list_view_model.dart';
import 'package:cake_wallet/view_model/order_details_view_model.dart'; import 'package:cake_wallet/view_model/order_details_view_model.dart';
import 'package:cake_wallet/view_model/rescan_view_model.dart'; import 'package:cake_wallet/view_model/rescan_view_model.dart';
import 'package:cake_wallet/view_model/restore/restore_from_qr_vm.dart';
import 'package:cake_wallet/view_model/restore_from_backup_view_model.dart'; import 'package:cake_wallet/view_model/restore_from_backup_view_model.dart';
import 'package:cake_wallet/view_model/seed_type_view_model.dart';
import 'package:cake_wallet/view_model/send/send_template_view_model.dart'; import 'package:cake_wallet/view_model/send/send_template_view_model.dart';
import 'package:cake_wallet/view_model/send/send_view_model.dart'; import 'package:cake_wallet/view_model/send/send_view_model.dart';
import 'package:cake_wallet/view_model/set_up_2fa_viewmodel.dart';
import 'package:cake_wallet/view_model/settings/display_settings_view_model.dart';
import 'package:cake_wallet/view_model/settings/other_settings_view_model.dart';
import 'package:cake_wallet/view_model/settings/privacy_settings_view_model.dart';
import 'package:cake_wallet/view_model/settings/security_settings_view_model.dart';
import 'package:cake_wallet/view_model/settings/silent_payments_settings_view_model.dart'; import 'package:cake_wallet/view_model/settings/silent_payments_settings_view_model.dart';
import 'package:cake_wallet/view_model/settings/trocador_providers_view_model.dart';
import 'package:cake_wallet/view_model/setup_pin_code_view_model.dart'; import 'package:cake_wallet/view_model/setup_pin_code_view_model.dart';
import 'package:cake_wallet/view_model/support_view_model.dart'; import 'package:cake_wallet/view_model/support_view_model.dart';
import 'package:cake_wallet/view_model/trade_details_view_model.dart'; import 'package:cake_wallet/view_model/trade_details_view_model.dart';
@ -213,25 +208,16 @@ import 'package:cake_wallet/view_model/unspent_coins/unspent_coins_details_view_
import 'package:cake_wallet/view_model/unspent_coins/unspent_coins_item.dart'; import 'package:cake_wallet/view_model/unspent_coins/unspent_coins_item.dart';
import 'package:cake_wallet/view_model/unspent_coins/unspent_coins_list_view_model.dart'; import 'package:cake_wallet/view_model/unspent_coins/unspent_coins_list_view_model.dart';
import 'package:cake_wallet/view_model/wallet_address_list/wallet_address_edit_or_create_view_model.dart'; import 'package:cake_wallet/view_model/wallet_address_list/wallet_address_edit_or_create_view_model.dart';
import 'package:cake_wallet/view_model/wallet_address_list/wallet_address_list_item.dart';
import 'package:cake_wallet/view_model/wallet_address_list/wallet_address_list_view_model.dart'; import 'package:cake_wallet/view_model/wallet_address_list/wallet_address_list_view_model.dart';
import 'package:cake_wallet/view_model/wallet_hardware_restore_view_model.dart'; import 'package:cake_wallet/view_model/wallet_hardware_restore_view_model.dart';
import 'package:cake_wallet/view_model/wallet_keys_view_model.dart'; import 'package:cake_wallet/view_model/wallet_keys_view_model.dart';
import 'package:cake_wallet/view_model/wallet_list/wallet_edit_view_model.dart';
import 'package:cake_wallet/view_model/wallet_list/wallet_list_item.dart';
import 'package:cake_wallet/view_model/wallet_list/wallet_list_view_model.dart'; import 'package:cake_wallet/view_model/wallet_list/wallet_list_view_model.dart';
import 'package:cake_wallet/view_model/wallet_new_vm.dart'; import 'package:cake_wallet/view_model/wallet_new_vm.dart';
import 'package:cake_wallet/view_model/wallet_restore_choose_derivation_view_model.dart';
import 'package:cake_wallet/view_model/wallet_restore_view_model.dart'; import 'package:cake_wallet/view_model/wallet_restore_view_model.dart';
import 'package:cake_wallet/view_model/wallet_seed_view_model.dart'; import 'package:cake_wallet/view_model/wallet_seed_view_model.dart';
import 'package:cw_core/crypto_currency.dart'; import 'package:cw_core/crypto_currency.dart';
import 'package:cw_core/nano_account.dart';
import 'package:cw_core/node.dart';
import 'package:cw_core/receive_page_option.dart'; import 'package:cw_core/receive_page_option.dart';
import 'package:cw_core/transaction_info.dart';
import 'package:cw_core/unspent_coins_info.dart';
import 'package:cw_core/wallet_info.dart'; import 'package:cw_core/wallet_info.dart';
import 'package:cw_core/wallet_service.dart';
import 'package:cw_core/wallet_type.dart'; import 'package:cw_core/wallet_type.dart';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter/widgets.dart'; import 'package:flutter/widgets.dart';
@ -239,6 +225,7 @@ import 'package:get_it/get_it.dart';
import 'package:hive/hive.dart'; import 'package:hive/hive.dart';
import 'package:mobx/mobx.dart'; import 'package:mobx/mobx.dart';
import 'package:shared_preferences/shared_preferences.dart'; import 'package:shared_preferences/shared_preferences.dart';
import 'cake_pay/cake_pay_payment_credantials.dart';
final getIt = GetIt.instance; final getIt = GetIt.instance;
@ -993,6 +980,8 @@ Future<void> setup({
trades: _tradesSource, trades: _tradesSource,
settingsStore: getIt.get<SettingsStore>())); settingsStore: getIt.get<SettingsStore>()));
getIt.registerFactory(() => CakeFeaturesViewModel(getIt.get<CakePayService>()));
getIt.registerFactory(() => BackupService(getIt.get<SecureStorage>(), _walletInfoSource, getIt.registerFactory(() => BackupService(getIt.get<SecureStorage>(), _walletInfoSource,
getIt.get<KeyService>(), getIt.get<SharedPreferences>())); getIt.get<KeyService>(), getIt.get<SharedPreferences>()));
@ -1088,113 +1077,60 @@ Future<void> setup({
getIt.registerFactoryParam<FullscreenQRPage, QrViewData, void>( getIt.registerFactoryParam<FullscreenQRPage, QrViewData, void>(
(QrViewData viewData, _) => FullscreenQRPage(qrViewData: viewData)); (QrViewData viewData, _) => FullscreenQRPage(qrViewData: viewData));
getIt.registerFactory(() => IoniaApi()); getIt.registerFactory(() => CakePayApi());
getIt.registerFactory(() => AnyPayApi()); getIt.registerFactory(() => AnyPayApi());
getIt.registerFactory<IoniaService>( getIt.registerFactory<CakePayService>(
() => IoniaService(getIt.get<SecureStorage>(), getIt.get<IoniaApi>())); () => CakePayService(getIt.get<SecureStorage>(), getIt.get<CakePayApi>()));
getIt.registerFactory<IoniaAnyPay>(() => IoniaAnyPay( getIt.registerFactory(() => CakePayCardsListViewModel(cakePayService: getIt.get<CakePayService>()));
getIt.get<IoniaService>(), getIt.get<AnyPayApi>(), getIt.get<AppStore>().wallet!));
getIt.registerFactory(() => IoniaGiftCardsListViewModel(ioniaService: getIt.get<IoniaService>())); getIt.registerFactory(() => CakePayAuthViewModel(cakePayService: getIt.get<CakePayService>()));
getIt.registerFactory(() => CakeFeaturesViewModel(getIt.get<IoniaService>())); getIt.registerFactoryParam<CakePayPurchaseViewModel, PaymentCredential, CakePayCard>(
(PaymentCredential paymentCredential, CakePayCard card) {
getIt.registerFactory(() => IoniaAuthViewModel(ioniaService: getIt.get<IoniaService>())); return CakePayPurchaseViewModel(
cakePayService: getIt.get<CakePayService>(),
getIt.registerFactoryParam<IoniaMerchPurchaseViewModel, double, IoniaMerchant>( paymentCredential: paymentCredential,
(double amount, merchant) { card: card,
return IoniaMerchPurchaseViewModel(
ioniaAnyPayService: getIt.get<IoniaAnyPay>(),
amount: amount,
ioniaMerchant: merchant,
sendViewModel: getIt.get<SendViewModel>()); sendViewModel: getIt.get<SendViewModel>());
}); });
getIt.registerFactoryParam<IoniaBuyCardViewModel, IoniaMerchant, void>( getIt.registerFactoryParam<CakePayBuyCardViewModel, CakePayVendor, void>(
(IoniaMerchant merchant, _) { (CakePayVendor vendor, _) {
return IoniaBuyCardViewModel(ioniaMerchant: merchant); return CakePayBuyCardViewModel(vendor: vendor);
}); });
getIt.registerFactory(() => IoniaAccountViewModel(ioniaService: getIt.get<IoniaService>())); getIt.registerFactory(() => CakePayAccountViewModel(cakePayService: getIt.get<CakePayService>()));
getIt.registerFactory(() => IoniaCreateAccountPage(getIt.get<IoniaAuthViewModel>())); getIt.registerFactory(() => CakePayWelcomePage(getIt.get<CakePayAuthViewModel>()));
getIt.registerFactory(() => IoniaLoginPage(getIt.get<IoniaAuthViewModel>())); getIt.registerFactoryParam<CakePayVerifyOtpPage, List<dynamic>, void>((List<dynamic> args, _) {
getIt.registerFactoryParam<IoniaVerifyIoniaOtp, List<dynamic>, void>((List<dynamic> args, _) {
final email = args.first as String; final email = args.first as String;
final isSignIn = args[1] as bool; final isSignIn = args[1] as bool;
return IoniaVerifyIoniaOtp(getIt.get<IoniaAuthViewModel>(), email, isSignIn); return CakePayVerifyOtpPage(getIt.get<CakePayAuthViewModel>(), email, isSignIn);
}); });
getIt.registerFactory(() => IoniaWelcomePage()); getIt.registerFactoryParam<CakePayBuyCardPage, List<dynamic>, void>((List<dynamic> args, _) {
final vendor = args.first as CakePayVendor;
getIt.registerFactoryParam<IoniaBuyGiftCardPage, List<dynamic>, void>((List<dynamic> args, _) { return CakePayBuyCardPage(getIt.get<CakePayBuyCardViewModel>(param1: vendor),
final merchant = args.first as IoniaMerchant; getIt.get<CakePayService>());
return IoniaBuyGiftCardPage(getIt.get<IoniaBuyCardViewModel>(param1: merchant));
}); });
getIt.registerFactoryParam<IoniaBuyGiftCardDetailPage, List<dynamic>, void>( getIt.registerFactoryParam<CakePayBuyCardDetailPage, List<dynamic>, void>(
(List<dynamic> args, _) { (List<dynamic> args, _) {
final amount = args.first as double; final paymentCredential = args.first as PaymentCredential;
final merchant = args.last as IoniaMerchant; final card = args[1] as CakePayCard;
return IoniaBuyGiftCardDetailPage( return CakePayBuyCardDetailPage(
getIt.get<IoniaMerchPurchaseViewModel>(param1: amount, param2: merchant)); getIt.get<CakePayPurchaseViewModel>(param1: paymentCredential, param2: card));
}); });
getIt.registerFactoryParam<IoniaGiftCardDetailsViewModel, IoniaGiftCard, void>( getIt.registerFactory(() => CakePayCardsPage(getIt.get<CakePayCardsListViewModel>()));
(IoniaGiftCard giftCard, _) {
return IoniaGiftCardDetailsViewModel(
ioniaService: getIt.get<IoniaService>(), giftCard: giftCard);
});
getIt.registerFactoryParam<IoniaCustomTipViewModel, List<dynamic>, void>((List<dynamic> args, _) { getIt.registerFactory(() => CakePayAccountPage(getIt.get<CakePayAccountViewModel>()));
final amount = args[0] as double;
final merchant = args[1] as IoniaMerchant;
final tip = args[2] as IoniaTip;
return IoniaCustomTipViewModel(amount: amount, tip: tip, ioniaMerchant: merchant);
});
getIt.registerFactoryParam<IoniaGiftCardDetailPage, IoniaGiftCard, void>(
(IoniaGiftCard giftCard, _) {
return IoniaGiftCardDetailPage(getIt.get<IoniaGiftCardDetailsViewModel>(param1: giftCard));
});
getIt.registerFactoryParam<IoniaMoreOptionsPage, List<dynamic>, void>((List<dynamic> args, _) {
final giftCard = args.first as IoniaGiftCard;
return IoniaMoreOptionsPage(giftCard);
});
getIt.registerFactoryParam<IoniaCustomRedeemViewModel, IoniaGiftCard, void>(
(IoniaGiftCard giftCard, _) =>
IoniaCustomRedeemViewModel(giftCard: giftCard, ioniaService: getIt.get<IoniaService>()));
getIt.registerFactoryParam<IoniaCustomRedeemPage, List<dynamic>, void>((List<dynamic> args, _) {
final giftCard = args.first as IoniaGiftCard;
return IoniaCustomRedeemPage(getIt.get<IoniaCustomRedeemViewModel>(param1: giftCard));
});
getIt.registerFactoryParam<IoniaCustomTipPage, List<dynamic>, void>((List<dynamic> args, _) {
return IoniaCustomTipPage(getIt.get<IoniaCustomTipViewModel>(param1: args));
});
getIt.registerFactory(() => IoniaManageCardsPage(getIt.get<IoniaGiftCardsListViewModel>()));
getIt.registerFactory(() => IoniaDebitCardPage(getIt.get<IoniaGiftCardsListViewModel>()));
getIt.registerFactory(() => IoniaActivateDebitCardPage(getIt.get<IoniaGiftCardsListViewModel>()));
getIt.registerFactory(() => IoniaAccountPage(getIt.get<IoniaAccountViewModel>()));
getIt.registerFactory(() => IoniaAccountCardsPage(getIt.get<IoniaAccountViewModel>()));
getIt.registerFactoryParam<RBFDetailsPage, TransactionInfo, void>( getIt.registerFactoryParam<RBFDetailsPage, TransactionInfo, void>(
(TransactionInfo transactionInfo, _) => RBFDetailsPage( (TransactionInfo transactionInfo, _) => RBFDetailsPage(
@ -1225,18 +1161,6 @@ Future<void> setup({
(AnonpayInvoiceInfo anonpayInvoiceInfo, _) => AnonpayDetailsPage( (AnonpayInvoiceInfo anonpayInvoiceInfo, _) => AnonpayDetailsPage(
anonpayDetailsViewModel: getIt.get<AnonpayDetailsViewModel>(param1: anonpayInvoiceInfo))); anonpayDetailsViewModel: getIt.get<AnonpayDetailsViewModel>(param1: anonpayInvoiceInfo)));
getIt.registerFactoryParam<IoniaPaymentStatusViewModel, IoniaAnyPayPaymentInfo,
AnyPayPaymentCommittedInfo>(
(IoniaAnyPayPaymentInfo paymentInfo, AnyPayPaymentCommittedInfo committedInfo) =>
IoniaPaymentStatusViewModel(getIt.get<IoniaService>(),
paymentInfo: paymentInfo, committedInfo: committedInfo));
getIt.registerFactoryParam<IoniaPaymentStatusPage, IoniaAnyPayPaymentInfo,
AnyPayPaymentCommittedInfo>(
(IoniaAnyPayPaymentInfo paymentInfo, AnyPayPaymentCommittedInfo committedInfo) =>
IoniaPaymentStatusPage(
getIt.get<IoniaPaymentStatusViewModel>(param1: paymentInfo, param2: committedInfo)));
getIt.registerFactoryParam<HomeSettingsPage, BalanceViewModel, void>((balanceViewModel, _) => getIt.registerFactoryParam<HomeSettingsPage, BalanceViewModel, void>((balanceViewModel, _) =>
HomeSettingsPage(getIt.get<HomeSettingsViewModel>(param1: balanceViewModel))); HomeSettingsPage(getIt.get<HomeSettingsViewModel>(param1: balanceViewModel)));

View file

@ -1,9 +0,0 @@
import 'package:cake_wallet/anypay/any_pay_payment.dart';
import 'package:cake_wallet/ionia/ionia_order.dart';
class IoniaAnyPayPaymentInfo {
const IoniaAnyPayPaymentInfo(this.ioniaOrder, this.anyPayPayment);
final IoniaOrder ioniaOrder;
final AnyPayPayment anyPayPayment;
}

View file

@ -1,91 +0,0 @@
import 'package:cw_core/monero_amount_format.dart';
import 'package:cw_core/monero_transaction_priority.dart';
import 'package:cw_core/output_info.dart';
import 'package:cw_core/pending_transaction.dart';
import 'package:cw_core/wallet_base.dart';
import 'package:cake_wallet/anypay/any_pay_payment.dart';
import 'package:cake_wallet/anypay/any_pay_payment_instruction.dart';
import 'package:cake_wallet/ionia/ionia_service.dart';
import 'package:cake_wallet/anypay/anypay_api.dart';
import 'package:cake_wallet/anypay/any_pay_chain.dart';
import 'package:cake_wallet/anypay/any_pay_trasnaction.dart';
import 'package:cake_wallet/bitcoin/bitcoin.dart';
import 'package:cake_wallet/monero/monero.dart';
import 'package:cake_wallet/anypay/any_pay_payment_committed_info.dart';
import 'package:cake_wallet/ionia/ionia_any_pay_payment_info.dart';
class IoniaAnyPay {
IoniaAnyPay(this.ioniaService, this.anyPayApi, this.wallet);
final IoniaService ioniaService;
final AnyPayApi anyPayApi;
final WalletBase wallet;
Future<IoniaAnyPayPaymentInfo> purchase({
required String merchId,
required double amount}) async {
final invoice = await ioniaService.purchaseGiftCard(
merchId: merchId,
amount: amount,
currency: wallet.currency.title.toUpperCase());
final anypayPayment = await anyPayApi.paymentRequest(invoice.uri);
return IoniaAnyPayPaymentInfo(invoice, anypayPayment);
}
Future<AnyPayPaymentCommittedInfo> commitInvoice(AnyPayPayment payment) async {
final transactionCredentials = payment.instructions
.where((instruction) => instruction.type == AnyPayPaymentInstruction.transactionType)
.map((AnyPayPaymentInstruction instruction) {
switch(payment.chain.toUpperCase()) {
case AnyPayChain.xmr:
return monero!.createMoneroTransactionCreationCredentialsRaw(
outputs: instruction.outputs.map((out) =>
OutputInfo(
isParsedAddress: false,
address: out.address,
cryptoAmount: moneroAmountToString(amount: out.amount),
formattedCryptoAmount: out.amount,
sendAll: false)).toList(),
priority: MoneroTransactionPriority.medium); // FIXME: HARDCODED PRIORITY
case AnyPayChain.btc:
return bitcoin!.createBitcoinTransactionCredentialsRaw(
instruction.outputs.map((out) =>
OutputInfo(
isParsedAddress: false,
address: out.address,
formattedCryptoAmount: out.amount,
sendAll: false)).toList(),
feeRate: instruction.requiredFeeRate);
case AnyPayChain.ltc:
return bitcoin!.createBitcoinTransactionCredentialsRaw(
instruction.outputs.map((out) =>
OutputInfo(
isParsedAddress: false,
address: out.address,
formattedCryptoAmount: out.amount,
sendAll: false)).toList(),
feeRate: instruction.requiredFeeRate);
default:
throw Exception('Incorrect transaction chain: ${payment.chain.toUpperCase()}');
}
});
final transactions = (await Future.wait(transactionCredentials
.map((Object credentials) async => await wallet.createTransaction(credentials))))
.map((PendingTransaction pendingTransaction) {
switch (payment.chain.toUpperCase()){
case AnyPayChain.xmr:
final ptx = monero!.pendingTransactionInfo(pendingTransaction);
return AnyPayTransaction(ptx['hex'] ?? '', id: ptx['id'] ?? '', key: ptx['key']);
default:
return AnyPayTransaction(pendingTransaction.hex, id: pendingTransaction.id, key: null);
}
})
.toList();
return await anyPayApi.payment(
payment.paymentUrl,
chain: payment.chain,
currency: payment.chain,
transactions: transactions);
}
}

View file

@ -1,440 +0,0 @@
import 'dart:convert';
import 'package:cake_wallet/ionia/ionia_merchant.dart';
import 'package:cake_wallet/ionia/ionia_order.dart';
import 'package:http/http.dart';
import 'package:cake_wallet/ionia/ionia_user_credentials.dart';
import 'package:cake_wallet/ionia/ionia_virtual_card.dart';
import 'package:cake_wallet/ionia/ionia_category.dart';
import 'package:cake_wallet/ionia/ionia_gift_card.dart';
class IoniaApi {
static const baseUri = 'api.ionia.io';
static const pathPrefix = 'cake';
static const requestedUUIDHeader = 'requestedUUID';
static final createUserUri = Uri.https(baseUri, '/$pathPrefix/CreateUser');
static final verifyEmailUri = Uri.https(baseUri, '/$pathPrefix/VerifyEmail');
static final signInUri = Uri.https(baseUri, '/$pathPrefix/SignIn');
static final createCardUri = Uri.https(baseUri, '/$pathPrefix/CreateCard');
static final getCardsUri = Uri.https(baseUri, '/$pathPrefix/GetCards');
static final getMerchantsUrl = Uri.https(baseUri, '/$pathPrefix/GetMerchants');
static final getMerchantsByFilterUrl = Uri.https(baseUri, '/$pathPrefix/GetMerchantsByFilter');
static final getPurchaseMerchantsUrl = Uri.https(baseUri, '/$pathPrefix/PurchaseGiftCard');
static final getCurrentUserGiftCardSummariesUrl = Uri.https(baseUri, '/$pathPrefix/GetCurrentUserGiftCardSummaries');
static final changeGiftCardUrl = Uri.https(baseUri, '/$pathPrefix/ChargeGiftCard');
static final getGiftCardUrl = Uri.https(baseUri, '/$pathPrefix/GetGiftCard');
static final getPaymentStatusUrl = Uri.https(baseUri, '/$pathPrefix/PaymentStatus');
// Create user
Future<String> createUser(String email, {required String clientId}) async {
final headers = <String, String>{'clientId': clientId};
final query = <String, String>{'emailAddress': email};
final uri = createUserUri.replace(queryParameters: query);
final response = await put(uri, headers: headers);
if (response.statusCode != 200) {
throw Exception('Unexpected http status: ${response.statusCode}');
}
final bodyJson = json.decode(response.body) as Map<String, dynamic>;
final data = bodyJson['Data'] as Map<String, dynamic>;
final isSuccessful = bodyJson['Successful'] as bool;
if (!isSuccessful) {
throw Exception(data['ErrorMessage'] as String);
}
return data['username'] as String;
}
// Verify email
Future<IoniaUserCredentials> verifyEmail({
required String email,
required String code,
required String clientId}) async {
final headers = <String, String>{
'clientId': clientId,
'EmailAddress': email};
final query = <String, String>{'verificationCode': code};
final uri = verifyEmailUri.replace(queryParameters: query);
final response = await put(uri, headers: headers);
if (response.statusCode != 200) {
throw Exception('Unexpected http status: ${response.statusCode}');
}
final bodyJson = json.decode(response.body) as Map<String, dynamic>;
final data = bodyJson['Data'] as Map<String, dynamic>;
final isSuccessful = bodyJson['Successful'] as bool;
if (!isSuccessful) {
throw Exception(bodyJson['ErrorMessage'] as String);
}
final password = data['password'] as String;
final username = data['username'] as String;
return IoniaUserCredentials(username, password);
}
// Sign In
Future<void> signIn(String email, {required String clientId}) async {
final headers = <String, String>{'clientId': clientId};
final query = <String, String>{'emailAddress': email};
final uri = signInUri.replace(queryParameters: query);
final response = await put(uri, headers: headers);
if (response.statusCode != 200) {
throw Exception('Unexpected http status: ${response.statusCode}');
}
final bodyJson = json.decode(response.body) as Map<String, dynamic>;
final data = bodyJson['Data'] as Map<String, dynamic>;
final isSuccessful = bodyJson['Successful'] as bool;
if (!isSuccessful) {
throw Exception(data['ErrorMessage'] as String);
}
}
// Get virtual card
Future<IoniaVirtualCard> getCards({
required String username,
required String password,
required String clientId}) async {
final headers = <String, String>{
'clientId': clientId,
'username': username,
'password': password};
final response = await post(getCardsUri, headers: headers);
if (response.statusCode != 200) {
throw Exception('Unexpected http status: ${response.statusCode}');
}
final bodyJson = json.decode(response.body) as Map<String, dynamic>;
final data = bodyJson['Data'] as Map<String, dynamic>;
final isSuccessful = bodyJson['Successful'] as bool;
if (!isSuccessful) {
throw Exception(data['message'] as String);
}
final virtualCard = data['VirtualCard'] as Map<String, dynamic>;
return IoniaVirtualCard.fromMap(virtualCard);
}
// Create virtual card
Future<IoniaVirtualCard> createCard({
required String username,
required String password,
required String clientId}) async {
final headers = <String, String>{
'clientId': clientId,
'username': username,
'password': password};
final response = await post(createCardUri, headers: headers);
if (response.statusCode != 200) {
throw Exception('Unexpected http status: ${response.statusCode}');
}
final bodyJson = json.decode(response.body) as Map<String, dynamic>;
final data = bodyJson['Data'] as Map<String, dynamic>;
final isSuccessful = bodyJson['Successful'] as bool? ?? false;
if (!isSuccessful) {
throw Exception(data['message'] as String);
}
return IoniaVirtualCard.fromMap(data);
}
// Get Merchants
Future<List<IoniaMerchant>> getMerchants({
required String username,
required String password,
required String clientId}) async {
final headers = <String, String>{
'clientId': clientId,
'username': username,
'password': password};
final response = await post(getMerchantsUrl, headers: headers);
if (response.statusCode != 200) {
return [];
}
final decodedBody = json.decode(response.body) as Map<String, dynamic>;
final isSuccessful = decodedBody['Successful'] as bool? ?? false;
if (!isSuccessful) {
return [];
}
final data = decodedBody['Data'] as List<dynamic>;
final merch = <IoniaMerchant>[];
for (final item in data) {
try {
final element = item as Map<String, dynamic>;
merch.add(IoniaMerchant.fromJsonMap(element));
} catch(_) {}
}
return merch;
}
// Get Merchants By Filter
Future<List<IoniaMerchant>> getMerchantsByFilter({
required String username,
required String password,
required String clientId,
String? search,
List<IoniaCategory>? categories,
int merchantFilterType = 0}) async {
// MerchantFilterType: {All = 0, Nearby = 1, Popular = 2, Online = 3, MyFaves = 4, Search = 5}
final headers = <String, String>{
'clientId': clientId,
'username': username,
'password': password,
'Content-Type': 'application/json'};
final body = <String, dynamic>{'MerchantFilterType': merchantFilterType};
if (search != null) {
body['SearchCriteria'] = search;
}
if (categories != null) {
body['Categories'] = categories
.map((e) => e.ids)
.expand((e) => e)
.toList();
}
final response = await post(getMerchantsByFilterUrl, headers: headers, body: json.encode(body));
if (response.statusCode != 200) {
return [];
}
final decodedBody = json.decode(response.body) as Map<String, dynamic>;
final isSuccessful = decodedBody['Successful'] as bool? ?? false;
if (!isSuccessful) {
return [];
}
final data = decodedBody['Data'] as List<dynamic>;
final merch = <IoniaMerchant>[];
for (final item in data) {
try {
final element = item['Merchant'] as Map<String, dynamic>;
merch.add(IoniaMerchant.fromJsonMap(element));
} catch(_) {}
}
return merch;
}
// Purchase Gift Card
Future<IoniaOrder> purchaseGiftCard({
required String requestedUUID,
required String merchId,
required double amount,
required String currency,
required String username,
required String password,
required String clientId}) async {
final headers = <String, String>{
'clientId': clientId,
'username': username,
'password': password,
requestedUUIDHeader: requestedUUID,
'Content-Type': 'application/json'};
final body = <String, dynamic>{
'Amount': amount,
'Currency': currency,
'MerchantId': merchId};
final response = await post(getPurchaseMerchantsUrl, headers: headers, body: json.encode(body));
if (response.statusCode != 200) {
throw Exception('Unexpected response');
}
final decodedBody = json.decode(response.body) as Map<String, dynamic>;
final isSuccessful = decodedBody['Successful'] as bool? ?? false;
if (!isSuccessful) {
throw Exception(decodedBody['ErrorMessage'] as String);
}
final data = decodedBody['Data'] as Map<String, dynamic>;
return IoniaOrder.fromMap(data);
}
// Get Current User Gift Card Summaries
Future<List<IoniaGiftCard>> getCurrentUserGiftCardSummaries({
required String username,
required String password,
required String clientId}) async {
final headers = <String, String>{
'clientId': clientId,
'username': username,
'password': password};
final response = await post(getCurrentUserGiftCardSummariesUrl, headers: headers);
if (response.statusCode != 200) {
return [];
}
final decodedBody = json.decode(response.body) as Map<String, dynamic>;
final isSuccessful = decodedBody['Successful'] as bool? ?? false;
if (!isSuccessful) {
return [];
}
final data = decodedBody['Data'] as List<dynamic>;
final cards = <IoniaGiftCard>[];
for (final item in data) {
try {
final element = item as Map<String, dynamic>;
cards.add(IoniaGiftCard.fromJsonMap(element));
} catch(_) {}
}
return cards;
}
// Charge Gift Card
Future<void> chargeGiftCard({
required String username,
required String password,
required String clientId,
required int giftCardId,
required double amount}) async {
final headers = <String, String>{
'clientId': clientId,
'username': username,
'password': password,
'Content-Type': 'application/json'};
final body = <String, dynamic>{
'Id': giftCardId,
'Amount': amount};
final response = await post(
changeGiftCardUrl,
headers: headers,
body: json.encode(body));
if (response.statusCode != 200) {
throw Exception('Failed to update Gift Card with ID ${giftCardId};Incorrect response status: ${response.statusCode};');
}
final decodedBody = json.decode(response.body) as Map<String, dynamic>;
final isSuccessful = decodedBody['Successful'] as bool? ?? false;
if (!isSuccessful) {
final data = decodedBody['Data'] as Map<String, dynamic>;
final msg = data['Message'] as String? ?? '';
if (msg.isNotEmpty) {
throw Exception(msg);
}
throw Exception('Failed to update Gift Card with ID ${giftCardId};');
}
}
// Get Gift Card
Future<IoniaGiftCard> getGiftCard({
required String username,
required String password,
required String clientId,
required int id}) async {
final headers = <String, String>{
'clientId': clientId,
'username': username,
'password': password,
'Content-Type': 'application/json'};
final body = <String, dynamic>{'Id': id};
final response = await post(
getGiftCardUrl,
headers: headers,
body: json.encode(body));
if (response.statusCode != 200) {
throw Exception('Failed to get Gift Card with ID ${id};Incorrect response status: ${response.statusCode};');
}
final decodedBody = json.decode(response.body) as Map<String, dynamic>;
final isSuccessful = decodedBody['Successful'] as bool? ?? false;
if (!isSuccessful) {
final msg = decodedBody['ErrorMessage'] as String ?? '';
if (msg.isNotEmpty) {
throw Exception(msg);
}
throw Exception('Failed to get Gift Card with ID ${id};');
}
final data = decodedBody['Data'] as Map<String, dynamic>;
return IoniaGiftCard.fromJsonMap(data);
}
// Payment Status
Future<int> getPaymentStatus({
required String username,
required String password,
required String clientId,
required String orderId,
required String paymentId}) async {
final headers = <String, String>{
'clientId': clientId,
'username': username,
'password': password,
'Content-Type': 'application/json'};
final body = <String, dynamic>{
'order_id': orderId,
'paymentId': paymentId};
final response = await post(
getPaymentStatusUrl,
headers: headers,
body: json.encode(body));
if (response.statusCode != 200) {
throw Exception('Failed to get Payment Status for order_id ${orderId} paymentId ${paymentId};Incorrect response status: ${response.statusCode};');
}
final decodedBody = json.decode(response.body) as Map<String, dynamic>;
final isSuccessful = decodedBody['Successful'] as bool? ?? false;
if (!isSuccessful) {
final msg = decodedBody['ErrorMessage'] as String ?? '';
if (msg.isNotEmpty) {
throw Exception(msg);
}
throw Exception('Failed to get Payment Status for order_id ${orderId} paymentId ${paymentId}');
}
final data = decodedBody['Data'] as Map<String, dynamic>;
return data['gift_card_id'] as int;
}
}

View file

@ -1,22 +0,0 @@
class IoniaCategory {
const IoniaCategory({
required this.index,
required this.title,
required this.ids,
required this.iconPath});
static const allCategories = <IoniaCategory>[all, apparel, onlineOnly, food, entertainment, delivery, travel];
static const all = IoniaCategory(index: 0, title: 'All', ids: [], iconPath: 'assets/images/category.png');
static const apparel = IoniaCategory(index: 1, title: 'Apparel', ids: [1], iconPath: 'assets/images/tshirt.png');
static const onlineOnly = IoniaCategory(index: 2, title: 'Online Only', ids: [13, 43], iconPath: 'assets/images/global.png');
static const food = IoniaCategory(index: 3, title: 'Food', ids: [4], iconPath: 'assets/images/food.png');
static const entertainment = IoniaCategory(index: 4, title: 'Entertainment', ids: [5], iconPath: 'assets/images/gaming.png');
static const delivery = IoniaCategory(index: 5, title: 'Delivery', ids: [114, 109], iconPath: 'assets/images/delivery.png');
static const travel = IoniaCategory(index: 6, title: 'Travel', ids: [12], iconPath: 'assets/images/airplane.png');
final int index;
final String title;
final List<int> ids;
final String iconPath;
}

View file

@ -1,68 +0,0 @@
import 'package:cake_wallet/ionia/ionia_virtual_card.dart';
import 'package:flutter/material.dart';
abstract class IoniaCreateAccountState {}
class IoniaInitialCreateState extends IoniaCreateAccountState {}
class IoniaCreateStateSuccess extends IoniaCreateAccountState {}
class IoniaCreateStateLoading extends IoniaCreateAccountState {}
class IoniaCreateStateFailure extends IoniaCreateAccountState {
IoniaCreateStateFailure({required this.error});
final String error;
}
abstract class IoniaOtpState {}
class IoniaOtpValidating extends IoniaOtpState {}
class IoniaOtpSuccess extends IoniaOtpState {}
class IoniaOtpSendDisabled extends IoniaOtpState {}
class IoniaOtpSendEnabled extends IoniaOtpState {}
class IoniaOtpFailure extends IoniaOtpState {
IoniaOtpFailure({required this.error});
final String error;
}
class IoniaCreateCardState {}
class IoniaCreateCardSuccess extends IoniaCreateCardState {}
class IoniaCreateCardLoading extends IoniaCreateCardState {}
class IoniaCreateCardFailure extends IoniaCreateCardState {
IoniaCreateCardFailure({required this.error});
final String error;
}
class IoniaFetchCardState {}
class IoniaNoCardState extends IoniaFetchCardState {}
class IoniaFetchingCard extends IoniaFetchCardState {}
class IoniaFetchCardFailure extends IoniaFetchCardState {}
class IoniaCardSuccess extends IoniaFetchCardState {
IoniaCardSuccess({required this.card});
final IoniaVirtualCard card;
}
abstract class IoniaMerchantState {}
class InitialIoniaMerchantLoadingState extends IoniaMerchantState {}
class IoniaLoadingMerchantState extends IoniaMerchantState {}
class IoniaLoadedMerchantState extends IoniaMerchantState {}

View file

@ -1,70 +0,0 @@
import 'dart:convert';
import 'package:cake_wallet/ionia/ionia_gift_card_instruction.dart';
import 'package:flutter/foundation.dart';
class IoniaGiftCard {
IoniaGiftCard({
required this.id,
required this.merchantId,
required this.legalName,
required this.systemName,
required this.barcodeUrl,
required this.cardNumber,
required this.cardPin,
required this.instructions,
required this.tip,
required this.purchaseAmount,
required this.actualAmount,
required this.totalTransactionAmount,
required this.totalDashTransactionAmount,
required this.remainingAmount,
required this.createdDateFormatted,
required this.lastTransactionDateFormatted,
required this.isActive,
required this.isEmpty,
required this.logoUrl});
factory IoniaGiftCard.fromJsonMap(Map<String, dynamic> element) {
return IoniaGiftCard(
id: element['Id'] as int,
merchantId: element['MerchantId'] as int,
legalName: element['LegalName'] as String,
systemName: element['SystemName'] as String,
barcodeUrl: element['BarcodeUrl'] as String,
cardNumber: element['CardNumber'] as String,
cardPin: element['CardPin'] as String,
tip: element['Tip'] as double,
purchaseAmount: element['PurchaseAmount'] as double,
actualAmount: element['ActualAmount'] as double,
totalTransactionAmount: element['TotalTransactionAmount'] as double,
totalDashTransactionAmount: (element['TotalDashTransactionAmount'] as double?) ?? 0.0,
remainingAmount: element['RemainingAmount'] as double,
isActive: element['IsActive'] as bool,
isEmpty: element['IsEmpty'] as bool,
logoUrl: element['LogoUrl'] as String,
createdDateFormatted: element['CreatedDate'] as String,
lastTransactionDateFormatted: element['LastTransactionDate'] as String,
instructions: IoniaGiftCardInstruction.parseListOfInstructions(element['PaymentInstructions'] as String));
}
final int id;
final int merchantId;
final String legalName;
final String systemName;
final String barcodeUrl;
final String cardNumber;
final String cardPin;
final List<IoniaGiftCardInstruction> instructions;
final double tip;
final double purchaseAmount;
final double actualAmount;
final double totalTransactionAmount;
final double totalDashTransactionAmount;
double remainingAmount;
final String createdDateFormatted;
final String lastTransactionDateFormatted;
final bool isActive;
final bool isEmpty;
final String logoUrl;
}

View file

@ -1,28 +0,0 @@
import 'dart:convert';
import 'package:intl/intl.dart' show toBeginningOfSentenceCase;
class IoniaGiftCardInstruction {
IoniaGiftCardInstruction(this.header, this.body);
factory IoniaGiftCardInstruction.fromJsonMap(Map<String, dynamic> element) {
return IoniaGiftCardInstruction(
toBeginningOfSentenceCase(element['title'] as String? ?? '') ?? '',
element['description'] as String);
}
static List<IoniaGiftCardInstruction> parseListOfInstructions(String instructionsJSON) {
List<IoniaGiftCardInstruction> instructions = <IoniaGiftCardInstruction>[];
if (instructionsJSON.isNotEmpty) {
final decodedInstructions = json.decode(instructionsJSON) as List<dynamic>;
instructions = decodedInstructions
.map((dynamic e) =>IoniaGiftCardInstruction.fromJsonMap(e as Map<String, dynamic>))
.toList();
}
return instructions;
}
final String header;
final String body;
}

View file

@ -1,101 +0,0 @@
import 'package:cake_wallet/ionia/ionia_gift_card_instruction.dart';
import 'package:cake_wallet/generated/i18n.dart';
class IoniaMerchant {
IoniaMerchant({
required this.id,
required this.legalName,
required this.systemName,
required this.description,
required this.website,
required this.termsAndConditions,
required this.logoUrl,
required this.cardImageUrl,
required this.cardholderAgreement,
required this.isActive,
required this.isOnline,
required this.isPhysical,
required this.isVariablePurchase,
required this.minimumCardPurchase,
required this.maximumCardPurchase,
required this.acceptsTips,
required this.createdDateFormatted,
required this.modifiedDateFormatted,
required this.usageInstructions,
required this.usageInstructionsBak,
required this.hasBarcode,
required this.instructions,
required this.savingsPercentage});
factory IoniaMerchant.fromJsonMap(Map<String, dynamic> element) {
return IoniaMerchant(
id: element["Id"] as int,
legalName: element["LegalName"] as String,
systemName: element["SystemName"] as String,
description: element["Description"] as String,
website: element["Website"] as String,
termsAndConditions: element["TermsAndConditions"] as String,
logoUrl: element["LogoUrl"] as String,
cardImageUrl: element["CardImageUrl"] as String,
cardholderAgreement: element["CardholderAgreement"] as String,
isActive: element["IsActive"] as bool?,
isOnline: element["IsOnline"] as bool,
isPhysical: element["IsPhysical"] as bool,
isVariablePurchase: element["IsVariablePurchase"] as bool,
minimumCardPurchase: element["MinimumCardPurchase"] as double,
maximumCardPurchase: element["MaximumCardPurchase"] as double,
acceptsTips: element["AcceptsTips"] as bool,
createdDateFormatted: element["CreatedDate"] as String?,
modifiedDateFormatted: element["ModifiedDate"] as String?,
usageInstructions: element["UsageInstructions"] as String?,
usageInstructionsBak: element["UsageInstructionsBak"] as String?,
hasBarcode: element["HasBarcode"] as bool,
instructions: IoniaGiftCardInstruction.parseListOfInstructions(element['PaymentInstructions'] as String),
savingsPercentage: element["SavingsPercentage"] as double);
}
final int id;
final String legalName;
final String systemName;
final String description;
final String website;
final String termsAndConditions;
final String logoUrl;
final String cardImageUrl;
final String cardholderAgreement;
final bool? isActive;
final bool isOnline;
final bool? isPhysical;
final bool isVariablePurchase;
final double minimumCardPurchase;
final double maximumCardPurchase;
final bool acceptsTips;
final String? createdDateFormatted;
final String? modifiedDateFormatted;
final String? usageInstructions;
final String? usageInstructionsBak;
final bool hasBarcode;
final List<IoniaGiftCardInstruction> instructions;
final double savingsPercentage;
double get discount => savingsPercentage;
String get avaibilityStatus {
var status = '';
if (isOnline) {
status += S.current.online;
}
if (isPhysical ?? false) {
if (status.isNotEmpty) {
status = '$status & ';
}
status = '${status}${S.current.in_store}';
}
return status;
}
}

View file

@ -1,23 +0,0 @@
import 'package:flutter/foundation.dart';
class IoniaOrder {
IoniaOrder({required this.id,
required this.uri,
required this.currency,
required this.amount,
required this.paymentId});
factory IoniaOrder.fromMap(Map<String, dynamic> obj) {
return IoniaOrder(
id: obj['order_id'] as String,
uri: obj['uri'] as String,
currency: obj['currency'] as String,
amount: obj['amount'] as double,
paymentId: obj['paymentId'] as String);
}
final String id;
final String uri;
final String currency;
final double amount;
final String paymentId;
}

View file

@ -1,171 +0,0 @@
import 'package:cake_wallet/core/secure_storage.dart';
import 'package:cake_wallet/ionia/ionia_merchant.dart';
import 'package:cake_wallet/ionia/ionia_order.dart';
import 'package:cake_wallet/ionia/ionia_virtual_card.dart';
import 'package:cake_wallet/.secrets.g.dart' as secrets;
import 'package:cake_wallet/ionia/ionia_api.dart';
import 'package:cake_wallet/ionia/ionia_gift_card.dart';
import 'package:cake_wallet/ionia/ionia_category.dart';
class IoniaService {
IoniaService(this.secureStorage, this.ioniaApi);
static const ioniaEmailStorageKey = 'ionia_email';
static const ioniaUsernameStorageKey = 'ionia_username';
static const ioniaPasswordStorageKey = 'ionia_password';
static String get clientId => secrets.ioniaClientId;
final SecureStorage secureStorage;
final IoniaApi ioniaApi;
// Create user
Future<void> createUser(String email) async {
final username = await ioniaApi.createUser(email, clientId: clientId);
await secureStorage.write(key: ioniaEmailStorageKey, value: email);
await secureStorage.write(key: ioniaUsernameStorageKey, value: username);
}
// Verify email
Future<void> verifyEmail(String code) async {
final email = (await secureStorage.read(key: ioniaEmailStorageKey))!;
final credentials = await ioniaApi.verifyEmail(email: email, code: code, clientId: clientId);
await secureStorage.write(key: ioniaPasswordStorageKey, value: credentials.password);
await secureStorage.write(key: ioniaUsernameStorageKey, value: credentials.username);
}
// Sign In
Future<void> signIn(String email) async {
await ioniaApi.signIn(email, clientId: clientId);
await secureStorage.write(key: ioniaEmailStorageKey, value: email);
}
Future<String> getUserEmail() async {
return (await secureStorage.read(key: ioniaEmailStorageKey))!;
}
// Check is user logined
Future<bool> isLogined() async {
final username = await secureStorage.read(key: ioniaUsernameStorageKey) ?? '';
final password = await secureStorage.read(key: ioniaPasswordStorageKey) ?? '';
return username.isNotEmpty && password.isNotEmpty;
}
// Logout
Future<void> logout() async {
await secureStorage.delete(key: ioniaUsernameStorageKey);
await secureStorage.delete(key: ioniaPasswordStorageKey);
}
// Create virtual card
Future<IoniaVirtualCard> createCard() async {
final username = (await secureStorage.read(key: ioniaUsernameStorageKey))!;
final password = (await secureStorage.read(key: ioniaPasswordStorageKey))!;
return ioniaApi.createCard(username: username, password: password, clientId: clientId);
}
// Get virtual card
Future<IoniaVirtualCard> getCard() async {
final username = (await secureStorage.read(key: ioniaUsernameStorageKey))!;
final password = (await secureStorage.read(key: ioniaPasswordStorageKey))!;
return ioniaApi.getCards(username: username, password: password, clientId: clientId);
}
// Get Merchants
Future<List<IoniaMerchant>> getMerchants() async {
final username = (await secureStorage.read(key: ioniaUsernameStorageKey))!;
final password = (await secureStorage.read(key: ioniaPasswordStorageKey))!;
return ioniaApi.getMerchants(username: username, password: password, clientId: clientId);
}
// Get Merchants By Filter
Future<List<IoniaMerchant>> getMerchantsByFilter({
String? search,
List<IoniaCategory>? categories,
int merchantFilterType = 0}) async {
final username = (await secureStorage.read(key: ioniaUsernameStorageKey))!;
final password = (await secureStorage.read(key: ioniaPasswordStorageKey))!;
return ioniaApi.getMerchantsByFilter(
username: username,
password: password,
clientId: clientId,
search: search,
categories: categories,
merchantFilterType: merchantFilterType);
}
// Purchase Gift Card
Future<IoniaOrder> purchaseGiftCard({
required String merchId,
required double amount,
required String currency}) async {
final username = (await secureStorage.read(key: ioniaUsernameStorageKey))!;
final password = (await secureStorage.read(key: ioniaPasswordStorageKey))!;
final deviceId = '';
return ioniaApi.purchaseGiftCard(
requestedUUID: deviceId,
merchId: merchId,
amount: amount,
currency: currency,
username: username,
password: password,
clientId: clientId);
}
// Get Current User Gift Card Summaries
Future<List<IoniaGiftCard>> getCurrentUserGiftCardSummaries() async {
final username = (await secureStorage.read(key: ioniaUsernameStorageKey))!;
final password = (await secureStorage.read(key: ioniaPasswordStorageKey))!;
return ioniaApi.getCurrentUserGiftCardSummaries(username: username, password: password, clientId: clientId);
}
// Charge Gift Card
Future<void> chargeGiftCard({
required int giftCardId,
required double amount}) async {
final username = (await secureStorage.read(key: ioniaUsernameStorageKey))!;
final password = (await secureStorage.read(key: ioniaPasswordStorageKey))!;
await ioniaApi.chargeGiftCard(
username: username,
password: password,
clientId: clientId,
giftCardId: giftCardId,
amount: amount);
}
// Redeem
Future<void> redeem({required int giftCardId, required double amount}) async {
await chargeGiftCard(giftCardId: giftCardId, amount: amount);
}
// Get Gift Card
Future<IoniaGiftCard> getGiftCard({required int id}) async {
final username = (await secureStorage.read(key: ioniaUsernameStorageKey))!;
final password = (await secureStorage.read(key: ioniaPasswordStorageKey))!;
return ioniaApi.getGiftCard(username: username, password: password, clientId: clientId,id: id);
}
// Payment Status
Future<int> getPaymentStatus({
required String orderId,
required String paymentId}) async {
final username = (await secureStorage.read(key: ioniaUsernameStorageKey))!;
final password = (await secureStorage.read(key: ioniaPasswordStorageKey))!;
return ioniaApi.getPaymentStatus(username: username, password: password, clientId: clientId, orderId: orderId, paymentId: paymentId);
}
}

View file

@ -1,18 +0,0 @@
class IoniaTip {
const IoniaTip({
required this.originalAmount,
required this.percentage,
this.isCustom = false});
final double originalAmount;
final double percentage;
final bool isCustom;
double get additionalAmount => double.parse((originalAmount * percentage / 100).toStringAsFixed(2));
static const tipList = [
IoniaTip(originalAmount: 0, percentage: 0),
IoniaTip(originalAmount: 10, percentage: 10),
IoniaTip(originalAmount: 20, percentage: 20)
];
}

View file

@ -1,43 +0,0 @@
import 'package:flutter/foundation.dart';
import 'dart:convert';
class IoniaTokenData {
IoniaTokenData({required this.accessToken, required this.tokenType, required this.expiredAt});
factory IoniaTokenData.fromJson(String source) {
final decoded = json.decode(source) as Map<String, dynamic>;
final accessToken = decoded['access_token'] as String;
final expiresIn = decoded['expires_in'] as int;
final tokenType = decoded['token_type'] as String;
final expiredAtInMilliseconds = decoded['expired_at'] as int;
DateTime expiredAt;
if (expiredAtInMilliseconds != null) {
expiredAt = DateTime.fromMillisecondsSinceEpoch(expiredAtInMilliseconds);
} else {
expiredAt = DateTime.now().add(Duration(seconds: expiresIn));
}
return IoniaTokenData(
accessToken: accessToken,
tokenType: tokenType,
expiredAt: expiredAt);
}
final String accessToken;
final String tokenType;
final DateTime expiredAt;
bool get isExpired => DateTime.now().isAfter(expiredAt);
@override
String toString() => '$tokenType $accessToken';
String toJson() {
return json.encode(<String, dynamic>{
'access_token': accessToken,
'token_type': tokenType,
'expired_at': expiredAt.millisecondsSinceEpoch
});
}
}

View file

@ -1,6 +0,0 @@
class IoniaUserCredentials {
const IoniaUserCredentials(this.username, this.password);
final String username;
final String password;
}

View file

@ -1,41 +0,0 @@
class IoniaVirtualCard {
IoniaVirtualCard({
required this.token,
required this.createdAt,
required this.lastFour,
required this.state,
required this.pan,
required this.cvv,
required this.expirationMonth,
required this.expirationYear,
required this.fundsLimit,
required this.spendLimit});
factory IoniaVirtualCard.fromMap(Map<String, dynamic> source) {
final created = source['created'] as String;
final createdAt = DateTime.tryParse(created);
return IoniaVirtualCard(
token: source['token'] as String,
createdAt: createdAt,
lastFour: source['lastFour'] as String,
state: source['state'] as String,
pan: source['pan'] as String,
cvv: source['cvv'] as String,
expirationMonth: source['expirationMonth'] as String,
expirationYear: source['expirationYear'] as String,
fundsLimit: source['FundsLimit'] as double,
spendLimit: source['spend_limit'] as double);
}
final String token;
final String lastFour;
final String state;
final String pan;
final String cvv;
final String expirationMonth;
final String expirationYear;
final DateTime? createdAt;
final double fundsLimit;
final double spendLimit;
}

View file

@ -1,6 +1,5 @@
import 'package:cake_wallet/anonpay/anonpay_info_base.dart'; import 'package:cake_wallet/anonpay/anonpay_info_base.dart';
import 'package:cake_wallet/anonpay/anonpay_invoice_info.dart'; import 'package:cake_wallet/anonpay/anonpay_invoice_info.dart';
import 'package:cake_wallet/anypay/any_pay_payment_committed_info.dart';
import 'package:cake_wallet/buy/order.dart'; import 'package:cake_wallet/buy/order.dart';
import 'package:cake_wallet/core/totp_request_details.dart'; import 'package:cake_wallet/core/totp_request_details.dart';
import 'package:cake_wallet/core/wallet_connect/web3wallet_service.dart'; import 'package:cake_wallet/core/wallet_connect/web3wallet_service.dart';
@ -10,7 +9,6 @@ import 'package:cake_wallet/entities/qr_view_data.dart';
import 'package:cake_wallet/entities/wallet_nft_response.dart'; import 'package:cake_wallet/entities/wallet_nft_response.dart';
import 'package:cake_wallet/exchange/trade.dart'; import 'package:cake_wallet/exchange/trade.dart';
import 'package:cake_wallet/generated/i18n.dart'; import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/ionia/ionia_any_pay_payment_info.dart';
import 'package:cake_wallet/routes.dart'; import 'package:cake_wallet/routes.dart';
import 'package:cake_wallet/src/screens/anonpay_details/anonpay_details_page.dart'; import 'package:cake_wallet/src/screens/anonpay_details/anonpay_details_page.dart';
import 'package:cake_wallet/src/screens/auth/auth_page.dart'; import 'package:cake_wallet/src/screens/auth/auth_page.dart';
@ -36,14 +34,6 @@ import 'package:cake_wallet/src/screens/exchange/exchange_template_page.dart';
import 'package:cake_wallet/src/screens/exchange_trade/exchange_confirm_page.dart'; import 'package:cake_wallet/src/screens/exchange_trade/exchange_confirm_page.dart';
import 'package:cake_wallet/src/screens/exchange_trade/exchange_trade_page.dart'; import 'package:cake_wallet/src/screens/exchange_trade/exchange_trade_page.dart';
import 'package:cake_wallet/src/screens/faq/faq_page.dart'; import 'package:cake_wallet/src/screens/faq/faq_page.dart';
import 'package:cake_wallet/src/screens/ionia/cards/ionia_account_cards_page.dart';
import 'package:cake_wallet/src/screens/ionia/cards/ionia_account_page.dart';
import 'package:cake_wallet/src/screens/ionia/cards/ionia_custom_redeem_page.dart';
import 'package:cake_wallet/src/screens/ionia/cards/ionia_custom_tip_page.dart';
import 'package:cake_wallet/src/screens/ionia/cards/ionia_gift_card_detail_page.dart';
import 'package:cake_wallet/src/screens/ionia/cards/ionia_more_options_page.dart';
import 'package:cake_wallet/src/screens/ionia/cards/ionia_payment_status_page.dart';
import 'package:cake_wallet/src/screens/ionia/ionia.dart';
import 'package:cake_wallet/src/screens/monero_accounts/monero_account_edit_or_create_page.dart'; import 'package:cake_wallet/src/screens/monero_accounts/monero_account_edit_or_create_page.dart';
import 'package:cake_wallet/src/screens/nano/nano_change_rep_page.dart'; import 'package:cake_wallet/src/screens/nano/nano_change_rep_page.dart';
import 'package:cake_wallet/src/screens/nano_accounts/nano_account_edit_or_create_page.dart'; import 'package:cake_wallet/src/screens/nano_accounts/nano_account_edit_or_create_page.dart';
@ -76,9 +66,11 @@ import 'package:cake_wallet/src/screens/settings/manage_nodes_page.dart';
import 'package:cake_wallet/src/screens/settings/other_settings_page.dart'; import 'package:cake_wallet/src/screens/settings/other_settings_page.dart';
import 'package:cake_wallet/src/screens/settings/privacy_page.dart'; import 'package:cake_wallet/src/screens/settings/privacy_page.dart';
import 'package:cake_wallet/src/screens/settings/security_backup_page.dart'; import 'package:cake_wallet/src/screens/settings/security_backup_page.dart';
import 'package:cake_wallet/src/screens/cake_pay/auth/cake_pay_account_page.dart';
import 'package:cake_wallet/src/screens/settings/silent_payments_settings.dart'; import 'package:cake_wallet/src/screens/settings/silent_payments_settings.dart';
import 'package:cake_wallet/src/screens/settings/tor_page.dart'; import 'package:cake_wallet/src/screens/settings/tor_page.dart';
import 'package:cake_wallet/src/screens/settings/trocador_providers_page.dart'; import 'package:cake_wallet/src/screens/settings/trocador_providers_page.dart';
import 'package:cake_wallet/src/screens/settings/tor_page.dart';
import 'package:cake_wallet/src/screens/setup_2fa/modify_2fa_page.dart'; import 'package:cake_wallet/src/screens/setup_2fa/modify_2fa_page.dart';
import 'package:cake_wallet/src/screens/setup_2fa/setup_2fa.dart'; import 'package:cake_wallet/src/screens/setup_2fa/setup_2fa.dart';
import 'package:cake_wallet/src/screens/setup_2fa/setup_2fa_enter_code_page.dart'; import 'package:cake_wallet/src/screens/setup_2fa/setup_2fa_enter_code_page.dart';
@ -120,7 +112,7 @@ import 'package:cw_core/wallet_type.dart';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:cake_wallet/src/screens/cake_pay/cake_pay.dart';
import 'src/screens/dashboard/pages/nft_import_page.dart'; import 'src/screens/dashboard/pages/nft_import_page.dart';
late RouteSettings currentRouteSettings; late RouteSettings currentRouteSettings;
@ -518,73 +510,30 @@ Route<dynamic> createRoute(RouteSettings settings) {
param1: settings.arguments as QrViewData, param1: settings.arguments as QrViewData,
)); ));
case Routes.ioniaWelcomePage: case Routes.cakePayCardsPage:
return CupertinoPageRoute<void>(builder: (_) => getIt.get<CakePayCardsPage>());
case Routes.cakePayBuyCardPage:
final args = settings.arguments as List;
return CupertinoPageRoute<void>( return CupertinoPageRoute<void>(
fullscreenDialog: true, builder: (_) => getIt.get<CakePayBuyCardPage>(param1: args));
builder: (_) => getIt.get<IoniaWelcomePage>(),
case Routes.cakePayBuyCardDetailPage:
final args = settings.arguments as List;
return CupertinoPageRoute<void>(
builder: (_) => getIt.get<CakePayBuyCardDetailPage>(param1: args));
case Routes.cakePayWelcomePage:
return CupertinoPageRoute<void>(
builder: (_) => getIt.get<CakePayWelcomePage>(),
); );
case Routes.ioniaLoginPage: case Routes.cakePayVerifyOtpPage:
return CupertinoPageRoute<void>(builder: (_) => getIt.get<IoniaLoginPage>());
case Routes.ioniaCreateAccountPage:
return CupertinoPageRoute<void>(builder: (_) => getIt.get<IoniaCreateAccountPage>());
case Routes.ioniaManageCardsPage:
return CupertinoPageRoute<void>(builder: (_) => getIt.get<IoniaManageCardsPage>());
case Routes.ioniaBuyGiftCardPage:
final args = settings.arguments as List; final args = settings.arguments as List;
return CupertinoPageRoute<void>( return CupertinoPageRoute<void>(builder: (_) => getIt.get<CakePayVerifyOtpPage>(param1: args));
builder: (_) => getIt.get<IoniaBuyGiftCardPage>(param1: args));
case Routes.ioniaBuyGiftCardDetailPage: case Routes.cakePayAccountPage:
final args = settings.arguments as List; return CupertinoPageRoute<void>(builder: (_) => getIt.get<CakePayAccountPage>());
return CupertinoPageRoute<void>(
builder: (_) => getIt.get<IoniaBuyGiftCardDetailPage>(param1: args));
case Routes.ioniaVerifyIoniaOtpPage:
final args = settings.arguments as List;
return CupertinoPageRoute<void>(builder: (_) => getIt.get<IoniaVerifyIoniaOtp>(param1: args));
case Routes.ioniaDebitCardPage:
return CupertinoPageRoute<void>(builder: (_) => getIt.get<IoniaDebitCardPage>());
case Routes.ioniaActivateDebitCardPage:
return CupertinoPageRoute<void>(builder: (_) => getIt.get<IoniaActivateDebitCardPage>());
case Routes.ioniaAccountPage:
return CupertinoPageRoute<void>(builder: (_) => getIt.get<IoniaAccountPage>());
case Routes.ioniaAccountCardsPage:
return CupertinoPageRoute<void>(builder: (_) => getIt.get<IoniaAccountCardsPage>());
case Routes.ioniaCustomTipPage:
final args = settings.arguments as List;
return CupertinoPageRoute<void>(builder: (_) => getIt.get<IoniaCustomTipPage>(param1: args));
case Routes.ioniaGiftCardDetailPage:
final args = settings.arguments as List;
return CupertinoPageRoute<void>(
builder: (_) => getIt.get<IoniaGiftCardDetailPage>(param1: args.first));
case Routes.ioniaCustomRedeemPage:
final args = settings.arguments as List;
return CupertinoPageRoute<void>(
builder: (_) => getIt.get<IoniaCustomRedeemPage>(param1: args));
case Routes.ioniaMoreOptionsPage:
final args = settings.arguments as List;
return CupertinoPageRoute<void>(
builder: (_) => getIt.get<IoniaMoreOptionsPage>(param1: args));
case Routes.ioniaPaymentStatusPage:
final args = settings.arguments as List;
final paymentInfo = args.first as IoniaAnyPayPaymentInfo;
final commitedInfo = args[1] as AnyPayPaymentCommittedInfo;
return CupertinoPageRoute<void>(
builder: (_) =>
getIt.get<IoniaPaymentStatusPage>(param1: paymentInfo, param2: commitedInfo));
case Routes.webViewPage: case Routes.webViewPage:
final args = settings.arguments as List; final args = settings.arguments as List;

View file

@ -64,22 +64,13 @@ class Routes {
static const unspentCoinsDetails = '/unspent_coins_details'; static const unspentCoinsDetails = '/unspent_coins_details';
static const addressPage = '/address_page'; static const addressPage = '/address_page';
static const fullscreenQR = '/fullscreen_qr'; static const fullscreenQR = '/fullscreen_qr';
static const ioniaWelcomePage = '/cake_pay_welcome_page'; static const cakePayWelcomePage = '/cake_pay_welcome_page';
static const ioniaCreateAccountPage = '/cake_pay_create_account_page'; static const cakePayLoginPage = '/cake_pay_login_page';
static const ioniaLoginPage = '/cake_pay_login_page'; static const cakePayCardsPage = '/cake_pay_cards_page';
static const ioniaManageCardsPage = '/manage_cards_page'; static const cakePayBuyCardPage = '/cake_pay_buy_card_page';
static const ioniaBuyGiftCardPage = '/buy_gift_card_page'; static const cakePayBuyCardDetailPage = '/cake_pay_buy_card_detail_page';
static const ioniaBuyGiftCardDetailPage = '/buy_gift_card_detail_page'; static const cakePayVerifyOtpPage = '/cake_pay_verify_otp_page';
static const ioniaVerifyIoniaOtpPage = '/cake_pay_verify_otp_page'; static const cakePayAccountPage = '/cake_pay_account_page';
static const ioniaDebitCardPage = '/debit_card_page';
static const ioniaActivateDebitCardPage = '/activate_debit_card_page';
static const ioniaAccountPage = 'ionia_account_page';
static const ioniaAccountCardsPage = 'ionia_account_cards_page';
static const ioniaCustomTipPage = 'ionia_custom_tip_page';
static const ioniaGiftCardDetailPage = '/ionia_gift_card_detail_page';
static const ioniaPaymentStatusPage = '/ionia_payment_status_page';
static const ioniaMoreOptionsPage = '/ionia_more_options_page';
static const ioniaCustomRedeemPage = '/ionia_custom_redeem_page';
static const webViewPage = '/web_view_page'; static const webViewPage = '/web_view_page';
static const silentPaymentsSettings = '/silent_payments_settings'; static const silentPaymentsSettings = '/silent_payments_settings';
static const connectionSync = '/connection_sync_page'; static const connectionSync = '/connection_sync_page';

View file

@ -7,7 +7,7 @@ import 'package:cake_wallet/store/settings_store.dart';
import 'package:cake_wallet/src/widgets/nav_bar.dart'; import 'package:cake_wallet/src/widgets/nav_bar.dart';
import 'package:cake_wallet/generated/i18n.dart'; import 'package:cake_wallet/generated/i18n.dart';
enum AppBarStyle { regular, withShadow, transparent } enum AppBarStyle { regular, withShadow, transparent, completelyTransparent }
abstract class BasePage extends StatelessWidget { abstract class BasePage extends StatelessWidget {
BasePage() : _scaffoldKey = GlobalKey<ScaffoldState>(); BasePage() : _scaffoldKey = GlobalKey<ScaffoldState>();
@ -125,7 +125,7 @@ abstract class BasePage extends StatelessWidget {
Widget? floatingActionButton(BuildContext context) => null; Widget? floatingActionButton(BuildContext context) => null;
ObstructingPreferredSizeWidget appBar(BuildContext context) { PreferredSizeWidget appBar(BuildContext context) {
final appBarColor = pageBackgroundColor(context); final appBarColor = pageBackgroundColor(context);
switch (appBarStyle) { switch (appBarStyle) {
@ -156,6 +156,16 @@ abstract class BasePage extends StatelessWidget {
border: null, border: null,
); );
case AppBarStyle.completelyTransparent:
return AppBar(
leading: leading(context),
title: middle(context),
actions: <Widget>[if (trailing(context) != null) trailing(context)!],
backgroundColor: Colors.transparent,
elevation: 0,
centerTitle: true,
);
default: default:
// FIX-ME: NavBar no context // FIX-ME: NavBar no context
return NavBar( return NavBar(

View file

@ -0,0 +1,90 @@
import 'package:cake_wallet/themes/extensions/cake_text_theme.dart';
import 'package:cake_wallet/routes.dart';
import 'package:cake_wallet/src/screens/base_page.dart';
import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/src/screens/cake_pay/widgets/cake_pay_tile.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/typography.dart';
import 'package:cake_wallet/view_model/cake_pay/cake_pay_account_view_model.dart';
import 'package:flutter/material.dart';
import 'package:flutter_mobx/flutter_mobx.dart';
class CakePayAccountPage extends BasePage {
CakePayAccountPage(this.cakePayAccountViewModel);
final CakePayAccountViewModel cakePayAccountViewModel;
@override
Widget leading(BuildContext context) {
return MergeSemantics(
child: SizedBox(
height: 37,
width: 37,
child: ButtonTheme(
minWidth: double.minPositive,
child: Semantics(
label: S.of(context).seed_alert_back,
child: TextButton(
style: ButtonStyle(
overlayColor: MaterialStateColor.resolveWith(
(states) => Colors.transparent),
),
onPressed: () => Navigator.pop(context),
child: backButton(context),
),
),
),
),
);
}
@override
Widget middle(BuildContext context) {
return Text(
S.current.account,
style: textMediumSemiBold(
color: Theme.of(context).extension<CakeTextTheme>()!.titleColor,
),
);
}
@override
Widget body(BuildContext context) {
return ScrollableWithBottomSection(
contentPadding: EdgeInsets.all(24),
content: Column(
children: [
SizedBox(height: 20),
Observer(
builder: (_) => Container(decoration: BoxDecoration(
border: Border(
bottom: BorderSide(
width: 1.0,
color:
Theme.of(context).extension<CakeTextTheme>()!.secondaryTextColor),
),
),
child: CakePayTile(title: S.of(context).email_address, subTitle: cakePayAccountViewModel.email)),
),
],
),
bottomSectionPadding: EdgeInsets.all(30),
bottomSection: Column(
children: [
PrimaryButton(
color: Theme.of(context).primaryColor,
textColor: Colors.white,
text: S.of(context).logout,
onPressed: () {
cakePayAccountViewModel.logout();
Navigator.pushNamedAndRemoveUntil(context, Routes.dashboard, (route) => false);
},
),
],
),
);
}
}

View file

@ -1,39 +1,38 @@
import 'package:cake_wallet/themes/extensions/cake_text_theme.dart'; import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/themes/extensions/keyboard_theme.dart'; import 'package:cake_wallet/cake_pay/cake_pay_states.dart';
import 'package:cake_wallet/ionia/ionia_create_state.dart';
import 'package:cake_wallet/palette.dart'; import 'package:cake_wallet/palette.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/widgets/alert_with_one_action.dart'; import 'package:cake_wallet/src/widgets/alert_with_one_action.dart';
import 'package:cake_wallet/src/widgets/base_text_form_field.dart'; import 'package:cake_wallet/src/widgets/base_text_form_field.dart';
import 'package:cake_wallet/src/widgets/keyboard_done_button.dart'; import 'package:cake_wallet/src/widgets/keyboard_done_button.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';
import 'package:cake_wallet/themes/extensions/cake_text_theme.dart';
import 'package:cake_wallet/themes/extensions/keyboard_theme.dart';
import 'package:cake_wallet/typography.dart'; import 'package:cake_wallet/typography.dart';
import 'package:cake_wallet/utils/show_pop_up.dart'; import 'package:cake_wallet/utils/show_pop_up.dart';
import 'package:cake_wallet/view_model/ionia/ionia_auth_view_model.dart'; import 'package:cake_wallet/view_model/cake_pay/cake_pay_auth_view_model.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:cake_wallet/generated/i18n.dart';
import 'package:flutter_mobx/flutter_mobx.dart'; import 'package:flutter_mobx/flutter_mobx.dart';
import 'package:keyboard_actions/keyboard_actions.dart'; import 'package:keyboard_actions/keyboard_actions.dart';
import 'package:mobx/mobx.dart'; import 'package:mobx/mobx.dart';
class IoniaVerifyIoniaOtp extends BasePage { class CakePayVerifyOtpPage extends BasePage {
IoniaVerifyIoniaOtp(this._authViewModel, this._email, this.isSignIn) CakePayVerifyOtpPage(this._authViewModel, this._email, this.isSignIn)
: _codeController = TextEditingController(), : _codeController = TextEditingController(),
_codeFocus = FocusNode() { _codeFocus = FocusNode() {
_codeController.addListener(() { _codeController.addListener(() {
final otp = _codeController.text; final otp = _codeController.text;
_authViewModel.otp = otp; _authViewModel.otp = otp;
if (otp.length > 3) { if (otp.length > 5) {
_authViewModel.otpState = IoniaOtpSendEnabled(); _authViewModel.otpState = CakePayOtpSendEnabled();
} else { } else {
_authViewModel.otpState = IoniaOtpSendDisabled(); _authViewModel.otpState = CakePayOtpSendDisabled();
} }
}); });
} }
final IoniaAuthViewModel _authViewModel; final CakePayAuthViewModel _authViewModel;
final bool isSignIn; final bool isSignIn;
final String _email; final String _email;
@ -53,11 +52,11 @@ class IoniaVerifyIoniaOtp extends BasePage {
@override @override
Widget body(BuildContext context) { Widget body(BuildContext context) {
reaction((_) => _authViewModel.otpState, (IoniaOtpState state) { reaction((_) => _authViewModel.otpState, (CakePayOtpState state) {
if (state is IoniaOtpFailure) { if (state is CakePayOtpFailure) {
_onOtpFailure(context, state.error); _onOtpFailure(context, state.error);
} }
if (state is IoniaOtpSuccess) { if (state is CakePayOtpSuccess) {
_onOtpSuccessful(context); _onOtpSuccessful(context);
} }
}); });
@ -98,9 +97,7 @@ class IoniaVerifyIoniaOtp extends BasePage {
Text(S.of(context).didnt_get_code), Text(S.of(context).didnt_get_code),
SizedBox(width: 20), SizedBox(width: 20),
InkWell( InkWell(
onTap: () => isSignIn onTap: () => _authViewModel.logIn(_email),
? _authViewModel.signIn(_email)
: _authViewModel.createUser(_email),
child: Text( child: Text(
S.of(context).resend_code, S.of(context).resend_code,
style: textSmallSemiBold(color: Palette.blueCraiola), style: textSmallSemiBold(color: Palette.blueCraiola),
@ -120,8 +117,8 @@ class IoniaVerifyIoniaOtp extends BasePage {
builder: (_) => LoadingPrimaryButton( builder: (_) => LoadingPrimaryButton(
text: S.of(context).continue_text, text: S.of(context).continue_text,
onPressed: _verify, onPressed: _verify,
isDisabled: _authViewModel.otpState is IoniaOtpSendDisabled, isDisabled: _authViewModel.otpState is CakePayOtpSendDisabled,
isLoading: _authViewModel.otpState is IoniaOtpValidating, isLoading: _authViewModel.otpState is CakePayOtpValidating,
color: Theme.of(context).primaryColor, color: Theme.of(context).primaryColor,
textColor: Colors.white, textColor: Colors.white,
), ),
@ -149,8 +146,7 @@ class IoniaVerifyIoniaOtp extends BasePage {
} }
void _onOtpSuccessful(BuildContext context) => void _onOtpSuccessful(BuildContext context) =>
Navigator.of(context) Navigator.pop(context);
.pushNamedAndRemoveUntil(Routes.ioniaManageCardsPage, (route) => route.isFirst);
void _verify() async => await _authViewModel.verifyEmail(_codeController.text); void _verify() async => await _authViewModel.verifyEmail(_codeController.text);
} }

View file

@ -1,22 +1,22 @@
import 'package:cake_wallet/core/email_validator.dart'; import 'package:cake_wallet/core/email_validator.dart';
import 'package:cake_wallet/themes/extensions/cake_text_theme.dart'; import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/ionia/ionia_create_state.dart'; import 'package:cake_wallet/cake_pay/cake_pay_states.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/widgets/alert_with_one_action.dart'; import 'package:cake_wallet/src/widgets/alert_with_one_action.dart';
import 'package:cake_wallet/src/widgets/base_text_form_field.dart'; import 'package:cake_wallet/src/widgets/base_text_form_field.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';
import 'package:cake_wallet/themes/extensions/cake_text_theme.dart';
import 'package:cake_wallet/typography.dart'; import 'package:cake_wallet/typography.dart';
import 'package:cake_wallet/utils/show_pop_up.dart'; import 'package:cake_wallet/utils/show_pop_up.dart';
import 'package:cake_wallet/view_model/ionia/ionia_auth_view_model.dart'; import 'package:cake_wallet/view_model/cake_pay/cake_pay_auth_view_model.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:cake_wallet/generated/i18n.dart';
import 'package:flutter_mobx/flutter_mobx.dart'; import 'package:flutter_mobx/flutter_mobx.dart';
import 'package:mobx/mobx.dart'; import 'package:mobx/mobx.dart';
class IoniaLoginPage extends BasePage { class CakePayWelcomePage extends BasePage {
IoniaLoginPage(this._authViewModel) CakePayWelcomePage(this._authViewModel)
: _formKey = GlobalKey<FormState>(), : _formKey = GlobalKey<FormState>(),
_emailController = TextEditingController() { _emailController = TextEditingController() {
_emailController.text = _authViewModel.email; _emailController.text = _authViewModel.email;
@ -25,14 +25,14 @@ class IoniaLoginPage extends BasePage {
final GlobalKey<FormState> _formKey; final GlobalKey<FormState> _formKey;
final IoniaAuthViewModel _authViewModel; final CakePayAuthViewModel _authViewModel;
final TextEditingController _emailController; final TextEditingController _emailController;
@override @override
Widget middle(BuildContext context) { Widget middle(BuildContext context) {
return Text( return Text(
S.current.login, S.current.welcome_to_cakepay,
style: textMediumSemiBold( style: textMediumSemiBold(
color: Theme.of(context).extension<CakeTextTheme>()!.titleColor, color: Theme.of(context).extension<CakeTextTheme>()!.titleColor,
), ),
@ -41,25 +41,40 @@ class IoniaLoginPage extends BasePage {
@override @override
Widget body(BuildContext context) { Widget body(BuildContext context) {
reaction((_) => _authViewModel.signInState, (IoniaCreateAccountState state) { reaction((_) => _authViewModel.userVerificationState, (CakePayUserVerificationState state) {
if (state is IoniaCreateStateFailure) { if (state is CakePayUserVerificationStateFailure) {
_onLoginUserFailure(context, state.error); _onLoginUserFailure(context, state.error);
} }
if (state is IoniaCreateStateSuccess) { if (state is CakePayUserVerificationStateSuccess) {
_onLoginSuccessful(context, _authViewModel); _onLoginSuccessful(context, _authViewModel);
} }
}); });
return ScrollableWithBottomSection( return ScrollableWithBottomSection(
contentPadding: EdgeInsets.all(24), contentPadding: EdgeInsets.all(24),
content: Form( content: Column(
key: _formKey, children: [
child: BaseTextFormField( SizedBox(height: 90),
hintText: S.of(context).email_address, Form(
keyboardType: TextInputType.emailAddress, key: _formKey,
validator: EmailValidator(), child: BaseTextFormField(
controller: _emailController, hintText: S.of(context).email_address,
onSubmit: (text) => _login(), keyboardType: TextInputType.emailAddress,
), validator: EmailValidator(),
controller: _emailController,
onSubmit: (text) => _login(),
),
),
SizedBox(height: 20),
Text(
S.of(context).about_cake_pay,
style: textLarge(
color: Theme.of(context).extension<CakeTextTheme>()!.titleColor,
),
),
SizedBox(height: 20),
Text(S.of(context).cake_pay_account_note,
style: textLarge(color: Theme.of(context).extension<CakeTextTheme>()!.titleColor)),
],
), ),
bottomSectionPadding: EdgeInsets.symmetric(vertical: 36, horizontal: 24), bottomSectionPadding: EdgeInsets.symmetric(vertical: 36, horizontal: 24),
bottomSection: Column( bottomSection: Column(
@ -71,7 +86,8 @@ class IoniaLoginPage extends BasePage {
builder: (_) => LoadingPrimaryButton( builder: (_) => LoadingPrimaryButton(
text: S.of(context).login, text: S.of(context).login,
onPressed: _login, onPressed: _login,
isLoading: _authViewModel.signInState is IoniaCreateStateLoading, isLoading:
_authViewModel.userVerificationState is CakePayUserVerificationStateLoading,
color: Theme.of(context).primaryColor, color: Theme.of(context).primaryColor,
textColor: Colors.white, textColor: Colors.white,
), ),
@ -98,9 +114,10 @@ class IoniaLoginPage extends BasePage {
}); });
} }
void _onLoginSuccessful(BuildContext context, IoniaAuthViewModel authViewModel) => Navigator.pushNamed( void _onLoginSuccessful(BuildContext context, CakePayAuthViewModel authViewModel) =>
Navigator.pushReplacementNamed(
context, context,
Routes.ioniaVerifyIoniaOtpPage, Routes.cakePayVerifyOtpPage,
arguments: [authViewModel.email, true], arguments: [authViewModel.email, true],
); );
@ -108,6 +125,6 @@ class IoniaLoginPage extends BasePage {
if (_formKey.currentState != null && !_formKey.currentState!.validate()) { if (_formKey.currentState != null && !_formKey.currentState!.validate()) {
return; return;
} }
await _authViewModel.signIn(_emailController.text); await _authViewModel.logIn(_emailController.text);
} }
} }

View file

@ -0,0 +1,5 @@
export 'auth/cake_pay_welcome_page.dart';
export 'auth/cake_pay_verify_otp_page.dart';
export 'cards/cake_pay_confirm_purchase_card_page.dart';
export 'cards/cake_pay_cards_page.dart';
export 'cards/cake_pay_buy_card_page.dart';

View file

@ -0,0 +1,474 @@
import 'package:auto_size_text/auto_size_text.dart';
import 'package:cake_wallet/cake_pay/cake_pay_card.dart';
import 'package:cake_wallet/cake_pay/cake_pay_payment_credantials.dart';
import 'package:cake_wallet/cake_pay/cake_pay_service.dart';
import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/routes.dart';
import 'package:cake_wallet/src/screens/base_page.dart';
import 'package:cake_wallet/src/screens/cake_pay/widgets/image_placeholder.dart';
import 'package:cake_wallet/src/screens/cake_pay/widgets/link_extractor.dart';
import 'package:cake_wallet/src/widgets/base_text_form_field.dart';
import 'package:cake_wallet/src/widgets/keyboard_done_button.dart';
import 'package:cake_wallet/src/widgets/number_text_fild_widget.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/themes/extensions/cake_text_theme.dart';
import 'package:cake_wallet/themes/extensions/keyboard_theme.dart';
import 'package:cake_wallet/themes/extensions/send_page_theme.dart';
import 'package:cake_wallet/typography.dart';
import 'package:cake_wallet/utils/responsive_layout_util.dart';
import 'package:cake_wallet/view_model/cake_pay/cake_pay_buy_card_view_model.dart';
import 'package:cake_wallet/view_model/dashboard/dropdown_filter_item_widget.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_mobx/flutter_mobx.dart';
import 'package:keyboard_actions/keyboard_actions.dart';
class CakePayBuyCardPage extends BasePage {
CakePayBuyCardPage(
this.cakePayBuyCardViewModel,
this.cakePayService,
) : _amountFieldFocus = FocusNode(),
_amountController = TextEditingController(),
_quantityFieldFocus = FocusNode(),
_quantityController =
TextEditingController(text: cakePayBuyCardViewModel.quantity.toString()) {
_amountController.addListener(() {
cakePayBuyCardViewModel.onAmountChanged(_amountController.text);
});
}
final CakePayBuyCardViewModel cakePayBuyCardViewModel;
final CakePayService cakePayService;
@override
String get title => cakePayBuyCardViewModel.card.name;
@override
bool get extendBodyBehindAppBar => true;
@override
AppBarStyle get appBarStyle => AppBarStyle.completelyTransparent;
@override
Widget? middle(BuildContext context) {
return Text(
title,
textAlign: TextAlign.center,
maxLines: 2,
style: TextStyle(
fontSize: 18.0,
fontWeight: FontWeight.bold,
fontFamily: 'Lato',
color: titleColor(context)),
);
}
final TextEditingController _amountController;
final FocusNode _amountFieldFocus;
final TextEditingController _quantityController;
final FocusNode _quantityFieldFocus;
@override
Widget body(BuildContext context) {
final card = cakePayBuyCardViewModel.card;
final vendor = cakePayBuyCardViewModel.vendor;
return KeyboardActions(
disableScroll: true,
config: KeyboardActionsConfig(
keyboardActionsPlatform: KeyboardActionsPlatform.IOS,
keyboardBarColor: Theme.of(context).extension<KeyboardTheme>()!.keyboardBarColor,
nextFocus: false,
actions: [
KeyboardActionsItem(
focusNode: _amountFieldFocus,
toolbarButtons: [(_) => KeyboardDoneButton()],
),
]),
child: Container(
color: Theme.of(context).colorScheme.background,
child: ScrollableWithBottomSection(
contentPadding: EdgeInsets.zero,
content: Column(
children: [
ClipRRect(
borderRadius: BorderRadius.only(
bottomLeft: Radius.circular(25.0), bottomRight: Radius.circular(25.0)),
child: Container(
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [
Theme.of(context).extension<SendPageTheme>()!.firstGradientColor,
Theme.of(context).extension<SendPageTheme>()!.secondGradientColor,
],
begin: Alignment.topLeft,
end: Alignment.bottomRight,
),
),
height: responsiveLayoutUtil.screenHeight * 0.35,
width: double.infinity,
child: Column(
children: [
Expanded(flex: 4, child: const SizedBox()),
Expanded(
flex: 7,
child: ClipRRect(
borderRadius: BorderRadius.all(Radius.circular(10)),
child: Image.network(
card.cardImageUrl ?? '',
fit: BoxFit.cover,
loadingBuilder: (BuildContext context, Widget child,
ImageChunkEvent? loadingProgress) {
if (loadingProgress == null) return child;
return Center(child: CircularProgressIndicator());
},
errorBuilder: (context, error, stackTrace) =>
CakePayCardImagePlaceholder(),
),
),
),
Expanded(child: const SizedBox()),
],
)),
),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 24),
child: Container(
height: responsiveLayoutUtil.screenHeight * 0.5,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SizedBox(height: 24),
Expanded(
child: Text(S.of(context).enter_amount,
style: TextStyle(
color: Theme.of(context).extension<CakeTextTheme>()!.titleColor,
fontSize: 24,
fontWeight: FontWeight.w600,
)),
),
card.denominations.isNotEmpty
? Expanded(
flex: 2,
child: _DenominationsAmountWidget(
fiatCurrency: card.fiatCurrency.title,
denominations: card.denominations,
amountFieldFocus: _amountFieldFocus,
amountController: _amountController,
quantityFieldFocus: _quantityFieldFocus,
quantityController: _quantityController,
onAmountChanged: cakePayBuyCardViewModel.onAmountChanged,
onQuantityChanged: cakePayBuyCardViewModel.onQuantityChanged,
cakePayBuyCardViewModel: cakePayBuyCardViewModel,
),
)
: Expanded(
flex: 2,
child: _EnterAmountWidget(
minValue: card.minValue ?? '-',
maxValue: card.maxValue ?? '-',
fiatCurrency: card.fiatCurrency.title,
amountFieldFocus: _amountFieldFocus,
amountController: _amountController,
onAmountChanged: cakePayBuyCardViewModel.onAmountChanged,
),
),
Expanded(
flex: 5,
child: Column(
children: [
if (vendor.cakeWarnings != null)
Padding(
padding: const EdgeInsets.only(bottom: 8.0),
child: Container(
decoration: BoxDecoration(
color: Theme.of(context).primaryColor,
borderRadius: BorderRadius.circular(10),
border: Border.all(color: Colors.white.withOpacity(0.20)),
),
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
vendor.cakeWarnings!,
textAlign: TextAlign.center,
style: textSmallSemiBold(color: Colors.white),
),
),
),
),
Expanded(
child: SingleChildScrollView(
child: ClickableLinksText(
text: card.description ?? '',
textStyle: TextStyle(
color: Theme.of(context)
.extension<CakeTextTheme>()!
.secondaryTextColor,
fontSize: 18,
fontWeight: FontWeight.w400,
),
),
),
),
],
),
),
],
),
),
),
],
),
bottomSection: Column(
children: [
Observer(builder: (_) {
return Padding(
padding: EdgeInsets.only(bottom: 12),
child: PrimaryButton(
onPressed: () => navigateToCakePayBuyCardDetailPage(context, card),
text: S.of(context).buy_now,
isDisabled: !cakePayBuyCardViewModel.isEnablePurchase,
color: Theme.of(context).primaryColor,
textColor: Colors.white,
),
);
}),
],
),
),
),
);
}
Future<void> navigateToCakePayBuyCardDetailPage(BuildContext context, CakePayCard card) async {
final userName = await cakePayService.getUserEmail();
final paymentCredential = PaymentCredential(
amount: cakePayBuyCardViewModel.amount,
quantity: cakePayBuyCardViewModel.quantity,
totalAmount: cakePayBuyCardViewModel.totalAmount,
userName: userName,
fiatCurrency: card.fiatCurrency.title,
);
Navigator.pushNamed(
context,
Routes.cakePayBuyCardDetailPage,
arguments: [paymentCredential, card],
);
}
}
class _DenominationsAmountWidget extends StatelessWidget {
const _DenominationsAmountWidget({
required this.fiatCurrency,
required this.denominations,
required this.amountFieldFocus,
required this.amountController,
required this.quantityFieldFocus,
required this.quantityController,
required this.cakePayBuyCardViewModel,
required this.onAmountChanged,
required this.onQuantityChanged,
});
final String fiatCurrency;
final List<String> denominations;
final FocusNode amountFieldFocus;
final TextEditingController amountController;
final FocusNode quantityFieldFocus;
final TextEditingController quantityController;
final CakePayBuyCardViewModel cakePayBuyCardViewModel;
final Function(String) onAmountChanged;
final Function(int?) onQuantityChanged;
@override
Widget build(BuildContext context) {
return Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expanded(
flex: 12,
child: Column(
children: [
Expanded(
child: DropdownFilterList(
items: denominations,
itemPrefix: fiatCurrency,
selectedItem: denominations.first,
textStyle: textMediumSemiBold(
color: Theme.of(context).extension<CakeTextTheme>()!.titleColor),
onItemSelected: (value) {
amountController.text = value;
onAmountChanged(value);
},
caption: '',
),
),
const SizedBox(height: 4),
Expanded(
child: Container(
width: double.infinity,
decoration: BoxDecoration(
border: Border(
top: BorderSide(
width: 1.0,
color: Theme.of(context).extension<CakeTextTheme>()!.secondaryTextColor),
),
),
child: Text(S.of(context).choose_card_value + ':',
maxLines: 2,
style: textSmall(
color: Theme.of(context).extension<CakeTextTheme>()!.secondaryTextColor)),
),
),
],
),
),
Expanded(child: const SizedBox()),
Expanded(
flex: 8,
child: Column(
children: [
Expanded(
child: NumberTextField(
controller: quantityController,
focusNode: quantityFieldFocus,
min: 1,
max: 99,
onChanged: (value) => onQuantityChanged(value),
),
),
const SizedBox(height: 4),
Expanded(
child: Container(
width: double.infinity,
decoration: BoxDecoration(
border: Border(
top: BorderSide(
width: 1.0,
color: Theme.of(context).extension<CakeTextTheme>()!.secondaryTextColor),
),
),
child: Text(S.of(context).quantity + ':',
maxLines: 1,
style: textSmall(
color: Theme.of(context).extension<CakeTextTheme>()!.secondaryTextColor)),
),
),
],
),
),
Expanded(child: const SizedBox()),
Expanded(
flex: 12,
child: Column(
children: [
Expanded(
child: Container(
alignment: Alignment.bottomCenter,
child: Observer(
builder: (_) => AutoSizeText(
'$fiatCurrency ${cakePayBuyCardViewModel.totalAmount}',
maxLines: 1,
style: textMediumSemiBold(
color:
Theme.of(context).extension<CakeTextTheme>()!.titleColor)))),
),
const SizedBox(height: 4),
Expanded(
child: Container(
width: double.infinity,
decoration: BoxDecoration(
border: Border(
top: BorderSide(
width: 1.0,
color:
Theme.of(context).extension<CakeTextTheme>()!.secondaryTextColor),
),
),
child: Text(S.of(context).total + ':',
maxLines: 1,
style: textSmall(
color:
Theme.of(context).extension<CakeTextTheme>()!.secondaryTextColor)),
),
),
],
)),
],
);
}
}
class _EnterAmountWidget extends StatelessWidget {
const _EnterAmountWidget({
required this.minValue,
required this.maxValue,
required this.fiatCurrency,
required this.amountFieldFocus,
required this.amountController,
required this.onAmountChanged,
});
final String minValue;
final String maxValue;
final String fiatCurrency;
final FocusNode amountFieldFocus;
final TextEditingController amountController;
final Function(String) onAmountChanged;
@override
Widget build(BuildContext context) {
return Column(
children: [
Container(
decoration: BoxDecoration(
border: Border(
bottom: BorderSide(
width: 1.0,
color: Theme.of(context).extension<CakeTextTheme>()!.secondaryTextColor),
),
),
child: BaseTextFormField(
controller: amountController,
keyboardType: TextInputType.numberWithOptions(signed: false, decimal: true),
hintText: '0.00',
maxLines: null,
borderColor: Colors.transparent,
prefixIcon: Padding(
padding: const EdgeInsets.only(top: 12),
child: Text(
'$fiatCurrency: ',
style: textMediumSemiBold(
color: Theme.of(context).extension<CakeTextTheme>()!.titleColor),
),
),
textStyle:
textMediumSemiBold(color: Theme.of(context).extension<CakeTextTheme>()!.titleColor),
placeholderTextStyle: textMediumSemiBold(
color: Theme.of(context).extension<CakeTextTheme>()!.secondaryTextColor),
inputFormatters: [
FilteringTextInputFormatter.deny(RegExp('[\-|\ ]')),
FilteringTextInputFormatter.allow(
RegExp(r'^\d+(\.|\,)?\d{0,2}'),
),
],
),
),
SizedBox(height: 4),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(S.of(context).min_amount(minValue) + ' $fiatCurrency',
style: textSmall(
color: Theme.of(context).extension<CakeTextTheme>()!.secondaryTextColor)),
Text(S.of(context).max_amount(maxValue) + ' $fiatCurrency',
style: textSmall(
color: Theme.of(context).extension<CakeTextTheme>()!.secondaryTextColor)),
],
),
],
);
}
}

View file

@ -1,42 +1,40 @@
import 'package:cake_wallet/ionia/ionia_create_state.dart'; import 'package:cake_wallet/cake_pay/cake_pay_states.dart';
import 'package:cake_wallet/ionia/ionia_merchant.dart'; import 'package:cake_wallet/cake_pay/cake_pay_vendor.dart';
import 'package:cake_wallet/generated/i18n.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/widgets/gradient_background.dart'; import 'package:cake_wallet/src/screens/cake_pay/widgets/card_item.dart';
import 'package:cake_wallet/src/screens/ionia/widgets/card_item.dart'; import 'package:cake_wallet/src/screens/cake_pay/widgets/card_menu.dart';
import 'package:cake_wallet/src/screens/ionia/widgets/card_menu.dart'; import 'package:cake_wallet/src/screens/dashboard/widgets/filter_widget.dart';
import 'package:cake_wallet/src/screens/ionia/widgets/ionia_filter_modal.dart';
import 'package:cake_wallet/src/widgets/cake_scrollbar.dart'; import 'package:cake_wallet/src/widgets/cake_scrollbar.dart';
import 'package:cake_wallet/themes/extensions/exchange_page_theme.dart'; import 'package:cake_wallet/src/widgets/gradient_background.dart';
import 'package:cake_wallet/themes/extensions/sync_indicator_theme.dart';
import 'package:cake_wallet/themes/theme_base.dart';
import 'package:cake_wallet/utils/debounce.dart';
import 'package:cake_wallet/typography.dart';
import 'package:cake_wallet/utils/show_pop_up.dart';
import 'package:cake_wallet/view_model/ionia/ionia_gift_cards_list_view_model.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:cake_wallet/generated/i18n.dart';
import 'package:flutter_mobx/flutter_mobx.dart';
import 'package:cake_wallet/themes/extensions/dashboard_page_theme.dart';
import 'package:cake_wallet/themes/extensions/balance_page_theme.dart'; import 'package:cake_wallet/themes/extensions/balance_page_theme.dart';
import 'package:cake_wallet/themes/extensions/dashboard_page_theme.dart';
import 'package:cake_wallet/themes/extensions/exchange_page_theme.dart';
import 'package:cake_wallet/themes/extensions/filter_theme.dart'; import 'package:cake_wallet/themes/extensions/filter_theme.dart';
import 'package:cake_wallet/themes/extensions/sync_indicator_theme.dart';
import 'package:cake_wallet/typography.dart';
import 'package:cake_wallet/utils/debounce.dart';
import 'package:cake_wallet/utils/responsive_layout_util.dart';
import 'package:cake_wallet/utils/show_pop_up.dart';
import 'package:cake_wallet/view_model/cake_pay/cake_pay_cards_list_view_model.dart';
import 'package:flutter/material.dart';
import 'package:flutter_mobx/flutter_mobx.dart';
class IoniaManageCardsPage extends BasePage { class CakePayCardsPage extends BasePage {
IoniaManageCardsPage(this._cardsListViewModel): searchFocusNode = FocusNode() { CakePayCardsPage(this._cardsListViewModel) : searchFocusNode = FocusNode() {
_searchController.addListener(() { _searchController.addListener(() {
if (_searchController.text != _cardsListViewModel.searchString) { if (_searchController.text != _cardsListViewModel.searchString) {
_searchDebounce.run(() { _searchDebounce.run(() {
_cardsListViewModel.searchMerchant(_searchController.text); _cardsListViewModel.resetLoadingNextPageState();
_cardsListViewModel.getVendors(text: _searchController.text);
}); });
} }
}); });
_cardsListViewModel.getMerchants();
} }
final FocusNode searchFocusNode; final FocusNode searchFocusNode;
final IoniaGiftCardsListViewModel _cardsListViewModel; final CakePayCardsListViewModel _cardsListViewModel;
final _searchDebounce = Debounce(Duration(milliseconds: 500)); final _searchDebounce = Debounce(Duration(milliseconds: 500));
final _searchController = TextEditingController(); final _searchController = TextEditingController();
@ -46,8 +44,7 @@ class IoniaManageCardsPage extends BasePage {
@override @override
Widget Function(BuildContext, Widget) get rootWrapper => Widget Function(BuildContext, Widget) get rootWrapper =>
(BuildContext context, Widget scaffold) => (BuildContext context, Widget scaffold) => GradientBackground(scaffold: scaffold);
GradientBackground(scaffold: scaffold);
@override @override
bool get resizeToAvoidBottomInset => false; bool get resizeToAvoidBottomInset => false;
@ -58,7 +55,7 @@ class IoniaManageCardsPage extends BasePage {
@override @override
Widget middle(BuildContext context) { Widget middle(BuildContext context) {
return Text( return Text(
S.of(context).gift_cards, 'Cake Pay',
style: textMediumSemiBold( style: textMediumSemiBold(
color: Theme.of(context).extension<DashboardPageTheme>()!.textColor, color: Theme.of(context).extension<DashboardPageTheme>()!.textColor,
), ),
@ -68,9 +65,17 @@ class IoniaManageCardsPage extends BasePage {
@override @override
Widget trailing(BuildContext context) { Widget trailing(BuildContext context) {
return _TrailingIcon( return _TrailingIcon(
asset: 'assets/images/profile.png', asset: 'assets/images/profile.png',
onPressed: () => Navigator.pushNamed(context, Routes.ioniaAccountPage), iconColor: pageIconColor(context) ?? Colors.white,
); onPressed: () {
_cardsListViewModel.isCakePayUserAuthenticated().then((value) {
if (value) {
Navigator.pushNamed(context, Routes.cakePayAccountPage);
return;
}
Navigator.pushNamed(context, Routes.cakePayWelcomePage);
});
});
} }
@override @override
@ -79,8 +84,12 @@ class IoniaManageCardsPage extends BasePage {
label: S.of(context).filter_by, label: S.of(context).filter_by,
child: InkWell( child: InkWell(
onTap: () async { onTap: () async {
await showCategoryFilter(context); _cardsListViewModel.storeInitialFilterStates();
_cardsListViewModel.getMerchants(); await showFilterWidget(context);
if (_cardsListViewModel.hasFiltersChanged) {
_cardsListViewModel.resetLoadingNextPageState();
_cardsListViewModel.getVendors();
}
}, },
child: Container( child: Container(
width: 32, width: 32,
@ -120,7 +129,7 @@ class IoniaManageCardsPage extends BasePage {
), ),
SizedBox(height: 8), SizedBox(height: 8),
Expanded( Expanded(
child: IoniaManageCardsPageBody( child: CakePayCardsPageBody(
cardsListViewModel: _cardsListViewModel, cardsListViewModel: _cardsListViewModel,
), ),
), ),
@ -129,36 +138,35 @@ class IoniaManageCardsPage extends BasePage {
); );
} }
Future <void> showCategoryFilter(BuildContext context) async { Future<void> showFilterWidget(BuildContext context) async {
return showPopUp<void>( return showPopUp<void>(
context: context, context: context,
builder: (BuildContext context) { builder: (BuildContext context) {
return IoniaFilterModal( return FilterWidget(filterItems: _cardsListViewModel.createFilterItems);
ioniaGiftCardsListViewModel: _cardsListViewModel,
);
}, },
); );
} }
} }
class IoniaManageCardsPageBody extends StatefulWidget { class CakePayCardsPageBody extends StatefulWidget {
const IoniaManageCardsPageBody({ const CakePayCardsPageBody({
Key? key, Key? key,
required this.cardsListViewModel, required this.cardsListViewModel,
}) : super(key: key); }) : super(key: key);
final IoniaGiftCardsListViewModel cardsListViewModel; final CakePayCardsListViewModel cardsListViewModel;
@override @override
_IoniaManageCardsPageBodyState createState() => _IoniaManageCardsPageBodyState(); _CakePayCardsPageBodyState createState() => _CakePayCardsPageBodyState();
} }
class _IoniaManageCardsPageBodyState extends State<IoniaManageCardsPageBody> { class _CakePayCardsPageBodyState extends State<CakePayCardsPageBody> {
double get backgroundHeight => MediaQuery.of(context).size.height * 0.75; double get backgroundHeight => MediaQuery.of(context).size.height * 0.75;
double thumbHeight = 72; double thumbHeight = 72;
bool get isAlwaysShowScrollThumb => merchantsList == null ? false : merchantsList.length > 3;
List<IoniaMerchant> get merchantsList => widget.cardsListViewModel.ioniaMerchants; bool get isAlwaysShowScrollThumb => merchantsList.isEmpty ? false : merchantsList.length > 3;
List<CakePayVendor> get merchantsList => widget.cardsListViewModel.cakePayVendors;
final _scrollController = ScrollController(); final _scrollController = ScrollController();
@ -166,61 +174,93 @@ class _IoniaManageCardsPageBodyState extends State<IoniaManageCardsPageBody> {
void initState() { void initState() {
_scrollController.addListener(() { _scrollController.addListener(() {
final scrollOffsetFromTop = _scrollController.hasClients final scrollOffsetFromTop = _scrollController.hasClients
? (_scrollController.offset / _scrollController.position.maxScrollExtent * (backgroundHeight - thumbHeight)) ? (_scrollController.offset /
_scrollController.position.maxScrollExtent *
(backgroundHeight - thumbHeight))
: 0.0; : 0.0;
widget.cardsListViewModel.setScrollOffsetFromTop(scrollOffsetFromTop); widget.cardsListViewModel.setScrollOffsetFromTop(scrollOffsetFromTop);
double threshold = 200.0;
bool isNearBottom =
_scrollController.offset >= _scrollController.position.maxScrollExtent - threshold;
if (isNearBottom && !_scrollController.position.outOfRange) {
widget.cardsListViewModel.fetchNextPage();
}
}); });
super.initState(); super.initState();
} }
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Observer( return Observer(builder: (_) {
builder: (_) { final vendorsState = widget.cardsListViewModel.vendorsState;
final merchantState = widget.cardsListViewModel.merchantState; if (vendorsState is CakePayVendorLoadedState) {
if (merchantState is IoniaLoadedMerchantState) { bool isLoadingMore = widget.cardsListViewModel.isLoadingNextPage;
final vendors = widget.cardsListViewModel.cakePayVendors;
if (vendors.isEmpty) {
return Center(child: Text(S.of(context).no_cards_found));
}
return Stack(children: [ return Stack(children: [
ListView.separated( GridView.builder(
padding: EdgeInsets.only(left: 2, right: 22), controller: _scrollController,
controller: _scrollController, gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
itemCount: merchantsList.length, crossAxisCount: responsiveLayoutUtil.shouldRenderTabletUI ? 2 : 1,
separatorBuilder: (_, __) => SizedBox(height: 4), childAspectRatio: 5,
itemBuilder: (_, index) { crossAxisSpacing: responsiveLayoutUtil.shouldRenderTabletUI ? 10 : 5,
final merchant = merchantsList[index]; mainAxisSpacing: responsiveLayoutUtil.shouldRenderTabletUI ? 10 : 5,
return CardItem( ),
logoUrl: merchant.logoUrl, padding: EdgeInsets.only(left: 2, right: 22),
onTap: () { itemCount: vendors.length + (isLoadingMore ? 1 : 0),
Navigator.of(context).pushNamed(Routes.ioniaBuyGiftCardPage, arguments: [merchant]); itemBuilder: (_, index) {
}, if (index >= vendors.length) {
title: merchant.legalName, return _VendorLoadedIndicator();
subTitle: merchant.avaibilityStatus, }
backgroundColor: Theme.of(context).extension<SyncIndicatorTheme>()!.syncedBackgroundColor, final vendor = vendors[index];
titleColor: Theme.of(context).extension<DashboardPageTheme>()!.textColor, return CardItem(
subtitleColor: Theme.of(context).extension<BalancePageTheme>()!.labelTextColor, logoUrl: vendor.card?.cardImageUrl,
discount: merchant.discount, onTap: () {
); Navigator.of(context).pushNamed(Routes.cakePayBuyCardPage, arguments: [vendor]);
}, },
), title: vendor.name,
isAlwaysShowScrollThumb subTitle: vendor.card?.description ?? '',
? CakeScrollbar( backgroundColor:
backgroundHeight: backgroundHeight, Theme.of(context).extension<SyncIndicatorTheme>()!.syncedBackgroundColor,
thumbHeight: thumbHeight, titleColor: Theme.of(context).extension<DashboardPageTheme>()!.textColor,
rightOffset: 1, subtitleColor: Theme.of(context).extension<BalancePageTheme>()!.labelTextColor,
width: 3, discount: 0.0,
backgroundColor: Theme.of(context).extension<FilterTheme>()!.iconColor.withOpacity(0.05), );
thumbColor: Theme.of(context).extension<FilterTheme>()!.iconColor.withOpacity(0.5), },
fromTop: widget.cardsListViewModel.scrollOffsetFromTop,
)
: Offstage()
]);
}
return Center(
child: CircularProgressIndicator(
backgroundColor: Theme.of(context).extension<DashboardPageTheme>()!.textColor,
valueColor: AlwaysStoppedAnimation<Color>(Theme.of(context).extension<ExchangePageTheme>()!.firstGradientBottomPanelColor),
), ),
); isAlwaysShowScrollThumb
? CakeScrollbar(
backgroundHeight: backgroundHeight,
thumbHeight: thumbHeight,
rightOffset: 1,
width: 3,
backgroundColor:
Theme.of(context).extension<FilterTheme>()!.iconColor.withOpacity(0.05),
thumbColor:
Theme.of(context).extension<FilterTheme>()!.iconColor.withOpacity(0.5),
fromTop: widget.cardsListViewModel.scrollOffsetFromTop,
)
: Offstage()
]);
} }
return _VendorLoadedIndicator();
});
}
}
class _VendorLoadedIndicator extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Center(
child: CircularProgressIndicator(
backgroundColor: Theme.of(context).extension<DashboardPageTheme>()!.textColor,
valueColor: AlwaysStoppedAnimation<Color>(
Theme.of(context).extension<ExchangePageTheme>()!.firstGradientBottomPanelColor),
),
); );
} }
} }
@ -233,6 +273,7 @@ class _SearchWidget extends StatelessWidget {
}) : super(key: key); }) : super(key: key);
final TextEditingController controller; final TextEditingController controller;
final FocusNode focusNode; final FocusNode focusNode;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final searchIcon = ExcludeSemantics( final searchIcon = ExcludeSemantics(
@ -284,30 +325,25 @@ class _SearchWidget extends StatelessWidget {
} }
class _TrailingIcon extends StatelessWidget { class _TrailingIcon extends StatelessWidget {
const _TrailingIcon({required this.asset, this.onPressed}); const _TrailingIcon({required this.asset, this.onPressed, required this.iconColor});
final String asset; final String asset;
final VoidCallback? onPressed; final VoidCallback? onPressed;
final Color iconColor;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Semantics( return Semantics(
label: S.of(context).profile, label: S.of(context).profile,
child: Material( child: Material(
color: Colors.transparent, color: Colors.transparent,
child: IconButton( child: IconButton(
padding: EdgeInsets.zero, padding: EdgeInsets.zero,
constraints: BoxConstraints(), constraints: BoxConstraints(),
highlightColor: Colors.transparent, highlightColor: Colors.transparent,
splashColor: Colors.transparent, onPressed: onPressed,
iconSize: 25, icon: ImageIcon(AssetImage(asset), size: 25, color: iconColor),
onPressed: onPressed,
icon: Image.asset(
asset,
color: Theme.of(context).extension<DashboardPageTheme>()!.textColor,
), ),
), ));
),
);
} }
} }

View file

@ -0,0 +1,403 @@
import 'package:cake_wallet/core/execution_state.dart';
import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/cake_pay/cake_pay_card.dart';
import 'package:cake_wallet/routes.dart';
import 'package:cake_wallet/src/screens/base_page.dart';
import 'package:cake_wallet/src/screens/cake_pay/widgets/cake_pay_alert_modal.dart';
import 'package:cake_wallet/src/screens/cake_pay/widgets/image_placeholder.dart';
import 'package:cake_wallet/src/screens/cake_pay/widgets/link_extractor.dart';
import 'package:cake_wallet/src/screens/cake_pay/widgets/text_icon_button.dart';
import 'package:cake_wallet/src/screens/send/widgets/confirm_sending_alert.dart';
import 'package:cake_wallet/src/widgets/alert_with_one_action.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/themes/extensions/cake_text_theme.dart';
import 'package:cake_wallet/themes/extensions/exchange_page_theme.dart';
import 'package:cake_wallet/themes/extensions/picker_theme.dart';
import 'package:cake_wallet/themes/extensions/receive_page_theme.dart';
import 'package:cake_wallet/themes/extensions/send_page_theme.dart';
import 'package:cake_wallet/typography.dart';
import 'package:cake_wallet/utils/show_pop_up.dart';
import 'package:cake_wallet/view_model/cake_pay/cake_pay_purchase_view_model.dart';
import 'package:cake_wallet/view_model/send/send_view_model_state.dart';
import 'package:flutter/material.dart';
import 'package:flutter_mobx/flutter_mobx.dart';
import 'package:mobx/mobx.dart';
class CakePayBuyCardDetailPage extends BasePage {
CakePayBuyCardDetailPage(this.cakePayPurchaseViewModel);
final CakePayPurchaseViewModel cakePayPurchaseViewModel;
@override
String get title => cakePayPurchaseViewModel.card.name;
@override
Widget? middle(BuildContext context) {
return Text(
title,
textAlign: TextAlign.center,
maxLines: 2,
style: TextStyle(
fontSize: 18.0,
fontWeight: FontWeight.bold,
fontFamily: 'Lato',
color: titleColor(context)),
);
}
@override
Widget? trailing(BuildContext context) => null;
bool _effectsInstalled = false;
@override
Widget body(BuildContext context) {
_setEffects(context);
final card = cakePayPurchaseViewModel.card;
return ScrollableWithBottomSection(
contentPadding: EdgeInsets.zero,
content: Observer(builder: (_) {
return Column(
children: [
SizedBox(height: 36),
ClipRRect(
borderRadius:
BorderRadius.horizontal(left: Radius.circular(20), right: Radius.circular(20)),
child: Container(
decoration: BoxDecoration(
color: Theme.of(context).extension<PickerTheme>()!.searchBackgroundFillColor,
borderRadius: BorderRadius.circular(20),
border: Border.all(color: Colors.white.withOpacity(0.20)),
),
child: Row(
children: [
Expanded(
child: Container(
child: ClipRRect(
borderRadius: BorderRadius.horizontal(
left: Radius.circular(20), right: Radius.circular(20)),
child: Image.network(
card.cardImageUrl ?? '',
fit: BoxFit.cover,
loadingBuilder: (BuildContext context, Widget child,
ImageChunkEvent? loadingProgress) {
if (loadingProgress == null) return child;
return Center(child: CircularProgressIndicator());
},
errorBuilder: (context, error, stackTrace) =>
CakePayCardImagePlaceholder(),
),
)),
),
Expanded(
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 8.0),
child: Column(children: [
Row(
children: [
Text(
S.of(context).value + ':',
style: textLarge(
color:
Theme.of(context).extension<CakeTextTheme>()!.titleColor),
),
SizedBox(width: 8),
Text(
'${cakePayPurchaseViewModel.amount.toStringAsFixed(2)} ${cakePayPurchaseViewModel.fiatCurrency}',
style: textLarge(
color:
Theme.of(context).extension<CakeTextTheme>()!.titleColor),
),
],
),
SizedBox(height: 16),
Row(
children: [
Text(
S.of(context).quantity + ':',
style: textLarge(
color:
Theme.of(context).extension<CakeTextTheme>()!.titleColor),
),
SizedBox(width: 8),
Text(
'${cakePayPurchaseViewModel.quantity}',
style: textLarge(
color:
Theme.of(context).extension<CakeTextTheme>()!.titleColor),
),
],
),
SizedBox(height: 16),
Row(
children: [
Text(
S.of(context).total + ':',
style: textLarge(
color:
Theme.of(context).extension<CakeTextTheme>()!.titleColor),
),
SizedBox(width: 8),
Text(
'${cakePayPurchaseViewModel.totalAmount.toStringAsFixed(2)} ${cakePayPurchaseViewModel.fiatCurrency}',
style: textLarge(
color:
Theme.of(context).extension<CakeTextTheme>()!.titleColor),
),
],
),
]),
),
)
],
),
),
),
SizedBox(height: 20),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 24.0),
child: TextIconButton(
label: S.of(context).how_to_use_card,
onTap: () => _showHowToUseCard(context, card),
),
),
SizedBox(height: 20),
if (card.expiryAndValidity != null && card.expiryAndValidity!.isNotEmpty)
Padding(
padding: const EdgeInsets.symmetric(horizontal: 24.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(S.of(context).expiry_and_validity + ':',
style: textMediumSemiBold(
color: Theme.of(context).extension<CakeTextTheme>()!.titleColor)),
SizedBox(height: 10),
Container(
width: double.infinity,
decoration: BoxDecoration(
border: Border(
bottom: BorderSide(
color: Theme.of(context).extension<CakeTextTheme>()!.secondaryTextColor,
width: 1,
),
),
),
child: Padding(
padding: const EdgeInsets.only(bottom: 8.0),
child: Text(
card.expiryAndValidity ?? '',
style: textMedium(
color: Theme.of(context).extension<CakeTextTheme>()!.secondaryTextColor,
),
),
),
),
],
),
),
],
);
}),
bottomSection: Column(
children: [
Padding(
padding: EdgeInsets.only(bottom: 12),
child: Observer(builder: (_) {
return LoadingPrimaryButton(
isLoading: cakePayPurchaseViewModel.sendViewModel.state is IsExecutingState,
onPressed: () => purchaseCard(context),
text: S.of(context).purchase_gift_card,
color: Theme.of(context).primaryColor,
textColor: Colors.white,
);
}),
),
SizedBox(height: 8),
InkWell(
onTap: () => _showTermsAndCondition(context, card.termsAndConditions),
child: Text(S.of(context).settings_terms_and_conditions,
style: textMediumSemiBold(
color: Theme.of(context).primaryColor,
).copyWith(fontSize: 12)),
),
SizedBox(height: 16)
],
),
);
}
void _showTermsAndCondition(BuildContext context, String? termsAndConditions) {
showPopUp<void>(
context: context,
builder: (BuildContext context) {
return CakePayAlertModal(
title: S.of(context).settings_terms_and_conditions,
content: Align(
alignment: Alignment.bottomLeft,
child: ClickableLinksText(
text: termsAndConditions ?? '',
textStyle: TextStyle(
color: Theme.of(context).extension<CakeTextTheme>()!.secondaryTextColor,
fontSize: 18,
fontWeight: FontWeight.w400,
),
),
),
actionTitle: S.of(context).agree,
showCloseButton: false,
heightFactor: 0.6,
);
});
}
Future<void> purchaseCard(BuildContext context) async {
bool isLogged = await cakePayPurchaseViewModel.cakePayService.isLogged();
if (!isLogged) {
Navigator.of(context).pushNamed(Routes.cakePayWelcomePage);
} else {
await cakePayPurchaseViewModel.createOrder();
}
}
void _showHowToUseCard(
BuildContext context,
CakePayCard card,
) {
showPopUp<void>(
context: context,
builder: (BuildContext context) {
return CakePayAlertModal(
title: S.of(context).how_to_use_card,
content: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
Padding(
padding: EdgeInsets.all(10),
child: Text(
card.name,
style: textLargeSemiBold(
color: Theme.of(context).extension<ReceivePageTheme>()!.tilesTextColor,
),
)),
ClickableLinksText(
text: card.howToUse ?? '',
textStyle: TextStyle(
color: Theme.of(context).extension<CakeTextTheme>()!.secondaryTextColor,
fontSize: 18,
fontWeight: FontWeight.w400,
),
linkStyle: TextStyle(
color: Theme.of(context).extension<CakeTextTheme>()!.titleColor,
fontSize: 18,
fontStyle: FontStyle.italic,
fontWeight: FontWeight.w400,
),
),
]),
actionTitle: S.current.got_it,
);
});
}
Future<void> _showConfirmSendingAlert(BuildContext context) async {
if (cakePayPurchaseViewModel.order == null) {
return;
}
ReactionDisposer? disposer;
disposer = reaction((_) => cakePayPurchaseViewModel.isOrderExpired, (bool isExpired) {
if (isExpired) {
if (Navigator.of(context).canPop()) {
Navigator.of(context).pop();
}
if (disposer != null) {
disposer();
}
}
});
final order = cakePayPurchaseViewModel.order;
final pendingTransaction = cakePayPurchaseViewModel.sendViewModel.pendingTransaction!;
await showPopUp<void>(
context: context,
builder: (_) {
return Observer(
builder: (_) => ConfirmSendingAlert(
alertTitle: S.of(context).confirm_sending,
paymentId: S.of(context).payment_id,
paymentIdValue: order?.orderId,
expirationTime: cakePayPurchaseViewModel.formattedRemainingTime,
onDispose: () => _handleDispose(disposer),
amount: S.of(context).send_amount,
amountValue: pendingTransaction.amountFormatted,
fiatAmountValue:
cakePayPurchaseViewModel.sendViewModel.pendingTransactionFiatAmountFormatted,
fee: S.of(context).send_fee,
feeValue: pendingTransaction.feeFormatted,
feeFiatAmount:
cakePayPurchaseViewModel.sendViewModel.pendingTransactionFeeFiatAmountFormatted,
feeRate: pendingTransaction.feeRate,
outputs: cakePayPurchaseViewModel.sendViewModel.outputs,
rightButtonText: S.of(context).send,
leftButtonText: S.of(context).cancel,
actionRightButton: () async {
Navigator.of(context).pop();
await cakePayPurchaseViewModel.sendViewModel.commitTransaction();
},
actionLeftButton: () => Navigator.of(context).pop()));
},
);
}
void _setEffects(BuildContext context) {
if (_effectsInstalled) {
return;
}
reaction((_) => cakePayPurchaseViewModel.sendViewModel.state, (ExecutionState state) {
if (state is FailureState) {
WidgetsBinding.instance.addPostFrameCallback((_) {
showStateAlert(context, S.of(context).error, state.error);
});
}
if (state is ExecutedSuccessfullyState) {
WidgetsBinding.instance.addPostFrameCallback((_) async {
await _showConfirmSendingAlert(context);
});
}
if (state is TransactionCommitted) {
WidgetsBinding.instance.addPostFrameCallback((_) {
cakePayPurchaseViewModel.sendViewModel.clearOutputs();
if (context.mounted) {
showStateAlert(context, S.of(context).sending, S.of(context).transaction_sent);
}
});
}
});
_effectsInstalled = true;
}
void showStateAlert(BuildContext context, String title, String content) {
showPopUp<void>(
context: context,
builder: (BuildContext context) {
return AlertWithOneAction(
alertTitle: title,
alertContent: content,
buttonText: S.of(context).ok,
buttonAction: () => Navigator.of(context).pop());
});
}
void _handleDispose(ReactionDisposer? disposer) {
cakePayPurchaseViewModel.dispose();
if (disposer != null) {
disposer();
}
}
}

View file

@ -5,8 +5,8 @@ import 'package:cake_wallet/themes/extensions/cake_scrollbar_theme.dart';
import 'package:cake_wallet/typography.dart'; import 'package:cake_wallet/typography.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
class IoniaAlertModal extends StatelessWidget { class CakePayAlertModal extends StatelessWidget {
const IoniaAlertModal({ const CakePayAlertModal({
Key? key, Key? key,
required this.title, required this.title,
required this.content, required this.content,

View file

@ -3,8 +3,8 @@ import 'package:cake_wallet/themes/extensions/cake_text_theme.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:cake_wallet/themes/extensions/transaction_trade_theme.dart'; import 'package:cake_wallet/themes/extensions/transaction_trade_theme.dart';
class IoniaTile extends StatelessWidget { class CakePayTile extends StatelessWidget {
const IoniaTile({ const CakePayTile({
Key? key, Key? key,
required this.title, required this.title,
required this.subTitle, required this.subTitle,

View file

@ -0,0 +1,104 @@
import 'package:flutter/material.dart';
import 'image_placeholder.dart';
class CardItem extends StatelessWidget {
CardItem({
required this.title,
required this.subTitle,
required this.backgroundColor,
required this.titleColor,
required this.subtitleColor,
this.hideBorder = false,
this.discount = 0.0,
this.isAmount = false,
this.discountBackground,
this.onTap,
this.logoUrl,
});
final VoidCallback? onTap;
final String title;
final String subTitle;
final String? logoUrl;
final double discount;
final bool isAmount;
final bool hideBorder;
final Color backgroundColor;
final Color titleColor;
final Color subtitleColor;
final AssetImage? discountBackground;
@override
Widget build(BuildContext context) {
return Theme(
data: ThemeData(
splashColor: Colors.transparent,
highlightColor: Colors.transparent,
),
child: InkWell(
onTap: onTap,
child: Container(
decoration: BoxDecoration(
color: backgroundColor,
borderRadius: BorderRadius.circular(10),
border: hideBorder
? Border.all(color: Colors.transparent)
: Border.all(color: Colors.white.withOpacity(0.20)),
),
child: Row(
children: [
if (logoUrl != null)
AspectRatio(
aspectRatio: 1.8,
child: ClipRRect(
borderRadius: BorderRadius.all(Radius.circular(10)),
child: Image.network(
logoUrl!,
fit: BoxFit.cover,
loadingBuilder:
(BuildContext context, Widget child, ImageChunkEvent? loadingProgress) {
if (loadingProgress == null) return child;
return Center(child: CircularProgressIndicator());
},
errorBuilder: (context, error, stackTrace) => CakePayCardImagePlaceholder(),
),
),
),
Expanded(
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 8),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
title,
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: TextStyle(
color: titleColor,
fontSize: 18,
fontWeight: FontWeight.w700,
),
),
Text(
subTitle,
maxLines: 2,
overflow: TextOverflow.ellipsis,
style: TextStyle(
color: titleColor,
fontSize: 10,
fontWeight: FontWeight.w700,
),
),
],
),
),
),
],
),
),
),
);
}
}

View file

@ -0,0 +1,29 @@
import 'package:flutter/material.dart';
class CakePayCardImagePlaceholder extends StatelessWidget {
const CakePayCardImagePlaceholder({this.text});
final String? text;
@override
Widget build(BuildContext context) {
return AspectRatio(
aspectRatio: 1.8,
child: Container(
child: Center(
child: Text(
text ?? 'Image not found!',
style: TextStyle(
color: Colors.black,
fontSize: 12,
fontWeight: FontWeight.w900,
),
),
),
decoration: BoxDecoration(
color: Colors.white,
),
),
);
}
}

View file

@ -0,0 +1,66 @@
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:url_launcher/url_launcher.dart';
class ClickableLinksText extends StatelessWidget {
const ClickableLinksText({
required this.text,
required this.textStyle,
this.linkStyle,
});
final String text;
final TextStyle textStyle;
final TextStyle? linkStyle;
@override
Widget build(BuildContext context) {
List<InlineSpan> spans = [];
RegExp linkRegExp = RegExp(r'(https?://[^\s]+)');
Iterable<Match> matches = linkRegExp.allMatches(text);
int previousEnd = 0;
matches.forEach((match) {
if (match.start > previousEnd) {
spans.add(TextSpan(text: text.substring(previousEnd, match.start), style: textStyle));
}
String url = text.substring(match.start, match.end);
if (url.toLowerCase().endsWith('.md')) {
spans.add(
TextSpan(
text: url,
style: TextStyle(
color: Colors.blue,
fontSize: 18,
fontWeight: FontWeight.w400,
),
recognizer: TapGestureRecognizer()
..onTap = () async {
if (await canLaunchUrl(Uri.parse(url))) {
await launchUrl(Uri.parse(url), mode: LaunchMode.externalApplication);
}
},
),
);
} else {
spans.add(
TextSpan(
text: url,
style: linkStyle,
recognizer: TapGestureRecognizer()
..onTap = () {
launchUrl(Uri.parse(url));
},
),
);
}
previousEnd = match.end;
});
if (previousEnd < text.length) {
spans.add(TextSpan(text: text.substring(previousEnd), style: textStyle));
}
return RichText(text: TextSpan(children: spans));
}
}

View file

@ -1,17 +1,18 @@
import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/routes.dart';
import 'package:cake_wallet/src/widgets/alert_with_one_action.dart';
import 'package:cake_wallet/src/widgets/dashboard_card_widget.dart'; import 'package:cake_wallet/src/widgets/dashboard_card_widget.dart';
import 'package:cake_wallet/themes/extensions/dashboard_page_theme.dart';
import 'package:cake_wallet/utils/show_pop_up.dart';
import 'package:cake_wallet/view_model/dashboard/dashboard_view_model.dart'; import 'package:cake_wallet/view_model/dashboard/dashboard_view_model.dart';
import 'package:cw_core/wallet_type.dart';
import 'package:cake_wallet/view_model/dashboard/cake_features_view_model.dart'; import 'package:cake_wallet/view_model/dashboard/cake_features_view_model.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:cake_wallet/generated/i18n.dart';
import 'package:url_launcher/url_launcher.dart'; import 'package:url_launcher/url_launcher.dart';
import 'package:cake_wallet/themes/extensions/dashboard_page_theme.dart';
import 'package:flutter_svg/flutter_svg.dart'; import 'package:flutter_svg/flutter_svg.dart';
class CakeFeaturesPage extends StatelessWidget { class CakeFeaturesPage extends StatelessWidget {
CakeFeaturesPage({ CakeFeaturesPage({required this.dashboardViewModel, required this.cakeFeaturesViewModel});
required this.dashboardViewModel,
required this.cakeFeaturesViewModel,
});
final DashboardViewModel dashboardViewModel; final DashboardViewModel dashboardViewModel;
final CakeFeaturesViewModel cakeFeaturesViewModel; final CakeFeaturesViewModel cakeFeaturesViewModel;
@ -45,20 +46,11 @@ class CakeFeaturesPage extends StatelessWidget {
child: ListView( child: ListView(
controller: _scrollController, controller: _scrollController,
children: <Widget>[ children: <Widget>[
// SizedBox(height: 20),
// DashBoardRoundedCardWidget(
// onTap: () => launchUrl(
// Uri.parse("https://cakelabs.com/news/cake-pay-mobile-to-shut-down/"),
// mode: LaunchMode.externalApplication,
// ),
// title: S.of(context).cake_pay_title,
// subTitle: S.of(context).cake_pay_subtitle,
// ),
SizedBox(height: 20), SizedBox(height: 20),
DashBoardRoundedCardWidget( DashBoardRoundedCardWidget(
onTap: () => _launchUrl("buy.cakepay.com"), onTap: () => _navigatorToGiftCardsPage(context),
title: S.of(context).cake_pay_web_cards_title, title: 'Cake Pay',
subTitle: S.of(context).cake_pay_web_cards_subtitle, subTitle: S.of(context).cake_pay_subtitle,
svgPicture: SvgPicture.asset( svgPicture: SvgPicture.asset(
'assets/images/cards.svg', 'assets/images/cards.svg',
height: 125, height: 125,
@ -88,6 +80,28 @@ class CakeFeaturesPage extends StatelessWidget {
Uri.https(url), Uri.https(url),
mode: LaunchMode.externalApplication, mode: LaunchMode.externalApplication,
); );
} catch (_) {} } catch (e) {
print(e);
}
}
void _navigatorToGiftCardsPage(BuildContext context) {
final walletType = dashboardViewModel.type;
switch (walletType) {
case WalletType.haven:
showPopUp<void>(
context: context,
builder: (BuildContext context) {
return AlertWithOneAction(
alertTitle: S.of(context).error,
alertContent: S.of(context).gift_cards_unavailable,
buttonText: S.of(context).ok,
buttonAction: () => Navigator.of(context).pop());
});
break;
default:
Navigator.pushNamed(context, Routes.cakePayCardsPage);
}
} }
} }

View file

@ -3,18 +3,21 @@ import 'package:cake_wallet/src/screens/dashboard/widgets/filter_tile.dart';
import 'package:cake_wallet/src/widgets/section_divider.dart'; import 'package:cake_wallet/src/widgets/section_divider.dart';
import 'package:cake_wallet/src/widgets/standard_checkbox.dart'; import 'package:cake_wallet/src/widgets/standard_checkbox.dart';
import 'package:cake_wallet/themes/extensions/menu_theme.dart'; import 'package:cake_wallet/themes/extensions/menu_theme.dart';
import 'package:cake_wallet/view_model/dashboard/dashboard_view_model.dart'; import 'package:cake_wallet/view_model/dashboard/dropdown_filter_item.dart';
import 'package:cake_wallet/view_model/dashboard/dropdown_filter_item_widget.dart';
import 'package:cake_wallet/view_model/dashboard/filter_item.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:cake_wallet/src/widgets/picker_wrapper_widget.dart'; import 'package:cake_wallet/src/widgets/picker_wrapper_widget.dart';
import 'package:cake_wallet/generated/i18n.dart'; import 'package:cake_wallet/generated/i18n.dart';
import 'package:flutter_mobx/flutter_mobx.dart'; import 'package:flutter_mobx/flutter_mobx.dart';
//import 'package:date_range_picker/date_range_picker.dart' as date_rage_picker; //import 'package:date_range_picker/date_range_picker.dart' as date_rage_picker;
import 'package:cake_wallet/themes/extensions/transaction_trade_theme.dart'; import 'package:cake_wallet/themes/extensions/transaction_trade_theme.dart';
class FilterWidget extends StatelessWidget { class FilterWidget extends StatelessWidget {
FilterWidget({required this.dashboardViewModel}); FilterWidget({required this.filterItems});
final DashboardViewModel dashboardViewModel; final Map<String, List<FilterItem>> filterItems;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -27,75 +30,90 @@ class FilterWidget extends StatelessWidget {
borderRadius: BorderRadius.all(Radius.circular(24)), borderRadius: BorderRadius.all(Radius.circular(24)),
child: Container( child: Container(
color: Theme.of(context).extension<CakeMenuTheme>()!.backgroundColor, color: Theme.of(context).extension<CakeMenuTheme>()!.backgroundColor,
child: Column( child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
crossAxisAlignment: CrossAxisAlignment.start, Padding(
children: [ padding: EdgeInsets.all(24.0),
Padding( child: Text(
padding: EdgeInsets.all(24.0), S.of(context).filter_by,
child: Text( style: TextStyle(
S.of(context).filter_by, color:
style: TextStyle( Theme.of(context).extension<TransactionTradeTheme>()!.detailsTitlesColor,
color: Theme.of(context).extension<TransactionTradeTheme>()!.detailsTitlesColor, fontSize: 16,
fontSize: 16, fontFamily: 'Lato',
fontFamily: 'Lato', decoration: TextDecoration.none,
decoration: TextDecoration.none, ),
),
),
sectionDivider,
ListView.separated(
padding: EdgeInsets.zero,
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
itemCount: filterItems.length,
separatorBuilder: (context, _) => sectionDivider,
itemBuilder: (_, index1) {
final title = filterItems.keys.elementAt(index1);
final section = filterItems.values.elementAt(index1);
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Padding(
padding: EdgeInsets.only(top: 20, left: 24, right: 24),
child: Text(
title,
style: TextStyle(
color: Theme.of(context).extension<CakeTextTheme>()!.titleColor,
fontSize: 16,
fontFamily: 'Lato',
fontWeight: FontWeight.bold,
decoration: TextDecoration.none),
),
), ),
), ListView.builder(
), padding: EdgeInsets.symmetric(horizontal: 28.0),
sectionDivider, shrinkWrap: true,
ListView.separated( physics: const NeverScrollableScrollPhysics(),
padding: EdgeInsets.zero, itemCount: section.length,
shrinkWrap: true, itemBuilder: (_, index2) {
physics: const NeverScrollableScrollPhysics(), final item = section[index2];
itemCount: dashboardViewModel.filterItems.length,
separatorBuilder: (context, _) => sectionDivider, if (item is DropdownFilterItem) {
itemBuilder: (_, index1) { return Padding(
final title = dashboardViewModel.filterItems.keys padding: EdgeInsets.fromLTRB(8, 0, 8, 16),
.elementAt(index1); child: Container(
final section = dashboardViewModel.filterItems.values decoration: BoxDecoration(
.elementAt(index1); border: Border(
return Column( bottom: BorderSide(
crossAxisAlignment: CrossAxisAlignment.start, width: 1.0,
children: <Widget>[ color: Theme.of(context).extension<CakeTextTheme>()!.secondaryTextColor),
Padding( ),
padding: ),
EdgeInsets.only(top: 20, left: 24, right: 24), child: DropdownFilterList(
child: Text( items: item.items,
title, caption: item.caption,
style: TextStyle( selectedItem: item.selectedItem,
color: Theme.of(context).extension<CakeTextTheme>()!.titleColor, onItemSelected: item.onItemSelected,
fontSize: 16, ),
fontFamily: 'Lato', ),
fontWeight: FontWeight.bold, );
decoration: TextDecoration.none), }
), final content = Observer(
), builder: (_) => StandardCheckbox(
ListView.builder( value: item.value(),
padding: EdgeInsets.symmetric(vertical: 8.0), caption: item.caption,
shrinkWrap: true, gradientBackground: true,
physics: const NeverScrollableScrollPhysics(), borderColor: Theme.of(context).dividerColor,
itemCount: section.length, iconColor: Colors.white,
itemBuilder: (_, index2) { onChanged: (value) => item.onChanged(),
final item = section[index2]; ));
final content = Observer( return FilterTile(child: content);
builder: (_) => StandardCheckbox( },
value: item.value(), )
caption: item.caption, ],
gradientBackground: true, );
borderColor: },
Theme.of(context).dividerColor, ),
iconColor: Colors.white, ]),
onChanged: (value) =>
item.onChanged(),
));
return FilterTile(child: content);
},
)
],
);
},
),
]),
), ),
), ),
) )

View file

@ -37,7 +37,7 @@ class HeaderRow extends StatelessWidget {
onTap: () { onTap: () {
showPopUp<void>( showPopUp<void>(
context: context, context: context,
builder: (context) => FilterWidget(dashboardViewModel: dashboardViewModel), builder: (context) => FilterWidget(filterItems: dashboardViewModel.filterItems),
); );
}, },
child: Semantics( child: Semantics(

View file

@ -1,6 +1,6 @@
import 'package:cake_wallet/src/widgets/alert_close_button.dart'; import 'package:cake_wallet/src/widgets/alert_close_button.dart';
import 'package:cake_wallet/themes/extensions/cake_text_theme.dart'; import 'package:cake_wallet/themes/extensions/cake_text_theme.dart';
import 'package:cake_wallet/src/screens/ionia/widgets/rounded_checkbox.dart'; import 'package:cake_wallet/src/screens/cake_pay/widgets/rounded_checkbox.dart';
import 'package:cake_wallet/src/widgets/alert_background.dart'; import 'package:cake_wallet/src/widgets/alert_background.dart';
import 'package:cake_wallet/typography.dart'; import 'package:cake_wallet/typography.dart';
import 'package:cake_wallet/utils/show_pop_up.dart'; import 'package:cake_wallet/utils/show_pop_up.dart';

View file

@ -1,159 +0,0 @@
import 'package:cake_wallet/themes/extensions/cake_text_theme.dart';
import 'package:cake_wallet/core/email_validator.dart';
import 'package:cake_wallet/ionia/ionia_create_state.dart';
import 'package:cake_wallet/routes.dart';
import 'package:cake_wallet/src/screens/base_page.dart';
import 'package:cake_wallet/src/widgets/alert_with_one_action.dart';
import 'package:cake_wallet/src/widgets/base_text_form_field.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/typography.dart';
import 'package:cake_wallet/utils/show_pop_up.dart';
import 'package:cake_wallet/view_model/ionia/ionia_auth_view_model.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:cake_wallet/generated/i18n.dart';
import 'package:flutter_mobx/flutter_mobx.dart';
import 'package:mobx/mobx.dart';
import 'package:url_launcher/url_launcher.dart';
class IoniaCreateAccountPage extends BasePage {
IoniaCreateAccountPage(this._authViewModel)
: _emailFocus = FocusNode(),
_emailController = TextEditingController(),
_formKey = GlobalKey<FormState>() {
_emailController.text = _authViewModel.email;
_emailController.addListener(() => _authViewModel.email = _emailController.text);
}
final IoniaAuthViewModel _authViewModel;
final GlobalKey<FormState> _formKey;
final FocusNode _emailFocus;
final TextEditingController _emailController;
static const privacyPolicyUrl = 'https://ionia.docsend.com/view/jhjvdn7qq7k3ukwt';
static const termsAndConditionsUrl = 'https://ionia.docsend.com/view/uceirymz2ijacq5g';
@override
Widget middle(BuildContext context) {
return Text(
S.current.sign_up,
style: textMediumSemiBold(
color: Theme.of(context).extension<CakeTextTheme>()!.titleColor,
),
);
}
@override
Widget body(BuildContext context) {
reaction((_) => _authViewModel.createUserState, (IoniaCreateAccountState state) {
if (state is IoniaCreateStateFailure) {
_onCreateUserFailure(context, state.error);
}
if (state is IoniaCreateStateSuccess) {
_onCreateSuccessful(context, _authViewModel);
}
});
return ScrollableWithBottomSection(
contentPadding: EdgeInsets.all(24),
content: Form(
key: _formKey,
child: BaseTextFormField(
hintText: S.of(context).email_address,
focusNode: _emailFocus,
validator: EmailValidator(),
keyboardType: TextInputType.emailAddress,
controller: _emailController,
onSubmit: (_) => _createAccount(),
),
),
bottomSectionPadding: EdgeInsets.symmetric(vertical: 36, horizontal: 24),
bottomSection: Column(
children: [
Column(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
Observer(
builder: (_) => LoadingPrimaryButton(
text: S.of(context).create_account,
onPressed: _createAccount,
isLoading:
_authViewModel.createUserState is IoniaCreateStateLoading,
color: Theme.of(context).primaryColor,
textColor: Colors.white,
),
),
SizedBox(
height: 20,
),
RichText(
textAlign: TextAlign.center,
text: TextSpan(
text: S.of(context).agree_to,
style: TextStyle(
color: Color(0xff7A93BA),
fontSize: 12,
fontFamily: 'Lato',
),
children: [
TextSpan(
text: S.of(context).settings_terms_and_conditions,
style: TextStyle(
color: Theme.of(context).primaryColor,
fontWeight: FontWeight.w700,
),
recognizer: TapGestureRecognizer()
..onTap = () async {
if (await canLaunch(termsAndConditionsUrl)) await launch(termsAndConditionsUrl);
},
),
TextSpan(text: ' ${S.of(context).and} '),
TextSpan(
text: S.of(context).privacy_policy,
style: TextStyle(
color: Theme.of(context).primaryColor,
fontWeight: FontWeight.w700,
),
recognizer: TapGestureRecognizer()
..onTap = () async {
if (await canLaunch(privacyPolicyUrl)) await launch(privacyPolicyUrl);
}),
TextSpan(text: ' ${S.of(context).by_cake_pay}'),
],
),
),
],
),
],
),
);
}
void _onCreateUserFailure(BuildContext context, String error) {
showPopUp<void>(
context: context,
builder: (BuildContext context) {
return AlertWithOneAction(
alertTitle: S.current.create_account,
alertContent: error,
buttonText: S.of(context).ok,
buttonAction: () => Navigator.of(context).pop());
});
}
void _onCreateSuccessful(BuildContext context, IoniaAuthViewModel authViewModel) => Navigator.pushNamed(
context,
Routes.ioniaVerifyIoniaOtpPage,
arguments: [authViewModel.email, false],
);
void _createAccount() async {
if (_formKey.currentState != null && !_formKey.currentState!.validate()) {
return;
}
await _authViewModel.createUser(_emailController.text);
}
}

View file

@ -1,95 +0,0 @@
import 'package:cake_wallet/themes/extensions/cake_text_theme.dart';
import 'package:cake_wallet/palette.dart';
import 'package:cake_wallet/routes.dart';
import 'package:cake_wallet/src/screens/base_page.dart';
import 'package:cake_wallet/src/widgets/primary_button.dart';
import 'package:cake_wallet/typography.dart';
import 'package:flutter/material.dart';
import 'package:cake_wallet/generated/i18n.dart';
class IoniaWelcomePage extends BasePage {
IoniaWelcomePage();
@override
Widget middle(BuildContext context) {
return Text(
S.current.welcome_to_cakepay,
style: textMediumSemiBold(
color: Theme.of(context).extension<CakeTextTheme>()!.titleColor,
),
);
}
@override
Widget body(BuildContext context) {
return Padding(
padding: const EdgeInsets.all(24.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Column(
children: [
SizedBox(height: 90),
Text(
S.of(context).about_cake_pay,
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.w400,
fontFamily: 'Lato',
color: Theme.of(context).extension<CakeTextTheme>()!.titleColor,
),
),
SizedBox(height: 20),
Text(
S.of(context).cake_pay_account_note,
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.w400,
fontFamily: 'Lato',
color: Theme.of(context).extension<CakeTextTheme>()!.titleColor,
),
),
],
),
Column(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
PrimaryButton(
text: S.of(context).create_account,
onPressed: () => Navigator.of(context).pushNamed(Routes.ioniaCreateAccountPage),
color: Theme.of(context).primaryColor,
textColor: Colors.white,
),
SizedBox(
height: 16,
),
Text(
S.of(context).already_have_account,
style: TextStyle(
fontSize: 15,
fontWeight: FontWeight.w500,
fontFamily: 'Lato',
color: Theme.of(context).extension<CakeTextTheme>()!.titleColor,
),
),
SizedBox(height: 8),
InkWell(
onTap: () => Navigator.of(context).pushNamed(Routes.ioniaLoginPage),
child: Text(
S.of(context).login,
style: TextStyle(
color: Palette.blueCraiola,
fontSize: 18,
letterSpacing: 1.5,
fontWeight: FontWeight.w900,
),
),
),
SizedBox(height: 20)
],
)
],
),
);
}
}

View file

@ -1,204 +0,0 @@
import 'package:cake_wallet/themes/extensions/cake_text_theme.dart';
import 'package:cake_wallet/ionia/ionia_create_state.dart';
import 'package:cake_wallet/ionia/ionia_gift_card.dart';
import 'package:cake_wallet/routes.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/themes/extensions/exchange_page_theme.dart';
import 'package:cake_wallet/themes/extensions/order_theme.dart';
import 'package:cake_wallet/typography.dart';
import 'package:cake_wallet/view_model/ionia/ionia_account_view_model.dart';
import 'package:flutter/material.dart';
import 'package:cake_wallet/generated/i18n.dart';
import 'package:flutter_mobx/flutter_mobx.dart';
import 'package:cake_wallet/themes/extensions/dashboard_page_theme.dart';
import 'package:cake_wallet/themes/extensions/transaction_trade_theme.dart';
class IoniaAccountCardsPage extends BasePage {
IoniaAccountCardsPage(this.ioniaAccountViewModel);
final IoniaAccountViewModel ioniaAccountViewModel;
@override
Widget middle(BuildContext context) {
return Text(
S.of(context).cards,
style: textLargeSemiBold(
color: Theme.of(context).extension<CakeTextTheme>()!.titleColor,
),
);
}
@override
Widget body(BuildContext context) {
return _IoniaCardTabs(ioniaAccountViewModel);
}
}
class _IoniaCardTabs extends StatefulWidget {
_IoniaCardTabs(this.ioniaAccountViewModel);
final IoniaAccountViewModel ioniaAccountViewModel;
@override
_IoniaCardTabsState createState() => _IoniaCardTabsState();
}
class _IoniaCardTabsState extends State<_IoniaCardTabs> with SingleTickerProviderStateMixin {
_IoniaCardTabsState();
TabController? _tabController;
@override
void initState() {
_tabController = TabController(length: 2, vsync: this);
super.initState();
}
@override
void dispose() {
super.dispose();
_tabController?.dispose();
}
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.all(24.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
height: 45,
width: 230,
padding: EdgeInsets.all(5),
decoration: BoxDecoration(
color: Theme.of(context).extension<CakeTextTheme>()!.titleColor
.withOpacity(0.1),
borderRadius: BorderRadius.circular(
25.0,
),
),
child: Theme(
data: ThemeData(primaryTextTheme: TextTheme(bodyLarge: TextStyle(backgroundColor: Colors.transparent))),
child: TabBar(
controller: _tabController,
indicator: BoxDecoration(
borderRadius: BorderRadius.circular(
25.0,
),
color: Theme.of(context).primaryColor,
),
labelColor: Theme.of(context).extension<OrderTheme>()!.iconColor,
unselectedLabelColor:
Theme.of(context).extension<CakeTextTheme>()!.titleColor,
tabs: [
Tab(
text: S.of(context).active,
),
Tab(
text: S.of(context).redeemed,
),
],
),
),
),
SizedBox(height: 16),
Expanded(
child: Observer(builder: (_) {
final viewModel = widget.ioniaAccountViewModel;
return TabBarView(
controller: _tabController,
children: [
_IoniaCardListView(
emptyText: S.of(context).gift_card_balance_note,
merchList: viewModel.activeMechs,
isLoading: viewModel.merchantState is IoniaLoadingMerchantState,
onTap: (giftCard) {
Navigator.pushNamed(
context,
Routes.ioniaGiftCardDetailPage,
arguments: [giftCard])
.then((_) => viewModel.updateUserGiftCards());
}),
_IoniaCardListView(
emptyText: S.of(context).gift_card_redeemed_note,
merchList: viewModel.redeemedMerchs,
isLoading: viewModel.merchantState is IoniaLoadingMerchantState,
onTap: (giftCard) {
Navigator.pushNamed(
context,
Routes.ioniaGiftCardDetailPage,
arguments: [giftCard])
.then((_) => viewModel.updateUserGiftCards());
}),
],
);
}),
),
],
),
);
}
}
class _IoniaCardListView extends StatelessWidget {
_IoniaCardListView({
Key? key,
required this.emptyText,
required this.merchList,
required this.onTap,
this.isLoading = false,
}) : super(key: key);
final String emptyText;
final List<IoniaGiftCard> merchList;
final void Function(IoniaGiftCard giftCard) onTap;
final bool isLoading;
@override
Widget build(BuildContext context) {
if(isLoading){
return Center(
child: CircularProgressIndicator(
backgroundColor: Theme.of(context).extension<DashboardPageTheme>()!.textColor,
valueColor: AlwaysStoppedAnimation<Color>(
Theme.of(context).extension<ExchangePageTheme>()!.firstGradientBottomPanelColor),
),
);
}
return merchList.isEmpty
? Center(
child: Text(
emptyText,
textAlign: TextAlign.center,
style: textSmall(
color: Theme.of(context).extension<TransactionTradeTheme>()!.detailsTitlesColor,
),
),
)
: ListView.builder(
itemCount: merchList.length,
itemBuilder: (context, index) {
final merchant = merchList[index];
return Padding(
padding: const EdgeInsets.only(bottom: 16),
child: CardItem(
onTap: () => onTap?.call(merchant),
title: merchant.legalName,
backgroundColor: Theme.of(context).extension<CakeTextTheme>()!.titleColor
.withOpacity(0.1),
discount: 0,
hideBorder: true,
discountBackground: AssetImage('assets/images/red_badge_discount.png'),
titleColor: Theme.of(context).extension<CakeTextTheme>()!.titleColor,
subtitleColor: Theme.of(context).hintColor,
subTitle: '',
logoUrl: merchant.logoUrl,
),
);
},
);
}
}

View file

@ -1,178 +0,0 @@
import 'package:cake_wallet/themes/extensions/cake_text_theme.dart';
import 'package:cake_wallet/routes.dart';
import 'package:cake_wallet/src/screens/base_page.dart';
import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/src/screens/ionia/widgets/ionia_tile.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/typography.dart';
import 'package:cake_wallet/view_model/ionia/ionia_account_view_model.dart';
import 'package:flutter/material.dart';
import 'package:flutter_mobx/flutter_mobx.dart';
import 'package:cake_wallet/themes/extensions/send_page_theme.dart';
class IoniaAccountPage extends BasePage {
IoniaAccountPage(this.ioniaAccountViewModel);
final IoniaAccountViewModel ioniaAccountViewModel;
@override
Widget middle(BuildContext context) {
return Text(
S.current.account,
style: textMediumSemiBold(
color: Theme.of(context).extension<CakeTextTheme>()!.titleColor,
),
);
}
@override
Widget body(BuildContext context) {
return ScrollableWithBottomSection(
contentPadding: EdgeInsets.all(24),
content: Column(
children: [
_GradiantContainer(
content: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Observer(
builder: (_) => RichText(
text: TextSpan(
text: '${ioniaAccountViewModel.countOfMerch}',
style: textLargeSemiBold(),
children: [
TextSpan(
text: ' ${S.of(context).active_cards}',
style: textSmall(color: Colors.white.withOpacity(0.7))),
],
),
)),
InkWell(
onTap: () {
Navigator.pushNamed(context, Routes.ioniaAccountCardsPage)
.then((_) => ioniaAccountViewModel.updateUserGiftCards());
},
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
S.of(context).view_all,
style: textSmallSemiBold(),
),
),
)
],
),
),
SizedBox(height: 8),
//Row(
// mainAxisAlignment: MainAxisAlignment.spaceBetween,
// children: [
// _GradiantContainer(
// padding: EdgeInsets.all(16),
// width: deviceWidth * 0.28,
// content: Column(
// crossAxisAlignment: CrossAxisAlignment.start,
// children: [
// Text(
// S.of(context).total_saving,
// style: textSmall(),
// ),
// SizedBox(height: 8),
// Text(
// '\$100',
// style: textMediumSemiBold(),
// ),
// ],
// ),
// ),
// _GradiantContainer(
// padding: EdgeInsets.all(16),
// width: deviceWidth * 0.28,
// content: Column(
// crossAxisAlignment: CrossAxisAlignment.start,
// children: [
// Text(
// S.of(context).last_30_days,
// style: textSmall(),
// ),
// SizedBox(height: 8),
// Text(
// '\$100',
// style: textMediumSemiBold(),
// ),
// ],
// ),
// ),
// _GradiantContainer(
// padding: EdgeInsets.all(16),
// width: deviceWidth * 0.28,
// content: Column(
// crossAxisAlignment: CrossAxisAlignment.start,
// children: [
// Text(
// S.of(context).avg_savings,
// style: textSmall(),
// ),
// SizedBox(height: 8),
// Text(
// '10%',
// style: textMediumSemiBold(),
// ),
// ],
// ),
// ),
// ],
//),
SizedBox(height: 40),
Observer(
builder: (_) => IoniaTile(title: S.of(context).email_address, subTitle: ioniaAccountViewModel.email ?? ''),
),
Divider()
],
),
bottomSectionPadding: EdgeInsets.all(30),
bottomSection: Column(
children: [
PrimaryButton(
color: Theme.of(context).primaryColor,
textColor: Colors.white,
text: S.of(context).logout,
onPressed: () {
ioniaAccountViewModel.logout();
Navigator.pushNamedAndRemoveUntil(context, Routes.dashboard, (route) => false);
},
),
],
),
);
}
}
class _GradiantContainer extends StatelessWidget {
const _GradiantContainer({
Key? key,
required this.content,
}) : super(key: key);
final Widget content;
@override
Widget build(BuildContext context) {
return Container(
child: content,
padding: EdgeInsets.all(24),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(15),
gradient: LinearGradient(
colors: [
Theme.of(context).extension<SendPageTheme>()!.secondGradientColor,
Theme.of(context).extension<SendPageTheme>()!.firstGradientColor,
],
begin: Alignment.topRight,
end: Alignment.bottomLeft,
),
),
);
}
}

View file

@ -1,115 +0,0 @@
import 'package:cake_wallet/themes/extensions/cake_text_theme.dart';
import 'package:cake_wallet/ionia/ionia_create_state.dart';
import 'package:cake_wallet/routes.dart';
import 'package:cake_wallet/src/screens/base_page.dart';
import 'package:cake_wallet/src/screens/ionia/widgets/text_icon_button.dart';
import 'package:cake_wallet/src/widgets/alert_with_one_action.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/typography.dart';
import 'package:cake_wallet/utils/show_pop_up.dart';
import 'package:cake_wallet/view_model/ionia/ionia_gift_cards_list_view_model.dart';
import 'package:flutter/material.dart';
import 'package:cake_wallet/generated/i18n.dart';
import 'package:mobx/mobx.dart';
class IoniaActivateDebitCardPage extends BasePage {
IoniaActivateDebitCardPage(this._cardsListViewModel);
final IoniaGiftCardsListViewModel _cardsListViewModel;
@override
Widget middle(BuildContext context) {
return Text(
S.current.debit_card,
style: textMediumSemiBold(
color: Theme.of(context).extension<CakeTextTheme>()!.titleColor,
),
);
}
@override
Widget body(BuildContext context) {
reaction((_) => _cardsListViewModel.createCardState, (IoniaCreateCardState state) {
if (state is IoniaCreateCardFailure) {
_onCreateCardFailure(context, state.error);
}
if (state is IoniaCreateCardSuccess) {
_onCreateCardSuccess(context);
}
});
return ScrollableWithBottomSection(
contentPadding: EdgeInsets.zero,
content: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
children: [
SizedBox(height: 16),
Text(S.of(context).debit_card_terms),
SizedBox(height: 24),
Text(S.of(context).please_reference_document),
SizedBox(height: 40),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 8.0),
child: Column(
children: [
TextIconButton(
label: S.current.cardholder_agreement,
onTap: () {},
),
SizedBox(
height: 24,
),
TextIconButton(
label: S.current.e_sign_consent,
onTap: () {},
),
],
),
),
],
),
),
bottomSection: LoadingPrimaryButton(
onPressed: () {
_cardsListViewModel.createCard();
},
isLoading: _cardsListViewModel.createCardState is IoniaCreateCardLoading,
text: S.of(context).agree_and_continue,
color: Theme.of(context).primaryColor,
textColor: Colors.white,
),
);
}
void _onCreateCardFailure(BuildContext context, String errorMessage) {
showPopUp<void>(
context: context,
builder: (BuildContext context) {
return AlertWithOneAction(
alertTitle: S.current.error,
alertContent: errorMessage,
buttonText: S.of(context).ok,
buttonAction: () => Navigator.of(context).pop());
});
}
void _onCreateCardSuccess(BuildContext context) {
Navigator.pushNamed(
context,
Routes.ioniaDebitCardPage,
);
showPopUp<void>(
context: context,
builder: (BuildContext context) {
return AlertWithOneAction(
alertTitle: S.of(context).congratulations,
alertContent: S.of(context).you_now_have_debit_card,
buttonText: S.of(context).ok,
buttonAction: () => Navigator.of(context).pop(),
);
},
);
}
}

View file

@ -1,478 +0,0 @@
import 'package:cake_wallet/core/execution_state.dart';
import 'package:cake_wallet/themes/extensions/receive_page_theme.dart';
import 'package:cake_wallet/themes/extensions/cake_text_theme.dart';
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/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';
import 'package:cake_wallet/src/widgets/discount_badge.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/themes/extensions/exchange_page_theme.dart';
import 'package:cake_wallet/typography.dart';
import 'package:cake_wallet/utils/show_pop_up.dart';
import 'package:cake_wallet/view_model/ionia/ionia_purchase_merch_view_model.dart';
import 'package:flutter/material.dart';
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';
import 'package:cake_wallet/themes/extensions/send_page_theme.dart';
import 'package:cake_wallet/themes/extensions/transaction_trade_theme.dart';
class IoniaBuyGiftCardDetailPage extends BasePage {
IoniaBuyGiftCardDetailPage(this.ioniaPurchaseViewModel);
final IoniaMerchPurchaseViewModel ioniaPurchaseViewModel;
@override
Widget middle(BuildContext context) {
return Text(
ioniaPurchaseViewModel.ioniaMerchant.legalName,
style: textMediumSemiBold(color: Theme.of(context).extension<CakeTextTheme>()!.titleColor),
);
}
@override
Widget? trailing(BuildContext context)
=> ioniaPurchaseViewModel.ioniaMerchant.discount > 0
? DiscountBadge(percentage: ioniaPurchaseViewModel.ioniaMerchant.discount)
: null;
@override
Widget body(BuildContext context) {
reaction((_) => ioniaPurchaseViewModel.invoiceCreationState, (ExecutionState state) {
if (state is FailureState) {
WidgetsBinding.instance.addPostFrameCallback((_) {
showPopUp<void>(
context: context,
builder: (BuildContext context) {
return AlertWithOneAction(
alertTitle: S.of(context).error,
alertContent: state.error,
buttonText: S.of(context).ok,
buttonAction: () => Navigator.of(context).pop());
});
});
}
});
reaction((_) => ioniaPurchaseViewModel.invoiceCommittingState, (ExecutionState state) {
if (state is FailureState) {
WidgetsBinding.instance.addPostFrameCallback((_) {
showPopUp<void>(
context: context,
builder: (BuildContext context) {
return AlertWithOneAction(
alertTitle: S.of(context).error,
alertContent: state.error,
buttonText: S.of(context).ok,
buttonAction: () => Navigator.of(context).pop());
});
});
}
if (state is ExecutedSuccessfullyState) {
WidgetsBinding.instance.addPostFrameCallback((_) {
Navigator.of(context).pushReplacementNamed(
Routes.ioniaPaymentStatusPage,
arguments: [
ioniaPurchaseViewModel.paymentInfo,
ioniaPurchaseViewModel.committedInfo]);
});
}
});
return ScrollableWithBottomSection(
contentPadding: EdgeInsets.zero,
content: Observer(builder: (_) {
final tipAmount = ioniaPurchaseViewModel.tipAmount;
return Column(
children: [
SizedBox(height: 36),
Container(
padding: EdgeInsets.symmetric(vertical: 24),
margin: EdgeInsets.symmetric(horizontal: 16),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20),
gradient: LinearGradient(
colors: [
Theme.of(context).extension<SendPageTheme>()!.firstGradientColor,
Theme.of(context).extension<SendPageTheme>()!.secondGradientColor,
],
begin: Alignment.topLeft,
end: Alignment.bottomRight,
),
),
child: Column(
children: [
Text(
S.of(context).gift_card_amount,
style: textSmall(),
),
SizedBox(height: 4),
Text(
'\$${ioniaPurchaseViewModel.giftCardAmount.toStringAsFixed(2)}',
style: textXLargeSemiBold(),
),
SizedBox(height: 24),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 24.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
S.of(context).bill_amount,
style: textSmall(),
),
SizedBox(height: 4),
Text(
'\$${ioniaPurchaseViewModel.billAmount.toStringAsFixed(2)}',
style: textLargeSemiBold(),
),
],
),
Column(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
Text(
S.of(context).tip,
style: textSmall(),
),
SizedBox(height: 4),
Text(
'\$${tipAmount.toStringAsFixed(2)}',
style: textLargeSemiBold(),
),
],
),
],
),
),
],
),
),
if(ioniaPurchaseViewModel.ioniaMerchant.acceptsTips)
Padding(
padding: const EdgeInsets.fromLTRB(24.0, 24.0, 0, 24.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
S.of(context).tip,
style: TextStyle(
color: Theme.of(context).extension<CakeTextTheme>()!.titleColor,
fontWeight: FontWeight.w700,
fontSize: 14,
),
),
SizedBox(height: 4),
Observer(
builder: (_) => TipButtonGroup(
selectedTip: ioniaPurchaseViewModel.selectedTip!.percentage,
tipsList: ioniaPurchaseViewModel.tips,
onSelect: (value) => ioniaPurchaseViewModel.addTip(value),
amount: ioniaPurchaseViewModel.amount,
merchant: ioniaPurchaseViewModel.ioniaMerchant,
),
)
],
),
),
SizedBox(height: 20),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 24.0),
child: TextIconButton(
label: S.of(context).how_to_use_card,
onTap: () => _showHowToUseCard(context, ioniaPurchaseViewModel.ioniaMerchant),
),
),
],
);
}),
bottomSection: Column(
children: [
Padding(
padding: EdgeInsets.only(bottom: 12),
child: Observer(builder: (_) {
return LoadingPrimaryButton(
isLoading: ioniaPurchaseViewModel.invoiceCreationState is IsExecutingState ||
ioniaPurchaseViewModel.invoiceCommittingState is IsExecutingState,
onPressed: () => purchaseCard(context),
text: S.of(context).purchase_gift_card,
color: Theme.of(context).primaryColor,
textColor: Colors.white,
);
}),
),
SizedBox(height: 8),
InkWell(
onTap: () => _showTermsAndCondition(context),
child: Text(S.of(context).settings_terms_and_conditions,
style: textMediumSemiBold(
color: Theme.of(context).extension<ExchangePageTheme>()!.firstGradientBottomPanelColor,
).copyWith(fontSize: 12)),
),
SizedBox(height: 16)
],
),
);
}
void _showTermsAndCondition(BuildContext context) {
showPopUp<void>(
context: context,
builder: (BuildContext context) {
return IoniaAlertModal(
title: S.of(context).settings_terms_and_conditions,
content: Align(
alignment: Alignment.bottomLeft,
child: Text(
ioniaPurchaseViewModel.ioniaMerchant.termsAndConditions,
style: textMedium(
color: Theme.of(context).extension<ReceivePageTheme>()!.tilesTextColor,
),
),
),
actionTitle: S.of(context).agree,
showCloseButton: false,
heightFactor: 0.6,
);
});
}
Future<void> purchaseCard(BuildContext context) async {
await ioniaPurchaseViewModel.createInvoice();
if (ioniaPurchaseViewModel.invoiceCreationState is ExecutedSuccessfullyState) {
await _presentSuccessfulInvoiceCreationPopup(context);
}
}
void _showHowToUseCard(
BuildContext context,
IoniaMerchant merchant,
) {
showPopUp<void>(
context: context,
builder: (BuildContext context) {
return IoniaAlertModal(
title: S.of(context).how_to_use_card,
content: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: merchant.instructions
.map((instruction) {
return [
Padding(
padding: EdgeInsets.all(10),
child: Text(
instruction.header,
style: textLargeSemiBold(
color: Theme.of(context).extension<ReceivePageTheme>()!.tilesTextColor,
),
)),
Text(
instruction.body,
style: textMedium(
color: Theme.of(context).extension<ReceivePageTheme>()!.tilesTextColor,
),
)
];
})
.expand((e) => e)
.toList()),
actionTitle: S.current.got_it,
);
});
}
Future<void> _presentSuccessfulInvoiceCreationPopup(BuildContext context) async {
if (ioniaPurchaseViewModel.invoice == null) {
return;
}
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<void>(
context: context,
builder: (_) {
return ConfirmSendingAlert(
alertTitle: S.of(context).confirm_sending,
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,
alertLeftActionButtonTextColor: Colors.white,
alertRightActionButtonTextColor: Colors.white,
alertLeftActionButtonColor: Palette.brightOrange,
alertRightActionButtonColor: Theme.of(context).primaryColor,
actionRightButton: () async {
Navigator.of(context).pop();
await ioniaPurchaseViewModel.commitPaymentInvoice();
},
actionLeftButton: () => Navigator.of(context).pop());
},
);
}
}
class TipButtonGroup extends StatelessWidget {
const TipButtonGroup({
Key? key,
required this.selectedTip,
required this.onSelect,
required this.tipsList,
required this.amount,
required this.merchant,
}) : super(key: key);
final Function(IoniaTip) onSelect;
final double selectedTip;
final List<IoniaTip> tipsList;
final double amount;
final IoniaMerchant merchant;
bool _isSelected(double value) => selectedTip == value;
Set<double> get filter => tipsList.map((e) => e.percentage).toSet();
bool get _isCustomSelected => !filter.contains(selectedTip);
@override
Widget build(BuildContext context) {
return Container(
height: 50,
child: ListView.builder(
scrollDirection: Axis.horizontal,
itemCount: tipsList.length,
itemBuilder: (BuildContext context, int index) {
final tip = tipsList[index];
return Padding(
padding: EdgeInsets.only(right: 5),
child: TipButton(
isSelected: tip.isCustom ? _isCustomSelected : _isSelected(tip.percentage),
onTap: () async {
IoniaTip ioniaTip = tip;
if(tip.isCustom){
final customTip = await Navigator.pushNamed(context, Routes.ioniaCustomTipPage, arguments: [amount, merchant, tip]) as IoniaTip?;
ioniaTip = customTip ?? tip;
}
onSelect(ioniaTip);
},
caption: tip.isCustom ? S.of(context).custom : '${tip.percentage.toStringAsFixed(0)}%',
subTitle: tip.isCustom ? null : '\$${tip.additionalAmount.toStringAsFixed(2)}',
));
}));
}
}
class TipButton extends StatelessWidget {
const TipButton({
required this.caption,
required this.onTap,
this.subTitle,
this.isSelected = false,
});
final String caption;
final String? subTitle;
final bool isSelected;
final void Function() onTap;
bool isDark(BuildContext context) => Theme.of(context).brightness == Brightness.dark;
Color captionTextColor(BuildContext context) {
if (isDark(context)) {
return Theme.of(context).extension<CakeTextTheme>()!.titleColor;
}
return isSelected
? Theme.of(context).dialogTheme.backgroundColor!
: Theme.of(context).extension<CakeTextTheme>()!.titleColor;
}
Color subTitleTextColor(BuildContext context) {
if (isDark(context)) {
return Theme.of(context).extension<CakeTextTheme>()!.titleColor;
}
return isSelected
? Theme.of(context).dialogTheme.backgroundColor!
: Theme.of(context).extension<TransactionTradeTheme>()!.detailsTitlesColor;
}
Color? backgroundColor(BuildContext context) {
if (isDark(context)) {
return isSelected
? null
: Theme.of(context).extension<CakeTextTheme>()!.titleColor.withOpacity(0.01);
}
return isSelected
? null
: Theme.of(context).extension<CakeTextTheme>()!.titleColor.withOpacity(0.1);
}
@override
Widget build(BuildContext context) {
return InkWell(
onTap: onTap,
child: Container(
height: 49,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(caption,
style: textSmallSemiBold(
color: captionTextColor(context))),
if (subTitle != null) ...[
SizedBox(height: 4),
Text(
subTitle!,
style: textXxSmallSemiBold(
color: subTitleTextColor(context),
),
),
]
],
),
padding: EdgeInsets.symmetric(horizontal: 18, vertical: 8),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
color: backgroundColor(context),
gradient: isSelected
? LinearGradient(
colors: [
Theme.of(context).extension<SendPageTheme>()!.firstGradientColor,
Theme.of(context).extension<SendPageTheme>()!.secondGradientColor,
],
begin: Alignment.topLeft,
end: Alignment.bottomRight,
)
: null,
),
),
);
}
}

View file

@ -1,186 +0,0 @@
import 'package:cake_wallet/themes/extensions/keyboard_theme.dart';
import 'package:cake_wallet/themes/extensions/cake_text_theme.dart';
import 'package:cake_wallet/routes.dart';
import 'package:cake_wallet/src/screens/base_page.dart';
import 'package:cake_wallet/src/screens/ionia/widgets/card_item.dart';
import 'package:cake_wallet/src/widgets/base_text_form_field.dart';
import 'package:cake_wallet/src/widgets/keyboard_done_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/themes/theme_base.dart';
import 'package:cake_wallet/utils/responsive_layout_util.dart';
import 'package:cake_wallet/view_model/ionia/ionia_buy_card_view_model.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_mobx/flutter_mobx.dart';
import 'package:keyboard_actions/keyboard_actions.dart';
import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/themes/extensions/send_page_theme.dart';
class IoniaBuyGiftCardPage extends BasePage {
IoniaBuyGiftCardPage(
this.ioniaBuyCardViewModel,
) : _amountFieldFocus = FocusNode(),
_amountController = TextEditingController() {
_amountController.addListener(() {
ioniaBuyCardViewModel.onAmountChanged(_amountController.text);
});
}
final IoniaBuyCardViewModel ioniaBuyCardViewModel;
@override
String get title => S.current.enter_amount;
@override
bool get extendBodyBehindAppBar => true;
@override
AppBarStyle get appBarStyle => AppBarStyle.transparent;
Color get textColor => currentTheme.type == ThemeType.dark ? Colors.white : Color(0xff393939);
final TextEditingController _amountController;
final FocusNode _amountFieldFocus;
@override
Widget body(BuildContext context) {
final merchant = ioniaBuyCardViewModel.ioniaMerchant;
return KeyboardActions(
disableScroll: true,
config: KeyboardActionsConfig(
keyboardActionsPlatform: KeyboardActionsPlatform.IOS,
keyboardBarColor: Theme.of(context).extension<KeyboardTheme>()!.keyboardBarColor,
nextFocus: false,
actions: [
KeyboardActionsItem(
focusNode: _amountFieldFocus,
toolbarButtons: [(_) => KeyboardDoneButton()],
),
]),
child: Container(
color: Theme.of(context).colorScheme.background,
child: ScrollableWithBottomSection(
contentPadding: EdgeInsets.zero,
content: Column(
children: [
Container(
padding: EdgeInsets.symmetric(horizontal: 25),
decoration: BoxDecoration(
borderRadius: BorderRadius.only(
bottomLeft: Radius.circular(24),
bottomRight: Radius.circular(24),
),
gradient: LinearGradient(colors: [
Theme.of(context).extension<SendPageTheme>()!.firstGradientColor,
Theme.of(context).extension<SendPageTheme>()!.secondGradientColor,
], begin: Alignment.topLeft, end: Alignment.bottomRight),
),
child: Column(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center,
children: [
SizedBox(height: 150),
SizedBox(
width: 200,
child: BaseTextFormField(
controller: _amountController,
focusNode: _amountFieldFocus,
keyboardType: TextInputType.numberWithOptions(signed: false, decimal: true),
inputFormatters: [
FilteringTextInputFormatter.deny(RegExp('[\-|\ ]')),
FilteringTextInputFormatter.allow(
RegExp(r'^\d+(\.|\,)?\d{0,2}'),
),
],
hintText: '1000',
placeholderTextStyle: TextStyle(
color: Theme.of(context).extension<SendPageTheme>()!.textFieldBorderColor,
fontWeight: FontWeight.w600,
fontSize: 36,
),
prefixIcon: Text(
'USD: ',
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.w600,
fontSize: 36,
),
),
textColor: Colors.white,
textStyle: TextStyle(
color: Colors.white,
fontSize: 36,
),
),
),
Divider(
color: Theme.of(context).extension<SendPageTheme>()!.textFieldBorderColor,
height: 1,
),
SizedBox(height: 8),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
S.of(context).min_amount(merchant.minimumCardPurchase.toStringAsFixed(2)),
style: TextStyle(
color: Theme.of(context).extension<SendPageTheme>()!.textFieldBorderColor,
),
),
Text(
S.of(context).max_amount(merchant.maximumCardPurchase.toStringAsFixed(2)),
style: TextStyle(
color: Theme.of(context).extension<SendPageTheme>()!.textFieldBorderColor,
),
),
],
),
SizedBox(height: 24),
],
),
),
Padding(
padding: const EdgeInsets.all(24.0),
child: CardItem(
title: merchant.legalName,
backgroundColor: Theme.of(context).extension<CakeTextTheme>()!.titleColor
.withOpacity(0.1),
discount: merchant.discount,
titleColor: Theme.of(context).extension<CakeTextTheme>()!.titleColor,
subtitleColor: Theme.of(context).hintColor,
subTitle: merchant.avaibilityStatus,
logoUrl: merchant.logoUrl,
),
)
],
),
bottomSection: Column(
children: [
Observer(builder: (_) {
return Padding(
padding: EdgeInsets.only(bottom: 12),
child: PrimaryButton(
onPressed: () => Navigator.of(context).pushNamed(
Routes.ioniaBuyGiftCardDetailPage,
arguments: [
ioniaBuyCardViewModel.amount,
ioniaBuyCardViewModel.ioniaMerchant,
],
),
text: S.of(context).continue_text,
isDisabled: !ioniaBuyCardViewModel.isEnablePurchase,
color: Theme.of(context).primaryColor,
textColor: Colors.white,
),
);
}),
SizedBox(height: 30),
],
),
),
),
);
}
}

View file

@ -1,175 +0,0 @@
import 'package:cake_wallet/themes/extensions/keyboard_theme.dart';
import 'package:cake_wallet/themes/extensions/cake_text_theme.dart';
import 'package:cake_wallet/core/execution_state.dart';
import 'package:cake_wallet/src/screens/base_page.dart';
import 'package:cake_wallet/src/screens/ionia/widgets/card_item.dart';
import 'package:cake_wallet/src/widgets/base_text_form_field.dart';
import 'package:cake_wallet/src/widgets/keyboard_done_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/themes/theme_base.dart';
import 'package:cake_wallet/view_model/ionia/ionia_custom_redeem_view_model.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_mobx/flutter_mobx.dart';
import 'package:keyboard_actions/keyboard_actions.dart';
import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/themes/extensions/send_page_theme.dart';
class IoniaCustomRedeemPage extends BasePage {
IoniaCustomRedeemPage(
this.ioniaCustomRedeemViewModel,
) : _amountFieldFocus = FocusNode(),
_amountController = TextEditingController() {
_amountController.addListener(() {
ioniaCustomRedeemViewModel.updateAmount(_amountController.text);
});
}
final IoniaCustomRedeemViewModel ioniaCustomRedeemViewModel;
@override
String get title => S.current.custom_redeem_amount;
@override
bool get extendBodyBehindAppBar => true;
@override
AppBarStyle get appBarStyle => AppBarStyle.transparent;
Color get textColor => currentTheme.type == ThemeType.dark ? Colors.white : Color(0xff393939);
final TextEditingController _amountController;
final FocusNode _amountFieldFocus;
@override
Widget body(BuildContext context) {
final _width = MediaQuery.of(context).size.width;
final giftCard = ioniaCustomRedeemViewModel.giftCard;
return KeyboardActions(
disableScroll: true,
config: KeyboardActionsConfig(
keyboardActionsPlatform: KeyboardActionsPlatform.IOS,
keyboardBarColor: Theme.of(context).extension<KeyboardTheme>()!.keyboardBarColor,
nextFocus: false,
actions: [
KeyboardActionsItem(
focusNode: _amountFieldFocus,
toolbarButtons: [(_) => KeyboardDoneButton()],
),
]),
child: Container(
color: Theme.of(context).colorScheme.background,
child: ScrollableWithBottomSection(
contentPadding: EdgeInsets.zero,
content: Column(
children: [
Container(
padding: EdgeInsets.symmetric(horizontal: 25),
decoration: BoxDecoration(
borderRadius: BorderRadius.only(
bottomLeft: Radius.circular(24), bottomRight: Radius.circular(24)),
gradient: LinearGradient(colors: [
Theme.of(context).extension<SendPageTheme>()!.firstGradientColor,
Theme.of(context).extension<SendPageTheme>()!.secondGradientColor,
], begin: Alignment.topLeft, end: Alignment.bottomRight),
),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
SizedBox(height: 150),
BaseTextFormField(
controller: _amountController,
focusNode: _amountFieldFocus,
keyboardType: TextInputType.numberWithOptions(signed: false, decimal: true),
inputFormatters: [FilteringTextInputFormatter.deny(RegExp('[\-|\ ]'))],
hintText: '1000',
placeholderTextStyle: TextStyle(
color: Theme.of(context).extension<SendPageTheme>()!.textFieldBorderColor,
fontWeight: FontWeight.w500,
fontSize: 36,
),
borderColor: Theme.of(context).extension<SendPageTheme>()!.textFieldBorderColor,
textColor: Colors.white,
textStyle: TextStyle(
color: Colors.white,
fontSize: 36,
),
suffixIcon: SizedBox(
width: _width / 6,
),
prefixIcon: Padding(
padding: EdgeInsets.only(
top: 5.0,
left: _width / 4,
),
child: Text(
'USD: ',
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.w900,
fontSize: 36,
),
),
),
),
SizedBox(height: 8),
Observer(
builder: (_) => !ioniaCustomRedeemViewModel.disableRedeem
? Center(
child: Text(
'\$${giftCard.remainingAmount} - \$${ioniaCustomRedeemViewModel.amount} = \$${ioniaCustomRedeemViewModel.formattedRemaining} ${S.of(context).remaining}',
style: TextStyle(
color: Theme.of(context).extension<SendPageTheme>()!.textFieldBorderColor,
),
),
)
: SizedBox.shrink(),
),
SizedBox(height: 24),
],
),
),
Padding(
padding: const EdgeInsets.all(24.0),
child: CardItem(
title: giftCard.legalName,
backgroundColor: Theme.of(context).extension<CakeTextTheme>()!.titleColor
.withOpacity(0.1),
discount: giftCard.remainingAmount,
isAmount: true,
discountBackground: AssetImage('assets/images/red_badge_discount.png'),
titleColor: Theme.of(context).extension<CakeTextTheme>()!.titleColor,
subtitleColor: Theme.of(context).hintColor,
subTitle: S.of(context).online,
logoUrl: giftCard.logoUrl,
),
),
],
),
bottomSection: Column(
children: [
Observer(
builder: (_) => Padding(
padding: EdgeInsets.only(bottom: 12),
child: LoadingPrimaryButton(
isLoading: ioniaCustomRedeemViewModel.redeemState is IsExecutingState,
isDisabled: ioniaCustomRedeemViewModel.disableRedeem,
text: S.of(context).add_custom_redemption,
color: Theme.of(context).primaryColor,
textColor: Colors.white,
onPressed: () => ioniaCustomRedeemViewModel.addCustomRedeem().then((value) {
Navigator.of(context).pop(ioniaCustomRedeemViewModel.remaining.toString());
}),
),
),
),
SizedBox(height: 30),
],
),
),
),
);
}
}

View file

@ -1,177 +0,0 @@
import 'package:cake_wallet/themes/extensions/keyboard_theme.dart';
import 'package:cake_wallet/themes/extensions/cake_text_theme.dart';
import 'package:cake_wallet/ionia/ionia_merchant.dart';
import 'package:cake_wallet/src/screens/base_page.dart';
import 'package:cake_wallet/src/screens/ionia/widgets/card_item.dart';
import 'package:cake_wallet/src/widgets/base_text_form_field.dart';
import 'package:cake_wallet/src/widgets/keyboard_done_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/themes/theme_base.dart';
import 'package:cake_wallet/view_model/ionia/ionia_custom_tip_view_model.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_mobx/flutter_mobx.dart';
import 'package:keyboard_actions/keyboard_actions.dart';
import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/themes/extensions/send_page_theme.dart';
class IoniaCustomTipPage extends BasePage {
IoniaCustomTipPage(
this.customTipViewModel,
) : _amountFieldFocus = FocusNode(),
_amountController = TextEditingController() {
_amountController.addListener(() {
customTipViewModel.onTipChanged(_amountController.text);
});
}
final IoniaCustomTipViewModel customTipViewModel;
@override
String get title => S.current.enter_amount;
@override
bool get extendBodyBehindAppBar => true;
@override
AppBarStyle get appBarStyle => AppBarStyle.transparent;
Color get textColor => currentTheme.type == ThemeType.dark ? Colors.white : Color(0xff393939);
final TextEditingController _amountController;
final FocusNode _amountFieldFocus;
@override
Widget body(BuildContext context) {
final _width = MediaQuery.of(context).size.width;
final merchant = customTipViewModel.ioniaMerchant;
return KeyboardActions(
disableScroll: true,
config: KeyboardActionsConfig(
keyboardActionsPlatform: KeyboardActionsPlatform.IOS,
keyboardBarColor: Theme.of(context).extension<KeyboardTheme>()!.keyboardBarColor,
nextFocus: false,
actions: [
KeyboardActionsItem(
focusNode: _amountFieldFocus,
toolbarButtons: [(_) => KeyboardDoneButton()],
),
]),
child: Container(
color: Theme.of(context).colorScheme.background,
child: ScrollableWithBottomSection(
contentPadding: EdgeInsets.zero,
content: Column(
children: [
Container(
padding: EdgeInsets.symmetric(horizontal: 25),
decoration: BoxDecoration(
borderRadius: BorderRadius.only(bottomLeft: Radius.circular(24), bottomRight: Radius.circular(24)),
gradient: LinearGradient(colors: [
Theme.of(context).extension<SendPageTheme>()!.firstGradientColor,
Theme.of(context).extension<SendPageTheme>()!.secondGradientColor,
], begin: Alignment.topLeft, end: Alignment.bottomRight),
),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
SizedBox(height: 150),
BaseTextFormField(
controller: _amountController,
focusNode: _amountFieldFocus,
keyboardType: TextInputType.numberWithOptions(signed: false, decimal: true),
inputFormatters: [FilteringTextInputFormatter.deny(RegExp('[\-|\ ]'))],
hintText: '1000',
placeholderTextStyle: TextStyle(
color: Theme.of(context).extension<SendPageTheme>()!.textFieldBorderColor,
fontWeight: FontWeight.w500,
fontSize: 36,
),
borderColor: Theme.of(context).extension<SendPageTheme>()!.textFieldBorderColor,
textColor: Colors.white,
textStyle: TextStyle(
color: Colors.white,
fontSize: 36,
),
suffixIcon: SizedBox(
width: _width / 6,
),
prefixIcon: Padding(
padding: EdgeInsets.only(
top: 5.0,
left: _width / 4,
),
child: Text(
'USD: ',
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.w900,
fontSize: 36,
),
),
),
),
SizedBox(height: 8),
Observer(builder: (_) {
if (customTipViewModel.percentage == 0.0) {
return SizedBox.shrink();
}
return RichText(
textAlign: TextAlign.center,
text: TextSpan(
text: '\$${_amountController.text}',
style: TextStyle(
color: Theme.of(context).extension<SendPageTheme>()!.textFieldBorderColor,
),
children: [
TextSpan(text: ' ${S.of(context).is_percentage} '),
TextSpan(text: '${customTipViewModel.percentage.toStringAsFixed(2)}%'),
TextSpan(text: ' ${S.of(context).percentageOf(customTipViewModel.amount.toStringAsFixed(2))} '),
],
),
);
}),
SizedBox(height: 24),
],
),
),
Padding(
padding: const EdgeInsets.all(24.0),
child: CardItem(
title: merchant.legalName,
backgroundColor: Theme.of(context).extension<CakeTextTheme>()!.titleColor
.withOpacity(0.1),
discount: 0.0,
titleColor: Theme.of(context).extension<CakeTextTheme>()!.titleColor,
subtitleColor: Theme.of(context).hintColor,
subTitle: merchant.isOnline ? S.of(context).online : S.of(context).offline,
logoUrl: merchant.logoUrl,
),
)
],
),
bottomSection: Column(
children: [
Padding(
padding: EdgeInsets.only(bottom: 12),
child: PrimaryButton(
onPressed: () {
Navigator.of(context).pop(customTipViewModel.customTip);
},
text: S.of(context).add_tip,
color: Theme.of(context).primaryColor,
textColor: Colors.white,
),
),
SizedBox(height: 30),
],
),
),
),
);
}
}

View file

@ -1,393 +0,0 @@
import 'package:cake_wallet/ionia/ionia_create_state.dart';
import 'package:cake_wallet/themes/extensions/receive_page_theme.dart';
import 'package:cake_wallet/themes/extensions/cake_text_theme.dart';
import 'package:cake_wallet/ionia/ionia_virtual_card.dart';
import 'package:cake_wallet/routes.dart';
import 'package:cake_wallet/src/screens/base_page.dart';
import 'package:cake_wallet/src/screens/ionia/widgets/text_icon_button.dart';
import 'package:cake_wallet/src/widgets/alert_background.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/themes/extensions/cake_scrollbar_theme.dart';
import 'package:cake_wallet/typography.dart';
import 'package:cake_wallet/utils/show_pop_up.dart';
import 'package:cake_wallet/view_model/ionia/ionia_gift_cards_list_view_model.dart';
import 'package:flutter/material.dart';
import 'package:cake_wallet/generated/i18n.dart';
import 'package:flutter_mobx/flutter_mobx.dart';
import 'package:cake_wallet/themes/extensions/send_page_theme.dart';
class IoniaDebitCardPage extends BasePage {
final IoniaGiftCardsListViewModel _cardsListViewModel;
IoniaDebitCardPage(this._cardsListViewModel);
@override
Widget middle(BuildContext context) {
return Text(
S.current.debit_card,
style: textMediumSemiBold(
color: Theme.of(context).extension<CakeTextTheme>()!.titleColor,
),
);
}
@override
Widget body(BuildContext context) {
return Observer(
builder: (_) {
final cardState = _cardsListViewModel.cardState;
if (cardState is IoniaFetchingCard) {
return Center(child: CircularProgressIndicator());
}
if (cardState is IoniaCardSuccess) {
return ScrollableWithBottomSection(
contentPadding: EdgeInsets.zero,
content: Padding(
padding: const EdgeInsets.all(16.0),
child: _IoniaDebitCard(
cardInfo: cardState.card,
),
),
bottomSection: Column(
children: [
Padding(
padding: const EdgeInsets.symmetric(horizontal: 20.0),
child: Text(
S.of(context).billing_address_info,
style: textSmall(
color: Theme.of(context).extension<ReceivePageTheme>()!.iconsColor),
textAlign: TextAlign.center,
),
),
SizedBox(height: 24),
PrimaryButton(
text: S.of(context).order_physical_card,
onPressed: () {},
color: Color(0xffE9F2FC),
textColor: Theme.of(context).extension<ReceivePageTheme>()!.tilesTextColor,
),
SizedBox(height: 8),
PrimaryButton(
text: S.of(context).add_value,
onPressed: () {},
color: Theme.of(context).primaryColor,
textColor: Colors.white,
),
SizedBox(height: 16)
],
),
);
}
return ScrollableWithBottomSection(
contentPadding: EdgeInsets.zero,
content: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
children: [
_IoniaDebitCard(isCardSample: true),
SizedBox(height: 40),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 8.0),
child: Column(
children: [
TextIconButton(
label: S.current.how_to_use_card,
onTap: () => _showHowToUseCard(context),
),
SizedBox(
height: 24,
),
TextIconButton(
label: S.current.frequently_asked_questions,
onTap: () {},
),
],
),
),
SizedBox(height: 50),
Container(
padding: EdgeInsets.all(20),
margin: EdgeInsets.all(8),
width: double.infinity,
decoration: BoxDecoration(
color: Color.fromRGBO(233, 242, 252, 1),
borderRadius: BorderRadius.circular(20),
),
child: RichText(
text: TextSpan(
text: S.of(context).get_a,
style: textMedium(
color:
Theme.of(context).extension<ReceivePageTheme>()!.tilesTextColor),
children: [
TextSpan(
text: S.of(context).digital_and_physical_card,
style: textMediumBold(
color: Theme.of(context).extension<ReceivePageTheme>()!.tilesTextColor),
),
TextSpan(
text: S.of(context).get_card_note,
)
],
)),
),
],
),
),
bottomSectionPadding: EdgeInsets.symmetric(
horizontal: 16,
vertical: 32,
),
bottomSection: PrimaryButton(
text: S.of(context).activate,
onPressed: () => _showHowToUseCard(context, activate: true),
color: Theme.of(context).primaryColor,
textColor: Colors.white,
),
);
},
);
}
void _showHowToUseCard(BuildContext context, {bool activate = false}) {
showPopUp<void>(
context: context,
builder: (BuildContext context) {
return AlertBackground(
child: Material(
color: Colors.transparent,
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
SizedBox(height: 10),
Container(
padding: EdgeInsets.only(top: 24, left: 24, right: 24),
margin: EdgeInsets.all(24),
decoration: BoxDecoration(
color: Theme.of(context).colorScheme.background,
borderRadius: BorderRadius.circular(30),
),
child: Column(
children: [
Text(
S.of(context).how_to_use_card,
style: textLargeSemiBold(
color:
Theme.of(context).extension<CakeScrollbarTheme>()!.thumbColor,
),
),
SizedBox(height: 24),
Align(
alignment: Alignment.bottomLeft,
child: Text(
S.of(context).signup_for_card_accept_terms,
style: textSmallSemiBold(
color: Theme.of(context).extension<ReceivePageTheme>()!.tilesTextColor,
),
),
),
SizedBox(height: 24),
_TitleSubtitleTile(
title: S.of(context).add_fund_to_card('1000'),
subtitle: S.of(context).use_card_info_two,
),
SizedBox(height: 21),
_TitleSubtitleTile(
title: S.of(context).use_card_info_three,
subtitle: S.of(context).optionally_order_card,
),
SizedBox(height: 35),
PrimaryButton(
onPressed: () => activate
? Navigator.pushNamed(context, Routes.ioniaActivateDebitCardPage)
: Navigator.pop(context),
text: S.of(context).got_it,
color: Color.fromRGBO(233, 242, 252, 1),
textColor:
Theme.of(context).extension<ReceivePageTheme>()!.tilesTextColor,
),
SizedBox(height: 21),
],
),
),
InkWell(
onTap: () => Navigator.pop(context),
child: Container(
margin: EdgeInsets.only(bottom: 40),
child: CircleAvatar(
child: Icon(
Icons.close,
color: Colors.black,
),
backgroundColor: Colors.white,
),
),
)
],
),
),
);
});
}
}
class _IoniaDebitCard extends StatefulWidget {
const _IoniaDebitCard({
Key? key,
this.cardInfo,
this.isCardSample = false,
}) : super(key: key);
final bool isCardSample;
final IoniaVirtualCard? cardInfo;
@override
_IoniaDebitCardState createState() => _IoniaDebitCardState();
}
class _IoniaDebitCardState extends State<_IoniaDebitCard> {
bool _showDetails = false;
void _toggleVisibility() {
setState(() => _showDetails = !_showDetails);
}
String _formatPan(String pan) {
if (pan == null) return '';
return pan.replaceAllMapped(RegExp(r'.{4}'), (match) => '${match.group(0)} ');
}
String get _getLast4 => widget.isCardSample ? '0000' : widget.cardInfo!.pan.substring(widget.cardInfo!.pan.length - 5);
String get _getSpendLimit => widget.isCardSample ? '10000' : widget.cardInfo!.spendLimit.toStringAsFixed(2);
@override
Widget build(BuildContext context) {
return Container(
padding: EdgeInsets.symmetric(horizontal: 24, vertical: 19),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(24),
gradient: LinearGradient(
colors: [
Theme.of(context).extension<SendPageTheme>()!.firstGradientColor,
Theme.of(context).extension<SendPageTheme>()!.secondGradientColor,
],
begin: Alignment.topLeft,
end: Alignment.bottomRight,
),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
SizedBox(height: 16),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
S.current.cakepay_prepaid_card,
style: textSmall(),
),
Image.asset(
'assets/images/mastercard.png',
width: 54,
),
],
),
Text(
widget.isCardSample ? S.of(context).upto(_getSpendLimit) : '\$$_getSpendLimit',
style: textXLargeSemiBold(),
),
SizedBox(height: 16),
Text(
_showDetails ? _formatPan(widget.cardInfo?.pan ?? '') : '**** **** **** $_getLast4',
style: textMediumSemiBold(),
),
SizedBox(height: 32),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
if (widget.isCardSample)
Text(
S.current.no_id_needed,
style: textMediumBold(),
)
else ...[
Column(
children: [
Text(
'CVV',
style: textXSmallSemiBold(),
),
SizedBox(height: 4),
Text(
_showDetails ? widget.cardInfo!.cvv : '***',
style: textMediumSemiBold(),
)
],
),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
S.of(context).expires,
style: textXSmallSemiBold(),
),
SizedBox(height: 4),
Text(
'${widget.cardInfo?.expirationMonth ?? S.of(context).mm}/${widget.cardInfo?.expirationYear ?? S.of(context).yy}',
style: textMediumSemiBold(),
)
],
),
]
],
),
if (!widget.isCardSample) ...[
SizedBox(height: 8),
Center(
child: InkWell(
onTap: () => _toggleVisibility(),
child: Text(
_showDetails ? S.of(context).hide_details : S.of(context).show_details,
style: textSmall(),
),
),
),
],
],
),
);
}
}
class _TitleSubtitleTile extends StatelessWidget {
const _TitleSubtitleTile({
Key? key,
required this.title,
required this.subtitle,
}) : super(key: key);
final String title;
final String subtitle;
@override
Widget build(BuildContext context) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
title,
style: textSmallSemiBold(
color: Theme.of(context).extension<ReceivePageTheme>()!.tilesTextColor),
),
SizedBox(height: 4),
Text(
subtitle,
style: textSmall(
color: Theme.of(context).extension<ReceivePageTheme>()!.tilesTextColor),
),
],
);
}
}

View file

@ -1,215 +0,0 @@
import 'package:cake_wallet/core/execution_state.dart';
import 'package:cake_wallet/themes/extensions/receive_page_theme.dart';
import 'package:cake_wallet/themes/extensions/cake_text_theme.dart';
import 'package:cake_wallet/ionia/ionia_gift_card.dart';
import 'package:cake_wallet/routes.dart';
import 'package:cake_wallet/src/screens/base_page.dart';
import 'package:cake_wallet/src/screens/ionia/widgets/ionia_alert_model.dart';
import 'package:cake_wallet/src/screens/ionia/widgets/ionia_tile.dart';
import 'package:cake_wallet/src/screens/ionia/widgets/text_icon_button.dart';
import 'package:cake_wallet/src/widgets/alert_with_one_action.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/typography.dart';
import 'package:cake_wallet/utils/show_bar.dart';
import 'package:cake_wallet/utils/show_pop_up.dart';
import 'package:cake_wallet/utils/route_aware.dart';
import 'package:cake_wallet/view_model/ionia/ionia_gift_card_details_view_model.dart';
import 'package:device_display_brightness/device_display_brightness.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:cake_wallet/generated/i18n.dart';
import 'package:flutter_mobx/flutter_mobx.dart';
import 'package:mobx/mobx.dart';
class IoniaGiftCardDetailPage extends BasePage {
IoniaGiftCardDetailPage(this.viewModel);
final IoniaGiftCardDetailsViewModel viewModel;
@override
Widget? leading(BuildContext context) {
if (ModalRoute.of(context)!.isFirst) {
return null;
}
final _backButton = Icon(
Icons.arrow_back_ios,
color: Theme.of(context).extension<CakeTextTheme>()!.titleColor,
size: 16,
);
return Padding(
padding: const EdgeInsets.only(left: 10.0),
child: SizedBox(
height: 37,
width: 37,
child: ButtonTheme(
minWidth: double.minPositive,
child: TextButton(
// FIX-ME: Style
//highlightColor: Colors.transparent,
//splashColor: Colors.transparent,
//padding: EdgeInsets.all(0),
onPressed: ()=> onClose(context),
child: _backButton),
),
),
);
}
@override
Widget middle(BuildContext context) {
return Text(
viewModel.giftCard.legalName,
style: textMediumSemiBold(
color: Theme.of(context).extension<CakeTextTheme>()!.titleColor),
);
}
@override
Widget body(BuildContext context) {
reaction((_) => viewModel.redeemState, (ExecutionState state) {
if (state is FailureState) {
WidgetsBinding.instance.addPostFrameCallback((_) {
showPopUp<void>(
context: context,
builder: (BuildContext context) {
return AlertWithOneAction(
alertTitle: S.of(context).error,
alertContent: state.error,
buttonText: S.of(context).ok,
buttonAction: () => Navigator.of(context).pop());
});
});
}
});
return ScrollableWithBottomSection(
contentPadding: EdgeInsets.all(24),
content: Column(
children: [
if (viewModel.giftCard.barcodeUrl != null && viewModel.giftCard.barcodeUrl.isNotEmpty)
Padding(
padding: const EdgeInsets.symmetric(
horizontal: 24.0,
vertical: 24,
),
child: Image.network(viewModel.giftCard.barcodeUrl),
),
SizedBox(height: 24),
buildIoniaTile(
context,
title: S.of(context).gift_card_number,
subTitle: viewModel.giftCard.cardNumber,
),
if (viewModel.giftCard.cardPin.isNotEmpty) ...[
Divider(height: 30),
buildIoniaTile(
context,
title: S.of(context).pin_number,
subTitle: viewModel.giftCard.cardPin,
)
],
Divider(height: 30),
Observer(
builder: (_) => buildIoniaTile(
context,
title: S.of(context).amount,
subTitle: viewModel.remainingAmount.toStringAsFixed(2),
)),
Divider(height: 50),
TextIconButton(
label: S.of(context).how_to_use_card,
onTap: () => _showHowToUseCard(context, viewModel.giftCard),
),
],
),
bottomSection: Padding(
padding: EdgeInsets.only(bottom: 12),
child: Observer(
builder: (_) {
if (!viewModel.giftCard.isEmpty) {
return Column(
children: [
PrimaryButton(
onPressed: () async {
await Navigator.of(context).pushNamed(
Routes.ioniaMoreOptionsPage,
arguments: [viewModel.giftCard]) as String?;
viewModel.refeshCard();
},
text: S.of(context).more_options,
color: Theme.of(context).cardColor,
textColor: Theme.of(context).extension<CakeTextTheme>()!.titleColor,
),
SizedBox(height: 12),
LoadingPrimaryButton(
isLoading: viewModel.redeemState is IsExecutingState,
onPressed: () => viewModel.redeem().then(
(_) {
Navigator.of(context).pushNamedAndRemoveUntil(
Routes.ioniaManageCardsPage, (route) => route.isFirst);
},
),
text: S.of(context).mark_as_redeemed,
color: Theme.of(context).primaryColor,
textColor: Colors.white,
),
],
);
}
return Container();
},
),
),
);
}
Widget buildIoniaTile(BuildContext context, {required String title, required String subTitle}) {
return IoniaTile(
title: title,
subTitle: subTitle,
onTap: () {
Clipboard.setData(ClipboardData(text: subTitle));
showBar<void>(context, S.of(context).transaction_details_copied(title));
});
}
void _showHowToUseCard(
BuildContext context,
IoniaGiftCard merchant,
) {
showPopUp<void>(
context: context,
builder: (BuildContext context) {
return IoniaAlertModal(
title: S.of(context).how_to_use_card,
content: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: viewModel.giftCard.instructions
.map((instruction) {
return [
Padding(
padding: EdgeInsets.all(10),
child: Text(
instruction.header,
style: textLargeSemiBold(
color: Theme.of(context).extension<ReceivePageTheme>()!.tilesTextColor,
),
)),
Text(
instruction.body,
style: textMedium(
color: Theme.of(context).extension<ReceivePageTheme>()!.tilesTextColor,
),
)
];
})
.expand((e) => e)
.toList()),
actionTitle: S.of(context).got_it,
);
});
}
}

View file

@ -1,91 +0,0 @@
import 'package:cake_wallet/ionia/ionia_gift_card.dart';
import 'package:cake_wallet/themes/extensions/cake_text_theme.dart';
import 'package:cake_wallet/routes.dart';
import 'package:cake_wallet/src/screens/base_page.dart';
import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/themes/extensions/dashboard_page_theme.dart';
import 'package:cake_wallet/typography.dart';
import 'package:flutter/material.dart';
class IoniaMoreOptionsPage extends BasePage {
IoniaMoreOptionsPage(this.giftCard);
final IoniaGiftCard giftCard;
@override
Widget middle(BuildContext context) {
return Text(
S.current.more_options,
style: textMediumSemiBold(
color: Theme.of(context).extension<CakeTextTheme>()!.titleColor,
),
);
}
@override
Widget body(BuildContext context) {
return Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
SizedBox(
height: 10,
),
Center(
child: Text(
S.of(context).choose_from_available_options,
style: textMedium(
color: Theme.of(context).extension<CakeTextTheme>()!.titleColor,
),
),
),
SizedBox(height: 40),
InkWell(
onTap: () async {
final amount = await Navigator.of(context)
.pushNamed(Routes.ioniaCustomRedeemPage, arguments: [giftCard]) as String?;
if (amount != null && amount.isNotEmpty) {
Navigator.pop(context);
}
},
child: _GradiantContainer(
content: Padding(
padding: const EdgeInsets.only(top: 24, left: 20, right: 24, bottom: 50),
child: Text(
S.of(context).custom_redeem_amount,
style: textXLargeSemiBold(),
),
),
),
)
],
),
);
}
}
class _GradiantContainer extends StatelessWidget {
const _GradiantContainer({Key? key, required this.content}) : super(key: key);
final Widget content;
@override
Widget build(BuildContext context) {
return Container(
child: content,
padding: EdgeInsets.all(24),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(15),
gradient: LinearGradient(
colors: [
Theme.of(context).extension<DashboardPageTheme>()!.secondGradientBackgroundColor,
Theme.of(context).extension<DashboardPageTheme>()!.firstGradientBackgroundColor,
],
begin: Alignment.topRight,
end: Alignment.bottomLeft,
),
),
);
}
}

View file

@ -1,222 +0,0 @@
import 'package:cake_wallet/ionia/ionia_gift_card.dart';
import 'package:cake_wallet/themes/extensions/cake_text_theme.dart';
import 'package:cake_wallet/routes.dart';
import 'package:cake_wallet/src/screens/base_page.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/typography.dart';
import 'package:cake_wallet/utils/show_bar.dart';
import 'package:cake_wallet/view_model/ionia/ionia_payment_status_view_model.dart';
import 'package:flutter/material.dart';
import 'package:cake_wallet/generated/i18n.dart';
import 'package:flutter/services.dart';
import 'package:flutter_mobx/flutter_mobx.dart';
import 'package:mobx/mobx.dart';
import 'package:cake_wallet/themes/extensions/transaction_trade_theme.dart';
class IoniaPaymentStatusPage extends BasePage {
IoniaPaymentStatusPage(this.viewModel);
final IoniaPaymentStatusViewModel viewModel;
@override
Widget middle(BuildContext context) {
return Text(
S.of(context).generating_gift_card,
textAlign: TextAlign.center,
style: textMediumSemiBold(
color: Theme.of(context).extension<CakeTextTheme>()!.titleColor));
}
@override
Widget body(BuildContext context) {
return _IoniaPaymentStatusPageBody(viewModel);
}
}
class _IoniaPaymentStatusPageBody extends StatefulWidget {
_IoniaPaymentStatusPageBody(this.viewModel);
final IoniaPaymentStatusViewModel viewModel;
@override
_IoniaPaymentStatusPageBodyBodyState createState() => _IoniaPaymentStatusPageBodyBodyState();
}
class _IoniaPaymentStatusPageBodyBodyState extends State<_IoniaPaymentStatusPageBody> {
ReactionDisposer? _onGiftCardReaction;
@override
void initState() {
if (widget.viewModel.giftCard != null) {
WidgetsBinding.instance.addPostFrameCallback((_) {
Navigator.of(context)
.pushReplacementNamed(Routes.ioniaGiftCardDetailPage, arguments: [widget.viewModel.giftCard]);
});
}
_onGiftCardReaction = reaction((_) => widget.viewModel.giftCard, (IoniaGiftCard? giftCard) {
WidgetsBinding.instance.addPostFrameCallback((_) {
Navigator.of(context)
.pushReplacementNamed(Routes.ioniaGiftCardDetailPage, arguments: [giftCard]);
});
});
super.initState();
}
@override
void dispose() {
_onGiftCardReaction?.reaction.dispose();
widget.viewModel.timer?.cancel();
super.dispose();
}
@override
Widget build(BuildContext context) {
return ScrollableWithBottomSection(
contentPadding: EdgeInsets.all(24),
content: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
Row(children: [
Padding(
padding: EdgeInsets.only(right: 10),
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
color: Colors.green),
height: 10,
width: 10)),
Text(
S.of(context).awaiting_payment_confirmation,
style: textLargeSemiBold(
color: Theme.of(context).extension<CakeTextTheme>()!.titleColor))
]),
SizedBox(height: 40),
Row(children: [
SizedBox(width: 20),
Expanded(child:
Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
...widget.viewModel
.committedInfo
.transactions
.map((transaction) => buildDescriptionTileWithCopy(context, S.of(context).transaction_details_transaction_id, transaction.id)),
if (widget.viewModel.paymentInfo.ioniaOrder.id != null)
...[Divider(height: 30),
buildDescriptionTileWithCopy(context, S.of(context).order_id, widget.viewModel.paymentInfo.ioniaOrder.id)],
if (widget.viewModel.paymentInfo.ioniaOrder.paymentId != null)
...[Divider(height: 30),
buildDescriptionTileWithCopy(context, S.of(context).payment_id, widget.viewModel.paymentInfo.ioniaOrder.paymentId)],
]))
]),
SizedBox(height: 40),
Observer(builder: (_) {
if (widget.viewModel.giftCard != null) {
return Container(
padding: EdgeInsets.only(top: 40),
child: Row(children: [
Padding(
padding: EdgeInsets.only(right: 10,),
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
color: Colors.green),
height: 10,
width: 10)),
Text(
S.of(context).gift_card_is_generated,
style: textLargeSemiBold(
color: Theme.of(context).extension<CakeTextTheme>()!.titleColor))
]));
}
return Row(children: [
Padding(
padding: EdgeInsets.only(right: 10),
child: Observer(builder: (_) {
return Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
color: widget.viewModel.giftCard == null ? Colors.grey : Colors.green),
height: 10,
width: 10);
})),
Text(
S.of(context).generating_gift_card,
style: textLargeSemiBold(
color: Theme.of(context).extension<CakeTextTheme>()!.titleColor))]);
}),
],
),
bottomSection: Padding(
padding: EdgeInsets.only(bottom: 12),
child: Column(children: [
Container(
padding: EdgeInsets.only(left: 40, right: 40, bottom: 20),
child: Text(
widget.viewModel.payingByBitcoin ? S.of(context).bitcoin_payments_require_1_confirmation
: S.of(context).proceed_after_one_minute,
style: textMedium(
color: Theme.of(context).extension<CakeTextTheme>()!.titleColor,
).copyWith(fontWeight: FontWeight.w500),
textAlign: TextAlign.center,
)),
Observer(builder: (_) {
if (widget.viewModel.giftCard != null) {
return PrimaryButton(
onPressed: () => Navigator.of(context)
.pushReplacementNamed(
Routes.ioniaGiftCardDetailPage,
arguments: [widget.viewModel.giftCard]),
text: S.of(context).open_gift_card,
color: Theme.of(context).primaryColor,
textColor: Colors.white);
}
return PrimaryButton(
onPressed: () => Navigator.of(context).pushNamed(Routes.support),
text: S.of(context).contact_support,
color: Theme.of(context).cardColor,
textColor: Theme.of(context).extension<CakeTextTheme>()!.titleColor);
})
])
),
);
}
Widget buildDescriptionTile(BuildContext context, String title, String subtitle, VoidCallback onTap) {
return GestureDetector(
onTap: () => onTap(),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
title,
style: textXSmall(
color: Theme.of(context).extension<TransactionTradeTheme>()!.detailsTitlesColor,
),
),
SizedBox(height: 8),
Text(
subtitle,
style: textMedium(
color: Theme.of(context).extension<CakeTextTheme>()!.titleColor,
),
),
],
));
}
Widget buildDescriptionTileWithCopy(BuildContext context, String title, String subtitle) {
return buildDescriptionTile(context, title, subtitle, () {
Clipboard.setData(ClipboardData(text: subtitle));
showBar<void>(context,
S.of(context).transaction_details_copied(title));
});
}
}

View file

@ -1,9 +0,0 @@
export 'auth/ionia_welcome_page.dart';
export 'auth/ionia_create_account_page.dart';
export 'auth/ionia_login_page.dart';
export 'auth/ionia_verify_otp_page.dart';
export 'cards/ionia_activate_debit_card_page.dart';
export 'cards/ionia_buy_card_detail_page.dart';
export 'cards/ionia_manage_cards_page.dart';
export 'cards/ionia_debit_card_page.dart';
export 'cards/ionia_buy_gift_card.dart';

View file

@ -1,144 +0,0 @@
import 'package:cake_wallet/src/widgets/discount_badge.dart';
import 'package:flutter/material.dart';
class CardItem extends StatelessWidget {
CardItem({
required this.title,
required this.subTitle,
required this.backgroundColor,
required this.titleColor,
required this.subtitleColor,
this.hideBorder = false,
this.discount = 0.0,
this.isAmount = false,
this.discountBackground,
this.onTap,
this.logoUrl,
});
final VoidCallback? onTap;
final String title;
final String subTitle;
final String? logoUrl;
final double discount;
final bool isAmount;
final bool hideBorder;
final Color backgroundColor;
final Color titleColor;
final Color subtitleColor;
final AssetImage? discountBackground;
@override
Widget build(BuildContext context) {
return InkWell(
onTap: onTap,
child: Stack(
children: [
Container(
padding: EdgeInsets.all(12),
width: double.infinity,
decoration: BoxDecoration(
color: backgroundColor,
borderRadius: BorderRadius.circular(20),
border: hideBorder ? Border.symmetric(horizontal: BorderSide.none, vertical: BorderSide.none) : Border.all(
color: Colors.white.withOpacity(0.20),
),
),
child: Row(
children: [
if (logoUrl != null) ...[
ClipOval(
child: Image.network(
logoUrl!,
width: 40.0,
height: 40.0,
fit: BoxFit.cover,
loadingBuilder: (BuildContext _, Widget child, ImageChunkEvent? loadingProgress) {
if (loadingProgress == null) {
return child;
} else {
return _PlaceholderContainer(text: 'Logo');
}
},
errorBuilder: (_, __, ___) => _PlaceholderContainer(text: '!'),
),
),
SizedBox(width: 5),
],
Column(
crossAxisAlignment: (subTitle?.isEmpty ?? false)
? CrossAxisAlignment.center
: CrossAxisAlignment.start,
children: [
SizedBox(
width: 200,
child: Text(
title,
overflow: TextOverflow.ellipsis,
style: TextStyle(
color: titleColor,
fontSize: 20,
fontWeight: FontWeight.w900,
),
),
),
if (subTitle?.isNotEmpty ?? false)
Padding(
padding: EdgeInsets.only(top: 5),
child: Text(
subTitle,
style: TextStyle(
color: subtitleColor,
fontWeight: FontWeight.w500,
fontFamily: 'Lato')),
)
],
),
],
),
),
if (discount != 0.0)
Align(
alignment: Alignment.topRight,
child: Padding(
padding: const EdgeInsets.only(top: 20.0),
child: DiscountBadge(
percentage: discount,
isAmount: isAmount,
discountBackground: discountBackground,
),
),
),
],
),
);
}
}
class _PlaceholderContainer extends StatelessWidget {
const _PlaceholderContainer({required this.text});
final String text;
@override
Widget build(BuildContext context) {
return Container(
height: 42,
width: 42,
child: Center(
child: Text(
text,
style: TextStyle(
color: Colors.black,
fontSize: 12,
fontWeight: FontWeight.w900,
),
),
),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(100),
),
);
}
}

View file

@ -1,132 +0,0 @@
import 'package:cake_wallet/src/screens/ionia/widgets/rounded_checkbox.dart';
import 'package:cake_wallet/themes/extensions/cake_text_theme.dart';
import 'package:cake_wallet/src/widgets/alert_background.dart';
import 'package:cake_wallet/typography.dart';
import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/view_model/ionia/ionia_gift_cards_list_view_model.dart';
import 'package:flutter/material.dart';
import 'package:flutter_mobx/flutter_mobx.dart';
import 'package:cake_wallet/palette.dart';
import 'package:cake_wallet/themes/extensions/menu_theme.dart';
class IoniaFilterModal extends StatelessWidget {
IoniaFilterModal({required this.ioniaGiftCardsListViewModel}){
ioniaGiftCardsListViewModel.resetIoniaCategories();
}
final IoniaGiftCardsListViewModel ioniaGiftCardsListViewModel;
@override
Widget build(BuildContext context) {
final searchIcon = Padding(
padding: EdgeInsets.all(10),
child: Image.asset(
'assets/images/mini_search_icon.png',
color: Theme.of(context).primaryColor,
),
);
return Scaffold(
resizeToAvoidBottomInset: false,
body: AlertBackground(
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
SizedBox(height: 10),
Container(
padding: EdgeInsets.only(top: 24, bottom: 20),
margin: EdgeInsets.all(24),
decoration: BoxDecoration(
color: Theme.of(context).colorScheme.background,
borderRadius: BorderRadius.circular(30),
),
child: Column(
children: [
SizedBox(
height: 40,
child: Padding(
padding: const EdgeInsets.only(left: 24, right: 24),
child: TextField(
onChanged: ioniaGiftCardsListViewModel.onSearchFilter,
style: textMedium(
color: Theme.of(context).extension<CakeTextTheme>()!.titleColor,
),
decoration: InputDecoration(
filled: true,
prefixIcon: searchIcon,
hintText: S.of(context).search_category,
contentPadding: EdgeInsets.only(bottom: 5),
fillColor: Theme.of(context).extension<CakeMenuTheme>()!.dividerColor.withOpacity(0.5),
border: OutlineInputBorder(
borderSide: BorderSide.none,
borderRadius: BorderRadius.circular(8),
),
),
),
),
),
SizedBox(height: 10),
Divider(thickness: 2),
SizedBox(height: 24),
Observer(builder: (_) {
return ListView.builder(
padding: EdgeInsets.zero,
shrinkWrap: true,
itemCount: ioniaGiftCardsListViewModel.ioniaCategories.length,
itemBuilder: (_, index) {
final category = ioniaGiftCardsListViewModel.ioniaCategories[index];
return Padding(
padding: const EdgeInsets.only(left: 24, right: 24, bottom: 24),
child: InkWell(
onTap: () => ioniaGiftCardsListViewModel.setSelectedFilter(category),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Row(
mainAxisSize: MainAxisSize.min,
children: [
Image.asset(
category.iconPath,
color: Theme.of(context).extension<CakeTextTheme>()!.titleColor,
),
SizedBox(width: 10),
Text(category.title,
style: textSmall(
color: Theme.of(context).extension<CakeTextTheme>()!.titleColor,
).copyWith(fontWeight: FontWeight.w500)),
],
),
Observer(builder: (_) {
final value = ioniaGiftCardsListViewModel.selectedIndices;
return RoundedCheckbox(
value: value.contains(category),
);
}),
],
),
),
);
},
);
}),
],
),
),
InkWell(
onTap: () => Navigator.pop(context),
child: Container(
margin: EdgeInsets.only(bottom: 40),
child: CircleAvatar(
child: Icon(
Icons.close,
color: Palette.darkBlueCraiola,
),
backgroundColor: Colors.white,
),
),
)
],
),
),
);
}
}

View file

@ -12,6 +12,7 @@ class ConfirmSendingAlert extends BaseAlertDialog {
{required this.alertTitle, {required this.alertTitle,
this.paymentId, this.paymentId,
this.paymentIdValue, this.paymentIdValue,
this.expirationTime,
required this.amount, required this.amount,
required this.amountValue, required this.amountValue,
required this.fiatAmountValue, required this.fiatAmountValue,
@ -28,11 +29,13 @@ class ConfirmSendingAlert extends BaseAlertDialog {
this.alertLeftActionButtonTextColor, this.alertLeftActionButtonTextColor,
this.alertRightActionButtonTextColor, this.alertRightActionButtonTextColor,
this.alertLeftActionButtonColor, this.alertLeftActionButtonColor,
this.alertRightActionButtonColor}); this.alertRightActionButtonColor,
this.onDispose});
final String alertTitle; final String alertTitle;
final String? paymentId; final String? paymentId;
final String? paymentIdValue; final String? paymentIdValue;
final String? expirationTime;
final String amount; final String amount;
final String amountValue; final String amountValue;
final String fiatAmountValue; final String fiatAmountValue;
@ -50,6 +53,7 @@ class ConfirmSendingAlert extends BaseAlertDialog {
final Color? alertRightActionButtonTextColor; final Color? alertRightActionButtonTextColor;
final Color? alertLeftActionButtonColor; final Color? alertLeftActionButtonColor;
final Color? alertRightActionButtonColor; final Color? alertRightActionButtonColor;
final Function? onDispose;
@override @override
String get titleText => alertTitle; String get titleText => alertTitle;
@ -88,6 +92,7 @@ class ConfirmSendingAlert extends BaseAlertDialog {
Widget content(BuildContext context) => ConfirmSendingAlertContent( Widget content(BuildContext context) => ConfirmSendingAlertContent(
paymentId: paymentId, paymentId: paymentId,
paymentIdValue: paymentIdValue, paymentIdValue: paymentIdValue,
expirationTime: expirationTime,
amount: amount, amount: amount,
amountValue: amountValue, amountValue: amountValue,
fiatAmountValue: fiatAmountValue, fiatAmountValue: fiatAmountValue,
@ -95,13 +100,15 @@ class ConfirmSendingAlert extends BaseAlertDialog {
feeRate: feeRate, feeRate: feeRate,
feeValue: feeValue, feeValue: feeValue,
feeFiatAmount: feeFiatAmount, feeFiatAmount: feeFiatAmount,
outputs: outputs); outputs: outputs,
onDispose: onDispose);
} }
class ConfirmSendingAlertContent extends StatefulWidget { class ConfirmSendingAlertContent extends StatefulWidget {
ConfirmSendingAlertContent( ConfirmSendingAlertContent(
{this.paymentId, {this.paymentId,
this.paymentIdValue, this.paymentIdValue,
this.expirationTime,
required this.amount, required this.amount,
required this.amountValue, required this.amountValue,
required this.fiatAmountValue, required this.fiatAmountValue,
@ -109,10 +116,12 @@ class ConfirmSendingAlertContent extends StatefulWidget {
this.feeRate, this.feeRate,
required this.feeValue, required this.feeValue,
required this.feeFiatAmount, required this.feeFiatAmount,
required this.outputs}); required this.outputs,
required this.onDispose}) {}
final String? paymentId; final String? paymentId;
final String? paymentIdValue; final String? paymentIdValue;
final String? expirationTime;
final String amount; final String amount;
final String amountValue; final String amountValue;
final String fiatAmountValue; final String fiatAmountValue;
@ -121,11 +130,13 @@ class ConfirmSendingAlertContent extends StatefulWidget {
final String feeValue; final String feeValue;
final String feeFiatAmount; final String feeFiatAmount;
final List<Output> outputs; final List<Output> outputs;
final Function? onDispose;
@override @override
ConfirmSendingAlertContentState createState() => ConfirmSendingAlertContentState( ConfirmSendingAlertContentState createState() => ConfirmSendingAlertContentState(
paymentId: paymentId, paymentId: paymentId,
paymentIdValue: paymentIdValue, paymentIdValue: paymentIdValue,
expirationTime: expirationTime,
amount: amount, amount: amount,
amountValue: amountValue, amountValue: amountValue,
fiatAmountValue: fiatAmountValue, fiatAmountValue: fiatAmountValue,
@ -133,13 +144,15 @@ class ConfirmSendingAlertContent extends StatefulWidget {
feeRate: feeRate, feeRate: feeRate,
feeValue: feeValue, feeValue: feeValue,
feeFiatAmount: feeFiatAmount, feeFiatAmount: feeFiatAmount,
outputs: outputs); outputs: outputs,
onDispose: onDispose);
} }
class ConfirmSendingAlertContentState extends State<ConfirmSendingAlertContent> { class ConfirmSendingAlertContentState extends State<ConfirmSendingAlertContent> {
ConfirmSendingAlertContentState( ConfirmSendingAlertContentState(
{this.paymentId, {this.paymentId,
this.paymentIdValue, this.paymentIdValue,
this.expirationTime,
required this.amount, required this.amount,
required this.amountValue, required this.amountValue,
required this.fiatAmountValue, required this.fiatAmountValue,
@ -147,7 +160,8 @@ class ConfirmSendingAlertContentState extends State<ConfirmSendingAlertContent>
this.feeRate, this.feeRate,
required this.feeValue, required this.feeValue,
required this.feeFiatAmount, required this.feeFiatAmount,
required this.outputs}) required this.outputs,
this.onDispose})
: recipientTitle = '' { : recipientTitle = '' {
recipientTitle = outputs.length > 1 recipientTitle = outputs.length > 1
? S.current.transaction_details_recipient_address ? S.current.transaction_details_recipient_address
@ -156,6 +170,7 @@ class ConfirmSendingAlertContentState extends State<ConfirmSendingAlertContent>
final String? paymentId; final String? paymentId;
final String? paymentIdValue; final String? paymentIdValue;
final String? expirationTime;
final String amount; final String amount;
final String amountValue; final String amountValue;
final String fiatAmountValue; final String fiatAmountValue;
@ -164,6 +179,7 @@ class ConfirmSendingAlertContentState extends State<ConfirmSendingAlertContent>
final String feeValue; final String feeValue;
final String feeFiatAmount; final String feeFiatAmount;
final List<Output> outputs; final List<Output> outputs;
final Function? onDispose;
final double backgroundHeight = 160; final double backgroundHeight = 160;
final double thumbHeight = 72; final double thumbHeight = 72;
@ -172,6 +188,12 @@ class ConfirmSendingAlertContentState extends State<ConfirmSendingAlertContent>
String recipientTitle; String recipientTitle;
bool showScrollbar = false; bool showScrollbar = false;
@override
void dispose() {
if (onDispose != null) onDispose!();
super.dispose();
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
controller.addListener(() { controller.addListener(() {
@ -217,14 +239,18 @@ class ConfirmSendingAlertContentState extends State<ConfirmSendingAlertContent>
Column( Column(
crossAxisAlignment: CrossAxisAlignment.end, crossAxisAlignment: CrossAxisAlignment.end,
children: [ children: [
Text( Container(
paymentIdValue!, width: 160,
style: TextStyle( child: Text(
fontSize: 18, paymentIdValue!,
fontWeight: FontWeight.w600, textAlign: TextAlign.right,
fontFamily: 'Lato', style: TextStyle(
color: Theme.of(context).extension<CakeTextTheme>()!.titleColor, fontSize: 16,
decoration: TextDecoration.none, fontWeight: FontWeight.w600,
fontFamily: 'Lato',
color: Theme.of(context).extension<CakeTextTheme>()!.titleColor,
decoration: TextDecoration.none,
),
), ),
), ),
], ],
@ -232,6 +258,8 @@ class ConfirmSendingAlertContentState extends State<ConfirmSendingAlertContent>
], ],
), ),
), ),
if (widget.expirationTime != null)
ExpirationTimeWidget(expirationTime: widget.expirationTime!),
Row( Row(
mainAxisSize: MainAxisSize.max, mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
@ -468,3 +496,46 @@ class ConfirmSendingAlertContentState extends State<ConfirmSendingAlertContent>
]); ]);
} }
} }
class ExpirationTimeWidget extends StatelessWidget {
const ExpirationTimeWidget({
required this.expirationTime,
});
final String expirationTime;
@override
Widget build(BuildContext context) {
return Padding(
padding: EdgeInsets.only(bottom: 32),
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
S.current.offer_expires_in,
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.normal,
fontFamily: 'Lato',
color: Theme.of(context).extension<CakeTextTheme>()!.titleColor,
decoration: TextDecoration.none,
),
),
Text(
expirationTime,
textAlign: TextAlign.right,
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.w600,
fontFamily: 'Lato',
color: Theme.of(context).extension<CakeTextTheme>()!.titleColor,
decoration: TextDecoration.none,
),
)
],
),
);
}
}

View file

@ -0,0 +1,145 @@
import 'package:cake_wallet/themes/extensions/cake_text_theme.dart';
import 'package:cake_wallet/typography.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
class NumberTextField extends StatefulWidget {
final TextEditingController? controller;
final FocusNode? focusNode;
final int min;
final int max;
final int step;
final double arrowsWidth;
final double arrowsHeight;
final EdgeInsets contentPadding;
final double borderWidth;
final ValueChanged<int?>? onChanged;
const NumberTextField({
Key? key,
this.controller,
this.focusNode,
this.min = 0,
this.max = 999,
this.step = 1,
this.arrowsWidth = 24,
this.arrowsHeight = kMinInteractiveDimension,
this.contentPadding = const EdgeInsets.symmetric(horizontal: 8),
this.borderWidth = 2,
this.onChanged,
}) : super(key: key);
@override
State<StatefulWidget> createState() => _NumberTextFieldState();
}
class _NumberTextFieldState extends State<NumberTextField> {
late TextEditingController _controller;
late FocusNode _focusNode;
bool _canGoUp = false;
bool _canGoDown = false;
@override
void initState() {
super.initState();
_controller = widget.controller ?? TextEditingController();
_focusNode = widget.focusNode ?? FocusNode();
_updateArrows(int.tryParse(_controller.text));
}
@override
void didUpdateWidget(covariant NumberTextField oldWidget) {
super.didUpdateWidget(oldWidget);
_controller = widget.controller ?? _controller;
_focusNode = widget.focusNode ?? _focusNode;
_updateArrows(int.tryParse(_controller.text));
}
@override
Widget build(BuildContext context) => TextField(
style: textMediumSemiBold(color: Theme.of(context).extension<CakeTextTheme>()!.titleColor),
enableInteractiveSelection: false,
textAlign: TextAlign.center,
textAlignVertical: TextAlignVertical.bottom,
controller: _controller,
focusNode: _focusNode,
textInputAction: TextInputAction.done,
keyboardType: TextInputType.number,
maxLength: widget.max.toString().length + (widget.min.isNegative ? 1 : 0),
decoration: InputDecoration(
border: InputBorder.none,
contentPadding: EdgeInsets.all(0),
fillColor: Colors.transparent,
counterText: '',
isDense: true,
filled: true,
suffixIconConstraints: BoxConstraints(
maxHeight: widget.arrowsHeight,
maxWidth: widget.arrowsWidth + widget.contentPadding.right),
prefixIconConstraints: BoxConstraints(
maxHeight: widget.arrowsHeight,
maxWidth: widget.arrowsWidth + widget.contentPadding.left),
prefixIcon: Material(
type: MaterialType.transparency,
child: InkWell(
child: Container(
width: widget.arrowsWidth,
alignment: Alignment.bottomCenter,
child: Icon(Icons.arrow_left_outlined, size: widget.arrowsWidth)),
onTap: _canGoDown ? () => _update(false) : null)),
suffixIcon: Material(
type: MaterialType.transparency,
child: InkWell(
child: Container(
width: widget.arrowsWidth,
alignment: Alignment.bottomCenter,
child: Icon(Icons.arrow_right_outlined, size: widget.arrowsWidth)),
onTap: _canGoUp ? () => _update(true) : null))),
maxLines: 1,
onChanged: (value) {
final intValue = int.tryParse(value);
widget.onChanged?.call(intValue);
_updateArrows(intValue);
},
inputFormatters: [_NumberTextInputFormatter(widget.min, widget.max)]);
void _update(bool up) {
var intValue = int.tryParse(_controller.text);
intValue == null ? intValue = widget.min : intValue += up ? widget.step : -widget.step;
intValue = intValue.clamp(widget.min, widget.max); // Ensure intValue is within range
_controller.text = intValue.toString();
// Manually call the onChanged callback after updating the controller's text
widget.onChanged?.call(intValue);
_updateArrows(intValue);
_focusNode.requestFocus();
}
void _updateArrows(int? value) {
final canGoUp = value == null || value < widget.max;
final canGoDown = value == null || value > widget.min;
if (_canGoUp != canGoUp || _canGoDown != canGoDown)
setState(() {
_canGoUp = canGoUp;
_canGoDown = canGoDown;
});
}
}
class _NumberTextInputFormatter extends TextInputFormatter {
final int min;
final int max;
_NumberTextInputFormatter(this.min, this.max);
@override
TextEditingValue formatEditUpdate(TextEditingValue oldValue, TextEditingValue newValue) {
if (const ['-', ''].contains(newValue.text)) return newValue;
final intValue = int.tryParse(newValue.text);
if (intValue == null) return oldValue;
if (intValue < min) return newValue.copyWith(text: min.toString());
if (intValue > max) return newValue.copyWith(text: max.toString());
return newValue.copyWith(text: intValue.toString());
}
}

View file

@ -0,0 +1,20 @@
import 'package:cake_wallet/cake_pay/cake_pay_service.dart';
import 'package:mobx/mobx.dart';
part 'cake_pay_account_view_model.g.dart';
class CakePayAccountViewModel = CakePayAccountViewModelBase with _$CakePayAccountViewModel;
abstract class CakePayAccountViewModelBase with Store {
CakePayAccountViewModelBase({required this.cakePayService}) : email = '' {
cakePayService.getUserEmail().then((email) => this.email = email ?? '');
}
final CakePayService cakePayService;
@observable
String email;
@action
Future<void> logout() async => cakePayService.logout(email);
}

View file

@ -0,0 +1,51 @@
import 'package:cake_wallet/cake_pay/cake_pay_states.dart';
import 'package:cake_wallet/cake_pay/cake_pay_service.dart';
import 'package:mobx/mobx.dart';
part 'cake_pay_auth_view_model.g.dart';
class CakePayAuthViewModel = CakePayAuthViewModelBase with _$CakePayAuthViewModel;
abstract class CakePayAuthViewModelBase with Store {
CakePayAuthViewModelBase({required this.cakePayService})
: userVerificationState = CakePayUserVerificationStateInitial(),
otpState = CakePayOtpSendDisabled(),
email = '',
otp = '';
final CakePayService cakePayService;
@observable
CakePayUserVerificationState userVerificationState;
@observable
CakePayOtpState otpState;
@observable
String email;
@observable
String otp;
@action
Future<void> verifyEmail(String code) async {
try {
otpState = CakePayOtpValidating();
await cakePayService.verifyEmail(code);
otpState = CakePayOtpSuccess();
} catch (_) {
otpState = CakePayOtpFailure(error: 'Invalid OTP. Try again');
}
}
@action
Future<void> logIn(String email) async {
try {
userVerificationState = CakePayUserVerificationStateLoading();
await cakePayService.logIn(email);
userVerificationState = CakePayUserVerificationStateSuccess();
} catch (e) {
userVerificationState = CakePayUserVerificationStateFailure(error: e.toString());
}
}
}

View file

@ -0,0 +1,48 @@
import 'package:cake_wallet/cake_pay/cake_pay_card.dart';
import 'package:cake_wallet/cake_pay/cake_pay_vendor.dart';
import 'package:mobx/mobx.dart';
part 'cake_pay_buy_card_view_model.g.dart';
class CakePayBuyCardViewModel = CakePayBuyCardViewModelBase with _$CakePayBuyCardViewModel;
abstract class CakePayBuyCardViewModelBase with Store {
CakePayBuyCardViewModelBase({required this.vendor})
: amount = vendor.card!.denominations.isNotEmpty
? double.parse(vendor.card!.denominations.first)
: 0,
quantity = 1,
min = double.parse(vendor.card!.minValue ?? '0'),
max = double.parse(vendor.card!.maxValue ?? '0'),
card = vendor.card!;
final CakePayVendor vendor;
final CakePayCard card;
final double min;
final double max;
bool get isDenominationSelected => card.denominations.isNotEmpty;
@observable
double amount;
@observable
int quantity;
@computed
bool get isEnablePurchase =>
(amount >= min && amount <= max) || (isDenominationSelected && quantity > 0);
@computed
double get totalAmount => amount * quantity;
@action
void onQuantityChanged(int? input) => quantity = input ?? 1;
@action
void onAmountChanged(String input) {
if (input.isEmpty) return;
amount = double.parse(input.replaceAll(',', '.'));
}
}

View file

@ -0,0 +1,221 @@
import 'package:cake_wallet/cake_pay/cake_pay_service.dart';
import 'package:cake_wallet/cake_pay/cake_pay_states.dart';
import 'package:cake_wallet/cake_pay/cake_pay_vendor.dart';
import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/view_model/dashboard/dropdown_filter_item.dart';
import 'package:cake_wallet/view_model/dashboard/filter_item.dart';
import 'package:mobx/mobx.dart';
part 'cake_pay_cards_list_view_model.g.dart';
class CakePayCardsListViewModel = CakePayCardsListViewModelBase with _$CakePayCardsListViewModel;
abstract class CakePayCardsListViewModelBase with Store {
CakePayCardsListViewModelBase({
required this.cakePayService,
}) : cardState = CakePayCardsStateNoCards(),
cakePayVendors = [],
availableCountries = [],
page = 1,
selectedCountry = 'USA',
displayPrepaidCards = true,
displayGiftCards = true,
displayDenominationsCards = true,
displayCustomValueCards = true,
scrollOffsetFromTop = 0.0,
vendorsState = InitialCakePayVendorLoadingState(),
createCardState = CakePayCreateCardState(),
searchString = '',
CakePayVendorList = <CakePayVendor>[] {
initialization();
}
void initialization() async {
await getCountries();
selectedCountry = availableCountries.first;
getVendors();
}
final CakePayService cakePayService;
List<CakePayVendor> CakePayVendorList;
Map<String, List<FilterItem>> get createFilterItems => {
S.current.filter_by: [
FilterItem(
value: () => displayPrepaidCards,
caption: S.current.prepaid_cards,
onChanged: togglePrepaidCards),
FilterItem(
value: () => displayGiftCards,
caption: S.current.gift_cards,
onChanged: toggleGiftCards),
],
S.current.value_type: [
FilterItem(
value: () => displayDenominationsCards,
caption: S.current.denominations,
onChanged: toggleDenominationsCards),
FilterItem(
value: () => displayCustomValueCards,
caption: S.current.custom_value,
onChanged: toggleCustomValueCards),
],
S.current.countries: [
DropdownFilterItem(
items: availableCountries,
caption: '',
selectedItem: selectedCountry,
onItemSelected: (String value) => setSelectedCountry(value),
),
]
};
String searchString;
int page;
late String _initialSelectedCountry;
late bool _initialDisplayPrepaidCards;
late bool _initialDisplayGiftCards;
late bool _initialDisplayDenominationsCards;
late bool _initialDisplayCustomValueCards;
@observable
double scrollOffsetFromTop;
@observable
CakePayCreateCardState createCardState;
@observable
CakePayCardsState cardState;
@observable
CakePayVendorState vendorsState;
@observable
bool hasMoreDataToFetch = true;
@observable
bool isLoadingNextPage = false;
@observable
List<CakePayVendor> cakePayVendors;
@observable
List<String> availableCountries;
@observable
bool displayPrepaidCards;
@observable
bool displayGiftCards;
@observable
bool displayDenominationsCards;
@observable
bool displayCustomValueCards;
@observable
String selectedCountry;
bool get hasFiltersChanged =>
selectedCountry != _initialSelectedCountry ||
displayPrepaidCards != _initialDisplayPrepaidCards ||
displayGiftCards != _initialDisplayGiftCards ||
displayDenominationsCards != _initialDisplayDenominationsCards ||
displayCustomValueCards != _initialDisplayCustomValueCards;
Future<void> getCountries() async {
availableCountries = await cakePayService.getCountries();
}
@action
Future<void> getVendors({
String? text,
int? currentPage,
}) async {
vendorsState = CakePayVendorLoadingState();
searchString = text ?? '';
var newVendors = await cakePayService.getVendors(
country: selectedCountry,
page: currentPage ?? page,
search: searchString,
giftCards: displayGiftCards,
prepaidCards: displayPrepaidCards,
custom: displayCustomValueCards,
onDemand: displayDenominationsCards);
cakePayVendors = CakePayVendorList = newVendors;
vendorsState = CakePayVendorLoadedState();
}
@action
Future<void> fetchNextPage() async {
if (vendorsState is CakePayVendorLoadingState || !hasMoreDataToFetch || isLoadingNextPage)
return;
isLoadingNextPage = true;
page++;
try {
var newVendors = await cakePayService.getVendors(
country: selectedCountry,
page: page,
search: searchString,
giftCards: displayGiftCards,
prepaidCards: displayPrepaidCards,
custom: displayCustomValueCards,
onDemand: displayDenominationsCards);
cakePayVendors.addAll(newVendors);
} catch (error) {
if (error.toString().contains('detail":"Invalid page."')) {
hasMoreDataToFetch = false;
}
} finally {
isLoadingNextPage = false;
}
}
Future<bool> isCakePayUserAuthenticated() async {
return await cakePayService.isLogged();
}
void resetLoadingNextPageState() {
hasMoreDataToFetch = true;
page = 1;
}
void storeInitialFilterStates() {
_initialSelectedCountry = selectedCountry;
_initialDisplayPrepaidCards = displayPrepaidCards;
_initialDisplayGiftCards = displayGiftCards;
_initialDisplayDenominationsCards = displayDenominationsCards;
_initialDisplayCustomValueCards = displayCustomValueCards;
}
@action
void setSelectedCountry(String country) => selectedCountry = country;
@action
void togglePrepaidCards() => displayPrepaidCards = !displayPrepaidCards;
@action
void toggleGiftCards() => displayGiftCards = !displayGiftCards;
@action
void toggleDenominationsCards() => displayDenominationsCards = !displayDenominationsCards;
@action
void toggleCustomValueCards() => displayCustomValueCards = !displayCustomValueCards;
void setScrollOffsetFromTop(double scrollOffset) {
scrollOffsetFromTop = scrollOffset;
}
}

View file

@ -0,0 +1,162 @@
import 'dart:async';
import 'package:cake_wallet/cake_pay/cake_pay_card.dart';
import 'package:cake_wallet/cake_pay/cake_pay_order.dart';
import 'package:cake_wallet/cake_pay/cake_pay_payment_credantials.dart';
import 'package:cake_wallet/cake_pay/cake_pay_service.dart';
import 'package:cake_wallet/core/execution_state.dart';
import 'package:cake_wallet/view_model/send/send_view_model.dart';
import 'package:cw_core/wallet_type.dart';
import 'package:mobx/mobx.dart';
part 'cake_pay_purchase_view_model.g.dart';
class CakePayPurchaseViewModel = CakePayPurchaseViewModelBase with _$CakePayPurchaseViewModel;
abstract class CakePayPurchaseViewModelBase with Store {
CakePayPurchaseViewModelBase({
required this.cakePayService,
required this.paymentCredential,
required this.card,
required this.sendViewModel,
}) : walletType = sendViewModel.walletType;
final WalletType walletType;
final PaymentCredential paymentCredential;
final CakePayCard card;
final SendViewModel sendViewModel;
final CakePayService cakePayService;
CakePayOrder? order;
Timer? _timer;
DateTime? expirationTime;
Duration? remainingTime;
String? get userName => paymentCredential.userName;
double get amount => paymentCredential.amount;
int get quantity => paymentCredential.quantity;
double get totalAmount => paymentCredential.totalAmount;
String get fiatCurrency => paymentCredential.fiatCurrency;
CryptoPaymentData? get cryptoPaymentData {
if (order == null) return null;
if (WalletType.monero == walletType) {
return order!.paymentData.xmr;
}
if (WalletType.bitcoin == walletType) {
final paymentUrls = order!.paymentData.btc.paymentUrls!.bip21;
final uri = Uri.parse(paymentUrls!);
final address = uri.path;
final price = uri.queryParameters['amount'];
return CryptoPaymentData(
address: address,
price: price ?? '0',
);
}
return null;
}
@observable
bool isOrderExpired = false;
@observable
String formattedRemainingTime = '';
@action
Future<void> createOrder() async {
if (walletType != WalletType.bitcoin && walletType != WalletType.monero) {
sendViewModel.state = FailureState('Unsupported wallet type, please use Bitcoin or Monero.');
}
try {
order = await cakePayService.createOrder(
cardId: card.id,
price: paymentCredential.amount.toString(),
quantity: paymentCredential.quantity);
await confirmSending();
expirationTime = order!.paymentData.expirationTime;
updateRemainingTime();
_startExpirationTimer();
} catch (e) {
sendViewModel.state = FailureState(
sendViewModel.translateErrorMessage(e, walletType, sendViewModel.wallet.currency));
}
}
@action
Future<void> confirmSending() async {
final cryptoPaymentData = this.cryptoPaymentData;
try {
if (order == null || cryptoPaymentData == null) return;
sendViewModel.clearOutputs();
final output = sendViewModel.outputs.first;
output.address = cryptoPaymentData.address;
output.setCryptoAmount(cryptoPaymentData.price);
await sendViewModel.createTransaction();
} catch (e) {
throw e;
}
}
@action
void updateRemainingTime() {
if (expirationTime == null) {
formattedRemainingTime = '';
return;
}
remainingTime = expirationTime!.difference(DateTime.now());
isOrderExpired = remainingTime!.isNegative;
if (isOrderExpired) {
disposeExpirationTimer();
sendViewModel.state = FailureState('Order has expired.');
} else {
formattedRemainingTime = formatDuration(remainingTime!);
}
}
void _startExpirationTimer() {
_timer?.cancel();
_timer = Timer.periodic(Duration(seconds: 1), (_) {
updateRemainingTime();
});
}
String formatDuration(Duration duration) {
final hours = duration.inHours;
final minutes = duration.inMinutes.remainder(60);
final seconds = duration.inSeconds.remainder(60);
return '${hours.toString().padLeft(2, '0')}:${minutes.toString().padLeft(2, '0')}:${seconds.toString().padLeft(2, '0')}';
}
void disposeExpirationTimer() {
_timer?.cancel();
remainingTime = null;
formattedRemainingTime = '';
expirationTime = null;
}
void dispose() {
disposeExpirationTimer();
}
}

View file

@ -1,4 +1,4 @@
import 'package:cake_wallet/ionia/ionia_service.dart'; import 'package:cake_wallet/cake_pay/cake_pay_service.dart';
import 'package:mobx/mobx.dart'; import 'package:mobx/mobx.dart';
part 'cake_features_view_model.g.dart'; part 'cake_features_view_model.g.dart';
@ -6,11 +6,11 @@ part 'cake_features_view_model.g.dart';
class CakeFeaturesViewModel = CakeFeaturesViewModelBase with _$CakeFeaturesViewModel; class CakeFeaturesViewModel = CakeFeaturesViewModelBase with _$CakeFeaturesViewModel;
abstract class CakeFeaturesViewModelBase with Store { abstract class CakeFeaturesViewModelBase with Store {
final IoniaService _ioniaService; final CakePayService _cakePayService;
CakeFeaturesViewModelBase(this._ioniaService); CakeFeaturesViewModelBase(this._cakePayService);
Future<bool> isIoniaUserAuthenticated() async { Future<bool> isIoniaUserAuthenticated() async {
return await _ioniaService.isLogined(); return await _cakePayService.isLogged();
} }
} }

View file

@ -0,0 +1,19 @@
import 'package:cake_wallet/view_model/dashboard/filter_item.dart';
class DropdownFilterItem extends FilterItem {
DropdownFilterItem({
required this.items,
required this.caption,
required this.selectedItem,
required this.onItemSelected,
}) : super(
value: () => false,
caption: caption,
onChanged: (_) {},
);
final List<String> items;
final String caption;
final String selectedItem;
final Function(String) onItemSelected;
}

View file

@ -0,0 +1,68 @@
import 'package:auto_size_text/auto_size_text.dart';
import 'package:cake_wallet/themes/extensions/picker_theme.dart';
import 'package:flutter/material.dart';
class DropdownFilterList extends StatefulWidget {
DropdownFilterList({
Key? key,
required this.items,
this.itemPrefix,
this.textStyle,
required this.caption,
required this.selectedItem,
required this.onItemSelected,
}) : super(key: key);
final List<String> items;
final String? itemPrefix;
final TextStyle? textStyle;
final String caption;
final String selectedItem;
final Function(String) onItemSelected;
@override
_DropdownFilterListState createState() => _DropdownFilterListState();
}
class _DropdownFilterListState extends State<DropdownFilterList> {
String? selectedValue;
@override
void initState() {
super.initState();
selectedValue = widget.selectedItem;
}
@override
Widget build(BuildContext context) {
return DropdownButtonHideUnderline(
child: Container(
child: DropdownButton<String>(
isExpanded: true,
icon: Container(
child: Column(
mainAxisAlignment: MainAxisAlignment.end,
children: [
Icon(Icons.arrow_drop_down, color: Theme.of(context).extension<PickerTheme>()!.searchIconColor),
],
),
),
dropdownColor: Theme.of(context).extension<PickerTheme>()!.searchBackgroundFillColor,
borderRadius: BorderRadius.circular(10),
items: widget.items
.map((item) => DropdownMenuItem<String>(
alignment: Alignment.bottomCenter,
value: item,
child: AutoSizeText('${widget.itemPrefix ?? ''} $item', style: widget.textStyle),
))
.toList(),
value: selectedValue,
onChanged: (newValue) {
setState(() => selectedValue = newValue);
widget.onItemSelected(newValue!);
},
),
),
);
}
}

View file

@ -1,50 +0,0 @@
import 'package:cake_wallet/ionia/ionia_create_state.dart';
import 'package:cake_wallet/ionia/ionia_service.dart';
import 'package:mobx/mobx.dart';
import 'package:cake_wallet/ionia/ionia_gift_card.dart';
part 'ionia_account_view_model.g.dart';
class IoniaAccountViewModel = IoniaAccountViewModelBase with _$IoniaAccountViewModel;
abstract class IoniaAccountViewModelBase with Store {
IoniaAccountViewModelBase({required this.ioniaService})
: email = '',
giftCards = [],
merchantState = InitialIoniaMerchantLoadingState() {
ioniaService.getUserEmail().then((email) => this.email = email);
updateUserGiftCards();
}
final IoniaService ioniaService;
@observable
String email;
@observable
List<IoniaGiftCard> giftCards;
@observable
IoniaMerchantState merchantState;
@computed
int get countOfMerch => giftCards.where((giftCard) => !giftCard.isEmpty).length;
@computed
List<IoniaGiftCard> get activeMechs => giftCards.where((giftCard) => !giftCard.isEmpty).toList();
@computed
List<IoniaGiftCard> get redeemedMerchs => giftCards.where((giftCard) => giftCard.isEmpty).toList();
@action
void logout() {
ioniaService.logout();
}
@action
Future<void> updateUserGiftCards() async {
merchantState = IoniaLoadingMerchantState();
giftCards = await ioniaService.getCurrentUserGiftCardSummaries();
merchantState = IoniaLoadedMerchantState();
}
}

View file

@ -1,69 +0,0 @@
import 'package:cake_wallet/ionia/ionia_create_state.dart';
import 'package:cake_wallet/ionia/ionia_service.dart';
import 'package:mobx/mobx.dart';
part 'ionia_auth_view_model.g.dart';
class IoniaAuthViewModel = IoniaAuthViewModelBase with _$IoniaAuthViewModel;
abstract class IoniaAuthViewModelBase with Store {
IoniaAuthViewModelBase({required this.ioniaService}):
createUserState = IoniaInitialCreateState(),
signInState = IoniaInitialCreateState(),
otpState = IoniaOtpSendDisabled(),
email = '',
otp = '';
final IoniaService ioniaService;
@observable
IoniaCreateAccountState createUserState;
@observable
IoniaCreateAccountState signInState;
@observable
IoniaOtpState otpState;
@observable
String email;
@observable
String otp;
@action
Future<void> verifyEmail(String code) async {
try {
otpState = IoniaOtpValidating();
await ioniaService.verifyEmail(code);
otpState = IoniaOtpSuccess();
} catch (_) {
otpState = IoniaOtpFailure(error: 'Invalid OTP. Try again');
}
}
@action
Future<void> createUser(String email) async {
try {
createUserState = IoniaCreateStateLoading();
await ioniaService.createUser(email);
createUserState = IoniaCreateStateSuccess();
} catch (e) {
createUserState = IoniaCreateStateFailure(error: e.toString());
}
}
@action
Future<void> signIn(String email) async {
try {
signInState = IoniaCreateStateLoading();
await ioniaService.signIn(email);
signInState = IoniaCreateStateSuccess();
} catch (e) {
signInState = IoniaCreateStateFailure(error: e.toString());
}
}
}

View file

@ -1,30 +0,0 @@
import 'package:cake_wallet/ionia/ionia_merchant.dart';
import 'package:mobx/mobx.dart';
part 'ionia_buy_card_view_model.g.dart';
class IoniaBuyCardViewModel = IoniaBuyCardViewModelBase with _$IoniaBuyCardViewModel;
abstract class IoniaBuyCardViewModelBase with Store {
IoniaBuyCardViewModelBase({required this.ioniaMerchant})
: isEnablePurchase = false,
amount = 0;
final IoniaMerchant ioniaMerchant;
@observable
double amount;
@observable
bool isEnablePurchase;
@action
void onAmountChanged(String input) {
if (input.isEmpty) return;
amount = double.parse(input.replaceAll(',', '.'));
final min = ioniaMerchant.minimumCardPurchase;
final max = ioniaMerchant.maximumCardPurchase;
isEnablePurchase = amount >= min && amount <= max;
}
}

View file

@ -1,51 +0,0 @@
import 'package:cake_wallet/core/execution_state.dart';
import 'package:cake_wallet/ionia/ionia_gift_card.dart';
import 'package:cake_wallet/ionia/ionia_service.dart';
import 'package:mobx/mobx.dart';
part 'ionia_custom_redeem_view_model.g.dart';
class IoniaCustomRedeemViewModel = IoniaCustomRedeemViewModelBase with _$IoniaCustomRedeemViewModel;
abstract class IoniaCustomRedeemViewModelBase with Store {
IoniaCustomRedeemViewModelBase({
required this.giftCard,
required this.ioniaService,
}) : amount = 0,
redeemState = InitialExecutionState();
final IoniaGiftCard giftCard;
final IoniaService ioniaService;
@observable
ExecutionState redeemState;
@observable
double amount;
@computed
double get remaining =>
amount <= giftCard.remainingAmount ? giftCard.remainingAmount - amount : 0;
@computed
String get formattedRemaining => remaining.toStringAsFixed(2);
@computed
bool get disableRedeem => amount > giftCard.remainingAmount;
@action
void updateAmount(String text) {
amount = double.tryParse(text.replaceAll(',', '.')) ?? 0;
}
@action
Future<void> addCustomRedeem() async {
try {
redeemState = IsExecutingState();
await ioniaService.redeem(giftCardId: giftCard.id, amount: amount);
redeemState = ExecutedSuccessfullyState();
} catch (e) {
redeemState = FailureState(e.toString());
}
}
}

View file

@ -1,34 +0,0 @@
import 'package:cake_wallet/ionia/ionia_merchant.dart';
import 'package:cake_wallet/ionia/ionia_tip.dart';
import 'package:mobx/mobx.dart';
part 'ionia_custom_tip_view_model.g.dart';
class IoniaCustomTipViewModel = IoniaCustomTipViewModelBase with _$IoniaCustomTipViewModel;
abstract class IoniaCustomTipViewModelBase with Store {
IoniaCustomTipViewModelBase({
required this.amount,
required this.tip,
required this.ioniaMerchant})
: customTip = tip,
percentage = 0;
final IoniaMerchant ioniaMerchant;
final double amount;
final IoniaTip tip;
@observable
IoniaTip customTip;
@observable
double percentage;
@action
void onTipChanged(String value){
final _amount = value.isEmpty ? 0 : double.parse(value.replaceAll(',', '.'));
percentage = _amount/amount * 100;
customTip = IoniaTip(percentage: percentage, originalAmount: amount);
}
}

View file

@ -1,54 +0,0 @@
import 'package:cake_wallet/core/execution_state.dart';
import 'package:cake_wallet/ionia/ionia_service.dart';
import 'package:cake_wallet/ionia/ionia_gift_card.dart';
import 'package:mobx/mobx.dart';
import 'package:device_display_brightness/device_display_brightness.dart';
part 'ionia_gift_card_details_view_model.g.dart';
class IoniaGiftCardDetailsViewModel = IoniaGiftCardDetailsViewModelBase
with _$IoniaGiftCardDetailsViewModel;
abstract class IoniaGiftCardDetailsViewModelBase with Store {
IoniaGiftCardDetailsViewModelBase({required this.ioniaService, required this.giftCard})
: redeemState = InitialExecutionState(),
remainingAmount = giftCard.remainingAmount,
brightness = 0;
final IoniaService ioniaService;
double brightness;
@observable
IoniaGiftCard giftCard;
@observable
double remainingAmount;
@observable
ExecutionState redeemState;
@action
Future<void> redeem() async {
giftCard.remainingAmount = remainingAmount;
try {
redeemState = IsExecutingState();
await ioniaService.redeem(giftCardId: giftCard.id, amount: giftCard.remainingAmount);
giftCard = await ioniaService.getGiftCard(id: giftCard.id);
redeemState = ExecutedSuccessfullyState();
} catch (e) {
redeemState = FailureState(e.toString());
}
}
@action
Future<void> refeshCard() async {
giftCard = await ioniaService.getGiftCard(id: giftCard.id);
remainingAmount = giftCard.remainingAmount;
}
void increaseBrightness() async {
brightness = await DeviceDisplayBrightness.getBrightness();
await DeviceDisplayBrightness.setBrightness(1.0);
}
}

View file

@ -1,139 +0,0 @@
import 'package:cake_wallet/ionia/ionia_category.dart';
import 'package:cake_wallet/ionia/ionia_service.dart';
import 'package:cake_wallet/ionia/ionia_create_state.dart';
import 'package:cake_wallet/ionia/ionia_merchant.dart';
import 'package:mobx/mobx.dart';
part 'ionia_gift_cards_list_view_model.g.dart';
class IoniaGiftCardsListViewModel = IoniaGiftCardsListViewModelBase with _$IoniaGiftCardsListViewModel;
abstract class IoniaGiftCardsListViewModelBase with Store {
IoniaGiftCardsListViewModelBase({
required this.ioniaService,
}) :
cardState = IoniaNoCardState(),
ioniaMerchants = [],
ioniaCategories = IoniaCategory.allCategories,
selectedIndices = ObservableList<IoniaCategory>.of([IoniaCategory.all]),
scrollOffsetFromTop = 0.0,
merchantState = InitialIoniaMerchantLoadingState(),
createCardState = IoniaCreateCardState(),
searchString = '',
ioniaMerchantList = <IoniaMerchant>[] {
}
final IoniaService ioniaService;
List<IoniaMerchant> ioniaMerchantList;
String searchString;
@observable
double scrollOffsetFromTop;
@observable
IoniaCreateCardState createCardState;
@observable
IoniaFetchCardState cardState;
@observable
IoniaMerchantState merchantState;
@observable
List<IoniaMerchant> ioniaMerchants;
@observable
List<IoniaCategory> ioniaCategories;
@observable
ObservableList<IoniaCategory> selectedIndices;
@action
Future<void> createCard() async {
try {
createCardState = IoniaCreateCardLoading();
await ioniaService.createCard();
createCardState = IoniaCreateCardSuccess();
} catch (e) {
createCardState = IoniaCreateCardFailure(error: e.toString());
}
}
@action
void searchMerchant(String text) {
if (text.isEmpty) {
ioniaMerchants = ioniaMerchantList;
return;
}
searchString = text;
ioniaService.getMerchantsByFilter(search: searchString).then((value) {
ioniaMerchants = value;
});
}
Future<void> _getCard() async {
cardState = IoniaFetchingCard();
try {
final card = await ioniaService.getCard();
cardState = IoniaCardSuccess(card: card);
} catch (_) {
cardState = IoniaFetchCardFailure();
}
}
void getMerchants() {
merchantState = IoniaLoadingMerchantState();
ioniaService.getMerchantsByFilter(categories: selectedIndices).then((value) {
value.sort((a, b) => a.legalName.toLowerCase().compareTo(b.legalName.toLowerCase()));
ioniaMerchants = ioniaMerchantList = value;
merchantState = IoniaLoadedMerchantState();
});
}
@action
void setSelectedFilter(IoniaCategory category) {
if (category == IoniaCategory.all) {
selectedIndices.clear();
selectedIndices.add(category);
return;
}
if (category != IoniaCategory.all) {
selectedIndices.remove(IoniaCategory.all);
}
if (selectedIndices.contains(category)) {
selectedIndices.remove(category);
if (selectedIndices.isEmpty) {
selectedIndices.add(IoniaCategory.all);
}
return;
}
selectedIndices.add(category);
}
@action
void onSearchFilter(String text) {
if (text.isEmpty) {
ioniaCategories = IoniaCategory.allCategories;
} else {
ioniaCategories = IoniaCategory.allCategories
.where((e) => e.title.toLowerCase().contains(text.toLowerCase()),)
.toList();
}
}
@action
void resetIoniaCategories() {
ioniaCategories = IoniaCategory.allCategories;
}
void setScrollOffsetFromTop(double scrollOffset) {
scrollOffsetFromTop = scrollOffset;
}
}

View file

@ -1,62 +0,0 @@
import 'dart:async';
import 'package:cake_wallet/anypay/any_pay_chain.dart';
import 'package:mobx/mobx.dart';
import 'package:flutter/foundation.dart';
import 'package:cake_wallet/ionia/ionia_service.dart';
import 'package:cake_wallet/ionia/ionia_gift_card.dart';
import 'package:cake_wallet/anypay/any_pay_payment_committed_info.dart';
import 'package:cake_wallet/ionia/ionia_any_pay_payment_info.dart';
part 'ionia_payment_status_view_model.g.dart';
class IoniaPaymentStatusViewModel = IoniaPaymentStatusViewModelBase with _$IoniaPaymentStatusViewModel;
abstract class IoniaPaymentStatusViewModelBase with Store {
IoniaPaymentStatusViewModelBase(
this.ioniaService, {
required this.paymentInfo,
required this.committedInfo})
: error = '' {
_timer = Timer.periodic(updateTime, (timer) async {
await updatePaymentStatus();
if (giftCard != null) {
timer?.cancel();
}
});
}
static const updateTime = Duration(seconds: 3);
final IoniaService ioniaService;
final IoniaAnyPayPaymentInfo paymentInfo;
final AnyPayPaymentCommittedInfo committedInfo;
@observable
IoniaGiftCard? giftCard;
@observable
String error;
Timer? get timer => _timer;
bool get payingByBitcoin => paymentInfo.anyPayPayment.chain == AnyPayChain.btc;
Timer? _timer;
@action
Future<void> updatePaymentStatus() async {
try {
final giftCardId = await ioniaService.getPaymentStatus(
orderId: paymentInfo.ioniaOrder.id,
paymentId: paymentInfo.ioniaOrder.paymentId);
if (giftCardId != null) {
giftCard = await ioniaService.getGiftCard(id: giftCardId);
}
} catch (e) {
error = e.toString();
}
}
}

View file

@ -1,104 +0,0 @@
import 'package:flutter/foundation.dart';
import 'package:mobx/mobx.dart';
import 'package:cake_wallet/anypay/any_pay_payment.dart';
import 'package:cake_wallet/anypay/any_pay_payment_committed_info.dart';
import 'package:cake_wallet/core/execution_state.dart';
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';
class IoniaMerchPurchaseViewModel = IoniaMerchPurchaseViewModelBase with _$IoniaMerchPurchaseViewModel;
abstract class IoniaMerchPurchaseViewModelBase with Store {
IoniaMerchPurchaseViewModelBase({
required this.ioniaAnyPayService,
required this.amount,
required this.ioniaMerchant,
required this.sendViewModel,
}) : tipAmount = 0.0,
percentage = 0.0,
invoiceCreationState = InitialExecutionState(),
invoiceCommittingState = InitialExecutionState(),
tips = <IoniaTip>[
IoniaTip(percentage: 0, originalAmount: amount),
IoniaTip(percentage: 15, originalAmount: amount),
IoniaTip(percentage: 18, originalAmount: amount),
IoniaTip(percentage: 20, originalAmount: amount),
IoniaTip(percentage: 0, originalAmount: amount, isCustom: true),
] {
selectedTip = tips.first;
}
final double amount;
List<IoniaTip> tips;
@observable
IoniaTip? selectedTip;
final IoniaMerchant ioniaMerchant;
final SendViewModel sendViewModel;
final IoniaAnyPay ioniaAnyPayService;
IoniaAnyPayPaymentInfo? paymentInfo;
AnyPayPayment? get invoice => paymentInfo?.anyPayPayment;
AnyPayPaymentCommittedInfo? committedInfo;
@observable
ExecutionState invoiceCreationState;
@observable
ExecutionState invoiceCommittingState;
@observable
double percentage;
@computed
double get giftCardAmount => double.parse((amount + tipAmount).toStringAsFixed(2));
@computed
double get billAmount => double.parse((giftCardAmount * (1 - (ioniaMerchant.discount / 100))).toStringAsFixed(2));
@observable
double tipAmount;
@action
void addTip(IoniaTip tip) {
tipAmount = tip.additionalAmount;
selectedTip = tip;
}
@action
Future<void> createInvoice() async {
try {
invoiceCreationState = IsExecutingState();
paymentInfo = await ioniaAnyPayService.purchase(merchId: ioniaMerchant.id.toString(), amount: giftCardAmount);
invoiceCreationState = ExecutedSuccessfullyState();
} catch (e) {
invoiceCreationState = FailureState(e.toString());
}
}
@action
Future<void> commitPaymentInvoice() async {
try {
if (invoice == null) {
throw Exception('Invoice is created. Invoince is null');
}
invoiceCommittingState = IsExecutingState();
committedInfo = await ioniaAnyPayService.commitInvoice(invoice!);
invoiceCommittingState = ExecutedSuccessfullyState(payload: committedInfo!);
} catch (e) {
invoiceCommittingState = FailureState(e.toString());
}
}
}

View file

@ -87,6 +87,7 @@
"buy": "اشتري", "buy": "اشتري",
"buy_alert_content": ".ﺎﻬﻴﻟﺇ ﻞﻳﺪﺒﺘﻟﺍ ﻭﺃ Monero ﻭﺃ Litecoin ﻭﺃ Ethereum ﻭﺃ Bitcoin ﺔﻈﻔﺤﻣ ءﺎﺸﻧﺇ ﻰﺟﺮﻳ .", "buy_alert_content": ".ﺎﻬﻴﻟﺇ ﻞﻳﺪﺒﺘﻟﺍ ﻭﺃ Monero ﻭﺃ Litecoin ﻭﺃ Ethereum ﻭﺃ Bitcoin ﺔﻈﻔﺤﻣ ءﺎﺸﻧﺇ ﻰﺟﺮﻳ .",
"buy_bitcoin": "شراء Bitcoin", "buy_bitcoin": "شراء Bitcoin",
"buy_now": "اشتري الآن",
"buy_provider_unavailable": "مزود حاليا غير متوفر.", "buy_provider_unavailable": "مزود حاليا غير متوفر.",
"buy_with": "اشتر بواسطة", "buy_with": "اشتر بواسطة",
"by_cake_pay": "عن طريق Cake Pay", "by_cake_pay": "عن طريق Cake Pay",
@ -94,8 +95,7 @@
"cake_dark_theme": "موضوع الكعكة الظلام", "cake_dark_theme": "موضوع الكعكة الظلام",
"cake_pay_account_note": "قم بالتسجيل باستخدام عنوان بريد إلكتروني فقط لمشاهدة البطاقات وشرائها. حتى أن بعضها متوفر بسعر مخفض!", "cake_pay_account_note": "قم بالتسجيل باستخدام عنوان بريد إلكتروني فقط لمشاهدة البطاقات وشرائها. حتى أن بعضها متوفر بسعر مخفض!",
"cake_pay_learn_more": "شراء واسترداد بطاقات الهدايا على الفور في التطبيق!\nاسحب من اليسار إلى اليمين لمعرفة المزيد.", "cake_pay_learn_more": "شراء واسترداد بطاقات الهدايا على الفور في التطبيق!\nاسحب من اليسار إلى اليمين لمعرفة المزيد.",
"cake_pay_subtitle": "شراء بطاقات هدايا مخفضة السعر (الولايات المتحدة فقط)", "cake_pay_subtitle": "شراء بطاقات مسبقة الدفع وبطاقات الهدايا في جميع أنحاء العالم",
"cake_pay_title": "بطاقات هدايا Cake Pay",
"cake_pay_web_cards_subtitle": "اشتري بطاقات مدفوعة مسبقا وبطاقات هدايا في جميع أنحاء العالم", "cake_pay_web_cards_subtitle": "اشتري بطاقات مدفوعة مسبقا وبطاقات هدايا في جميع أنحاء العالم",
"cake_pay_web_cards_title": "بطاقات Cake Pay Web", "cake_pay_web_cards_title": "بطاقات Cake Pay Web",
"cake_wallet": "Cake Wallet", "cake_wallet": "Cake Wallet",
@ -123,6 +123,7 @@
"change_wallet_alert_title": "تغيير المحفظة الحالية", "change_wallet_alert_title": "تغيير المحفظة الحالية",
"choose_account": "اختر حساب", "choose_account": "اختر حساب",
"choose_address": "\n\nالرجاء اختيار عنوان:", "choose_address": "\n\nالرجاء اختيار عنوان:",
"choose_card_value": "اختر قيمة بطاقة",
"choose_derivation": "اختر اشتقاق المحفظة", "choose_derivation": "اختر اشتقاق المحفظة",
"choose_from_available_options": "اختر من بين الخيارات المتاحة:", "choose_from_available_options": "اختر من بين الخيارات المتاحة:",
"choose_one": "اختر واحدة", "choose_one": "اختر واحدة",
@ -166,6 +167,7 @@
"copy_address": "نسخ العنوان", "copy_address": "نسخ العنوان",
"copy_id": "نسخ معرف العملية", "copy_id": "نسخ معرف العملية",
"copyWalletConnectLink": "ﺎﻨﻫ ﻪﻘﺼﻟﺍﻭ dApp ﻦﻣ WalletConnect ﻂﺑﺍﺭ ﺦﺴﻧﺍ", "copyWalletConnectLink": "ﺎﻨﻫ ﻪﻘﺼﻟﺍﻭ dApp ﻦﻣ WalletConnect ﻂﺑﺍﺭ ﺦﺴﻧﺍ",
"countries": "بلدان",
"create_account": "إنشاء حساب", "create_account": "إنشاء حساب",
"create_backup": "انشئ نسخة احتياطية", "create_backup": "انشئ نسخة احتياطية",
"create_donation_link": "إنشاء رابط التبرع", "create_donation_link": "إنشاء رابط التبرع",
@ -178,6 +180,7 @@
"custom": "مخصصة", "custom": "مخصصة",
"custom_drag": "مخصص (عقد وسحب)", "custom_drag": "مخصص (عقد وسحب)",
"custom_redeem_amount": "مبلغ الاسترداد مخصص", "custom_redeem_amount": "مبلغ الاسترداد مخصص",
"custom_value": "القيمة الجمركية",
"dark_theme": "داكن", "dark_theme": "داكن",
"debit_card": "بطاقة ائتمان", "debit_card": "بطاقة ائتمان",
"debit_card_terms": "يخضع تخزين واستخدام رقم بطاقة الدفع الخاصة بك (وبيانات الاعتماد المقابلة لرقم بطاقة الدفع الخاصة بك) في هذه المحفظة الرقمية لشروط وأحكام اتفاقية حامل البطاقة المعمول بها مع جهة إصدار بطاقة الدفع ، كما هو معمول به من وقت لآخر.", "debit_card_terms": "يخضع تخزين واستخدام رقم بطاقة الدفع الخاصة بك (وبيانات الاعتماد المقابلة لرقم بطاقة الدفع الخاصة بك) في هذه المحفظة الرقمية لشروط وأحكام اتفاقية حامل البطاقة المعمول بها مع جهة إصدار بطاقة الدفع ، كما هو معمول به من وقت لآخر.",
@ -190,6 +193,7 @@
"delete_wallet": "حذف المحفظة", "delete_wallet": "حذف المحفظة",
"delete_wallet_confirm_message": "هل أنت متأكد أنك تريد حذف محفظة ${wallet_name}؟", "delete_wallet_confirm_message": "هل أنت متأكد أنك تريد حذف محفظة ${wallet_name}؟",
"deleteConnectionConfirmationPrompt": "ـﺑ ﻝﺎﺼﺗﻻﺍ ﻑﺬﺣ ﺪﻳﺮﺗ ﻚﻧﺃ ﺪﻛﺄﺘﻣ ﺖﻧﺃ ﻞﻫ", "deleteConnectionConfirmationPrompt": "ـﺑ ﻝﺎﺼﺗﻻﺍ ﻑﺬﺣ ﺪﻳﺮﺗ ﻚﻧﺃ ﺪﻛﺄﺘﻣ ﺖﻧﺃ ﻞﻫ",
"denominations": "الطوائف",
"descending": "النزول", "descending": "النزول",
"description": "ﻒﺻﻭ", "description": "ﻒﺻﻭ",
"destination_tag": "علامة الوجهة:", "destination_tag": "علامة الوجهة:",
@ -277,6 +281,7 @@
"expired": "منتهي الصلاحية", "expired": "منتهي الصلاحية",
"expires": "تنتهي", "expires": "تنتهي",
"expiresOn": "ﻲﻓ ﻪﺘﻴﺣﻼﺻ ﻲﻬﺘﻨﺗ", "expiresOn": "ﻲﻓ ﻪﺘﻴﺣﻼﺻ ﻲﻬﺘﻨﺗ",
"expiry_and_validity": "انتهاء الصلاحية والصلاحية",
"export_backup": "تصدير نسخة احتياطية", "export_backup": "تصدير نسخة احتياطية",
"extra_id": "معرف إضافي:", "extra_id": "معرف إضافي:",
"extracted_address_content": "سوف ترسل الأموال إلى\n${recipient_name}", "extracted_address_content": "سوف ترسل الأموال إلى\n${recipient_name}",
@ -384,6 +389,7 @@
"new_template": "قالب جديد", "new_template": "قالب جديد",
"new_wallet": "إنشاء محفظة جديدة", "new_wallet": "إنشاء محفظة جديدة",
"newConnection": "ﺪﻳﺪﺟ ﻝﺎﺼﺗﺍ", "newConnection": "ﺪﻳﺪﺟ ﻝﺎﺼﺗﺍ",
"no_cards_found": "لم يتم العثور على بطاقات",
"no_id_needed": "لا حاجة لID!", "no_id_needed": "لا حاجة لID!",
"no_id_required": "لا ID مطلوب. اشحن وانفق في أي مكان", "no_id_required": "لا ID مطلوب. اشحن وانفق في أي مكان",
"no_relay_on_domain": ".ﻡﺍﺪﺨﺘﺳﻼﻟ ﻊﺑﺎﺘﺘﻟﺍ ﺭﺎﻴﺘﺧﺍ ءﺎﺟﺮﻟﺍ .ﺡﺎﺘﻣ ﺮﻴﻏ ﻞﻴﺣﺮﺘﻟﺍ ﻥﺃ ﻭﺃ ﻡﺪﺨﺘﺴﻤﻟﺍ ﻝﺎﺠﻤﻟ ﻞﻴﺣﺮﺗ ﺪ", "no_relay_on_domain": ".ﻡﺍﺪﺨﺘﺳﻼﻟ ﻊﺑﺎﺘﺘﻟﺍ ﺭﺎﻴﺘﺧﺍ ءﺎﺟﺮﻟﺍ .ﺡﺎﺘﻣ ﺮﻴﻏ ﻞﻴﺣﺮﺘﻟﺍ ﻥﺃ ﻭﺃ ﻡﺪﺨﺘﺴﻤﻟﺍ ﻝﺎﺠﻤﻟ ﻞﻴﺣﺮﺗ ﺪ",
@ -452,6 +458,7 @@
"pre_seed_button_text": "انا أفهم. أرني سييد الخاص بي", "pre_seed_button_text": "انا أفهم. أرني سييد الخاص بي",
"pre_seed_description": "في الصفحة التالية ستشاهد سلسلة من الكلمات ${words}. هذه هي سييد الفريدة والخاصة بك وهي الطريقة الوحيدة لاسترداد محفظتك في حالة فقدها أو عطلها. تقع على عاتقك مسؤولية تدوينها وتخزينها في مكان آمن خارج تطبيق Cake Wallet.", "pre_seed_description": "في الصفحة التالية ستشاهد سلسلة من الكلمات ${words}. هذه هي سييد الفريدة والخاصة بك وهي الطريقة الوحيدة لاسترداد محفظتك في حالة فقدها أو عطلها. تقع على عاتقك مسؤولية تدوينها وتخزينها في مكان آمن خارج تطبيق Cake Wallet.",
"pre_seed_title": "مهم", "pre_seed_title": "مهم",
"prepaid_cards": "البطاقات المدفوعة مسبقا",
"prevent_screenshots": "منع لقطات الشاشة وتسجيل الشاشة", "prevent_screenshots": "منع لقطات الشاشة وتسجيل الشاشة",
"privacy": "خصوصية", "privacy": "خصوصية",
"privacy_policy": "سياسة الخصوصية", "privacy_policy": "سياسة الخصوصية",
@ -467,6 +474,7 @@
"purple_dark_theme": "موضوع الظلام الأرجواني", "purple_dark_theme": "موضوع الظلام الأرجواني",
"qr_fullscreen": "انقر لفتح ال QR بملء الشاشة", "qr_fullscreen": "انقر لفتح ال QR بملء الشاشة",
"qr_payment_amount": "يحتوي هذا ال QR على مبلغ الدفع. هل تريد تغير المبلغ فوق القيمة الحالية؟", "qr_payment_amount": "يحتوي هذا ال QR على مبلغ الدفع. هل تريد تغير المبلغ فوق القيمة الحالية؟",
"quantity": "كمية",
"question_to_disable_2fa": "هل أنت متأكد أنك تريد تعطيل Cake 2FA؟ لن تكون هناك حاجة إلى رمز 2FA للوصول إلى المحفظة ووظائف معينة.", "question_to_disable_2fa": "هل أنت متأكد أنك تريد تعطيل Cake 2FA؟ لن تكون هناك حاجة إلى رمز 2FA للوصول إلى المحفظة ووظائف معينة.",
"receivable_balance": "التوازن القادم", "receivable_balance": "التوازن القادم",
"receive": "استلام", "receive": "استلام",
@ -708,6 +716,7 @@
"tokenID": "ﻒﻳﺮﻌﺗ ﺔﻗﺎﻄﺑ", "tokenID": "ﻒﻳﺮﻌﺗ ﺔﻗﺎﻄﺑ",
"tor_connection": "ﺭﻮﺗ ﻝﺎﺼﺗﺍ", "tor_connection": "ﺭﻮﺗ ﻝﺎﺼﺗﺍ",
"tor_only": "Tor فقط", "tor_only": "Tor فقط",
"total": "المجموع",
"total_saving": "إجمالي المدخرات", "total_saving": "إجمالي المدخرات",
"totp_2fa_failure": "شفرة خاطئة. يرجى تجربة رمز مختلف أو إنشاء مفتاح سري جديد. استخدم تطبيق 2FA متوافقًا يدعم الرموز المكونة من 8 أرقام و SHA512.", "totp_2fa_failure": "شفرة خاطئة. يرجى تجربة رمز مختلف أو إنشاء مفتاح سري جديد. استخدم تطبيق 2FA متوافقًا يدعم الرموز المكونة من 8 أرقام و SHA512.",
"totp_2fa_success": "نجاح! تم تمكين Cake 2FA لهذه المحفظة. تذكر حفظ بذرة ذاكري في حالة فقد الوصول إلى المحفظة.", "totp_2fa_success": "نجاح! تم تمكين Cake 2FA لهذه المحفظة. تذكر حفظ بذرة ذاكري في حالة فقد الوصول إلى المحفظة.",
@ -798,6 +807,8 @@
"use_ssl": "استخدم SSL", "use_ssl": "استخدم SSL",
"use_suggested": "استخدام المقترح", "use_suggested": "استخدام المقترح",
"use_testnet": "استخدم testnet", "use_testnet": "استخدم testnet",
"value": "قيمة",
"value_type": "نوع القيمة",
"variable_pair_not_supported": "هذا الزوج المتغير غير مدعوم في التبادلات المحددة", "variable_pair_not_supported": "هذا الزوج المتغير غير مدعوم في التبادلات المحددة",
"verification": "تَحَقّق", "verification": "تَحَقّق",
"verify_with_2fa": "تحقق مع Cake 2FA", "verify_with_2fa": "تحقق مع Cake 2FA",

View file

@ -87,6 +87,7 @@
"buy": "Купуване", "buy": "Купуване",
"buy_alert_content": "В момента поддържаме само закупуването на Bitcoin, Ethereum, Litecoin и Monero. Моля, създайте или превключете към своя портфейл Bitcoin, Ethereum, Litecoin или Monero.", "buy_alert_content": "В момента поддържаме само закупуването на Bitcoin, Ethereum, Litecoin и Monero. Моля, създайте или превключете към своя портфейл Bitcoin, Ethereum, Litecoin или Monero.",
"buy_bitcoin": "Купуване на Bitcoin", "buy_bitcoin": "Купуване на Bitcoin",
"buy_now": "Купи сега",
"buy_provider_unavailable": "Понастоящем доставчик не е наличен.", "buy_provider_unavailable": "Понастоящем доставчик не е наличен.",
"buy_with": "Купуване чрез", "buy_with": "Купуване чрез",
"by_cake_pay": "от Cake Pay", "by_cake_pay": "от Cake Pay",
@ -94,8 +95,7 @@
"cake_dark_theme": "Торта тъмна тема", "cake_dark_theme": "Торта тъмна тема",
"cake_pay_account_note": "Регистрайте се само с един имейл, за да виждате и купувате карти. За някои има дори и отстъпка!", "cake_pay_account_note": "Регистрайте се само с един имейл, за да виждате и купувате карти. За някои има дори и отстъпка!",
"cake_pay_learn_more": "Купете и използвайте гифткарти директно в приложението!\nПлъзнете отляво надясно, за да научите още.", "cake_pay_learn_more": "Купете и използвайте гифткарти директно в приложението!\nПлъзнете отляво надясно, за да научите още.",
"cake_pay_subtitle": "Купете гифткарти на намалени цени (само за САЩ)", "cake_pay_subtitle": "Купете предплатени карти и карти за подаръци в световен мащаб",
"cake_pay_title": "Cake Pay Gift Карти",
"cake_pay_web_cards_subtitle": "Купете световно признати предплатени и гифт карти", "cake_pay_web_cards_subtitle": "Купете световно признати предплатени и гифт карти",
"cake_pay_web_cards_title": "Cake Pay Онлайн Карти", "cake_pay_web_cards_title": "Cake Pay Онлайн Карти",
"cake_wallet": "Cake Wallet", "cake_wallet": "Cake Wallet",
@ -123,6 +123,7 @@
"change_wallet_alert_title": "Смяна на сегашния портфейл", "change_wallet_alert_title": "Смяна на сегашния портфейл",
"choose_account": "Избиране на профил", "choose_account": "Избиране на профил",
"choose_address": "\n\nМоля, изберете адреса:", "choose_address": "\n\nМоля, изберете адреса:",
"choose_card_value": "Изберете стойност на картата",
"choose_derivation": "Изберете производно на портфейла", "choose_derivation": "Изберете производно на портфейла",
"choose_from_available_options": "Изберете от следните опции:", "choose_from_available_options": "Изберете от следните опции:",
"choose_one": "Изберете едно", "choose_one": "Изберете едно",
@ -166,6 +167,7 @@
"copy_address": "Copy Address", "copy_address": "Copy Address",
"copy_id": "Копиране на ID", "copy_id": "Копиране на ID",
"copyWalletConnectLink": "Копирайте връзката WalletConnect от dApp и я поставете тук", "copyWalletConnectLink": "Копирайте връзката WalletConnect от dApp и я поставете тук",
"countries": "Държави",
"create_account": "Създаване на профил", "create_account": "Създаване на профил",
"create_backup": "Създаване на резервно копие", "create_backup": "Създаване на резервно копие",
"create_donation_link": "Създайте връзка за дарение", "create_donation_link": "Създайте връзка за дарение",
@ -178,6 +180,7 @@
"custom": "персонализирано", "custom": "персонализирано",
"custom_drag": "Персонализиране (задръжте и плъзнете)", "custom_drag": "Персонализиране (задръжте и плъзнете)",
"custom_redeem_amount": "Персонализирана сума за използване", "custom_redeem_amount": "Персонализирана сума за използване",
"custom_value": "Персонализирана стойност",
"dark_theme": "Тъмно", "dark_theme": "Тъмно",
"debit_card": "Дебитна карта", "debit_card": "Дебитна карта",
"debit_card_terms": "Съхранението и използването на данните от вашата платежна карта в този дигитален портфейл подлежат на условията на съответното съгласие за картодържец от издателя на картата.", "debit_card_terms": "Съхранението и използването на данните от вашата платежна карта в този дигитален портфейл подлежат на условията на съответното съгласие за картодържец от издателя на картата.",
@ -190,6 +193,7 @@
"delete_wallet": "Изтриване на портфейл", "delete_wallet": "Изтриване на портфейл",
"delete_wallet_confirm_message": "Сигурни ли сте, че искате да изтриете протфейла ${wallet_name}?", "delete_wallet_confirm_message": "Сигурни ли сте, че искате да изтриете протфейла ${wallet_name}?",
"deleteConnectionConfirmationPrompt": "Сигурни ли сте, че искате да изтриете връзката към", "deleteConnectionConfirmationPrompt": "Сигурни ли сте, че искате да изтриете връзката към",
"denominations": "Деноминации",
"descending": "Низходящ", "descending": "Низходящ",
"description": "Описание", "description": "Описание",
"destination_tag": "Destination tag:", "destination_tag": "Destination tag:",
@ -277,6 +281,7 @@
"expired": "Изтекло", "expired": "Изтекло",
"expires": "Изтича", "expires": "Изтича",
"expiresOn": "Изтича на", "expiresOn": "Изтича на",
"expiry_and_validity": "Изтичане и валидност",
"export_backup": "Експортиране на резервно копие", "export_backup": "Експортиране на резервно копие",
"extra_id": "Допълнително ID:", "extra_id": "Допълнително ID:",
"extracted_address_content": "Ще изпратите средства на \n${recipient_name}", "extracted_address_content": "Ще изпратите средства на \n${recipient_name}",
@ -308,7 +313,7 @@
"gift_card_is_generated": "Gift Card бе създадена", "gift_card_is_generated": "Gift Card бе създадена",
"gift_card_number": "Номер на Gift Card", "gift_card_number": "Номер на Gift Card",
"gift_card_redeemed_note": "Използваните гифткарти ще се покажат тук", "gift_card_redeemed_note": "Използваните гифткарти ще се покажат тук",
"gift_cards": "Gift Карти", "gift_cards": "Карти за подаръци",
"gift_cards_unavailable": "В момента гифткарти могат да бъдат закупени само с Monero, Bitcoin и Litecoin", "gift_cards_unavailable": "В момента гифткарти могат да бъдат закупени само с Monero, Bitcoin и Litecoin",
"got_it": "Готово", "got_it": "Готово",
"gross_balance": "Брутен баланс", "gross_balance": "Брутен баланс",
@ -384,6 +389,7 @@
"new_template": "Нов шаблон", "new_template": "Нов шаблон",
"new_wallet": "Нов портфейл", "new_wallet": "Нов портфейл",
"newConnection": "Нова връзка", "newConnection": "Нова връзка",
"no_cards_found": "Не са намерени карти",
"no_id_needed": "Без нужда от документ за самоличност!", "no_id_needed": "Без нужда от документ за самоличност!",
"no_id_required": "Без нужда от документ за самоличност. Използвайте навсякъде", "no_id_required": "Без нужда от документ за самоличност. Използвайте навсякъде",
"no_relay_on_domain": "Няма реле за домейна на потребителя или релето не е налично. Моля, изберете реле, което да използвате.", "no_relay_on_domain": "Няма реле за домейна на потребителя или релето не е налично. Моля, изберете реле, което да използвате.",
@ -452,6 +458,7 @@
"pre_seed_button_text": "Разбирам. Покажи seed", "pre_seed_button_text": "Разбирам. Покажи seed",
"pre_seed_description": "На следващата страница ще видите поредица от ${words} думи. Това е вашият таен личен seed и е единственият начин да възстановите портфейла си. Отговорността за съхранението му на сигурно място извън приложението на Cake Wallet е изцяло ВАША.", "pre_seed_description": "На следващата страница ще видите поредица от ${words} думи. Това е вашият таен личен seed и е единственият начин да възстановите портфейла си. Отговорността за съхранението му на сигурно място извън приложението на Cake Wallet е изцяло ВАША.",
"pre_seed_title": "ВАЖНО", "pre_seed_title": "ВАЖНО",
"prepaid_cards": "Предплатени карти",
"prevent_screenshots": "Предотвратете екранни снимки и запис на екрана", "prevent_screenshots": "Предотвратете екранни снимки и запис на екрана",
"privacy": "Поверителност", "privacy": "Поверителност",
"privacy_policy": "Политика за поверителността", "privacy_policy": "Политика за поверителността",
@ -467,6 +474,7 @@
"purple_dark_theme": "Лилава тъмна тема", "purple_dark_theme": "Лилава тъмна тема",
"qr_fullscreen": "Натиснете, за да отворите QR кода на цял екран", "qr_fullscreen": "Натиснете, за да отворите QR кода на цял екран",
"qr_payment_amount": "Този QR код съдържа сума за плащане. Искате ли да промените стойността?", "qr_payment_amount": "Този QR код съдържа сума за плащане. Искате ли да промените стойността?",
"quantity": "Количество",
"question_to_disable_2fa": "Сигурни ли сте, че искате да деактивирате Cake 2FA? Вече няма да е необходим 2FA код за достъп до портфейла и определени функции.", "question_to_disable_2fa": "Сигурни ли сте, че искате да деактивирате Cake 2FA? Вече няма да е необходим 2FA код за достъп до портфейла и определени функции.",
"receivable_balance": "Баланс за вземания", "receivable_balance": "Баланс за вземания",
"receive": "Получи", "receive": "Получи",
@ -708,6 +716,7 @@
"tokenID": "документ за самоличност", "tokenID": "документ за самоличност",
"tor_connection": "Tor връзка", "tor_connection": "Tor връзка",
"tor_only": "Само чрез Tor", "tor_only": "Само чрез Tor",
"total": "Обща сума",
"total_saving": "Общо спестявания", "total_saving": "Общо спестявания",
"totp_2fa_failure": "Грешен код. Моля, опитайте с различен код или генерирайте нов таен ключ. Използвайте съвместимо 2FA приложение, което поддържа 8-цифрени кодове и SHA512.", "totp_2fa_failure": "Грешен код. Моля, опитайте с различен код или генерирайте нов таен ключ. Използвайте съвместимо 2FA приложение, което поддържа 8-цифрени кодове и SHA512.",
"totp_2fa_success": "Успех! Cake 2FA е активиран за този портфейл. Не забравяйте да запазите мнемоничното начало, в случай че загубите достъп до портфейла.", "totp_2fa_success": "Успех! Cake 2FA е активиран за този портфейл. Не забравяйте да запазите мнемоничното начало, в случай че загубите достъп до портфейла.",
@ -798,6 +807,8 @@
"use_ssl": "Използване на SSL", "use_ssl": "Използване на SSL",
"use_suggested": "Използване на предложеното", "use_suggested": "Използване на предложеното",
"use_testnet": "Използвайте TestNet", "use_testnet": "Използвайте TestNet",
"value": "Стойност",
"value_type": "Тип стойност",
"variable_pair_not_supported": "Този variable pair не се поддържа от избраната борса", "variable_pair_not_supported": "Този variable pair не се поддържа от избраната борса",
"verification": "Потвърждаване", "verification": "Потвърждаване",
"verify_with_2fa": "Проверете с Cake 2FA", "verify_with_2fa": "Проверете с Cake 2FA",

View file

@ -87,6 +87,7 @@
"buy": "Koupit", "buy": "Koupit",
"buy_alert_content": "V současné době podporujeme pouze nákup bitcoinů, etherea, litecoinů a monero. Vytvořte nebo přepněte na svou peněženku bitcoinů, etherea, litecoinů nebo monero.", "buy_alert_content": "V současné době podporujeme pouze nákup bitcoinů, etherea, litecoinů a monero. Vytvořte nebo přepněte na svou peněženku bitcoinů, etherea, litecoinů nebo monero.",
"buy_bitcoin": "Nakoupit Bitcoin", "buy_bitcoin": "Nakoupit Bitcoin",
"buy_now": "Kup nyní",
"buy_provider_unavailable": "Poskytovatel aktuálně nedostupný.", "buy_provider_unavailable": "Poskytovatel aktuálně nedostupný.",
"buy_with": "Nakoupit pomocí", "buy_with": "Nakoupit pomocí",
"by_cake_pay": "od Cake Pay", "by_cake_pay": "od Cake Pay",
@ -94,8 +95,7 @@
"cake_dark_theme": "Dort tmavé téma", "cake_dark_theme": "Dort tmavé téma",
"cake_pay_account_note": "Přihlaste se svou e-mailovou adresou pro zobrazení a nákup karet. Některé jsou dostupné ve slevě!", "cake_pay_account_note": "Přihlaste se svou e-mailovou adresou pro zobrazení a nákup karet. Některé jsou dostupné ve slevě!",
"cake_pay_learn_more": "Okamžitý nákup a uplatnění dárkových karet v aplikaci!\nPřejeďte prstem zleva doprava pro další informace.", "cake_pay_learn_more": "Okamžitý nákup a uplatnění dárkových karet v aplikaci!\nPřejeďte prstem zleva doprava pro další informace.",
"cake_pay_subtitle": "Kupte si zlevněné dárkové karty (pouze USA)", "cake_pay_subtitle": "Kupte si celosvětové předplacené karty a dárkové karty",
"cake_pay_title": "Cake Pay dárkové karty",
"cake_pay_web_cards_subtitle": "Kupte si celosvětové předplacené a dárkové karty", "cake_pay_web_cards_subtitle": "Kupte si celosvětové předplacené a dárkové karty",
"cake_pay_web_cards_title": "Cake Pay webové karty", "cake_pay_web_cards_title": "Cake Pay webové karty",
"cake_wallet": "Cake Wallet", "cake_wallet": "Cake Wallet",
@ -123,6 +123,7 @@
"change_wallet_alert_title": "Přepnout peněženku", "change_wallet_alert_title": "Přepnout peněženku",
"choose_account": "Zvolte částku", "choose_account": "Zvolte částku",
"choose_address": "\n\nProsím vyberte adresu:", "choose_address": "\n\nProsím vyberte adresu:",
"choose_card_value": "Vyberte hodnotu karty",
"choose_derivation": "Vyberte derivaci peněženky", "choose_derivation": "Vyberte derivaci peněženky",
"choose_from_available_options": "Zvolte si z dostupných možností:", "choose_from_available_options": "Zvolte si z dostupných možností:",
"choose_one": "Zvolte si", "choose_one": "Zvolte si",
@ -166,6 +167,7 @@
"copy_address": "Zkopírovat adresu", "copy_address": "Zkopírovat adresu",
"copy_id": "Kopírovat ID", "copy_id": "Kopírovat ID",
"copyWalletConnectLink": "Zkopírujte odkaz WalletConnect z dApp a vložte jej sem", "copyWalletConnectLink": "Zkopírujte odkaz WalletConnect z dApp a vložte jej sem",
"countries": "Země",
"create_account": "Vytvořit účet", "create_account": "Vytvořit účet",
"create_backup": "Vytvořit zálohu", "create_backup": "Vytvořit zálohu",
"create_donation_link": "Vytvořit odkaz na darování", "create_donation_link": "Vytvořit odkaz na darování",
@ -178,6 +180,7 @@
"custom": "vlastní", "custom": "vlastní",
"custom_drag": "Custom (Hold and Drag)", "custom_drag": "Custom (Hold and Drag)",
"custom_redeem_amount": "Vlastní částka pro uplatnění", "custom_redeem_amount": "Vlastní částka pro uplatnění",
"custom_value": "Vlastní hodnota",
"dark_theme": "Tmavý", "dark_theme": "Tmavý",
"debit_card": "Debetní karta", "debit_card": "Debetní karta",
"debit_card_terms": "Uložení a použití vašeho čísla platební karty (a přihlašovací údaje k vašemu číslu karty) v této digitální peněžence se řídí Obchodními podmínkami smlouvy příslušného držitele karty s vydavatelem karty (v jejich nejaktuálnější verzi).", "debit_card_terms": "Uložení a použití vašeho čísla platební karty (a přihlašovací údaje k vašemu číslu karty) v této digitální peněžence se řídí Obchodními podmínkami smlouvy příslušného držitele karty s vydavatelem karty (v jejich nejaktuálnější verzi).",
@ -190,6 +193,7 @@
"delete_wallet": "Smazat peněženku", "delete_wallet": "Smazat peněženku",
"delete_wallet_confirm_message": "Opravdu chcete smazat ${wallet_name} peněženku?", "delete_wallet_confirm_message": "Opravdu chcete smazat ${wallet_name} peněženku?",
"deleteConnectionConfirmationPrompt": "Jste si jisti, že chcete smazat připojení k?", "deleteConnectionConfirmationPrompt": "Jste si jisti, že chcete smazat připojení k?",
"denominations": "Označení",
"descending": "Klesající", "descending": "Klesající",
"description": "Popis", "description": "Popis",
"destination_tag": "Destination Tag:", "destination_tag": "Destination Tag:",
@ -277,6 +281,7 @@
"expired": "Vypršelo", "expired": "Vypršelo",
"expires": "Vyprší", "expires": "Vyprší",
"expiresOn": "Vyprší dne", "expiresOn": "Vyprší dne",
"expiry_and_validity": "Vypršení a platnost",
"export_backup": "Exportovat zálohu", "export_backup": "Exportovat zálohu",
"extra_id": "Extra ID:", "extra_id": "Extra ID:",
"extracted_address_content": "Prostředky budete posílat na\n${recipient_name}", "extracted_address_content": "Prostředky budete posílat na\n${recipient_name}",
@ -384,6 +389,7 @@
"new_template": "Nová šablona", "new_template": "Nová šablona",
"new_wallet": "Nová peněženka", "new_wallet": "Nová peněženka",
"newConnection": "Nové připojení", "newConnection": "Nové připojení",
"no_cards_found": "Žádné karty nenalezeny",
"no_id_needed": "Žádné ID není potřeba!", "no_id_needed": "Žádné ID není potřeba!",
"no_id_required": "Žádní ID není potřeba. Dobijte si a utrácejte kdekoliv", "no_id_required": "Žádní ID není potřeba. Dobijte si a utrácejte kdekoliv",
"no_relay_on_domain": "Pro doménu uživatele neexistuje přenos nebo je přenos nedostupný. Vyberte relé, které chcete použít.", "no_relay_on_domain": "Pro doménu uživatele neexistuje přenos nebo je přenos nedostupný. Vyberte relé, které chcete použít.",
@ -452,6 +458,7 @@
"pre_seed_button_text": "Rozumím. Ukaž mi můj seed.", "pre_seed_button_text": "Rozumím. Ukaž mi můj seed.",
"pre_seed_description": "Na následující stránce uvidíte sérii ${words} slov. Je to váš tzv. seed a je to JEDINÁ možnost, jak můžete později obnovit svou peněženku v případě ztráty nebo poruchy. Je VAŠÍ zodpovědností zapsat si ho a uložit si ho na bezpečném místě mimo aplikaci Cake Wallet.", "pre_seed_description": "Na následující stránce uvidíte sérii ${words} slov. Je to váš tzv. seed a je to JEDINÁ možnost, jak můžete později obnovit svou peněženku v případě ztráty nebo poruchy. Je VAŠÍ zodpovědností zapsat si ho a uložit si ho na bezpečném místě mimo aplikaci Cake Wallet.",
"pre_seed_title": "DŮLEŽITÉ", "pre_seed_title": "DŮLEŽITÉ",
"prepaid_cards": "Předplacené karty",
"prevent_screenshots": "Zabránit vytváření snímků obrazovky a nahrávání obrazovky", "prevent_screenshots": "Zabránit vytváření snímků obrazovky a nahrávání obrazovky",
"privacy": "Soukromí", "privacy": "Soukromí",
"privacy_policy": "Zásady ochrany soukromí", "privacy_policy": "Zásady ochrany soukromí",
@ -467,6 +474,7 @@
"purple_dark_theme": "Fialové temné téma", "purple_dark_theme": "Fialové temné téma",
"qr_fullscreen": "Poklepáním otevřete QR kód na celé obrazovce", "qr_fullscreen": "Poklepáním otevřete QR kód na celé obrazovce",
"qr_payment_amount": "Tento QR kód obsahuje i částku. Chcete přepsat současnou hodnotu?", "qr_payment_amount": "Tento QR kód obsahuje i částku. Chcete přepsat současnou hodnotu?",
"quantity": "Množství",
"question_to_disable_2fa": "Opravdu chcete deaktivovat Cake 2FA? Pro přístup k peněžence a některým funkcím již nebude potřeba kód 2FA.", "question_to_disable_2fa": "Opravdu chcete deaktivovat Cake 2FA? Pro přístup k peněžence a některým funkcím již nebude potřeba kód 2FA.",
"receivable_balance": "Zůstatek pohledávek", "receivable_balance": "Zůstatek pohledávek",
"receive": "Přijmout", "receive": "Přijmout",
@ -708,6 +716,7 @@
"tokenID": "ID", "tokenID": "ID",
"tor_connection": "Připojení Tor", "tor_connection": "Připojení Tor",
"tor_only": "Pouze Tor", "tor_only": "Pouze Tor",
"total": "Celkový",
"total_saving": "Celkem ušetřeno", "total_saving": "Celkem ušetřeno",
"totp_2fa_failure": "Nesprávný kód. Zkuste prosím jiný kód nebo vygenerujte nový tajný klíč. Použijte kompatibilní aplikaci 2FA, která podporuje 8místné kódy a SHA512.", "totp_2fa_failure": "Nesprávný kód. Zkuste prosím jiný kód nebo vygenerujte nový tajný klíč. Použijte kompatibilní aplikaci 2FA, která podporuje 8místné kódy a SHA512.",
"totp_2fa_success": "Úspěch! Pro tuto peněženku povolen Cake 2FA. Nezapomeňte si uložit mnemotechnický klíč pro případ, že ztratíte přístup k peněžence.", "totp_2fa_success": "Úspěch! Pro tuto peněženku povolen Cake 2FA. Nezapomeňte si uložit mnemotechnický klíč pro případ, že ztratíte přístup k peněžence.",
@ -798,6 +807,8 @@
"use_ssl": "Použít SSL", "use_ssl": "Použít SSL",
"use_suggested": "Použít doporučený", "use_suggested": "Použít doporučený",
"use_testnet": "Použijte testNet", "use_testnet": "Použijte testNet",
"value": "Hodnota",
"value_type": "Typ hodnoty",
"variable_pair_not_supported": "Tento pár s tržním kurzem není ve zvolené směnárně podporován", "variable_pair_not_supported": "Tento pár s tržním kurzem není ve zvolené směnárně podporován",
"verification": "Ověření", "verification": "Ověření",
"verify_with_2fa": "Ověřte pomocí Cake 2FA", "verify_with_2fa": "Ověřte pomocí Cake 2FA",

View file

@ -87,6 +87,7 @@
"buy": "Kaufen", "buy": "Kaufen",
"buy_alert_content": "Derzeit unterstützen wir nur den Kauf von Bitcoin, Ethereum, Litecoin und Monero. Bitte erstellen Sie Ihr Bitcoin-, Ethereum-, Litecoin- oder Monero-Wallet oder wechseln Sie zu diesem.", "buy_alert_content": "Derzeit unterstützen wir nur den Kauf von Bitcoin, Ethereum, Litecoin und Monero. Bitte erstellen Sie Ihr Bitcoin-, Ethereum-, Litecoin- oder Monero-Wallet oder wechseln Sie zu diesem.",
"buy_bitcoin": "Bitcoin kaufen", "buy_bitcoin": "Bitcoin kaufen",
"buy_now": "Kaufe jetzt",
"buy_provider_unavailable": "Anbieter derzeit nicht verfügbar.", "buy_provider_unavailable": "Anbieter derzeit nicht verfügbar.",
"buy_with": "Kaufen mit", "buy_with": "Kaufen mit",
"by_cake_pay": "von Cake Pay", "by_cake_pay": "von Cake Pay",
@ -94,8 +95,7 @@
"cake_dark_theme": "Cake Dark Thema", "cake_dark_theme": "Cake Dark Thema",
"cake_pay_account_note": "Melden Sie sich nur mit einer E-Mail-Adresse an, um Karten anzuzeigen und zu kaufen. Einige sind sogar mit Rabatt erhältlich!", "cake_pay_account_note": "Melden Sie sich nur mit einer E-Mail-Adresse an, um Karten anzuzeigen und zu kaufen. Einige sind sogar mit Rabatt erhältlich!",
"cake_pay_learn_more": "Kaufen und lösen Sie Geschenkkarten sofort in der App ein!\nWischen Sie von links nach rechts, um mehr zu erfahren.", "cake_pay_learn_more": "Kaufen und lösen Sie Geschenkkarten sofort in der App ein!\nWischen Sie von links nach rechts, um mehr zu erfahren.",
"cake_pay_subtitle": "Kaufen Sie ermäßigte Geschenkkarten (nur USA)", "cake_pay_subtitle": "Kaufen Sie weltweite Prepaid -Karten und Geschenkkarten",
"cake_pay_title": "Cake Pay-Geschenkkarten",
"cake_pay_web_cards_subtitle": "Kaufen Sie weltweit Prepaid-Karten und Geschenkkarten", "cake_pay_web_cards_subtitle": "Kaufen Sie weltweit Prepaid-Karten und Geschenkkarten",
"cake_pay_web_cards_title": "Cake Pay-Webkarten", "cake_pay_web_cards_title": "Cake Pay-Webkarten",
"cake_wallet": "Cake Wallet", "cake_wallet": "Cake Wallet",
@ -123,6 +123,7 @@
"change_wallet_alert_title": "Aktuelle Wallet ändern", "change_wallet_alert_title": "Aktuelle Wallet ändern",
"choose_account": "Konto auswählen", "choose_account": "Konto auswählen",
"choose_address": "\n\nBitte wählen Sie die Adresse:", "choose_address": "\n\nBitte wählen Sie die Adresse:",
"choose_card_value": "Wählen Sie einen Kartenwert",
"choose_derivation": "Wählen Sie Wallet-Ableitung", "choose_derivation": "Wählen Sie Wallet-Ableitung",
"choose_from_available_options": "Wähle aus verfügbaren Optionen:", "choose_from_available_options": "Wähle aus verfügbaren Optionen:",
"choose_one": "Wähle ein", "choose_one": "Wähle ein",
@ -166,6 +167,7 @@
"copy_address": "Adresse kopieren", "copy_address": "Adresse kopieren",
"copy_id": "ID kopieren", "copy_id": "ID kopieren",
"copyWalletConnectLink": "Kopieren Sie den WalletConnect-Link von dApp und fügen Sie ihn hier ein", "copyWalletConnectLink": "Kopieren Sie den WalletConnect-Link von dApp und fügen Sie ihn hier ein",
"countries": "Länder",
"create_account": "Konto erstellen", "create_account": "Konto erstellen",
"create_backup": "Backup erstellen", "create_backup": "Backup erstellen",
"create_donation_link": "Spendenlink erstellen", "create_donation_link": "Spendenlink erstellen",
@ -178,6 +180,7 @@
"custom": "benutzerdefiniert", "custom": "benutzerdefiniert",
"custom_drag": "Custom (Hold and Drag)", "custom_drag": "Custom (Hold and Drag)",
"custom_redeem_amount": "Benutzerdefinierter Einlösungsbetrag", "custom_redeem_amount": "Benutzerdefinierter Einlösungsbetrag",
"custom_value": "Benutzerdefinierten Wert",
"dark_theme": "Dunkel", "dark_theme": "Dunkel",
"debit_card": "Debitkarte", "debit_card": "Debitkarte",
"debit_card_terms": "Die Speicherung und Nutzung Ihrer Zahlungskartennummer (und Ihrer Zahlungskartennummer entsprechenden Anmeldeinformationen) in dieser digitalen Geldbörse unterliegt den Allgemeinen Geschäftsbedingungen des geltenden Karteninhabervertrags mit dem Zahlungskartenaussteller, gültig ab von Zeit zu Zeit.", "debit_card_terms": "Die Speicherung und Nutzung Ihrer Zahlungskartennummer (und Ihrer Zahlungskartennummer entsprechenden Anmeldeinformationen) in dieser digitalen Geldbörse unterliegt den Allgemeinen Geschäftsbedingungen des geltenden Karteninhabervertrags mit dem Zahlungskartenaussteller, gültig ab von Zeit zu Zeit.",
@ -190,6 +193,7 @@
"delete_wallet": "Wallet löschen", "delete_wallet": "Wallet löschen",
"delete_wallet_confirm_message": "Sind Sie sicher, dass Sie das ${wallet_name} Wallet löschen möchten?", "delete_wallet_confirm_message": "Sind Sie sicher, dass Sie das ${wallet_name} Wallet löschen möchten?",
"deleteConnectionConfirmationPrompt": "Sind Sie sicher, dass Sie die Verbindung zu löschen möchten?", "deleteConnectionConfirmationPrompt": "Sind Sie sicher, dass Sie die Verbindung zu löschen möchten?",
"denominations": "Konfessionen",
"descending": "Absteigend", "descending": "Absteigend",
"description": "Beschreibung", "description": "Beschreibung",
"destination_tag": "Ziel-Tag:", "destination_tag": "Ziel-Tag:",
@ -277,6 +281,7 @@
"expired": "Abgelaufen", "expired": "Abgelaufen",
"expires": "Läuft ab", "expires": "Läuft ab",
"expiresOn": "Läuft aus am", "expiresOn": "Läuft aus am",
"expiry_and_validity": "Ablauf und Gültigkeit",
"export_backup": "Sicherung exportieren", "export_backup": "Sicherung exportieren",
"extra_id": "Extra ID:", "extra_id": "Extra ID:",
"extracted_address_content": "Sie senden Geld an\n${recipient_name}", "extracted_address_content": "Sie senden Geld an\n${recipient_name}",
@ -384,6 +389,7 @@
"new_template": "neue Vorlage", "new_template": "neue Vorlage",
"new_wallet": "Neue Wallet", "new_wallet": "Neue Wallet",
"newConnection": "Neue Verbindung", "newConnection": "Neue Verbindung",
"no_cards_found": "Keine Karten gefunden",
"no_id_needed": "Keine ID erforderlich!", "no_id_needed": "Keine ID erforderlich!",
"no_id_required": "Keine ID erforderlich. Upgraden und überall ausgeben", "no_id_required": "Keine ID erforderlich. Upgraden und überall ausgeben",
"no_relay_on_domain": "Es gibt kein Relay für die Domäne des Benutzers oder das Relay ist nicht verfügbar. Bitte wählen Sie ein zu verwendendes Relais aus.", "no_relay_on_domain": "Es gibt kein Relay für die Domäne des Benutzers oder das Relay ist nicht verfügbar. Bitte wählen Sie ein zu verwendendes Relais aus.",
@ -442,8 +448,8 @@
"placeholder_transactions": "Ihre Transaktionen werden hier angezeigt", "placeholder_transactions": "Ihre Transaktionen werden hier angezeigt",
"please_fill_totp": "Bitte geben Sie den 8-stelligen Code ein, der auf Ihrem anderen Gerät vorhanden ist", "please_fill_totp": "Bitte geben Sie den 8-stelligen Code ein, der auf Ihrem anderen Gerät vorhanden ist",
"please_make_selection": "Bitte treffen Sie unten eine Auswahl zum Erstellen oder Wiederherstellen Ihrer Wallet.", "please_make_selection": "Bitte treffen Sie unten eine Auswahl zum Erstellen oder Wiederherstellen Ihrer Wallet.",
"please_reference_document": "Bitte verweisen Sie auf die folgenden Dokumente, um weitere Informationen zu erhalten.",
"Please_reference_document": "Weitere Informationen finden Sie in den Dokumenten unten.", "Please_reference_document": "Weitere Informationen finden Sie in den Dokumenten unten.",
"please_reference_document": "Bitte verweisen Sie auf die folgenden Dokumente, um weitere Informationen zu erhalten.",
"please_select": "Bitte auswählen:", "please_select": "Bitte auswählen:",
"please_select_backup_file": "Bitte wählen Sie die Sicherungsdatei und geben Sie das Sicherungskennwort ein.", "please_select_backup_file": "Bitte wählen Sie die Sicherungsdatei und geben Sie das Sicherungskennwort ein.",
"please_try_to_connect_to_another_node": "Bitte versuchen Sie, sich mit einem anderen Knoten zu verbinden", "please_try_to_connect_to_another_node": "Bitte versuchen Sie, sich mit einem anderen Knoten zu verbinden",
@ -453,6 +459,7 @@
"pre_seed_button_text": "Verstanden. Zeig mir meinen Seed", "pre_seed_button_text": "Verstanden. Zeig mir meinen Seed",
"pre_seed_description": "Auf der nächsten Seite sehen Sie eine Reihe von ${words} Wörtern. Dies ist Ihr einzigartiger und privater Seed und der EINZIGE Weg, um Ihre Wallet im Falle eines Verlusts oder einer Fehlfunktion wiederherzustellen. Es liegt in IHRER Verantwortung, ihn aufzuschreiben und an einem sicheren Ort außerhalb der Cake Wallet-App aufzubewahren.", "pre_seed_description": "Auf der nächsten Seite sehen Sie eine Reihe von ${words} Wörtern. Dies ist Ihr einzigartiger und privater Seed und der EINZIGE Weg, um Ihre Wallet im Falle eines Verlusts oder einer Fehlfunktion wiederherzustellen. Es liegt in IHRER Verantwortung, ihn aufzuschreiben und an einem sicheren Ort außerhalb der Cake Wallet-App aufzubewahren.",
"pre_seed_title": "WICHTIG", "pre_seed_title": "WICHTIG",
"prepaid_cards": "Karten mit Guthaben",
"prevent_screenshots": "Verhindern Sie Screenshots und Bildschirmaufzeichnungen", "prevent_screenshots": "Verhindern Sie Screenshots und Bildschirmaufzeichnungen",
"privacy": "Datenschutz", "privacy": "Datenschutz",
"privacy_policy": "Datenschutzrichtlinie", "privacy_policy": "Datenschutzrichtlinie",
@ -468,6 +475,7 @@
"purple_dark_theme": "Lila dunkle Thema", "purple_dark_theme": "Lila dunkle Thema",
"qr_fullscreen": "Tippen Sie hier, um den QR-Code im Vollbildmodus zu öffnen", "qr_fullscreen": "Tippen Sie hier, um den QR-Code im Vollbildmodus zu öffnen",
"qr_payment_amount": "This QR code contains a payment amount. Do you want to overwrite the current value?", "qr_payment_amount": "This QR code contains a payment amount. Do you want to overwrite the current value?",
"quantity": "Menge",
"question_to_disable_2fa": "Sind Sie sicher, dass Sie Cake 2FA deaktivieren möchten? Für den Zugriff auf die Wallet und bestimmte Funktionen wird kein 2FA-Code mehr benötigt.", "question_to_disable_2fa": "Sind Sie sicher, dass Sie Cake 2FA deaktivieren möchten? Für den Zugriff auf die Wallet und bestimmte Funktionen wird kein 2FA-Code mehr benötigt.",
"receivable_balance": "Forderungsbilanz", "receivable_balance": "Forderungsbilanz",
"receive": "Empfangen", "receive": "Empfangen",
@ -709,6 +717,7 @@
"tokenID": "AUSWEIS", "tokenID": "AUSWEIS",
"tor_connection": "Tor-Verbindung", "tor_connection": "Tor-Verbindung",
"tor_only": "Nur Tor", "tor_only": "Nur Tor",
"total": "Gesamt",
"total_saving": "Gesamteinsparungen", "total_saving": "Gesamteinsparungen",
"totp_2fa_failure": "Falscher Code. Bitte versuchen Sie es mit einem anderen Code oder generieren Sie einen neuen geheimen Schlüssel. Verwenden Sie eine kompatible 2FA-App, die 8-stellige Codes und SHA512 unterstützt.", "totp_2fa_failure": "Falscher Code. Bitte versuchen Sie es mit einem anderen Code oder generieren Sie einen neuen geheimen Schlüssel. Verwenden Sie eine kompatible 2FA-App, die 8-stellige Codes und SHA512 unterstützt.",
"totp_2fa_success": "Erfolg! Cake 2FA für dieses Wallet aktiviert. Denken Sie daran, Ihren mnemonischen Seed zu speichern, falls Sie den Zugriff auf die Wallet verlieren.", "totp_2fa_success": "Erfolg! Cake 2FA für dieses Wallet aktiviert. Denken Sie daran, Ihren mnemonischen Seed zu speichern, falls Sie den Zugriff auf die Wallet verlieren.",
@ -800,6 +809,8 @@
"use_ssl": "SSL verwenden", "use_ssl": "SSL verwenden",
"use_suggested": "Vorgeschlagen verwenden", "use_suggested": "Vorgeschlagen verwenden",
"use_testnet": "TESTNET verwenden", "use_testnet": "TESTNET verwenden",
"value": "Wert",
"value_type": "Werttyp",
"variable_pair_not_supported": "Dieses Variablenpaar wird von den ausgewählten Börsen nicht unterstützt", "variable_pair_not_supported": "Dieses Variablenpaar wird von den ausgewählten Börsen nicht unterstützt",
"verification": "Verifizierung", "verification": "Verifizierung",
"verify_with_2fa": "Verifizieren Sie mit Cake 2FA", "verify_with_2fa": "Verifizieren Sie mit Cake 2FA",

View file

@ -87,6 +87,7 @@
"buy": "Buy", "buy": "Buy",
"buy_alert_content": "Currently we only support the purchase of Bitcoin, Ethereum, Litecoin, and Monero. Please create or switch to your Bitcoin, Ethereum, Litecoin, or Monero wallet.", "buy_alert_content": "Currently we only support the purchase of Bitcoin, Ethereum, Litecoin, and Monero. Please create or switch to your Bitcoin, Ethereum, Litecoin, or Monero wallet.",
"buy_bitcoin": "Buy Bitcoin", "buy_bitcoin": "Buy Bitcoin",
"buy_now": "Buy Now",
"buy_provider_unavailable": "Provider currently unavailable.", "buy_provider_unavailable": "Provider currently unavailable.",
"buy_with": "Buy with", "buy_with": "Buy with",
"by_cake_pay": "by Cake Pay", "by_cake_pay": "by Cake Pay",
@ -94,8 +95,7 @@
"cake_dark_theme": "Cake Dark Theme", "cake_dark_theme": "Cake Dark Theme",
"cake_pay_account_note": "Sign up with just an email address to see and purchase cards. Some are even available at a discount!", "cake_pay_account_note": "Sign up with just an email address to see and purchase cards. Some are even available at a discount!",
"cake_pay_learn_more": "Instantly purchase and redeem gift cards in the app!\nSwipe left to right to learn more.", "cake_pay_learn_more": "Instantly purchase and redeem gift cards in the app!\nSwipe left to right to learn more.",
"cake_pay_subtitle": "Buy discounted gift cards (USA only)", "cake_pay_subtitle": "Buy worldwide prepaid cards and gift cards",
"cake_pay_title": "Cake Pay Gift Cards",
"cake_pay_web_cards_subtitle": "Buy worldwide prepaid cards and gift cards", "cake_pay_web_cards_subtitle": "Buy worldwide prepaid cards and gift cards",
"cake_pay_web_cards_title": "Cake Pay Web Cards", "cake_pay_web_cards_title": "Cake Pay Web Cards",
"cake_wallet": "Cake Wallet", "cake_wallet": "Cake Wallet",
@ -123,6 +123,7 @@
"change_wallet_alert_title": "Change current wallet", "change_wallet_alert_title": "Change current wallet",
"choose_account": "Choose account", "choose_account": "Choose account",
"choose_address": "\n\nPlease choose the address:", "choose_address": "\n\nPlease choose the address:",
"choose_card_value": "Choose a card value",
"choose_derivation": "Choose Wallet Derivation", "choose_derivation": "Choose Wallet Derivation",
"choose_from_available_options": "Choose from the available options:", "choose_from_available_options": "Choose from the available options:",
"choose_one": "Choose one", "choose_one": "Choose one",
@ -166,6 +167,7 @@
"copy_address": "Copy Address", "copy_address": "Copy Address",
"copy_id": "Copy ID", "copy_id": "Copy ID",
"copyWalletConnectLink": "Copy the WalletConnect link from dApp and paste here", "copyWalletConnectLink": "Copy the WalletConnect link from dApp and paste here",
"countries": "Countries",
"create_account": "Create Account", "create_account": "Create Account",
"create_backup": "Create backup", "create_backup": "Create backup",
"create_donation_link": "Create donation link", "create_donation_link": "Create donation link",
@ -178,6 +180,7 @@
"custom": "Custom", "custom": "Custom",
"custom_drag": "Custom (Hold and Drag)", "custom_drag": "Custom (Hold and Drag)",
"custom_redeem_amount": "Custom Redeem Amount", "custom_redeem_amount": "Custom Redeem Amount",
"custom_value": "Custom Value",
"dark_theme": "Dark", "dark_theme": "Dark",
"debit_card": "Debit Card", "debit_card": "Debit Card",
"debit_card_terms": "The storage and usage of your payment card number (and credentials corresponding to your payment card number) in this digital wallet are subject to the Terms and Conditions of the applicable cardholder agreement with the payment card issuer, as in effect from time to time.", "debit_card_terms": "The storage and usage of your payment card number (and credentials corresponding to your payment card number) in this digital wallet are subject to the Terms and Conditions of the applicable cardholder agreement with the payment card issuer, as in effect from time to time.",
@ -190,6 +193,7 @@
"delete_wallet": "Delete wallet", "delete_wallet": "Delete wallet",
"delete_wallet_confirm_message": "Are you sure that you want to delete ${wallet_name} wallet?", "delete_wallet_confirm_message": "Are you sure that you want to delete ${wallet_name} wallet?",
"deleteConnectionConfirmationPrompt": "Are you sure that you want to delete the connection to", "deleteConnectionConfirmationPrompt": "Are you sure that you want to delete the connection to",
"denominations": "Denominations",
"descending": "Descending", "descending": "Descending",
"description": "Description", "description": "Description",
"destination_tag": "Destination tag:", "destination_tag": "Destination tag:",
@ -277,6 +281,7 @@
"expired": "Expired", "expired": "Expired",
"expires": "Expires", "expires": "Expires",
"expiresOn": "Expires on", "expiresOn": "Expires on",
"expiry_and_validity": "Expiry and Validity",
"export_backup": "Export backup", "export_backup": "Export backup",
"extra_id": "Extra ID:", "extra_id": "Extra ID:",
"extracted_address_content": "You will be sending funds to\n${recipient_name}", "extracted_address_content": "You will be sending funds to\n${recipient_name}",
@ -384,6 +389,7 @@
"new_template": "New Template", "new_template": "New Template",
"new_wallet": "New Wallet", "new_wallet": "New Wallet",
"newConnection": "New Connection", "newConnection": "New Connection",
"no_cards_found": "No cards found",
"no_id_needed": "No ID needed!", "no_id_needed": "No ID needed!",
"no_id_required": "No ID required. Top up and spend anywhere", "no_id_required": "No ID required. Top up and spend anywhere",
"no_relay_on_domain": "There isn't a relay for user's domain or the relay is unavailable. Please choose a relay to use.", "no_relay_on_domain": "There isn't a relay for user's domain or the relay is unavailable. Please choose a relay to use.",
@ -452,6 +458,7 @@
"pre_seed_button_text": "I understand. Show me my seed", "pre_seed_button_text": "I understand. Show me my seed",
"pre_seed_description": "On the next page you will see a series of ${words} words. This is your unique and private seed and it is the ONLY way to recover your wallet in case of loss or malfunction. It is YOUR responsibility to write it down and store it in a safe place outside of the Cake Wallet app.", "pre_seed_description": "On the next page you will see a series of ${words} words. This is your unique and private seed and it is the ONLY way to recover your wallet in case of loss or malfunction. It is YOUR responsibility to write it down and store it in a safe place outside of the Cake Wallet app.",
"pre_seed_title": "IMPORTANT", "pre_seed_title": "IMPORTANT",
"prepaid_cards": "Prepaid Cards",
"prevent_screenshots": "Prevent screenshots and screen recording", "prevent_screenshots": "Prevent screenshots and screen recording",
"privacy": "Privacy", "privacy": "Privacy",
"privacy_policy": "Privacy Policy", "privacy_policy": "Privacy Policy",
@ -467,6 +474,7 @@
"purple_dark_theme": "Purple Dark Theme", "purple_dark_theme": "Purple Dark Theme",
"qr_fullscreen": "Tap to open full screen QR code", "qr_fullscreen": "Tap to open full screen QR code",
"qr_payment_amount": "This QR code contains a payment amount. Do you want to overwrite the current value?", "qr_payment_amount": "This QR code contains a payment amount. Do you want to overwrite the current value?",
"quantity": "Quantity",
"question_to_disable_2fa": "Are you sure that you want to disable Cake 2FA? A 2FA code will no longer be needed to access the wallet and certain functions.", "question_to_disable_2fa": "Are you sure that you want to disable Cake 2FA? A 2FA code will no longer be needed to access the wallet and certain functions.",
"receivable_balance": "Receivable Balance", "receivable_balance": "Receivable Balance",
"receive": "Receive", "receive": "Receive",
@ -708,6 +716,7 @@
"tokenID": "ID", "tokenID": "ID",
"tor_connection": "Tor connection", "tor_connection": "Tor connection",
"tor_only": "Tor only", "tor_only": "Tor only",
"total": "Total",
"total_saving": "Total Savings", "total_saving": "Total Savings",
"totp_2fa_failure": "Incorrect code. Please try a different code or generate a new secret key. Use a compatible 2FA app that supports 8-digit codes and SHA512.", "totp_2fa_failure": "Incorrect code. Please try a different code or generate a new secret key. Use a compatible 2FA app that supports 8-digit codes and SHA512.",
"totp_2fa_success": "Success! Cake 2FA enabled for this wallet. Remember to save your mnemonic seed in case you lose wallet access.", "totp_2fa_success": "Success! Cake 2FA enabled for this wallet. Remember to save your mnemonic seed in case you lose wallet access.",
@ -798,6 +807,8 @@
"use_ssl": "Use SSL", "use_ssl": "Use SSL",
"use_suggested": "Use Suggested", "use_suggested": "Use Suggested",
"use_testnet": "Use Testnet", "use_testnet": "Use Testnet",
"value": "Value",
"value_type": "Value Type",
"variable_pair_not_supported": "This variable pair is not supported with the selected exchanges", "variable_pair_not_supported": "This variable pair is not supported with the selected exchanges",
"verification": "Verification", "verification": "Verification",
"verify_with_2fa": "Verify with Cake 2FA", "verify_with_2fa": "Verify with Cake 2FA",

View file

@ -87,6 +87,7 @@
"buy": "Comprar", "buy": "Comprar",
"buy_alert_content": "Actualmente solo admitimos la compra de Bitcoin, Ethereum, Litecoin y Monero. Cree o cambie a su billetera Bitcoin, Ethereum, Litecoin o Monero.", "buy_alert_content": "Actualmente solo admitimos la compra de Bitcoin, Ethereum, Litecoin y Monero. Cree o cambie a su billetera Bitcoin, Ethereum, Litecoin o Monero.",
"buy_bitcoin": "Comprar Bitcoin", "buy_bitcoin": "Comprar Bitcoin",
"buy_now": "Comprar ahora",
"buy_provider_unavailable": "Proveedor actualmente no disponible.", "buy_provider_unavailable": "Proveedor actualmente no disponible.",
"buy_with": "Compra con", "buy_with": "Compra con",
"by_cake_pay": "por Cake Pay", "by_cake_pay": "por Cake Pay",
@ -94,8 +95,7 @@
"cake_dark_theme": "Tema oscuro del pastel", "cake_dark_theme": "Tema oscuro del pastel",
"cake_pay_account_note": "Regístrese con solo una dirección de correo electrónico para ver y comprar tarjetas. ¡Algunas incluso están disponibles con descuento!", "cake_pay_account_note": "Regístrese con solo una dirección de correo electrónico para ver y comprar tarjetas. ¡Algunas incluso están disponibles con descuento!",
"cake_pay_learn_more": "¡Compre y canjee tarjetas de regalo al instante en la aplicación!\nDeslice el dedo de izquierda a derecha para obtener más información.", "cake_pay_learn_more": "¡Compre y canjee tarjetas de regalo al instante en la aplicación!\nDeslice el dedo de izquierda a derecha para obtener más información.",
"cake_pay_subtitle": "Compre tarjetas de regalo con descuento (solo EE. UU.)", "cake_pay_subtitle": "Compre tarjetas prepagas y tarjetas de regalo en todo el mundo",
"cake_pay_title": "Tarjetas de regalo Cake Pay",
"cake_pay_web_cards_subtitle": "Compre tarjetas de prepago y tarjetas de regalo en todo el mundo", "cake_pay_web_cards_subtitle": "Compre tarjetas de prepago y tarjetas de regalo en todo el mundo",
"cake_pay_web_cards_title": "Tarjetas Web Cake Pay", "cake_pay_web_cards_title": "Tarjetas Web Cake Pay",
"cake_wallet": "Cake Wallet", "cake_wallet": "Cake Wallet",
@ -123,6 +123,7 @@
"change_wallet_alert_title": "Cambiar billetera actual", "change_wallet_alert_title": "Cambiar billetera actual",
"choose_account": "Elegir cuenta", "choose_account": "Elegir cuenta",
"choose_address": "\n\nPor favor elija la dirección:", "choose_address": "\n\nPor favor elija la dirección:",
"choose_card_value": "Elija un valor de tarjeta",
"choose_derivation": "Elija la derivación de la billetera", "choose_derivation": "Elija la derivación de la billetera",
"choose_from_available_options": "Elija entre las opciones disponibles:", "choose_from_available_options": "Elija entre las opciones disponibles:",
"choose_one": "Elige uno", "choose_one": "Elige uno",
@ -166,6 +167,7 @@
"copy_address": "Copiar dirección ", "copy_address": "Copiar dirección ",
"copy_id": "Copiar ID", "copy_id": "Copiar ID",
"copyWalletConnectLink": "Copie el enlace de WalletConnect de dApp y péguelo aquí", "copyWalletConnectLink": "Copie el enlace de WalletConnect de dApp y péguelo aquí",
"countries": "Países",
"create_account": "Crear Cuenta", "create_account": "Crear Cuenta",
"create_backup": "Crear copia de seguridad", "create_backup": "Crear copia de seguridad",
"create_donation_link": "Crear enlace de donación", "create_donation_link": "Crear enlace de donación",
@ -178,6 +180,7 @@
"custom": "Costumbre", "custom": "Costumbre",
"custom_drag": "Custom (mantenía y arrastre)", "custom_drag": "Custom (mantenía y arrastre)",
"custom_redeem_amount": "Cantidad de canje personalizada", "custom_redeem_amount": "Cantidad de canje personalizada",
"custom_value": "Valor personalizado",
"dark_theme": "Oscura", "dark_theme": "Oscura",
"debit_card": "Tarjeta de Débito", "debit_card": "Tarjeta de Débito",
"debit_card_terms": "El almacenamiento y el uso de su número de tarjeta de pago (y las credenciales correspondientes a su número de tarjeta de pago) en esta billetera digital están sujetos a los Términos y condiciones del acuerdo del titular de la tarjeta aplicable con el emisor de la tarjeta de pago, en vigor desde tiempo al tiempo.", "debit_card_terms": "El almacenamiento y el uso de su número de tarjeta de pago (y las credenciales correspondientes a su número de tarjeta de pago) en esta billetera digital están sujetos a los Términos y condiciones del acuerdo del titular de la tarjeta aplicable con el emisor de la tarjeta de pago, en vigor desde tiempo al tiempo.",
@ -190,6 +193,7 @@
"delete_wallet": "Eliminar billetera", "delete_wallet": "Eliminar billetera",
"delete_wallet_confirm_message": "¿Está seguro de que desea eliminar la billetera ${wallet_name}?", "delete_wallet_confirm_message": "¿Está seguro de que desea eliminar la billetera ${wallet_name}?",
"deleteConnectionConfirmationPrompt": "¿Está seguro de que desea eliminar la conexión a", "deleteConnectionConfirmationPrompt": "¿Está seguro de que desea eliminar la conexión a",
"denominations": "Denominaciones",
"descending": "Descendente", "descending": "Descendente",
"description": "Descripción", "description": "Descripción",
"destination_tag": "Etiqueta de destino:", "destination_tag": "Etiqueta de destino:",
@ -277,6 +281,7 @@
"expired": "Muerto", "expired": "Muerto",
"expires": "Caduca", "expires": "Caduca",
"expiresOn": "Expira el", "expiresOn": "Expira el",
"expiry_and_validity": "Vencimiento y validez",
"export_backup": "Exportar copia de seguridad", "export_backup": "Exportar copia de seguridad",
"extra_id": "ID adicional:", "extra_id": "ID adicional:",
"extracted_address_content": "Enviará fondos a\n${recipient_name}", "extracted_address_content": "Enviará fondos a\n${recipient_name}",
@ -384,6 +389,7 @@
"new_template": "Nueva plantilla", "new_template": "Nueva plantilla",
"new_wallet": "Nueva billetera", "new_wallet": "Nueva billetera",
"newConnection": "Nueva conexión", "newConnection": "Nueva conexión",
"no_cards_found": "No se encuentran cartas",
"no_id_needed": "¡No se necesita identificación!", "no_id_needed": "¡No se necesita identificación!",
"no_id_required": "No se requiere identificación. Recargue y gaste en cualquier lugar", "no_id_required": "No se requiere identificación. Recargue y gaste en cualquier lugar",
"no_relay_on_domain": "No hay una retransmisión para el dominio del usuario o la retransmisión no está disponible. Elija un relé para usar.", "no_relay_on_domain": "No hay una retransmisión para el dominio del usuario o la retransmisión no está disponible. Elija un relé para usar.",
@ -453,6 +459,7 @@
"pre_seed_button_text": "Entiendo. Muéstrame mi semilla", "pre_seed_button_text": "Entiendo. Muéstrame mi semilla",
"pre_seed_description": "En la página siguiente verá una serie de ${words} palabras. Esta es su semilla única y privada y es la ÚNICA forma de recuperar su billetera en caso de pérdida o mal funcionamiento. Es SU responsabilidad escribirlo y guardarlo en un lugar seguro fuera de la aplicación Cake Wallet.", "pre_seed_description": "En la página siguiente verá una serie de ${words} palabras. Esta es su semilla única y privada y es la ÚNICA forma de recuperar su billetera en caso de pérdida o mal funcionamiento. Es SU responsabilidad escribirlo y guardarlo en un lugar seguro fuera de la aplicación Cake Wallet.",
"pre_seed_title": "IMPORTANTE", "pre_seed_title": "IMPORTANTE",
"prepaid_cards": "Tajetas prepagadas",
"prevent_screenshots": "Evitar capturas de pantalla y grabación de pantalla", "prevent_screenshots": "Evitar capturas de pantalla y grabación de pantalla",
"privacy": "Privacidad", "privacy": "Privacidad",
"privacy_policy": "Política de privacidad", "privacy_policy": "Política de privacidad",
@ -468,6 +475,7 @@
"purple_dark_theme": "Tema morado oscuro", "purple_dark_theme": "Tema morado oscuro",
"qr_fullscreen": "Toque para abrir el código QR en pantalla completa", "qr_fullscreen": "Toque para abrir el código QR en pantalla completa",
"qr_payment_amount": "This QR code contains a payment amount. Do you want to overwrite the current value?", "qr_payment_amount": "This QR code contains a payment amount. Do you want to overwrite the current value?",
"quantity": "Cantidad",
"question_to_disable_2fa": "¿Está seguro de que desea deshabilitar Cake 2FA? Ya no se necesitará un código 2FA para acceder a la billetera y a ciertas funciones.", "question_to_disable_2fa": "¿Está seguro de que desea deshabilitar Cake 2FA? Ya no se necesitará un código 2FA para acceder a la billetera y a ciertas funciones.",
"receivable_balance": "Saldo de cuentas por cobrar", "receivable_balance": "Saldo de cuentas por cobrar",
"receive": "Recibir", "receive": "Recibir",
@ -709,6 +717,7 @@
"tokenID": "IDENTIFICACIÓN", "tokenID": "IDENTIFICACIÓN",
"tor_connection": "conexión tor", "tor_connection": "conexión tor",
"tor_only": "solo Tor", "tor_only": "solo Tor",
"total": "Total",
"total_saving": "Ahorro Total", "total_saving": "Ahorro Total",
"totp_2fa_failure": "Código incorrecto. Intente con un código diferente o genere una nueva clave secreta. Use una aplicación 2FA compatible que admita códigos de 8 dígitos y SHA512.", "totp_2fa_failure": "Código incorrecto. Intente con un código diferente o genere una nueva clave secreta. Use una aplicación 2FA compatible que admita códigos de 8 dígitos y SHA512.",
"totp_2fa_success": "¡Éxito! Cake 2FA habilitado para esta billetera. Recuerde guardar su semilla mnemotécnica en caso de que pierda el acceso a la billetera.", "totp_2fa_success": "¡Éxito! Cake 2FA habilitado para esta billetera. Recuerde guardar su semilla mnemotécnica en caso de que pierda el acceso a la billetera.",
@ -799,6 +808,8 @@
"use_ssl": "Utilice SSL", "use_ssl": "Utilice SSL",
"use_suggested": "Usar sugerido", "use_suggested": "Usar sugerido",
"use_testnet": "Use TestNet", "use_testnet": "Use TestNet",
"value": "Valor",
"value_type": "Tipo de valor",
"variable_pair_not_supported": "Este par de variables no es compatible con los intercambios seleccionados", "variable_pair_not_supported": "Este par de variables no es compatible con los intercambios seleccionados",
"verification": "Verificación", "verification": "Verificación",
"verify_with_2fa": "Verificar con Cake 2FA", "verify_with_2fa": "Verificar con Cake 2FA",

View file

@ -87,6 +87,7 @@
"buy": "Acheter", "buy": "Acheter",
"buy_alert_content": "Actuellement, nous ne prenons en charge que l'achat de Bitcoin, Ethereum, Litecoin et Monero. Veuillez créer ou basculer vers votre portefeuille Bitcoin, Ethereum, Litecoin ou Monero.", "buy_alert_content": "Actuellement, nous ne prenons en charge que l'achat de Bitcoin, Ethereum, Litecoin et Monero. Veuillez créer ou basculer vers votre portefeuille Bitcoin, Ethereum, Litecoin ou Monero.",
"buy_bitcoin": "Acheter du Bitcoin", "buy_bitcoin": "Acheter du Bitcoin",
"buy_now": "Acheter maintenant",
"buy_provider_unavailable": "Fournisseur actuellement indisponible.", "buy_provider_unavailable": "Fournisseur actuellement indisponible.",
"buy_with": "Acheter avec", "buy_with": "Acheter avec",
"by_cake_pay": "par Cake Pay", "by_cake_pay": "par Cake Pay",
@ -94,8 +95,7 @@
"cake_dark_theme": "Thème sombre du gâteau", "cake_dark_theme": "Thème sombre du gâteau",
"cake_pay_account_note": "Inscrivez-vous avec juste une adresse e-mail pour voir et acheter des cartes. Certaines sont même disponibles à prix réduit !", "cake_pay_account_note": "Inscrivez-vous avec juste une adresse e-mail pour voir et acheter des cartes. Certaines sont même disponibles à prix réduit !",
"cake_pay_learn_more": "Achetez et utilisez instantanément des cartes-cadeaux dans l'application !\nBalayer de gauche à droite pour en savoir plus.", "cake_pay_learn_more": "Achetez et utilisez instantanément des cartes-cadeaux dans l'application !\nBalayer de gauche à droite pour en savoir plus.",
"cake_pay_subtitle": "Achetez des cartes-cadeaux à prix réduit (États-Unis uniquement)", "cake_pay_subtitle": "Achetez des cartes et des cartes-cadeaux prépayées mondiales",
"cake_pay_title": "Cartes cadeaux Cake Pay",
"cake_pay_web_cards_subtitle": "Achetez des cartes prépayées et des cartes-cadeaux dans le monde entier", "cake_pay_web_cards_subtitle": "Achetez des cartes prépayées et des cartes-cadeaux dans le monde entier",
"cake_pay_web_cards_title": "Cartes Web Cake Pay", "cake_pay_web_cards_title": "Cartes Web Cake Pay",
"cake_wallet": "Cake Wallet", "cake_wallet": "Cake Wallet",
@ -123,6 +123,7 @@
"change_wallet_alert_title": "Changer le portefeuille (wallet) actuel", "change_wallet_alert_title": "Changer le portefeuille (wallet) actuel",
"choose_account": "Choisir le compte", "choose_account": "Choisir le compte",
"choose_address": "\n\nMerci de choisir l'adresse :", "choose_address": "\n\nMerci de choisir l'adresse :",
"choose_card_value": "Choisissez une valeur de carte",
"choose_derivation": "Choisissez le chemin de dérivation du portefeuille", "choose_derivation": "Choisissez le chemin de dérivation du portefeuille",
"choose_from_available_options": "Choisissez parmi les options disponibles :", "choose_from_available_options": "Choisissez parmi les options disponibles :",
"choose_one": "Choisissez-en un", "choose_one": "Choisissez-en un",
@ -166,6 +167,7 @@
"copy_address": "Copier l'Adresse", "copy_address": "Copier l'Adresse",
"copy_id": "Copier l'ID", "copy_id": "Copier l'ID",
"copyWalletConnectLink": "Copiez le lien WalletConnect depuis l'application décentralisée (dApp) et collez-le ici", "copyWalletConnectLink": "Copiez le lien WalletConnect depuis l'application décentralisée (dApp) et collez-le ici",
"countries": "Des pays",
"create_account": "Créer un compte", "create_account": "Créer un compte",
"create_backup": "Créer une sauvegarde", "create_backup": "Créer une sauvegarde",
"create_donation_link": "Créer un lien de don", "create_donation_link": "Créer un lien de don",
@ -178,6 +180,7 @@
"custom": "personnalisé", "custom": "personnalisé",
"custom_drag": "Custom (maintenir et traîner)", "custom_drag": "Custom (maintenir et traîner)",
"custom_redeem_amount": "Montant d'échange personnalisé", "custom_redeem_amount": "Montant d'échange personnalisé",
"custom_value": "Valeur personnalisée",
"dark_theme": "Sombre", "dark_theme": "Sombre",
"debit_card": "Carte de débit", "debit_card": "Carte de débit",
"debit_card_terms": "Le stockage et l'utilisation de votre numéro de carte de paiement (et des informations d'identification correspondant à votre numéro de carte de paiement) dans ce portefeuille (wallet) numérique peuvent être soumis aux conditions générales de l'accord du titulaire de carte parfois en vigueur avec l'émetteur de la carte de paiement.", "debit_card_terms": "Le stockage et l'utilisation de votre numéro de carte de paiement (et des informations d'identification correspondant à votre numéro de carte de paiement) dans ce portefeuille (wallet) numérique peuvent être soumis aux conditions générales de l'accord du titulaire de carte parfois en vigueur avec l'émetteur de la carte de paiement.",
@ -190,6 +193,7 @@
"delete_wallet": "Supprimer le portefeuille (wallet)", "delete_wallet": "Supprimer le portefeuille (wallet)",
"delete_wallet_confirm_message": "Êtes-vous sûr de vouloir supprimer le portefeuille (wallet) ${wallet_name}?", "delete_wallet_confirm_message": "Êtes-vous sûr de vouloir supprimer le portefeuille (wallet) ${wallet_name}?",
"deleteConnectionConfirmationPrompt": "Êtes-vous sûr de vouloir supprimer la connexion à", "deleteConnectionConfirmationPrompt": "Êtes-vous sûr de vouloir supprimer la connexion à",
"denominations": "Dénominations",
"descending": "Descendant", "descending": "Descendant",
"description": "Description", "description": "Description",
"destination_tag": "Tag de destination :", "destination_tag": "Tag de destination :",
@ -277,6 +281,7 @@
"expired": "Expirée", "expired": "Expirée",
"expires": "Expire", "expires": "Expire",
"expiresOn": "Expire le", "expiresOn": "Expire le",
"expiry_and_validity": "Expiration et validité",
"export_backup": "Exporter la sauvegarde", "export_backup": "Exporter la sauvegarde",
"extra_id": "ID supplémentaire :", "extra_id": "ID supplémentaire :",
"extracted_address_content": "Vous allez envoyer des fonds à\n${recipient_name}", "extracted_address_content": "Vous allez envoyer des fonds à\n${recipient_name}",
@ -308,7 +313,7 @@
"gift_card_is_generated": "La carte-cadeau est générée", "gift_card_is_generated": "La carte-cadeau est générée",
"gift_card_number": "Numéro de carte cadeau", "gift_card_number": "Numéro de carte cadeau",
"gift_card_redeemed_note": "Les cartes-cadeaux que vous avez utilisées apparaîtront ici", "gift_card_redeemed_note": "Les cartes-cadeaux que vous avez utilisées apparaîtront ici",
"gift_cards": "Cartes-Cadeaux", "gift_cards": "Cartes cadeaux",
"gift_cards_unavailable": "Les cartes-cadeaux ne sont disponibles à l'achat que via Monero, Bitcoin et Litecoin pour le moment", "gift_cards_unavailable": "Les cartes-cadeaux ne sont disponibles à l'achat que via Monero, Bitcoin et Litecoin pour le moment",
"got_it": "Compris", "got_it": "Compris",
"gross_balance": "Solde brut", "gross_balance": "Solde brut",
@ -384,6 +389,7 @@
"new_template": "Nouveau Modèle", "new_template": "Nouveau Modèle",
"new_wallet": "Nouveau Portefeuille (Wallet)", "new_wallet": "Nouveau Portefeuille (Wallet)",
"newConnection": "Nouvelle connexion", "newConnection": "Nouvelle connexion",
"no_cards_found": "Pas de cartes trouvées",
"no_id_needed": "Aucune pièce d'identité nécessaire !", "no_id_needed": "Aucune pièce d'identité nécessaire !",
"no_id_required": "Aucune pièce d'identité requise. Rechargez et dépensez n'importe où", "no_id_required": "Aucune pièce d'identité requise. Rechargez et dépensez n'importe où",
"no_relay_on_domain": "Il n'existe pas de relais pour le domaine de l'utilisateur ou le relais n'est pas disponible. Veuillez choisir un relais à utiliser.", "no_relay_on_domain": "Il n'existe pas de relais pour le domaine de l'utilisateur ou le relais n'est pas disponible. Veuillez choisir un relais à utiliser.",
@ -452,6 +458,7 @@
"pre_seed_button_text": "J'ai compris. Montrez moi ma phrase secrète (seed)", "pre_seed_button_text": "J'ai compris. Montrez moi ma phrase secrète (seed)",
"pre_seed_description": "Sur la page suivante vous allez voir une série de ${words} mots. Ils constituent votre phrase secrète (seed) unique et privée et sont le SEUL moyen de restaurer votre portefeuille (wallet) en cas de perte ou de dysfonctionnement. Il est de VOTRE responsabilité d'écrire cette série de mots et de la stocker dans un lieu sûr en dehors de l'application Cake Wallet.", "pre_seed_description": "Sur la page suivante vous allez voir une série de ${words} mots. Ils constituent votre phrase secrète (seed) unique et privée et sont le SEUL moyen de restaurer votre portefeuille (wallet) en cas de perte ou de dysfonctionnement. Il est de VOTRE responsabilité d'écrire cette série de mots et de la stocker dans un lieu sûr en dehors de l'application Cake Wallet.",
"pre_seed_title": "IMPORTANT", "pre_seed_title": "IMPORTANT",
"prepaid_cards": "Cartes prépayées",
"prevent_screenshots": "Empêcher les captures d'écran et l'enregistrement d'écran", "prevent_screenshots": "Empêcher les captures d'écran et l'enregistrement d'écran",
"privacy": "Confidentialité", "privacy": "Confidentialité",
"privacy_policy": "Politique de confidentialité", "privacy_policy": "Politique de confidentialité",
@ -467,6 +474,7 @@
"purple_dark_theme": "THÈME PURPLE DARK", "purple_dark_theme": "THÈME PURPLE DARK",
"qr_fullscreen": "Appuyez pour ouvrir le QR code en mode plein écran", "qr_fullscreen": "Appuyez pour ouvrir le QR code en mode plein écran",
"qr_payment_amount": "Ce QR code contient un montant de paiement. Voulez-vous remplacer la valeur actuelle ?", "qr_payment_amount": "Ce QR code contient un montant de paiement. Voulez-vous remplacer la valeur actuelle ?",
"quantity": "Quantité",
"question_to_disable_2fa": "Êtes-vous sûr de vouloir désactiver Cake 2FA ? Un code 2FA ne sera plus nécessaire pour accéder au portefeuille (wallet) et à certaines fonctions.", "question_to_disable_2fa": "Êtes-vous sûr de vouloir désactiver Cake 2FA ? Un code 2FA ne sera plus nécessaire pour accéder au portefeuille (wallet) et à certaines fonctions.",
"receivable_balance": "Solde de créances", "receivable_balance": "Solde de créances",
"receive": "Recevoir", "receive": "Recevoir",
@ -708,6 +716,7 @@
"tokenID": "IDENTIFIANT", "tokenID": "IDENTIFIANT",
"tor_connection": "Connexion Tor", "tor_connection": "Connexion Tor",
"tor_only": "Tor uniquement", "tor_only": "Tor uniquement",
"total": "Total",
"total_saving": "Économies totales", "total_saving": "Économies totales",
"totp_2fa_failure": "Code incorrect. Veuillez essayer un code différent ou générer un nouveau secret TOTP. Utilisez une application 2FA compatible qui prend en charge les codes à 8 chiffres et SHA512.", "totp_2fa_failure": "Code incorrect. Veuillez essayer un code différent ou générer un nouveau secret TOTP. Utilisez une application 2FA compatible qui prend en charge les codes à 8 chiffres et SHA512.",
"totp_2fa_success": "Succès! Cake 2FA est activé pour ce portefeuille. N'oubliez pas de sauvegarder votre phrase secrète (seed) au cas où vous perdriez l'accès au portefeuille (wallet).", "totp_2fa_success": "Succès! Cake 2FA est activé pour ce portefeuille. N'oubliez pas de sauvegarder votre phrase secrète (seed) au cas où vous perdriez l'accès au portefeuille (wallet).",
@ -798,6 +807,8 @@
"use_ssl": "Utiliser SSL", "use_ssl": "Utiliser SSL",
"use_suggested": "Suivre la suggestion", "use_suggested": "Suivre la suggestion",
"use_testnet": "Utiliser TestNet", "use_testnet": "Utiliser TestNet",
"value": "Valeur",
"value_type": "Type de valeur",
"variable_pair_not_supported": "Cette paire variable n'est pas prise en charge avec les échanges sélectionnés", "variable_pair_not_supported": "Cette paire variable n'est pas prise en charge avec les échanges sélectionnés",
"verification": "Vérification", "verification": "Vérification",
"verify_with_2fa": "Vérifier avec Cake 2FA", "verify_with_2fa": "Vérifier avec Cake 2FA",

View file

@ -87,6 +87,7 @@
"buy": "Sayi", "buy": "Sayi",
"buy_alert_content": "A halin yanzu muna tallafawa kawai siyan Bitcoin, Ethereum, Litecoin, da Monero. Da fatan za a ƙirƙiri ko canza zuwa Bitcoin, Ethereum, Litecoin, ko Monero walat.", "buy_alert_content": "A halin yanzu muna tallafawa kawai siyan Bitcoin, Ethereum, Litecoin, da Monero. Da fatan za a ƙirƙiri ko canza zuwa Bitcoin, Ethereum, Litecoin, ko Monero walat.",
"buy_bitcoin": "Sayi Bitcoin", "buy_bitcoin": "Sayi Bitcoin",
"buy_now": "Saya yanzu",
"buy_provider_unavailable": "Mai ba da kyauta a halin yanzu babu.", "buy_provider_unavailable": "Mai ba da kyauta a halin yanzu babu.",
"buy_with": "Saya da", "buy_with": "Saya da",
"by_cake_pay": "da Cake Pay", "by_cake_pay": "da Cake Pay",
@ -94,8 +95,7 @@
"cake_dark_theme": "Cake Dark Jigo", "cake_dark_theme": "Cake Dark Jigo",
"cake_pay_account_note": "Yi rajista tare da adireshin imel kawai don gani da siyan katunan. Wasu ma suna samuwa a rangwame!", "cake_pay_account_note": "Yi rajista tare da adireshin imel kawai don gani da siyan katunan. Wasu ma suna samuwa a rangwame!",
"cake_pay_learn_more": "Nan take siya ku kwaso katunan kyaututtuka a cikin app!\nTake hagu zuwa dama don ƙarin koyo.", "cake_pay_learn_more": "Nan take siya ku kwaso katunan kyaututtuka a cikin app!\nTake hagu zuwa dama don ƙarin koyo.",
"cake_pay_subtitle": "Sayi katunan kyauta masu rahusa (Amurka kawai)", "cake_pay_subtitle": "Sayi katunan shirye-shiryen duniya da katunan kyauta",
"cake_pay_title": "Cake Pay Gift Cards",
"cake_pay_web_cards_subtitle": "Sayi katunan da aka riga aka biya na duniya da katunan kyauta", "cake_pay_web_cards_subtitle": "Sayi katunan da aka riga aka biya na duniya da katunan kyauta",
"cake_pay_web_cards_title": "Cake Pay Web Cards", "cake_pay_web_cards_title": "Cake Pay Web Cards",
"cake_wallet": "Cake Wallet", "cake_wallet": "Cake Wallet",
@ -123,6 +123,7 @@
"change_wallet_alert_title": "Canja walat yanzu", "change_wallet_alert_title": "Canja walat yanzu",
"choose_account": "Zaɓi asusu", "choose_account": "Zaɓi asusu",
"choose_address": "\n\n Da fatan za a zaɓi adireshin:", "choose_address": "\n\n Da fatan za a zaɓi adireshin:",
"choose_card_value": "Zabi darajar katin",
"choose_derivation": "Zaɓi walatawa", "choose_derivation": "Zaɓi walatawa",
"choose_from_available_options": "Zaɓi daga zaɓuɓɓukan da ake da su:", "choose_from_available_options": "Zaɓi daga zaɓuɓɓukan da ake da su:",
"choose_one": "Zaɓi ɗaya", "choose_one": "Zaɓi ɗaya",
@ -166,6 +167,7 @@
"copy_address": "Kwafi Adireshin", "copy_address": "Kwafi Adireshin",
"copy_id": "Kwafi ID", "copy_id": "Kwafi ID",
"copyWalletConnectLink": "Kwafi hanyar haɗin WalletConnect daga dApp kuma liƙa a nan", "copyWalletConnectLink": "Kwafi hanyar haɗin WalletConnect daga dApp kuma liƙa a nan",
"countries": "Kasashe",
"create_account": "Kirkira ajiya", "create_account": "Kirkira ajiya",
"create_backup": "Ƙirƙiri madadin", "create_backup": "Ƙirƙiri madadin",
"create_donation_link": "Sanya hanyar sadaka", "create_donation_link": "Sanya hanyar sadaka",
@ -178,6 +180,7 @@
"custom": "al'ada", "custom": "al'ada",
"custom_drag": "Al'ada (riƙe da ja)", "custom_drag": "Al'ada (riƙe da ja)",
"custom_redeem_amount": "Adadin Fansa na Musamman", "custom_redeem_amount": "Adadin Fansa na Musamman",
"custom_value": "Darajar al'ada",
"dark_theme": "Duhu", "dark_theme": "Duhu",
"debit_card": "Katin Zare kudi", "debit_card": "Katin Zare kudi",
"debit_card_terms": "Adana da amfani da lambar katin kuɗin ku (da takaddun shaida masu dacewa da lambar katin kuɗin ku) a cikin wannan walat ɗin dijital suna ƙarƙashin Sharuɗɗa da Sharuɗɗa na yarjejeniya mai amfani da katin tare da mai fitar da katin biyan kuɗi, kamar yadda yake aiki daga lokaci zuwa lokaci.", "debit_card_terms": "Adana da amfani da lambar katin kuɗin ku (da takaddun shaida masu dacewa da lambar katin kuɗin ku) a cikin wannan walat ɗin dijital suna ƙarƙashin Sharuɗɗa da Sharuɗɗa na yarjejeniya mai amfani da katin tare da mai fitar da katin biyan kuɗi, kamar yadda yake aiki daga lokaci zuwa lokaci.",
@ -190,6 +193,7 @@
"delete_wallet": "Share walat", "delete_wallet": "Share walat",
"delete_wallet_confirm_message": "Shin kun tabbata cewa kuna son share jakar ${wallet_name}?", "delete_wallet_confirm_message": "Shin kun tabbata cewa kuna son share jakar ${wallet_name}?",
"deleteConnectionConfirmationPrompt": "Shin kun tabbata cewa kuna son share haɗin zuwa", "deleteConnectionConfirmationPrompt": "Shin kun tabbata cewa kuna son share haɗin zuwa",
"denominations": "Denominations",
"descending": "Saukowa", "descending": "Saukowa",
"description": "Bayani", "description": "Bayani",
"destination_tag": "Tambarin makoma:", "destination_tag": "Tambarin makoma:",
@ -277,6 +281,7 @@
"expired": "Karewa", "expired": "Karewa",
"expires": "Ya ƙare", "expires": "Ya ƙare",
"expiresOn": "Yana ƙarewa", "expiresOn": "Yana ƙarewa",
"expiry_and_validity": "Karewa da inganci",
"export_backup": "Ajiyayyen fitarwa", "export_backup": "Ajiyayyen fitarwa",
"extra_id": "Karin ID:", "extra_id": "Karin ID:",
"extracted_address_content": "Za ku aika da kudade zuwa\n${recipient_name}", "extracted_address_content": "Za ku aika da kudade zuwa\n${recipient_name}",
@ -384,6 +389,7 @@
"new_template": "Sabon Samfura", "new_template": "Sabon Samfura",
"new_wallet": "Sabuwar Wallet", "new_wallet": "Sabuwar Wallet",
"newConnection": "Sabuwar Haɗi", "newConnection": "Sabuwar Haɗi",
"no_cards_found": "Babu katunan da aka samo",
"no_id_needed": "Babu ID da ake buƙata!", "no_id_needed": "Babu ID da ake buƙata!",
"no_id_required": "Babu ID da ake buƙata. Yi da kuma ciyar a ko'ina", "no_id_required": "Babu ID da ake buƙata. Yi da kuma ciyar a ko'ina",
"no_relay_on_domain": "Babu gudun ba da sanda ga yankin mai amfani ko kuma ba a samu ba. Da fatan za a zaɓi gudun ba da sanda don amfani.", "no_relay_on_domain": "Babu gudun ba da sanda ga yankin mai amfani ko kuma ba a samu ba. Da fatan za a zaɓi gudun ba da sanda don amfani.",
@ -454,6 +460,7 @@
"pre_seed_button_text": "Ina fahimta. Nuna mini seed din nawa", "pre_seed_button_text": "Ina fahimta. Nuna mini seed din nawa",
"pre_seed_description": "A kan shafin nan za ku ga wata ƙungiya na ${words} kalmomi. Wannan shine tsarin daban-daban ku kuma na sirri kuma shine hanya ɗaya kadai don mai da purse dinku a cikin yanayin rasa ko rashin aiki. Yana da damar da kuke a cikin tabbatar da kuyi rubuta shi kuma kuyi ajiye shi a wuri na aminci wanda ya wuce wurin app na Cake Wallet.", "pre_seed_description": "A kan shafin nan za ku ga wata ƙungiya na ${words} kalmomi. Wannan shine tsarin daban-daban ku kuma na sirri kuma shine hanya ɗaya kadai don mai da purse dinku a cikin yanayin rasa ko rashin aiki. Yana da damar da kuke a cikin tabbatar da kuyi rubuta shi kuma kuyi ajiye shi a wuri na aminci wanda ya wuce wurin app na Cake Wallet.",
"pre_seed_title": "MUHIMMANCI", "pre_seed_title": "MUHIMMANCI",
"prepaid_cards": "Katunan shirye-shirye",
"prevent_screenshots": "Fada lambobi da jarrabobi na kayan lambobi", "prevent_screenshots": "Fada lambobi da jarrabobi na kayan lambobi",
"privacy": "Keɓantawa", "privacy": "Keɓantawa",
"privacy_policy": "takardar kebantawa", "privacy_policy": "takardar kebantawa",
@ -469,6 +476,7 @@
"purple_dark_theme": "M duhu jigo", "purple_dark_theme": "M duhu jigo",
"qr_fullscreen": "Matsa don buɗe lambar QR na cikakken allo", "qr_fullscreen": "Matsa don buɗe lambar QR na cikakken allo",
"qr_payment_amount": "Wannan QR code yana da adadin kuɗi. Kuna so ku overwrite wannan adadi?", "qr_payment_amount": "Wannan QR code yana da adadin kuɗi. Kuna so ku overwrite wannan adadi?",
"quantity": "Yawa",
"question_to_disable_2fa": "Ka tabbata cewa kana son kashe cake 2fa? Ba za a sake buƙatar lambar 2FA ba don samun damar yin walat da takamaiman ayyuka.", "question_to_disable_2fa": "Ka tabbata cewa kana son kashe cake 2fa? Ba za a sake buƙatar lambar 2FA ba don samun damar yin walat da takamaiman ayyuka.",
"receivable_balance": "Daidaituwa da daidaituwa", "receivable_balance": "Daidaituwa da daidaituwa",
"receive": "Samu", "receive": "Samu",
@ -710,6 +718,7 @@
"tokenID": "ID", "tokenID": "ID",
"tor_connection": "Tor haɗin gwiwa", "tor_connection": "Tor haɗin gwiwa",
"tor_only": "Tor kawai", "tor_only": "Tor kawai",
"total": "Duka",
"total_saving": "Jimlar Adana", "total_saving": "Jimlar Adana",
"totp_2fa_failure": "Ba daidai ba. Da fatan za a gwada wata lamba ta daban ko samar da sabon maɓallin asirin. Yi amfani da aikace-aikacen da ya dace 2FA wanda ke tallafawa lambobin lambobi 8 da Sha512.", "totp_2fa_failure": "Ba daidai ba. Da fatan za a gwada wata lamba ta daban ko samar da sabon maɓallin asirin. Yi amfani da aikace-aikacen da ya dace 2FA wanda ke tallafawa lambobin lambobi 8 da Sha512.",
"totp_2fa_success": "Nasara! Cake 2FA ya dogara da wannan waljin. Ka tuna domin adana zuriyar mnemmonic naka idan ka rasa damar walat.", "totp_2fa_success": "Nasara! Cake 2FA ya dogara da wannan waljin. Ka tuna domin adana zuriyar mnemmonic naka idan ka rasa damar walat.",
@ -800,6 +809,8 @@
"use_ssl": "Yi amfani da SSL", "use_ssl": "Yi amfani da SSL",
"use_suggested": "Amfani da Shawarwari", "use_suggested": "Amfani da Shawarwari",
"use_testnet": "Amfani da gwaji", "use_testnet": "Amfani da gwaji",
"value": "Daraja",
"value_type": "Nau'in darajar",
"variable_pair_not_supported": "Ba a samun goyan bayan wannan m biyu tare da zaɓaɓɓun musayar", "variable_pair_not_supported": "Ba a samun goyan bayan wannan m biyu tare da zaɓaɓɓun musayar",
"verification": "tabbatar", "verification": "tabbatar",
"verify_with_2fa": "Tabbatar da Cake 2FA", "verify_with_2fa": "Tabbatar da Cake 2FA",

View file

@ -87,6 +87,7 @@
"buy": "खरीदें", "buy": "खरीदें",
"buy_alert_content": "वर्तमान में हम केवल बिटकॉइन, एथेरियम, लाइटकॉइन और मोनेरो की खरीद का समर्थन करते हैं। कृपया अपना बिटकॉइन, एथेरियम, लाइटकॉइन, या मोनेरो वॉलेट बनाएं या उस पर स्विच करें।", "buy_alert_content": "वर्तमान में हम केवल बिटकॉइन, एथेरियम, लाइटकॉइन और मोनेरो की खरीद का समर्थन करते हैं। कृपया अपना बिटकॉइन, एथेरियम, लाइटकॉइन, या मोनेरो वॉलेट बनाएं या उस पर स्विच करें।",
"buy_bitcoin": "बिटकॉइन खरीदें", "buy_bitcoin": "बिटकॉइन खरीदें",
"buy_now": "अभी खरीदें",
"buy_provider_unavailable": "वर्तमान में प्रदाता अनुपलब्ध है।", "buy_provider_unavailable": "वर्तमान में प्रदाता अनुपलब्ध है।",
"buy_with": "के साथ खरीदें", "buy_with": "के साथ खरीदें",
"by_cake_pay": "केकपे द्वारा", "by_cake_pay": "केकपे द्वारा",
@ -94,8 +95,7 @@
"cake_dark_theme": "केक डार्क थीम", "cake_dark_theme": "केक डार्क थीम",
"cake_pay_account_note": "कार्ड देखने और खरीदने के लिए केवल एक ईमेल पते के साथ साइन अप करें। कुछ छूट पर भी उपलब्ध हैं!", "cake_pay_account_note": "कार्ड देखने और खरीदने के लिए केवल एक ईमेल पते के साथ साइन अप करें। कुछ छूट पर भी उपलब्ध हैं!",
"cake_pay_learn_more": "ऐप में उपहार कार्ड तुरंत खरीदें और रिडीम करें!\nअधिक जानने के लिए बाएं से दाएं स्वाइप करें।", "cake_pay_learn_more": "ऐप में उपहार कार्ड तुरंत खरीदें और रिडीम करें!\nअधिक जानने के लिए बाएं से दाएं स्वाइप करें।",
"cake_pay_subtitle": "रियायती उपहार कार्ड खरीदें (केवल यूएसए)", "cake_pay_subtitle": "दुनिया भर में प्रीपेड कार्ड और उपहार कार्ड खरीदें",
"cake_pay_title": "केक पे गिफ्ट कार्ड्स",
"cake_pay_web_cards_subtitle": "दुनिया भर में प्रीपेड कार्ड और गिफ्ट कार्ड खरीदें", "cake_pay_web_cards_subtitle": "दुनिया भर में प्रीपेड कार्ड और गिफ्ट कार्ड खरीदें",
"cake_pay_web_cards_title": "केक भुगतान वेब कार्ड", "cake_pay_web_cards_title": "केक भुगतान वेब कार्ड",
"cake_wallet": "Cake Wallet", "cake_wallet": "Cake Wallet",
@ -123,6 +123,7 @@
"change_wallet_alert_title": "वर्तमान बटुआ बदलें", "change_wallet_alert_title": "वर्तमान बटुआ बदलें",
"choose_account": "खाता चुनें", "choose_account": "खाता चुनें",
"choose_address": "\n\nकृपया पता चुनें:", "choose_address": "\n\nकृपया पता चुनें:",
"choose_card_value": "एक कार्ड मूल्य चुनें",
"choose_derivation": "वॉलेट व्युत्पत्ति चुनें", "choose_derivation": "वॉलेट व्युत्पत्ति चुनें",
"choose_from_available_options": "उपलब्ध विकल्पों में से चुनें:", "choose_from_available_options": "उपलब्ध विकल्पों में से चुनें:",
"choose_one": "एक का चयन", "choose_one": "एक का चयन",
@ -166,6 +167,7 @@
"copy_address": "पता कॉपी करें", "copy_address": "पता कॉपी करें",
"copy_id": "प्रतिलिपि ID", "copy_id": "प्रतिलिपि ID",
"copyWalletConnectLink": "dApp से वॉलेटकनेक्ट लिंक को कॉपी करें और यहां पेस्ट करें", "copyWalletConnectLink": "dApp से वॉलेटकनेक्ट लिंक को कॉपी करें और यहां पेस्ट करें",
"countries": "देशों",
"create_account": "खाता बनाएं", "create_account": "खाता बनाएं",
"create_backup": "बैकअप बनाएँ", "create_backup": "बैकअप बनाएँ",
"create_donation_link": "दान लिंक बनाएं", "create_donation_link": "दान लिंक बनाएं",
@ -178,6 +180,7 @@
"custom": "कस्टम", "custom": "कस्टम",
"custom_drag": "कस्टम (पकड़ और खींचें)", "custom_drag": "कस्टम (पकड़ और खींचें)",
"custom_redeem_amount": "कस्टम रिडीम राशि", "custom_redeem_amount": "कस्टम रिडीम राशि",
"custom_value": "कस्टम मूल्य",
"dark_theme": "अंधेरा", "dark_theme": "अंधेरा",
"debit_card": "डेबिट कार्ड", "debit_card": "डेबिट कार्ड",
"debit_card_terms": "इस डिजिटल वॉलेट में आपके भुगतान कार्ड नंबर (और आपके भुगतान कार्ड नंबर से संबंधित क्रेडेंशियल) का भंडारण और उपयोग भुगतान कार्ड जारीकर्ता के साथ लागू कार्डधारक समझौते के नियमों और शर्तों के अधीन है, जैसा कि प्रभावी है समय - समय पर।", "debit_card_terms": "इस डिजिटल वॉलेट में आपके भुगतान कार्ड नंबर (और आपके भुगतान कार्ड नंबर से संबंधित क्रेडेंशियल) का भंडारण और उपयोग भुगतान कार्ड जारीकर्ता के साथ लागू कार्डधारक समझौते के नियमों और शर्तों के अधीन है, जैसा कि प्रभावी है समय - समय पर।",
@ -190,6 +193,7 @@
"delete_wallet": "वॉलेट हटाएं", "delete_wallet": "वॉलेट हटाएं",
"delete_wallet_confirm_message": "क्या आप वाकई ${wallet_name} वॉलेट हटाना चाहते हैं?", "delete_wallet_confirm_message": "क्या आप वाकई ${wallet_name} वॉलेट हटाना चाहते हैं?",
"deleteConnectionConfirmationPrompt": "क्या आप वाकई कनेक्शन हटाना चाहते हैं?", "deleteConnectionConfirmationPrompt": "क्या आप वाकई कनेक्शन हटाना चाहते हैं?",
"denominations": "मूल्यवर्ग",
"descending": "अवरोही", "descending": "अवरोही",
"description": "विवरण", "description": "विवरण",
"destination_tag": "गंतव्य टैग:", "destination_tag": "गंतव्य टैग:",
@ -277,6 +281,7 @@
"expired": "समय सीमा समाप्त", "expired": "समय सीमा समाप्त",
"expires": "समाप्त हो जाता है", "expires": "समाप्त हो जाता है",
"expiresOn": "पर समय सीमा समाप्त", "expiresOn": "पर समय सीमा समाप्त",
"expiry_and_validity": "समाप्ति और वैधता",
"export_backup": "निर्यात बैकअप", "export_backup": "निर्यात बैकअप",
"extra_id": "अतिरिक्त आईडी:", "extra_id": "अतिरिक्त आईडी:",
"extracted_address_content": "आपको धनराशि भेजी जाएगी\n${recipient_name}", "extracted_address_content": "आपको धनराशि भेजी जाएगी\n${recipient_name}",
@ -384,6 +389,7 @@
"new_template": "नया टेम्पलेट", "new_template": "नया टेम्पलेट",
"new_wallet": "नया बटुआ", "new_wallet": "नया बटुआ",
"newConnection": "नया कनेक्शन", "newConnection": "नया कनेक्शन",
"no_cards_found": "कोई कार्ड नहीं मिला",
"no_id_needed": "कोई आईडी नहीं चाहिए!", "no_id_needed": "कोई आईडी नहीं चाहिए!",
"no_id_required": "कोई आईडी आवश्यक नहीं है। टॉप अप करें और कहीं भी खर्च करें", "no_id_required": "कोई आईडी आवश्यक नहीं है। टॉप अप करें और कहीं भी खर्च करें",
"no_relay_on_domain": "उपयोगकर्ता के डोमेन के लिए कोई रिले नहीं है या रिले अनुपलब्ध है। कृपया उपयोग करने के लिए एक रिले चुनें।", "no_relay_on_domain": "उपयोगकर्ता के डोमेन के लिए कोई रिले नहीं है या रिले अनुपलब्ध है। कृपया उपयोग करने के लिए एक रिले चुनें।",
@ -453,6 +459,7 @@
"pre_seed_button_text": "मै समझता हुँ। मुझे अपना बीज दिखाओ", "pre_seed_button_text": "मै समझता हुँ। मुझे अपना बीज दिखाओ",
"pre_seed_description": "अगले पेज पर आपको ${words} शब्दों की एक श्रृंखला दिखाई देगी। यह आपका अद्वितीय और निजी बीज है और नुकसान या खराबी के मामले में अपने बटुए को पुनर्प्राप्त करने का एकमात्र तरीका है। यह आपकी जिम्मेदारी है कि इसे नीचे लिखें और इसे Cake Wallet ऐप के बाहर सुरक्षित स्थान पर संग्रहीत करें।", "pre_seed_description": "अगले पेज पर आपको ${words} शब्दों की एक श्रृंखला दिखाई देगी। यह आपका अद्वितीय और निजी बीज है और नुकसान या खराबी के मामले में अपने बटुए को पुनर्प्राप्त करने का एकमात्र तरीका है। यह आपकी जिम्मेदारी है कि इसे नीचे लिखें और इसे Cake Wallet ऐप के बाहर सुरक्षित स्थान पर संग्रहीत करें।",
"pre_seed_title": "महत्वपूर्ण", "pre_seed_title": "महत्वपूर्ण",
"prepaid_cards": "पूर्वदत्त कार्ड",
"prevent_screenshots": "स्क्रीनशॉट और स्क्रीन रिकॉर्डिंग रोकें", "prevent_screenshots": "स्क्रीनशॉट और स्क्रीन रिकॉर्डिंग रोकें",
"privacy": "गोपनीयता", "privacy": "गोपनीयता",
"privacy_policy": "गोपनीयता नीति", "privacy_policy": "गोपनीयता नीति",
@ -468,6 +475,7 @@
"purple_dark_theme": "पर्पल डार्क थीम", "purple_dark_theme": "पर्पल डार्क थीम",
"qr_fullscreen": "फ़ुल स्क्रीन क्यूआर कोड खोलने के लिए टैप करें", "qr_fullscreen": "फ़ुल स्क्रीन क्यूआर कोड खोलने के लिए टैप करें",
"qr_payment_amount": "This QR code contains a payment amount. Do you want to overwrite the current value?", "qr_payment_amount": "This QR code contains a payment amount. Do you want to overwrite the current value?",
"quantity": "मात्रा",
"question_to_disable_2fa": "क्या आप सुनिश्चित हैं कि आप Cake 2FA को अक्षम करना चाहते हैं? वॉलेट और कुछ कार्यों तक पहुँचने के लिए अब 2FA कोड की आवश्यकता नहीं होगी।", "question_to_disable_2fa": "क्या आप सुनिश्चित हैं कि आप Cake 2FA को अक्षम करना चाहते हैं? वॉलेट और कुछ कार्यों तक पहुँचने के लिए अब 2FA कोड की आवश्यकता नहीं होगी।",
"ready_have_account": "क्या आपके पास पहले से ही एक खाता है?", "ready_have_account": "क्या आपके पास पहले से ही एक खाता है?",
"receivable_balance": "प्राप्य शेष", "receivable_balance": "प्राप्य शेष",
@ -710,6 +718,7 @@
"tokenID": "पहचान", "tokenID": "पहचान",
"tor_connection": "टोर कनेक्शन", "tor_connection": "टोर कनेक्शन",
"tor_only": "Tor केवल", "tor_only": "Tor केवल",
"total": "कुल",
"total_saving": "कुल बचत", "total_saving": "कुल बचत",
"totp_2fa_failure": "गलत कोड़। कृपया एक अलग कोड का प्रयास करें या एक नई गुप्त कुंजी उत्पन्न करें। 8-अंकीय कोड और SHA512 का समर्थन करने वाले संगत 2FA ऐप का उपयोग करें।", "totp_2fa_failure": "गलत कोड़। कृपया एक अलग कोड का प्रयास करें या एक नई गुप्त कुंजी उत्पन्न करें। 8-अंकीय कोड और SHA512 का समर्थन करने वाले संगत 2FA ऐप का उपयोग करें।",
"totp_2fa_success": "सफलता! इस वॉलेट के लिए Cake 2FA सक्षम है। यदि आप वॉलेट एक्सेस खो देते हैं तो अपने स्मरक बीज को सहेजना याद रखें।", "totp_2fa_success": "सफलता! इस वॉलेट के लिए Cake 2FA सक्षम है। यदि आप वॉलेट एक्सेस खो देते हैं तो अपने स्मरक बीज को सहेजना याद रखें।",
@ -800,6 +809,8 @@
"use_ssl": "उपयोग SSL", "use_ssl": "उपयोग SSL",
"use_suggested": "सुझाए गए का प्रयोग करें", "use_suggested": "सुझाए गए का प्रयोग करें",
"use_testnet": "टेस्टनेट का उपयोग करें", "use_testnet": "टेस्टनेट का उपयोग करें",
"value": "कीमत",
"value_type": "मान प्रकार",
"variable_pair_not_supported": "यह परिवर्तनीय जोड़ी चयनित एक्सचेंजों के साथ समर्थित नहीं है", "variable_pair_not_supported": "यह परिवर्तनीय जोड़ी चयनित एक्सचेंजों के साथ समर्थित नहीं है",
"verification": "सत्यापन", "verification": "सत्यापन",
"verify_with_2fa": "केक 2FA के साथ सत्यापित करें", "verify_with_2fa": "केक 2FA के साथ सत्यापित करें",

View file

@ -87,6 +87,7 @@
"buy": "Kupi", "buy": "Kupi",
"buy_alert_content": "Trenutno podržavamo samo kupnju Bitcoina, Ethereuma, Litecoina i Monera. Izradite ili prijeđite na svoj Bitcoin, Ethereum, Litecoin ili Monero novčanik.", "buy_alert_content": "Trenutno podržavamo samo kupnju Bitcoina, Ethereuma, Litecoina i Monera. Izradite ili prijeđite na svoj Bitcoin, Ethereum, Litecoin ili Monero novčanik.",
"buy_bitcoin": "Kupite Bitcoin", "buy_bitcoin": "Kupite Bitcoin",
"buy_now": "Kupi sada",
"buy_provider_unavailable": "Davatelj trenutno nije dostupan.", "buy_provider_unavailable": "Davatelj trenutno nije dostupan.",
"buy_with": "Kupite s", "buy_with": "Kupite s",
"by_cake_pay": "od Cake Paya", "by_cake_pay": "od Cake Paya",
@ -94,8 +95,7 @@
"cake_dark_theme": "TOKA DARKA TEMA", "cake_dark_theme": "TOKA DARKA TEMA",
"cake_pay_account_note": "Prijavite se samo s adresom e-pošte da biste vidjeli i kupili kartice. Neke su čak dostupne uz popust!", "cake_pay_account_note": "Prijavite se samo s adresom e-pošte da biste vidjeli i kupili kartice. Neke su čak dostupne uz popust!",
"cake_pay_learn_more": "Azonnal vásárolhat és válthat be ajándékutalványokat az alkalmazásban!\nTovábbi információért csúsztassa balról jobbra az ujját.", "cake_pay_learn_more": "Azonnal vásárolhat és válthat be ajándékutalványokat az alkalmazásban!\nTovábbi információért csúsztassa balról jobbra az ujját.",
"cake_pay_subtitle": "Kupite darovne kartice s popustom (samo SAD)", "cake_pay_subtitle": "Kupite svjetske unaprijed plaćene kartice i poklon kartice",
"cake_pay_title": "Cake Pay poklon kartice",
"cake_pay_web_cards_subtitle": "Kupujte prepaid kartice i poklon kartice diljem svijeta", "cake_pay_web_cards_subtitle": "Kupujte prepaid kartice i poklon kartice diljem svijeta",
"cake_pay_web_cards_title": "Cake Pay Web kartice", "cake_pay_web_cards_title": "Cake Pay Web kartice",
"cake_wallet": "Cake Wallet", "cake_wallet": "Cake Wallet",
@ -123,6 +123,7 @@
"change_wallet_alert_title": "Izmijeni trenutni novčanik", "change_wallet_alert_title": "Izmijeni trenutni novčanik",
"choose_account": "Odaberi račun", "choose_account": "Odaberi račun",
"choose_address": "\n\nOdaberite adresu:", "choose_address": "\n\nOdaberite adresu:",
"choose_card_value": "Odaberite vrijednost kartice",
"choose_derivation": "Odaberite izvedbu novčanika", "choose_derivation": "Odaberite izvedbu novčanika",
"choose_from_available_options": "Odaberite neku od dostupnih opcija:", "choose_from_available_options": "Odaberite neku od dostupnih opcija:",
"choose_one": "Izaberi jedan", "choose_one": "Izaberi jedan",
@ -166,6 +167,7 @@
"copy_address": "Kopiraj adresu", "copy_address": "Kopiraj adresu",
"copy_id": "Kopirati ID", "copy_id": "Kopirati ID",
"copyWalletConnectLink": "Kopirajte vezu WalletConnect iz dApp-a i zalijepite je ovdje", "copyWalletConnectLink": "Kopirajte vezu WalletConnect iz dApp-a i zalijepite je ovdje",
"countries": "Zemalja",
"create_account": "Stvori račun", "create_account": "Stvori račun",
"create_backup": "Stvori sigurnosnu kopiju", "create_backup": "Stvori sigurnosnu kopiju",
"create_donation_link": "Izradi poveznicu za donaciju", "create_donation_link": "Izradi poveznicu za donaciju",
@ -178,6 +180,7 @@
"custom": "prilagođeno", "custom": "prilagođeno",
"custom_drag": "Prilagođeni (držite i povucite)", "custom_drag": "Prilagođeni (držite i povucite)",
"custom_redeem_amount": "Prilagođeni iznos otkupa", "custom_redeem_amount": "Prilagođeni iznos otkupa",
"custom_value": "Prilagođena vrijednost",
"dark_theme": "Tamna", "dark_theme": "Tamna",
"debit_card": "Debitna kartica", "debit_card": "Debitna kartica",
"debit_card_terms": "Pohranjivanje i korištenje broja vaše platne kartice (i vjerodajnica koje odgovaraju broju vaše platne kartice) u ovom digitalnom novčaniku podliježu Uvjetima i odredbama važećeg ugovora vlasnika kartice s izdavateljem platne kartice, koji su na snazi od S vremena na vrijeme.", "debit_card_terms": "Pohranjivanje i korištenje broja vaše platne kartice (i vjerodajnica koje odgovaraju broju vaše platne kartice) u ovom digitalnom novčaniku podliježu Uvjetima i odredbama važećeg ugovora vlasnika kartice s izdavateljem platne kartice, koji su na snazi od S vremena na vrijeme.",
@ -190,6 +193,7 @@
"delete_wallet": "Izbriši novčanik", "delete_wallet": "Izbriši novčanik",
"delete_wallet_confirm_message": "Jeste li sigurni da želite izbrisati ${wallet_name} novčanik?", "delete_wallet_confirm_message": "Jeste li sigurni da želite izbrisati ${wallet_name} novčanik?",
"deleteConnectionConfirmationPrompt": "Jeste li sigurni da želite izbrisati vezu s", "deleteConnectionConfirmationPrompt": "Jeste li sigurni da želite izbrisati vezu s",
"denominations": "Denominacije",
"descending": "Silazni", "descending": "Silazni",
"description": "Opis", "description": "Opis",
"destination_tag": "Odredišna oznaka:", "destination_tag": "Odredišna oznaka:",
@ -277,6 +281,7 @@
"expired": "Isteklo", "expired": "Isteklo",
"expires": "Ističe", "expires": "Ističe",
"expiresOn": "Istječe", "expiresOn": "Istječe",
"expiry_and_validity": "Istek i valjanost",
"export_backup": "Izvezi sigurnosnu kopiju", "export_backup": "Izvezi sigurnosnu kopiju",
"extra_id": "Dodatni ID:", "extra_id": "Dodatni ID:",
"extracted_address_content": "Poslat ćete sredstva primatelju\n${recipient_name}", "extracted_address_content": "Poslat ćete sredstva primatelju\n${recipient_name}",
@ -308,7 +313,7 @@
"gift_card_is_generated": "Poklon kartica je generirana", "gift_card_is_generated": "Poklon kartica je generirana",
"gift_card_number": "Broj darovne kartice", "gift_card_number": "Broj darovne kartice",
"gift_card_redeemed_note": "Poklon kartice koje ste iskoristili pojavit će se ovdje", "gift_card_redeemed_note": "Poklon kartice koje ste iskoristili pojavit će se ovdje",
"gift_cards": "Ajándékkártya", "gift_cards": "Darovne kartice",
"gift_cards_unavailable": "Poklon kartice trenutno su dostupne za kupnju samo putem Monera, Bitcoina i Litecoina", "gift_cards_unavailable": "Poklon kartice trenutno su dostupne za kupnju samo putem Monera, Bitcoina i Litecoina",
"got_it": "U redu", "got_it": "U redu",
"gross_balance": "Bruto bilanca", "gross_balance": "Bruto bilanca",
@ -384,6 +389,7 @@
"new_template": "novi predložak", "new_template": "novi predložak",
"new_wallet": "Novi novčanik", "new_wallet": "Novi novčanik",
"newConnection": "Nova veza", "newConnection": "Nova veza",
"no_cards_found": "Nisu pronađene kartice",
"no_id_needed": "Nije potreban ID!", "no_id_needed": "Nije potreban ID!",
"no_id_required": "Nije potreban ID. Nadopunite i potrošite bilo gdje", "no_id_required": "Nije potreban ID. Nadopunite i potrošite bilo gdje",
"no_relay_on_domain": "Ne postoji relej za korisničku domenu ili je relej nedostupan. Odaberite relej za korištenje.", "no_relay_on_domain": "Ne postoji relej za korisničku domenu ili je relej nedostupan. Odaberite relej za korištenje.",
@ -452,6 +458,7 @@
"pre_seed_button_text": "Razumijem. Prikaži mi moj pristupni izraz", "pre_seed_button_text": "Razumijem. Prikaži mi moj pristupni izraz",
"pre_seed_description": "Na sljedećoj ćete stranici vidjeti niz ${words} riječi. Radi se o Vašem jedinstvenom i tajnom pristupnom izrazu koji je ujedno i JEDINI način na koji možete oporaviti svoj novčanik u slučaju gubitka ili kvara. VAŠA je odgovornost zapisati ga te pohraniti na sigurno mjesto izvan Cake Wallet aplikacije.", "pre_seed_description": "Na sljedećoj ćete stranici vidjeti niz ${words} riječi. Radi se o Vašem jedinstvenom i tajnom pristupnom izrazu koji je ujedno i JEDINI način na koji možete oporaviti svoj novčanik u slučaju gubitka ili kvara. VAŠA je odgovornost zapisati ga te pohraniti na sigurno mjesto izvan Cake Wallet aplikacije.",
"pre_seed_title": "VAŽNO", "pre_seed_title": "VAŽNO",
"prepaid_cards": "Unaprijed plaćene kartice",
"prevent_screenshots": "Spriječite snimke zaslona i snimanje zaslona", "prevent_screenshots": "Spriječite snimke zaslona i snimanje zaslona",
"privacy": "Privatnost", "privacy": "Privatnost",
"privacy_policy": "Pravila privatnosti", "privacy_policy": "Pravila privatnosti",
@ -467,6 +474,7 @@
"purple_dark_theme": "Ljubičasta tamna tema", "purple_dark_theme": "Ljubičasta tamna tema",
"qr_fullscreen": "Dodirnite za otvaranje QR koda preko cijelog zaslona", "qr_fullscreen": "Dodirnite za otvaranje QR koda preko cijelog zaslona",
"qr_payment_amount": "This QR code contains a payment amount. Do you want to overwrite the current value?", "qr_payment_amount": "This QR code contains a payment amount. Do you want to overwrite the current value?",
"quantity": "Količina",
"question_to_disable_2fa": "Jeste li sigurni da želite onemogućiti Cake 2FA? 2FA kod više neće biti potreban za pristup novčaniku i određenim funkcijama.", "question_to_disable_2fa": "Jeste li sigurni da želite onemogućiti Cake 2FA? 2FA kod više neće biti potreban za pristup novčaniku i određenim funkcijama.",
"receivable_balance": "Stanje potraživanja", "receivable_balance": "Stanje potraživanja",
"receive": "Primi", "receive": "Primi",
@ -708,6 +716,7 @@
"tokenID": "iskaznica", "tokenID": "iskaznica",
"tor_connection": "Tor veza", "tor_connection": "Tor veza",
"tor_only": "Samo Tor", "tor_only": "Samo Tor",
"total": "Ukupno",
"total_saving": "Ukupna ušteda", "total_saving": "Ukupna ušteda",
"totp_2fa_failure": "Neispravan kod. Pokušajte s drugim kodom ili generirajte novi tajni ključ. Koristite kompatibilnu 2FA aplikaciju koja podržava 8-znamenkasti kod i SHA512.", "totp_2fa_failure": "Neispravan kod. Pokušajte s drugim kodom ili generirajte novi tajni ključ. Koristite kompatibilnu 2FA aplikaciju koja podržava 8-znamenkasti kod i SHA512.",
"totp_2fa_success": "Uspjeh! Cake 2FA omogućen za ovaj novčanik. Ne zaboravite spremiti svoje mnemoničko sjeme u slučaju da izgubite pristup novčaniku.", "totp_2fa_success": "Uspjeh! Cake 2FA omogućen za ovaj novčanik. Ne zaboravite spremiti svoje mnemoničko sjeme u slučaju da izgubite pristup novčaniku.",
@ -798,6 +807,8 @@
"use_ssl": "Koristi SSL", "use_ssl": "Koristi SSL",
"use_suggested": "Koristite predloženo", "use_suggested": "Koristite predloženo",
"use_testnet": "Koristite TestNet", "use_testnet": "Koristite TestNet",
"value": "Vrijednost",
"value_type": "Tipa vrijednosti",
"variable_pair_not_supported": "Ovaj par varijabli nije podržan s odabranim burzama", "variable_pair_not_supported": "Ovaj par varijabli nije podržan s odabranim burzama",
"verification": "Potvrda", "verification": "Potvrda",
"verify_with_2fa": "Provjerite s Cake 2FA", "verify_with_2fa": "Provjerite s Cake 2FA",

View file

@ -87,6 +87,7 @@
"buy": "Beli", "buy": "Beli",
"buy_alert_content": "Saat ini kami hanya mendukung pembelian Bitcoin, Ethereum, Litecoin, dan Monero. Harap buat atau alihkan ke dompet Bitcoin, Ethereum, Litecoin, atau Monero Anda.", "buy_alert_content": "Saat ini kami hanya mendukung pembelian Bitcoin, Ethereum, Litecoin, dan Monero. Harap buat atau alihkan ke dompet Bitcoin, Ethereum, Litecoin, atau Monero Anda.",
"buy_bitcoin": "Beli Bitcoin", "buy_bitcoin": "Beli Bitcoin",
"buy_now": "Beli sekarang",
"buy_provider_unavailable": "Penyedia saat ini tidak tersedia.", "buy_provider_unavailable": "Penyedia saat ini tidak tersedia.",
"buy_with": "Beli dengan", "buy_with": "Beli dengan",
"by_cake_pay": "oleh Cake Pay", "by_cake_pay": "oleh Cake Pay",
@ -94,8 +95,7 @@
"cake_dark_theme": "Tema Kue Gelap", "cake_dark_theme": "Tema Kue Gelap",
"cake_pay_account_note": "Daftar hanya dengan alamat email untuk melihat dan membeli kartu. Beberapa di antaranya bahkan tersedia dengan diskon!", "cake_pay_account_note": "Daftar hanya dengan alamat email untuk melihat dan membeli kartu. Beberapa di antaranya bahkan tersedia dengan diskon!",
"cake_pay_learn_more": "Beli dan tukar kartu hadiah secara instan di aplikasi!\nGeser ke kanan untuk informasi lebih lanjut.", "cake_pay_learn_more": "Beli dan tukar kartu hadiah secara instan di aplikasi!\nGeser ke kanan untuk informasi lebih lanjut.",
"cake_pay_subtitle": "Beli kartu hadiah dengan harga diskon (hanya USA)", "cake_pay_subtitle": "Beli kartu prabayar di seluruh dunia dan kartu hadiah",
"cake_pay_title": "Kartu Hadiah Cake Pay",
"cake_pay_web_cards_subtitle": "Beli kartu prabayar dan kartu hadiah secara global", "cake_pay_web_cards_subtitle": "Beli kartu prabayar dan kartu hadiah secara global",
"cake_pay_web_cards_title": "Kartu Web Cake Pay", "cake_pay_web_cards_title": "Kartu Web Cake Pay",
"cake_wallet": "Cake Wallet", "cake_wallet": "Cake Wallet",
@ -123,6 +123,7 @@
"change_wallet_alert_title": "Ganti dompet saat ini", "change_wallet_alert_title": "Ganti dompet saat ini",
"choose_account": "Pilih akun", "choose_account": "Pilih akun",
"choose_address": "\n\nSilakan pilih alamat:", "choose_address": "\n\nSilakan pilih alamat:",
"choose_card_value": "Pilih nilai kartu",
"choose_derivation": "Pilih dompet dompet", "choose_derivation": "Pilih dompet dompet",
"choose_from_available_options": "Pilih dari pilihan yang tersedia:", "choose_from_available_options": "Pilih dari pilihan yang tersedia:",
"choose_one": "Pilih satu", "choose_one": "Pilih satu",
@ -166,6 +167,7 @@
"copy_address": "Salin Alamat", "copy_address": "Salin Alamat",
"copy_id": "Salin ID", "copy_id": "Salin ID",
"copyWalletConnectLink": "Salin tautan WalletConnect dari dApp dan tempel di sini", "copyWalletConnectLink": "Salin tautan WalletConnect dari dApp dan tempel di sini",
"countries": "Negara",
"create_account": "Buat Akun", "create_account": "Buat Akun",
"create_backup": "Buat cadangan", "create_backup": "Buat cadangan",
"create_donation_link": "Buat tautan donasi", "create_donation_link": "Buat tautan donasi",
@ -178,6 +180,7 @@
"custom": "kustom", "custom": "kustom",
"custom_drag": "Khusus (tahan dan seret)", "custom_drag": "Khusus (tahan dan seret)",
"custom_redeem_amount": "Jumlah Tukar Kustom", "custom_redeem_amount": "Jumlah Tukar Kustom",
"custom_value": "Nilai khusus",
"dark_theme": "Gelap", "dark_theme": "Gelap",
"debit_card": "Kartu Debit", "debit_card": "Kartu Debit",
"debit_card_terms": "Penyimpanan dan penggunaan nomor kartu pembayaran Anda (dan kredensial yang sesuai dengan nomor kartu pembayaran Anda) dalam dompet digital ini tertakluk pada Syarat dan Ketentuan persetujuan pemegang kartu yang berlaku dengan penerbit kartu pembayaran, seperti yang berlaku dari waktu ke waktu.", "debit_card_terms": "Penyimpanan dan penggunaan nomor kartu pembayaran Anda (dan kredensial yang sesuai dengan nomor kartu pembayaran Anda) dalam dompet digital ini tertakluk pada Syarat dan Ketentuan persetujuan pemegang kartu yang berlaku dengan penerbit kartu pembayaran, seperti yang berlaku dari waktu ke waktu.",
@ -190,6 +193,7 @@
"delete_wallet": "Hapus dompet", "delete_wallet": "Hapus dompet",
"delete_wallet_confirm_message": "Apakah Anda yakin ingin menghapus dompet ${wallet_name}?", "delete_wallet_confirm_message": "Apakah Anda yakin ingin menghapus dompet ${wallet_name}?",
"deleteConnectionConfirmationPrompt": "Apakah Anda yakin ingin menghapus koneksi ke", "deleteConnectionConfirmationPrompt": "Apakah Anda yakin ingin menghapus koneksi ke",
"denominations": "Denominasi",
"descending": "Menurun", "descending": "Menurun",
"description": "Keterangan", "description": "Keterangan",
"destination_tag": "Tag tujuan:", "destination_tag": "Tag tujuan:",
@ -277,6 +281,7 @@
"expired": "Kedaluwarsa", "expired": "Kedaluwarsa",
"expires": "Kadaluarsa", "expires": "Kadaluarsa",
"expiresOn": "Kadaluarsa pada", "expiresOn": "Kadaluarsa pada",
"expiry_and_validity": "Kedaluwarsa dan validitas",
"export_backup": "Ekspor cadangan", "export_backup": "Ekspor cadangan",
"extra_id": "ID tambahan:", "extra_id": "ID tambahan:",
"extracted_address_content": "Anda akan mengirim dana ke\n${recipient_name}", "extracted_address_content": "Anda akan mengirim dana ke\n${recipient_name}",
@ -308,7 +313,7 @@
"gift_card_is_generated": "Kartu Hadiah telah dibuat", "gift_card_is_generated": "Kartu Hadiah telah dibuat",
"gift_card_number": "Nomor Kartu Hadiah", "gift_card_number": "Nomor Kartu Hadiah",
"gift_card_redeemed_note": "Kartu hadiah yang sudah Anda tukar akan muncul di sini", "gift_card_redeemed_note": "Kartu hadiah yang sudah Anda tukar akan muncul di sini",
"gift_cards": "Kartu Hadiah", "gift_cards": "Kartu hadiah",
"gift_cards_unavailable": "Kartu hadiah hanya tersedia untuk dibeli dengan Monero, Bitcoin, dan Litecoin saat ini", "gift_cards_unavailable": "Kartu hadiah hanya tersedia untuk dibeli dengan Monero, Bitcoin, dan Litecoin saat ini",
"got_it": "Sudah paham", "got_it": "Sudah paham",
"gross_balance": "Saldo Kotor", "gross_balance": "Saldo Kotor",
@ -384,6 +389,7 @@
"new_template": "Template Baru", "new_template": "Template Baru",
"new_wallet": "Dompet Baru", "new_wallet": "Dompet Baru",
"newConnection": "Koneksi Baru", "newConnection": "Koneksi Baru",
"no_cards_found": "Tidak ada kartu yang ditemukan",
"no_id_needed": "Tidak perlu ID!", "no_id_needed": "Tidak perlu ID!",
"no_id_required": "Tidak perlu ID. Isi ulang dan belanja di mana saja", "no_id_required": "Tidak perlu ID. Isi ulang dan belanja di mana saja",
"no_relay_on_domain": "Tidak ada relai untuk domain pengguna atau relai tidak tersedia. Silakan pilih relai yang akan digunakan.", "no_relay_on_domain": "Tidak ada relai untuk domain pengguna atau relai tidak tersedia. Silakan pilih relai yang akan digunakan.",
@ -454,6 +460,7 @@
"pre_seed_button_text": "Saya mengerti. Tampilkan seed saya", "pre_seed_button_text": "Saya mengerti. Tampilkan seed saya",
"pre_seed_description": "Di halaman berikutnya Anda akan melihat serangkaian kata ${words}. Ini adalah seed unik dan pribadi Anda dan itu SATU-SATUNYA cara untuk mengembalikan dompet Anda jika hilang atau rusak. Ini adalah TANGGUNG JAWAB Anda untuk menuliskannya dan menyimpan di tempat yang aman di luar aplikasi Cake Wallet.", "pre_seed_description": "Di halaman berikutnya Anda akan melihat serangkaian kata ${words}. Ini adalah seed unik dan pribadi Anda dan itu SATU-SATUNYA cara untuk mengembalikan dompet Anda jika hilang atau rusak. Ini adalah TANGGUNG JAWAB Anda untuk menuliskannya dan menyimpan di tempat yang aman di luar aplikasi Cake Wallet.",
"pre_seed_title": "PENTING", "pre_seed_title": "PENTING",
"prepaid_cards": "Kartu prabayar",
"prevent_screenshots": "Cegah tangkapan layar dan perekaman layar", "prevent_screenshots": "Cegah tangkapan layar dan perekaman layar",
"privacy": "Privasi", "privacy": "Privasi",
"privacy_policy": "Kebijakan Privasi", "privacy_policy": "Kebijakan Privasi",
@ -469,6 +476,7 @@
"purple_dark_theme": "Tema gelap ungu", "purple_dark_theme": "Tema gelap ungu",
"qr_fullscreen": "Tap untuk membuka layar QR code penuh", "qr_fullscreen": "Tap untuk membuka layar QR code penuh",
"qr_payment_amount": "QR code ini berisi jumlah pembayaran. Apakah Anda ingin menimpa nilai saat ini?", "qr_payment_amount": "QR code ini berisi jumlah pembayaran. Apakah Anda ingin menimpa nilai saat ini?",
"quantity": "Kuantitas",
"question_to_disable_2fa": "Apakah Anda yakin ingin menonaktifkan Cake 2FA? Kode 2FA tidak lagi diperlukan untuk mengakses dompet dan fungsi tertentu.", "question_to_disable_2fa": "Apakah Anda yakin ingin menonaktifkan Cake 2FA? Kode 2FA tidak lagi diperlukan untuk mengakses dompet dan fungsi tertentu.",
"receivable_balance": "Saldo piutang", "receivable_balance": "Saldo piutang",
"receive": "Menerima", "receive": "Menerima",
@ -711,6 +719,7 @@
"tokenID": "PENGENAL", "tokenID": "PENGENAL",
"tor_connection": "koneksi Tor", "tor_connection": "koneksi Tor",
"tor_only": "Hanya Tor", "tor_only": "Hanya Tor",
"total": "Total",
"total_saving": "Total Pembayaran", "total_saving": "Total Pembayaran",
"totp_2fa_failure": "Kode salah. Silakan coba kode lain atau buat kunci rahasia baru. Gunakan aplikasi 2FA yang kompatibel yang mendukung kode 8 digit dan SHA512.", "totp_2fa_failure": "Kode salah. Silakan coba kode lain atau buat kunci rahasia baru. Gunakan aplikasi 2FA yang kompatibel yang mendukung kode 8 digit dan SHA512.",
"totp_2fa_success": "Kesuksesan! Cake 2FA diaktifkan untuk dompet ini. Ingatlah untuk menyimpan benih mnemonik Anda jika Anda kehilangan akses dompet.", "totp_2fa_success": "Kesuksesan! Cake 2FA diaktifkan untuk dompet ini. Ingatlah untuk menyimpan benih mnemonik Anda jika Anda kehilangan akses dompet.",
@ -801,6 +810,8 @@
"use_ssl": "Gunakan SSL", "use_ssl": "Gunakan SSL",
"use_suggested": "Gunakan yang Disarankan", "use_suggested": "Gunakan yang Disarankan",
"use_testnet": "Gunakan TestNet", "use_testnet": "Gunakan TestNet",
"value": "Nilai",
"value_type": "Jenis Nilai",
"variable_pair_not_supported": "Pasangan variabel ini tidak didukung dengan bursa yang dipilih", "variable_pair_not_supported": "Pasangan variabel ini tidak didukung dengan bursa yang dipilih",
"verification": "Verifikasi", "verification": "Verifikasi",
"verify_with_2fa": "Verifikasi dengan Cake 2FA", "verify_with_2fa": "Verifikasi dengan Cake 2FA",

View file

@ -87,6 +87,7 @@
"buy": "Comprare", "buy": "Comprare",
"buy_alert_content": "Attualmente supportiamo solo l'acquisto di Bitcoin, Ethereum, Litecoin e Monero. Crea o passa al tuo portafoglio Bitcoin, Ethereum, Litecoin o Monero.", "buy_alert_content": "Attualmente supportiamo solo l'acquisto di Bitcoin, Ethereum, Litecoin e Monero. Crea o passa al tuo portafoglio Bitcoin, Ethereum, Litecoin o Monero.",
"buy_bitcoin": "Acquista Bitcoin", "buy_bitcoin": "Acquista Bitcoin",
"buy_now": "Acquista ora",
"buy_provider_unavailable": "Provider attualmente non disponibile.", "buy_provider_unavailable": "Provider attualmente non disponibile.",
"buy_with": "Acquista con", "buy_with": "Acquista con",
"by_cake_pay": "da Cake Pay", "by_cake_pay": "da Cake Pay",
@ -94,8 +95,7 @@
"cake_dark_theme": "Tema oscuro della torta", "cake_dark_theme": "Tema oscuro della torta",
"cake_pay_account_note": "Iscriviti con solo un indirizzo email per vedere e acquistare le carte. Alcune sono anche disponibili con uno sconto!", "cake_pay_account_note": "Iscriviti con solo un indirizzo email per vedere e acquistare le carte. Alcune sono anche disponibili con uno sconto!",
"cake_pay_learn_more": "Acquista e riscatta istantaneamente carte regalo nell'app!\nScorri da sinistra a destra per saperne di più.", "cake_pay_learn_more": "Acquista e riscatta istantaneamente carte regalo nell'app!\nScorri da sinistra a destra per saperne di più.",
"cake_pay_subtitle": "Acquista buoni regalo scontati (solo USA)", "cake_pay_subtitle": "Acquista carte prepagate in tutto il mondo e carte regalo",
"cake_pay_title": "Carte regalo Cake Pay",
"cake_pay_web_cards_subtitle": "Acquista carte prepagate e carte regalo in tutto il mondo", "cake_pay_web_cards_subtitle": "Acquista carte prepagate e carte regalo in tutto il mondo",
"cake_pay_web_cards_title": "Carte Web Cake Pay", "cake_pay_web_cards_title": "Carte Web Cake Pay",
"cake_wallet": "Cake Wallet", "cake_wallet": "Cake Wallet",
@ -123,6 +123,7 @@
"change_wallet_alert_title": "Cambia portafoglio attuale", "change_wallet_alert_title": "Cambia portafoglio attuale",
"choose_account": "Scegli account", "choose_account": "Scegli account",
"choose_address": "\n\nSi prega di scegliere l'indirizzo:", "choose_address": "\n\nSi prega di scegliere l'indirizzo:",
"choose_card_value": "Scegli un valore della carta",
"choose_derivation": "Scegli la derivazione del portafoglio", "choose_derivation": "Scegli la derivazione del portafoglio",
"choose_from_available_options": "Scegli tra le opzioni disponibili:", "choose_from_available_options": "Scegli tra le opzioni disponibili:",
"choose_one": "Scegline uno", "choose_one": "Scegline uno",
@ -167,6 +168,7 @@
"copy_address": "Copia Indirizzo", "copy_address": "Copia Indirizzo",
"copy_id": "Copia ID", "copy_id": "Copia ID",
"copyWalletConnectLink": "Copia il collegamento WalletConnect dalla dApp e incollalo qui", "copyWalletConnectLink": "Copia il collegamento WalletConnect dalla dApp e incollalo qui",
"countries": "Paesi",
"create_account": "Crea account", "create_account": "Crea account",
"create_backup": "Crea backup", "create_backup": "Crea backup",
"create_donation_link": "Crea un link per la donazione", "create_donation_link": "Crea un link per la donazione",
@ -179,6 +181,7 @@
"custom": "personalizzato", "custom": "personalizzato",
"custom_drag": "Custom (Hold and Drag)", "custom_drag": "Custom (Hold and Drag)",
"custom_redeem_amount": "Importo di riscatto personalizzato", "custom_redeem_amount": "Importo di riscatto personalizzato",
"custom_value": "Valore personalizzato",
"dark_theme": "Scuro", "dark_theme": "Scuro",
"debit_card": "Carta di debito", "debit_card": "Carta di debito",
"debit_card_terms": "L'archiviazione e l'utilizzo del numero della carta di pagamento (e delle credenziali corrispondenti al numero della carta di pagamento) in questo portafoglio digitale sono soggetti ai Termini e condizioni del contratto applicabile con il titolare della carta con l'emittente della carta di pagamento, come in vigore da tempo al tempo.", "debit_card_terms": "L'archiviazione e l'utilizzo del numero della carta di pagamento (e delle credenziali corrispondenti al numero della carta di pagamento) in questo portafoglio digitale sono soggetti ai Termini e condizioni del contratto applicabile con il titolare della carta con l'emittente della carta di pagamento, come in vigore da tempo al tempo.",
@ -191,6 +194,7 @@
"delete_wallet": "Elimina portafoglio", "delete_wallet": "Elimina portafoglio",
"delete_wallet_confirm_message": "Sei sicuro di voler eliminare il portafoglio ${wallet_name}?", "delete_wallet_confirm_message": "Sei sicuro di voler eliminare il portafoglio ${wallet_name}?",
"deleteConnectionConfirmationPrompt": "Sei sicuro di voler eliminare la connessione a", "deleteConnectionConfirmationPrompt": "Sei sicuro di voler eliminare la connessione a",
"denominations": "Denominazioni",
"descending": "Discendente", "descending": "Discendente",
"description": "Descrizione", "description": "Descrizione",
"destination_tag": "Tag destinazione:", "destination_tag": "Tag destinazione:",
@ -278,6 +282,7 @@
"expired": "Scaduta", "expired": "Scaduta",
"expires": "Scade", "expires": "Scade",
"expiresOn": "Scade il", "expiresOn": "Scade il",
"expiry_and_validity": "Scadenza e validità",
"export_backup": "Esporta backup", "export_backup": "Esporta backup",
"extra_id": "Extra ID:", "extra_id": "Extra ID:",
"extracted_address_content": "Invierai i tuoi fondi a\n${recipient_name}", "extracted_address_content": "Invierai i tuoi fondi a\n${recipient_name}",
@ -385,6 +390,7 @@
"new_template": "Nuovo modello", "new_template": "Nuovo modello",
"new_wallet": "Nuovo Portafoglio", "new_wallet": "Nuovo Portafoglio",
"newConnection": "Nuova connessione", "newConnection": "Nuova connessione",
"no_cards_found": "Nessuna carta trovata",
"no_id_needed": "Nessun ID necessario!", "no_id_needed": "Nessun ID necessario!",
"no_id_required": "Nessun ID richiesto. Ricarica e spendi ovunque", "no_id_required": "Nessun ID richiesto. Ricarica e spendi ovunque",
"no_relay_on_domain": "Non esiste un inoltro per il dominio dell'utente oppure l'inoltro non è disponibile. Scegli un relè da utilizzare.", "no_relay_on_domain": "Non esiste un inoltro per il dominio dell'utente oppure l'inoltro non è disponibile. Scegli un relè da utilizzare.",
@ -454,6 +460,7 @@
"pre_seed_button_text": "Ho capito. Mostrami il seme", "pre_seed_button_text": "Ho capito. Mostrami il seme",
"pre_seed_description": "Nella pagina seguente ti sarà mostrata una serie di parole ${words}. Questo è il tuo seme unico e privato ed è l'UNICO modo per recuperare il tuo portafoglio in caso di perdita o malfunzionamento. E' TUA responsabilità trascriverlo e conservarlo in un posto sicuro fuori dall'app Cake Wallet.", "pre_seed_description": "Nella pagina seguente ti sarà mostrata una serie di parole ${words}. Questo è il tuo seme unico e privato ed è l'UNICO modo per recuperare il tuo portafoglio in caso di perdita o malfunzionamento. E' TUA responsabilità trascriverlo e conservarlo in un posto sicuro fuori dall'app Cake Wallet.",
"pre_seed_title": "IMPORTANTE", "pre_seed_title": "IMPORTANTE",
"prepaid_cards": "Carte prepagata",
"prevent_screenshots": "Impedisci screenshot e registrazione dello schermo", "prevent_screenshots": "Impedisci screenshot e registrazione dello schermo",
"privacy": "Privacy", "privacy": "Privacy",
"privacy_policy": "Informativa sulla privacy", "privacy_policy": "Informativa sulla privacy",
@ -469,6 +476,7 @@
"purple_dark_theme": "Tema oscuro viola", "purple_dark_theme": "Tema oscuro viola",
"qr_fullscreen": "Tocca per aprire il codice QR a schermo intero", "qr_fullscreen": "Tocca per aprire il codice QR a schermo intero",
"qr_payment_amount": "Questo codice QR contiene l'ammontare del pagamento. Vuoi sovrascrivere il varlore attuale?", "qr_payment_amount": "Questo codice QR contiene l'ammontare del pagamento. Vuoi sovrascrivere il varlore attuale?",
"quantity": "Quantità",
"question_to_disable_2fa": "Sei sicuro di voler disabilitare Cake 2FA? Non sarà più necessario un codice 2FA per accedere al portafoglio e ad alcune funzioni.", "question_to_disable_2fa": "Sei sicuro di voler disabilitare Cake 2FA? Non sarà più necessario un codice 2FA per accedere al portafoglio e ad alcune funzioni.",
"receivable_balance": "Bilanciamento creditizio", "receivable_balance": "Bilanciamento creditizio",
"receive": "Ricevi", "receive": "Ricevi",
@ -710,6 +718,7 @@
"tokenID": "ID", "tokenID": "ID",
"tor_connection": "Connessione Tor", "tor_connection": "Connessione Tor",
"tor_only": "Solo Tor", "tor_only": "Solo Tor",
"total": "Totale",
"total_saving": "Risparmio totale", "total_saving": "Risparmio totale",
"totp_2fa_failure": "Codice non corretto. Prova un codice diverso o genera una nuova chiave segreta. Utilizza un'app 2FA compatibile che supporti codici a 8 cifre e SHA512.", "totp_2fa_failure": "Codice non corretto. Prova un codice diverso o genera una nuova chiave segreta. Utilizza un'app 2FA compatibile che supporti codici a 8 cifre e SHA512.",
"totp_2fa_success": "Successo! Cake 2FA abilitato per questo portafoglio. Ricordati di salvare il tuo seme mnemonico nel caso in cui perdi l'accesso al portafoglio.", "totp_2fa_success": "Successo! Cake 2FA abilitato per questo portafoglio. Ricordati di salvare il tuo seme mnemonico nel caso in cui perdi l'accesso al portafoglio.",
@ -800,6 +809,8 @@
"use_ssl": "Usa SSL", "use_ssl": "Usa SSL",
"use_suggested": "Usa suggerito", "use_suggested": "Usa suggerito",
"use_testnet": "Usa TestNet", "use_testnet": "Usa TestNet",
"value": "Valore",
"value_type": "Tipo di valore",
"variable_pair_not_supported": "Questa coppia di variabili non è supportata con gli scambi selezionati", "variable_pair_not_supported": "Questa coppia di variabili non è supportata con gli scambi selezionati",
"verification": "Verifica", "verification": "Verifica",
"verify_with_2fa": "Verifica con Cake 2FA", "verify_with_2fa": "Verifica con Cake 2FA",

View file

@ -87,6 +87,7 @@
"buy": "購入", "buy": "購入",
"buy_alert_content": "現在、ビットコイン、イーサリアム、ライトコイン、モネロの購入のみをサポートしています。ビットコイン、イーサリアム、ライトコイン、またはモネロのウォレットを作成するか、これらのウォレットに切り替えてください。", "buy_alert_content": "現在、ビットコイン、イーサリアム、ライトコイン、モネロの購入のみをサポートしています。ビットコイン、イーサリアム、ライトコイン、またはモネロのウォレットを作成するか、これらのウォレットに切り替えてください。",
"buy_bitcoin": "ビットコインを購入する", "buy_bitcoin": "ビットコインを購入する",
"buy_now": "今すぐ購入",
"buy_provider_unavailable": "現在、プロバイダーは利用できません。", "buy_provider_unavailable": "現在、プロバイダーは利用できません。",
"buy_with": "で購入", "buy_with": "で購入",
"by_cake_pay": "by Cake Pay", "by_cake_pay": "by Cake Pay",
@ -94,8 +95,7 @@
"cake_dark_theme": "ケーキ暗いテーマ", "cake_dark_theme": "ケーキ暗いテーマ",
"cake_pay_account_note": "メールアドレスだけでサインアップして、カードを表示して購入できます。割引価格で利用できるカードもあります!", "cake_pay_account_note": "メールアドレスだけでサインアップして、カードを表示して購入できます。割引価格で利用できるカードもあります!",
"cake_pay_learn_more": "アプリですぐにギフトカードを購入して引き換えましょう!\n左から右にスワイプして詳細をご覧ください。", "cake_pay_learn_more": "アプリですぐにギフトカードを購入して引き換えましょう!\n左から右にスワイプして詳細をご覧ください。",
"cake_pay_subtitle": "割引ギフトカードを購入する (米国のみ)", "cake_pay_subtitle": "世界中のプリペイドカードとギフトカードを購入します",
"cake_pay_title": "ケーキペイギフトカード",
"cake_pay_web_cards_subtitle": "世界中のプリペイド カードとギフト カードを購入する", "cake_pay_web_cards_subtitle": "世界中のプリペイド カードとギフト カードを購入する",
"cake_pay_web_cards_title": "Cake Pay ウェブカード", "cake_pay_web_cards_title": "Cake Pay ウェブカード",
"cake_wallet": "Cake Wallet", "cake_wallet": "Cake Wallet",
@ -123,6 +123,7 @@
"change_wallet_alert_title": "現在のウォレットを変更する", "change_wallet_alert_title": "現在のウォレットを変更する",
"choose_account": "アカウントを選択", "choose_account": "アカウントを選択",
"choose_address": "\n\n住所を選択してください", "choose_address": "\n\n住所を選択してください",
"choose_card_value": "カード値を選択します",
"choose_derivation": "ウォレット派生を選択します", "choose_derivation": "ウォレット派生を選択します",
"choose_from_available_options": "利用可能なオプションから選択してください:", "choose_from_available_options": "利用可能なオプションから選択してください:",
"choose_one": "1 つ選択してください", "choose_one": "1 つ選択してください",
@ -166,6 +167,7 @@
"copy_address": "住所をコピー", "copy_address": "住所をコピー",
"copy_id": "IDをコピー", "copy_id": "IDをコピー",
"copyWalletConnectLink": "dApp から WalletConnect リンクをコピーし、ここに貼り付けます", "copyWalletConnectLink": "dApp から WalletConnect リンクをコピーし、ここに貼り付けます",
"countries": "国",
"create_account": "アカウントの作成", "create_account": "アカウントの作成",
"create_backup": "バックアップを作成", "create_backup": "バックアップを作成",
"create_donation_link": "寄付リンクを作成", "create_donation_link": "寄付リンクを作成",
@ -178,6 +180,7 @@
"custom": "カスタム", "custom": "カスタム",
"custom_drag": "カスタム(ホールドとドラッグ)", "custom_drag": "カスタム(ホールドとドラッグ)",
"custom_redeem_amount": "カスタム交換金額", "custom_redeem_amount": "カスタム交換金額",
"custom_value": "カスタム値",
"dark_theme": "闇", "dark_theme": "闇",
"debit_card": "デビットカード", "debit_card": "デビットカード",
"debit_card_terms": "このデジタルウォレットでの支払いカード番号(および支払いカード番号に対応する資格情報)の保存と使用には、支払いカード発行者との該当するカード所有者契約の利用規約が適用されます。時々。", "debit_card_terms": "このデジタルウォレットでの支払いカード番号(および支払いカード番号に対応する資格情報)の保存と使用には、支払いカード発行者との該当するカード所有者契約の利用規約が適用されます。時々。",
@ -190,6 +193,7 @@
"delete_wallet": "ウォレットを削除", "delete_wallet": "ウォレットを削除",
"delete_wallet_confirm_message": "${wallet_name} ウォレットを削除してもよろしいですか?", "delete_wallet_confirm_message": "${wallet_name} ウォレットを削除してもよろしいですか?",
"deleteConnectionConfirmationPrompt": "への接続を削除してもよろしいですか?", "deleteConnectionConfirmationPrompt": "への接続を削除してもよろしいですか?",
"denominations": "宗派",
"descending": "下降", "descending": "下降",
"description": "説明", "description": "説明",
"destination_tag": "宛先タグ:", "destination_tag": "宛先タグ:",
@ -277,6 +281,7 @@
"expired": "期限切れ", "expired": "期限切れ",
"expires": "Expires", "expires": "Expires",
"expiresOn": "有効期限は次のとおりです", "expiresOn": "有効期限は次のとおりです",
"expiry_and_validity": "有効期限と有効性",
"export_backup": "バックアップのエクスポート", "export_backup": "バックアップのエクスポート",
"extra_id": "追加ID:", "extra_id": "追加ID:",
"extracted_address_content": "に送金します\n${recipient_name}", "extracted_address_content": "に送金します\n${recipient_name}",
@ -385,6 +390,7 @@
"new_template": "新しいテンプレート", "new_template": "新しいテンプレート",
"new_wallet": "新しいウォレット", "new_wallet": "新しいウォレット",
"newConnection": "新しい接続", "newConnection": "新しい接続",
"no_cards_found": "カードは見つかりません",
"no_id_needed": "IDは必要ありません", "no_id_needed": "IDは必要ありません",
"no_id_required": "IDは必要ありません。どこにでも補充して使用できます", "no_id_required": "IDは必要ありません。どこにでも補充して使用できます",
"no_relay_on_domain": "ユーザーのドメインのリレーが存在しないか、リレーが使用できません。使用するリレーを選択してください。", "no_relay_on_domain": "ユーザーのドメインのリレーが存在しないか、リレーが使用できません。使用するリレーを選択してください。",
@ -453,6 +459,7 @@
"pre_seed_button_text": "わかります。 種を見せて", "pre_seed_button_text": "わかります。 種を見せて",
"pre_seed_description": "次のページでは、一連の${words}語が表示されます。 これはあなたのユニークでプライベートなシードであり、紛失や誤動作が発生した場合にウォレットを回復する唯一の方法です。 それを書き留めて、Cake Wallet アプリの外の安全な場所に保管するのはあなたの責任です。", "pre_seed_description": "次のページでは、一連の${words}語が表示されます。 これはあなたのユニークでプライベートなシードであり、紛失や誤動作が発生した場合にウォレットを回復する唯一の方法です。 それを書き留めて、Cake Wallet アプリの外の安全な場所に保管するのはあなたの責任です。",
"pre_seed_title": "重要", "pre_seed_title": "重要",
"prepaid_cards": "プリペイドカード",
"prevent_screenshots": "スクリーンショットと画面録画を防止する", "prevent_screenshots": "スクリーンショットと画面録画を防止する",
"privacy": "プライバシー", "privacy": "プライバシー",
"privacy_policy": "プライバシーポリシー", "privacy_policy": "プライバシーポリシー",
@ -468,6 +475,7 @@
"purple_dark_theme": "紫色の暗いテーマ", "purple_dark_theme": "紫色の暗いテーマ",
"qr_fullscreen": "タップして全画面QRコードを開く", "qr_fullscreen": "タップして全画面QRコードを開く",
"qr_payment_amount": "This QR code contains a payment amount. Do you want to overwrite the current value?", "qr_payment_amount": "This QR code contains a payment amount. Do you want to overwrite the current value?",
"quantity": "量",
"question_to_disable_2fa": "Cake 2FA を無効にしてもよろしいですか?ウォレットと特定の機能にアクセスするために 2FA コードは必要なくなります。", "question_to_disable_2fa": "Cake 2FA を無効にしてもよろしいですか?ウォレットと特定の機能にアクセスするために 2FA コードは必要なくなります。",
"receivable_balance": "売掛金残高", "receivable_balance": "売掛金残高",
"receive": "受け取る", "receive": "受け取る",
@ -709,6 +717,7 @@
"tokenID": "ID", "tokenID": "ID",
"tor_connection": "Tor接続", "tor_connection": "Tor接続",
"tor_only": "Torのみ", "tor_only": "Torのみ",
"total": "合計",
"total_saving": "合計節約額", "total_saving": "合計節約額",
"totp_2fa_failure": "コードが正しくありません。 別のコードを試すか、新しい秘密鍵を生成してください。 8 桁のコードと SHA512 をサポートする互換性のある 2FA アプリを使用してください。", "totp_2fa_failure": "コードが正しくありません。 別のコードを試すか、新しい秘密鍵を生成してください。 8 桁のコードと SHA512 をサポートする互換性のある 2FA アプリを使用してください。",
"totp_2fa_success": "成功!このウォレットでは Cake 2FA が有効になっています。ウォレットへのアクセスを失った場合に備えて、ニーモニック シードを忘れずに保存してください。", "totp_2fa_success": "成功!このウォレットでは Cake 2FA が有効になっています。ウォレットへのアクセスを失った場合に備えて、ニーモニック シードを忘れずに保存してください。",
@ -799,6 +808,8 @@
"use_ssl": "SSLを使用する", "use_ssl": "SSLを使用する",
"use_suggested": "推奨を使用", "use_suggested": "推奨を使用",
"use_testnet": "テストネットを使用します", "use_testnet": "テストネットを使用します",
"value": "価値",
"value_type": "値タイプ",
"variable_pair_not_supported": "この変数ペアは、選択した取引所ではサポートされていません", "variable_pair_not_supported": "この変数ペアは、選択した取引所ではサポートされていません",
"verification": "検証", "verification": "検証",
"verify_with_2fa": "Cake 2FA で検証する", "verify_with_2fa": "Cake 2FA で検証する",

View file

@ -87,6 +87,7 @@
"buy": "구입", "buy": "구입",
"buy_alert_content": "현재 Bitcoin, Ethereum, Litecoin 및 Monero 구매만 지원합니다. Bitcoin, Ethereum, Litecoin 또는 Monero 지갑을 생성하거나 전환하십시오.", "buy_alert_content": "현재 Bitcoin, Ethereum, Litecoin 및 Monero 구매만 지원합니다. Bitcoin, Ethereum, Litecoin 또는 Monero 지갑을 생성하거나 전환하십시오.",
"buy_bitcoin": "비트 코인 구매", "buy_bitcoin": "비트 코인 구매",
"buy_now": "지금 구매하십시오",
"buy_provider_unavailable": "제공자는 현재 사용할 수 없습니다.", "buy_provider_unavailable": "제공자는 현재 사용할 수 없습니다.",
"buy_with": "구매", "buy_with": "구매",
"by_cake_pay": "Cake Pay로", "by_cake_pay": "Cake Pay로",
@ -94,8 +95,7 @@
"cake_dark_theme": "케이크 다크 테마", "cake_dark_theme": "케이크 다크 테마",
"cake_pay_account_note": "이메일 주소로 가입하면 카드를 보고 구매할 수 있습니다. 일부는 할인된 가격으로 사용 가능합니다!", "cake_pay_account_note": "이메일 주소로 가입하면 카드를 보고 구매할 수 있습니다. 일부는 할인된 가격으로 사용 가능합니다!",
"cake_pay_learn_more": "앱에서 즉시 기프트 카드를 구매하고 사용하세요!\n자세히 알아보려면 왼쪽에서 오른쪽으로 스와이프하세요.", "cake_pay_learn_more": "앱에서 즉시 기프트 카드를 구매하고 사용하세요!\n자세히 알아보려면 왼쪽에서 오른쪽으로 스와이프하세요.",
"cake_pay_subtitle": "할인된 기프트 카드 구매(미국만 해당)", "cake_pay_subtitle": "전세계 선불 카드와 기프트 카드를 구입하십시오",
"cake_pay_title": "케이크 페이 기프트 카드",
"cake_pay_web_cards_subtitle": "전 세계 선불 카드 및 기프트 카드 구매", "cake_pay_web_cards_subtitle": "전 세계 선불 카드 및 기프트 카드 구매",
"cake_pay_web_cards_title": "케이크페이 웹카드", "cake_pay_web_cards_title": "케이크페이 웹카드",
"cake_wallet": "Cake Wallet", "cake_wallet": "Cake Wallet",
@ -123,6 +123,7 @@
"change_wallet_alert_title": "현재 지갑 변경", "change_wallet_alert_title": "현재 지갑 변경",
"choose_account": "계정을 선택하십시오", "choose_account": "계정을 선택하십시오",
"choose_address": "\n\n주소를 선택하십시오:", "choose_address": "\n\n주소를 선택하십시오:",
"choose_card_value": "카드 값을 선택하십시오",
"choose_derivation": "지갑 파생을 선택하십시오", "choose_derivation": "지갑 파생을 선택하십시오",
"choose_from_available_options": "사용 가능한 옵션에서 선택:", "choose_from_available_options": "사용 가능한 옵션에서 선택:",
"choose_one": "하나 선택", "choose_one": "하나 선택",
@ -166,6 +167,7 @@
"copy_address": "주소 복사", "copy_address": "주소 복사",
"copy_id": "부 ID", "copy_id": "부 ID",
"copyWalletConnectLink": "dApp에서 WalletConnect 링크를 복사하여 여기에 붙여넣으세요.", "copyWalletConnectLink": "dApp에서 WalletConnect 링크를 복사하여 여기에 붙여넣으세요.",
"countries": "국가",
"create_account": "계정 만들기", "create_account": "계정 만들기",
"create_backup": "백업 생성", "create_backup": "백업 생성",
"create_donation_link": "기부 링크 만들기", "create_donation_link": "기부 링크 만들기",
@ -178,6 +180,7 @@
"custom": "커스텀", "custom": "커스텀",
"custom_drag": "사용자 정의 (홀드 앤 드래그)", "custom_drag": "사용자 정의 (홀드 앤 드래그)",
"custom_redeem_amount": "사용자 지정 상환 금액", "custom_redeem_amount": "사용자 지정 상환 금액",
"custom_value": "맞춤 가치",
"dark_theme": "어두운", "dark_theme": "어두운",
"debit_card": "직불 카드", "debit_card": "직불 카드",
"debit_card_terms": "이 디지털 지갑에 있는 귀하의 지불 카드 번호(및 귀하의 지불 카드 번호에 해당하는 자격 증명)의 저장 및 사용은 부터 발효되는 지불 카드 발행자와의 해당 카드 소지자 계약의 이용 약관을 따릅니다. 수시로.", "debit_card_terms": "이 디지털 지갑에 있는 귀하의 지불 카드 번호(및 귀하의 지불 카드 번호에 해당하는 자격 증명)의 저장 및 사용은 부터 발효되는 지불 카드 발행자와의 해당 카드 소지자 계약의 이용 약관을 따릅니다. 수시로.",
@ -190,6 +193,7 @@
"delete_wallet": "지갑 삭제", "delete_wallet": "지갑 삭제",
"delete_wallet_confirm_message": "${wallet_name} 지갑을 삭제하시겠습니까?", "delete_wallet_confirm_message": "${wallet_name} 지갑을 삭제하시겠습니까?",
"deleteConnectionConfirmationPrompt": "다음 연결을 삭제하시겠습니까?", "deleteConnectionConfirmationPrompt": "다음 연결을 삭제하시겠습니까?",
"denominations": "교파",
"descending": "내림차순", "descending": "내림차순",
"description": "설명", "description": "설명",
"destination_tag": "목적지 태그:", "destination_tag": "목적지 태그:",
@ -277,6 +281,7 @@
"expired": "만료", "expired": "만료",
"expires": "만료", "expires": "만료",
"expiresOn": "만료 날짜", "expiresOn": "만료 날짜",
"expiry_and_validity": "만료와 타당성",
"export_backup": "백업 내보내기", "export_backup": "백업 내보내기",
"extra_id": "추가 ID:", "extra_id": "추가 ID:",
"extracted_address_content": "당신은에 자금을 보낼 것입니다\n${recipient_name}", "extracted_address_content": "당신은에 자금을 보낼 것입니다\n${recipient_name}",
@ -384,6 +389,7 @@
"new_template": "새 템플릿", "new_template": "새 템플릿",
"new_wallet": "새 월렛", "new_wallet": "새 월렛",
"newConnection": "새로운 연결", "newConnection": "새로운 연결",
"no_cards_found": "카드를 찾지 못했습니다",
"no_id_needed": "ID가 필요하지 않습니다!", "no_id_needed": "ID가 필요하지 않습니다!",
"no_id_required": "신분증이 필요하지 않습니다. 충전하고 어디에서나 사용하세요", "no_id_required": "신분증이 필요하지 않습니다. 충전하고 어디에서나 사용하세요",
"no_relay_on_domain": "사용자 도메인에 릴레이가 없거나 릴레이를 사용할 수 없습니다. 사용할 릴레이를 선택해주세요.", "no_relay_on_domain": "사용자 도메인에 릴레이가 없거나 릴레이를 사용할 수 없습니다. 사용할 릴레이를 선택해주세요.",
@ -453,6 +459,7 @@
"pre_seed_button_text": "이해 했어요. 내 씨앗을 보여줘", "pre_seed_button_text": "이해 했어요. 내 씨앗을 보여줘",
"pre_seed_description": "다음 페이지에서 ${words} 개의 단어를 볼 수 있습니다. 이것은 귀하의 고유하고 개인적인 시드이며 분실 또는 오작동시 지갑을 복구하는 유일한 방법입니다. 기록해두고 Cake Wallet 앱 외부의 안전한 장소에 보관하는 것은 귀하의 책임입니다.", "pre_seed_description": "다음 페이지에서 ${words} 개의 단어를 볼 수 있습니다. 이것은 귀하의 고유하고 개인적인 시드이며 분실 또는 오작동시 지갑을 복구하는 유일한 방법입니다. 기록해두고 Cake Wallet 앱 외부의 안전한 장소에 보관하는 것은 귀하의 책임입니다.",
"pre_seed_title": "중대한", "pre_seed_title": "중대한",
"prepaid_cards": "선불 카드",
"prevent_screenshots": "스크린샷 및 화면 녹화 방지", "prevent_screenshots": "스크린샷 및 화면 녹화 방지",
"privacy": "프라이버시", "privacy": "프라이버시",
"privacy_policy": "개인 정보 보호 정책", "privacy_policy": "개인 정보 보호 정책",
@ -468,6 +475,7 @@
"purple_dark_theme": "보라색 어두운 테마", "purple_dark_theme": "보라색 어두운 테마",
"qr_fullscreen": "전체 화면 QR 코드를 열려면 탭하세요.", "qr_fullscreen": "전체 화면 QR 코드를 열려면 탭하세요.",
"qr_payment_amount": "This QR code contains a payment amount. Do you want to overwrite the current value?", "qr_payment_amount": "This QR code contains a payment amount. Do you want to overwrite the current value?",
"quantity": "수량",
"question_to_disable_2fa": "Cake 2FA를 비활성화하시겠습니까? 지갑 및 특정 기능에 액세스하는 데 더 이상 2FA 코드가 필요하지 않습니다.", "question_to_disable_2fa": "Cake 2FA를 비활성화하시겠습니까? 지갑 및 특정 기능에 액세스하는 데 더 이상 2FA 코드가 필요하지 않습니다.",
"receivable_balance": "채권 잔액", "receivable_balance": "채권 잔액",
"receive": "받다", "receive": "받다",
@ -709,6 +717,7 @@
"tokenID": "ID", "tokenID": "ID",
"tor_connection": "토르 연결", "tor_connection": "토르 연결",
"tor_only": "Tor 뿐", "tor_only": "Tor 뿐",
"total": "총",
"total_saving": "총 절감액", "total_saving": "총 절감액",
"totp_2fa_failure": "잘못된 코드입니다. 다른 코드를 시도하거나 새 비밀 키를 생성하십시오. 8자리 코드와 SHA512를 지원하는 호환되는 2FA 앱을 사용하세요.", "totp_2fa_failure": "잘못된 코드입니다. 다른 코드를 시도하거나 새 비밀 키를 생성하십시오. 8자리 코드와 SHA512를 지원하는 호환되는 2FA 앱을 사용하세요.",
"totp_2fa_success": "성공! 이 지갑에 케이크 2FA가 활성화되었습니다. 지갑 액세스 권한을 잃을 경우를 대비하여 니모닉 시드를 저장하는 것을 잊지 마십시오.", "totp_2fa_success": "성공! 이 지갑에 케이크 2FA가 활성화되었습니다. 지갑 액세스 권한을 잃을 경우를 대비하여 니모닉 시드를 저장하는 것을 잊지 마십시오.",
@ -799,6 +808,8 @@
"use_ssl": "SSL 사용", "use_ssl": "SSL 사용",
"use_suggested": "추천 사용", "use_suggested": "추천 사용",
"use_testnet": "TestNet을 사용하십시오", "use_testnet": "TestNet을 사용하십시오",
"value": "값",
"value_type": "가치 유형",
"variable_pair_not_supported": "이 변수 쌍은 선택한 교환에서 지원되지 않습니다.", "variable_pair_not_supported": "이 변수 쌍은 선택한 교환에서 지원되지 않습니다.",
"verification": "검증", "verification": "검증",
"verify_with_2fa": "케이크 2FA로 확인", "verify_with_2fa": "케이크 2FA로 확인",

View file

@ -87,6 +87,7 @@
"buy": "ဝယ်ပါ။", "buy": "ဝယ်ပါ။",
"buy_alert_content": "လက်ရှိတွင် ကျွန်ုပ်တို့သည် Bitcoin၊ Ethereum၊ Litecoin နှင့် Monero တို့ကိုသာ ဝယ်ယူမှုကို ပံ့ပိုးပေးပါသည်။ သင်၏ Bitcoin၊ Ethereum၊ Litecoin သို့မဟုတ် Monero ပိုက်ဆံအိတ်ကို ဖန်တီးပါ သို့မဟုတ် ပြောင်းပါ။", "buy_alert_content": "လက်ရှိတွင် ကျွန်ုပ်တို့သည် Bitcoin၊ Ethereum၊ Litecoin နှင့် Monero တို့ကိုသာ ဝယ်ယူမှုကို ပံ့ပိုးပေးပါသည်။ သင်၏ Bitcoin၊ Ethereum၊ Litecoin သို့မဟုတ် Monero ပိုက်ဆံအိတ်ကို ဖန်တီးပါ သို့မဟုတ် ပြောင်းပါ။",
"buy_bitcoin": "Bitcoin ကိုဝယ်ပါ။", "buy_bitcoin": "Bitcoin ကိုဝယ်ပါ။",
"buy_now": "အခုဝယ်ပါ",
"buy_provider_unavailable": "လက်ရှိတွင်လက်ရှိမရနိုင်ပါ။", "buy_provider_unavailable": "လက်ရှိတွင်လက်ရှိမရနိုင်ပါ။",
"buy_with": "အတူဝယ်ပါ။", "buy_with": "အတူဝယ်ပါ။",
"by_cake_pay": "Cake Pay ဖြင့်", "by_cake_pay": "Cake Pay ဖြင့်",
@ -94,8 +95,7 @@
"cake_dark_theme": "ကိတ်မုန့် Dark Theme", "cake_dark_theme": "ကိတ်မုန့် Dark Theme",
"cake_pay_account_note": "ကတ်များကြည့်ရှုဝယ်ယူရန် အီးမေးလ်လိပ်စာတစ်ခုဖြင့် စာရင်းသွင်းပါ။ အချို့ကို လျှော့ဈေးဖြင့်ပင် ရနိုင်သည်။", "cake_pay_account_note": "ကတ်များကြည့်ရှုဝယ်ယူရန် အီးမေးလ်လိပ်စာတစ်ခုဖြင့် စာရင်းသွင်းပါ။ အချို့ကို လျှော့ဈေးဖြင့်ပင် ရနိုင်သည်။",
"cake_pay_learn_more": "အက်ပ်ရှိ လက်ဆောင်ကတ်များကို ချက်ချင်းဝယ်ယူပြီး ကူပွန်ဖြင့် လဲလှယ်ပါ။\nပိုမိုလေ့လာရန် ဘယ်မှညာသို့ ပွတ်ဆွဲပါ။", "cake_pay_learn_more": "အက်ပ်ရှိ လက်ဆောင်ကတ်များကို ချက်ချင်းဝယ်ယူပြီး ကူပွန်ဖြင့် လဲလှယ်ပါ။\nပိုမိုလေ့လာရန် ဘယ်မှညာသို့ ပွတ်ဆွဲပါ။",
"cake_pay_subtitle": "လျှော့စျေးလက်ဆောင်ကတ်များဝယ်ပါ (USA သာ)", "cake_pay_subtitle": "Worldwide ကြိုတင်ငွေဖြည့်ကဒ်များနှင့်လက်ဆောင်ကဒ်များကို 0 ယ်ပါ",
"cake_pay_title": "ကိတ်မုန့်လက်ဆောင်ကတ်များ",
"cake_pay_web_cards_subtitle": "ကမ္ဘာတစ်ဝှမ်း ကြိုတင်ငွေပေးကတ်များနှင့် လက်ဆောင်ကတ်များကို ဝယ်ယူပါ။", "cake_pay_web_cards_subtitle": "ကမ္ဘာတစ်ဝှမ်း ကြိုတင်ငွေပေးကတ်များနှင့် လက်ဆောင်ကတ်များကို ဝယ်ယူပါ။",
"cake_pay_web_cards_title": "Cake Pay ဝဘ်ကတ်များ", "cake_pay_web_cards_title": "Cake Pay ဝဘ်ကတ်များ",
"cake_wallet": "Cake ပိုက်ဆံအိတ်", "cake_wallet": "Cake ပိုက်ဆံအိတ်",
@ -123,6 +123,7 @@
"change_wallet_alert_title": "လက်ရှိပိုက်ဆံအိတ်ကို ပြောင်းပါ။", "change_wallet_alert_title": "လက်ရှိပိုက်ဆံအိတ်ကို ပြောင်းပါ။",
"choose_account": "အကောင့်ကို ရွေးပါ။", "choose_account": "အကောင့်ကို ရွေးပါ။",
"choose_address": "\n\nလိပ်စာကို ရွေးပါ-", "choose_address": "\n\nလိပ်စာကို ရွေးပါ-",
"choose_card_value": "ကဒ်တန်ဖိုးတစ်ခုရွေးပါ",
"choose_derivation": "ပိုက်ဆံအိတ်ကိုရွေးချယ်ပါ", "choose_derivation": "ပိုက်ဆံအိတ်ကိုရွေးချယ်ပါ",
"choose_from_available_options": "ရနိုင်သောရွေးချယ်မှုများမှ ရွေးပါ-", "choose_from_available_options": "ရနိုင်သောရွေးချယ်မှုများမှ ရွေးပါ-",
"choose_one": "တစ်ခုရွေးပါ။", "choose_one": "တစ်ခုရွေးပါ။",
@ -166,6 +167,7 @@
"copy_address": "လိပ်စာကို ကူးယူပါ။", "copy_address": "လိပ်စာကို ကူးယူပါ။",
"copy_id": "ID ကူးယူပါ။", "copy_id": "ID ကူးယူပါ။",
"copyWalletConnectLink": "dApp မှ WalletConnect လင့်ခ်ကို ကူးယူပြီး ဤနေရာတွင် ကူးထည့်ပါ။", "copyWalletConnectLink": "dApp မှ WalletConnect လင့်ခ်ကို ကူးယူပြီး ဤနေရာတွင် ကူးထည့်ပါ။",
"countries": "နိုင်ငံများ",
"create_account": "အကောင့်ပြုလုပ်ပါ", "create_account": "အကောင့်ပြုလုပ်ပါ",
"create_backup": "အရန်သိမ်းခြင်းကို ဖန်တီးပါ။", "create_backup": "အရန်သိမ်းခြင်းကို ဖန်တီးပါ။",
"create_donation_link": "လှူဒါန်းမှုလင့်ခ်ကို ဖန်တီးပါ။", "create_donation_link": "လှူဒါန်းမှုလင့်ခ်ကို ဖန်တီးပါ။",
@ -178,6 +180,7 @@
"custom": "စိတ်ကြိုက်", "custom": "စိတ်ကြိုက်",
"custom_drag": "စိတ်ကြိုက် (Drag)", "custom_drag": "စိတ်ကြိုက် (Drag)",
"custom_redeem_amount": "စိတ်ကြိုက်သုံးငွေပမာဏ", "custom_redeem_amount": "စိတ်ကြိုက်သုံးငွေပမာဏ",
"custom_value": "စိတ်ကြိုက်တန်ဖိုး",
"dark_theme": "မှောငျမိုကျသော", "dark_theme": "မှောငျမိုကျသော",
"debit_card": "ဒက်ဘစ်ကတ်", "debit_card": "ဒက်ဘစ်ကတ်",
"debit_card_terms": "ဤဒစ်ဂျစ်တယ်ပိုက်ဆံအိတ်ရှိ သင့်ငွေပေးချေမှုကတ်နံပါတ် (နှင့် သင့်ငွေပေးချေကတ်နံပါတ်နှင့် သက်ဆိုင်သောအထောက်အထားများ) ၏ သိုလှောင်မှုနှင့် အသုံးပြုမှုသည် အချိန်အခါနှင့်အမျှ သက်ရောက်မှုရှိသကဲ့သို့ ကတ်ကိုင်ဆောင်ထားသူ၏ သဘောတူညီချက်၏ စည်းကမ်းသတ်မှတ်ချက်များနှင့် ကိုက်ညီပါသည်။", "debit_card_terms": "ဤဒစ်ဂျစ်တယ်ပိုက်ဆံအိတ်ရှိ သင့်ငွေပေးချေမှုကတ်နံပါတ် (နှင့် သင့်ငွေပေးချေကတ်နံပါတ်နှင့် သက်ဆိုင်သောအထောက်အထားများ) ၏ သိုလှောင်မှုနှင့် အသုံးပြုမှုသည် အချိန်အခါနှင့်အမျှ သက်ရောက်မှုရှိသကဲ့သို့ ကတ်ကိုင်ဆောင်ထားသူ၏ သဘောတူညီချက်၏ စည်းကမ်းသတ်မှတ်ချက်များနှင့် ကိုက်ညီပါသည်။",
@ -190,6 +193,7 @@
"delete_wallet": "ပိုက်ဆံအိတ်ကို ဖျက်ပါ။", "delete_wallet": "ပိုက်ဆံအိတ်ကို ဖျက်ပါ။",
"delete_wallet_confirm_message": "${wallet_name} ပိုက်ဆံအိတ်ကို ဖျက်လိုသည်မှာ သေချာပါသလား။", "delete_wallet_confirm_message": "${wallet_name} ပိုက်ဆံအိတ်ကို ဖျက်လိုသည်မှာ သေချာပါသလား။",
"deleteConnectionConfirmationPrompt": "ချိတ်ဆက်မှုကို ဖျက်လိုသည်မှာ သေချာပါသလား။", "deleteConnectionConfirmationPrompt": "ချိတ်ဆက်မှုကို ဖျက်လိုသည်မှာ သေချာပါသလား။",
"denominations": "ဂိုဏ်းချုပ်ပစ္စည်းများ",
"descending": "ဆင်း", "descending": "ဆင်း",
"description": "ဖော်ပြချက်", "description": "ဖော်ပြချက်",
"destination_tag": "ခရီးဆုံးအမှတ်-", "destination_tag": "ခရီးဆုံးအမှတ်-",
@ -277,6 +281,7 @@
"expired": "သက်တမ်းကုန်သွားပြီ", "expired": "သက်တမ်းကုန်သွားပြီ",
"expires": "သက်တမ်းကုန်သည်။", "expires": "သက်တမ်းကုန်သည်။",
"expiresOn": "သက်တမ်းကုန်သည်။", "expiresOn": "သက်တမ်းကုန်သည်။",
"expiry_and_validity": "သက်တမ်းကုန်ဆုံးခြင်းနှင့်တရားဝင်မှု",
"export_backup": "အရန်ကူးထုတ်ရန်", "export_backup": "အရန်ကူးထုတ်ရန်",
"extra_id": "အပို ID-", "extra_id": "အပို ID-",
"extracted_address_content": "သင်သည် \n${recipient_name} သို့ ရန်ပုံငွေများ ပေးပို့ပါမည်", "extracted_address_content": "သင်သည် \n${recipient_name} သို့ ရန်ပုံငွေများ ပေးပို့ပါမည်",
@ -384,6 +389,7 @@
"new_template": "ပုံစံအသစ်", "new_template": "ပုံစံအသစ်",
"new_wallet": "ပိုက်ဆံအိတ်အသစ်", "new_wallet": "ပိုက်ဆံအိတ်အသစ်",
"newConnection": "ချိတ်ဆက်မှုအသစ်", "newConnection": "ချိတ်ဆက်မှုအသစ်",
"no_cards_found": "ကဒ်များမရှိပါ",
"no_id_needed": "ID မလိုအပ်ပါ။", "no_id_needed": "ID မလိုအပ်ပါ။",
"no_id_required": "ID မလိုအပ်ပါ။ ငွေဖြည့်ပြီး ဘယ်နေရာမဆို သုံးစွဲပါ။", "no_id_required": "ID မလိုအပ်ပါ။ ငွေဖြည့်ပြီး ဘယ်နေရာမဆို သုံးစွဲပါ။",
"no_relay_on_domain": "အသုံးပြုသူ၏ဒိုမိန်းအတွက် ထပ်ဆင့်လွှင့်ခြင်း မရှိပါ သို့မဟုတ် ထပ်ဆင့်လွှင့်ခြင်း မရနိုင်ပါ။ အသုံးပြုရန် relay ကိုရွေးချယ်ပါ။", "no_relay_on_domain": "အသုံးပြုသူ၏ဒိုမိန်းအတွက် ထပ်ဆင့်လွှင့်ခြင်း မရှိပါ သို့မဟုတ် ထပ်ဆင့်လွှင့်ခြင်း မရနိုင်ပါ။ အသုံးပြုရန် relay ကိုရွေးချယ်ပါ။",
@ -452,6 +458,7 @@
"pre_seed_button_text": "ကျွန်တော်နားလည်ပါတယ်။ ငါ့အမျိုးအနွယ်ကို ပြလော့", "pre_seed_button_text": "ကျွန်တော်နားလည်ပါတယ်။ ငါ့အမျိုးအနွယ်ကို ပြလော့",
"pre_seed_description": "နောက်စာမျက်နှာတွင် ${words} စကားလုံးများ အတွဲလိုက်ကို တွေ့ရပါမည်။ ၎င်းသည် သင်၏ထူးခြားပြီး သီးသန့်မျိုးစေ့ဖြစ်ပြီး ပျောက်ဆုံးခြင်း သို့မဟုတ် ချွတ်ယွင်းမှုရှိပါက သင့်ပိုက်ဆံအိတ်ကို ပြန်လည်ရယူရန် တစ်ခုတည်းသောနည်းလမ်းဖြစ်သည်။ ၎င်းကို Cake Wallet အက်ပ်၏အပြင်ဘက်တွင် လုံခြုံသောနေရာတွင် သိမ်းဆည်းရန်မှာ သင်၏တာဝန်ဖြစ်သည်။", "pre_seed_description": "နောက်စာမျက်နှာတွင် ${words} စကားလုံးများ အတွဲလိုက်ကို တွေ့ရပါမည်။ ၎င်းသည် သင်၏ထူးခြားပြီး သီးသန့်မျိုးစေ့ဖြစ်ပြီး ပျောက်ဆုံးခြင်း သို့မဟုတ် ချွတ်ယွင်းမှုရှိပါက သင့်ပိုက်ဆံအိတ်ကို ပြန်လည်ရယူရန် တစ်ခုတည်းသောနည်းလမ်းဖြစ်သည်။ ၎င်းကို Cake Wallet အက်ပ်၏အပြင်ဘက်တွင် လုံခြုံသောနေရာတွင် သိမ်းဆည်းရန်မှာ သင်၏တာဝန်ဖြစ်သည်။",
"pre_seed_title": "အရေးကြီးသည်။", "pre_seed_title": "အရေးကြီးသည်။",
"prepaid_cards": "ကြိုတင်ငွေဖြည့်ကဒ်များ",
"prevent_screenshots": "ဖန်သားပြင်ဓာတ်ပုံများနှင့် မျက်နှာပြင်ရိုက်ကူးခြင်းကို တားဆီးပါ။", "prevent_screenshots": "ဖန်သားပြင်ဓာတ်ပုံများနှင့် မျက်နှာပြင်ရိုက်ကူးခြင်းကို တားဆီးပါ။",
"privacy": "ကိုယ်ရေးကိုယ်တာ", "privacy": "ကိုယ်ရေးကိုယ်တာ",
"privacy_policy": "ကိုယ်ရေးအချက်အလက်မူဝါဒ", "privacy_policy": "ကိုယ်ရေးအချက်အလက်မူဝါဒ",
@ -467,6 +474,7 @@
"purple_dark_theme": "ခရမ်းရောင် Drwing Theme", "purple_dark_theme": "ခရမ်းရောင် Drwing Theme",
"qr_fullscreen": "မျက်နှာပြင်အပြည့် QR ကုဒ်ကိုဖွင့်ရန် တို့ပါ။", "qr_fullscreen": "မျက်နှာပြင်အပြည့် QR ကုဒ်ကိုဖွင့်ရန် တို့ပါ။",
"qr_payment_amount": "ဤ QR ကုဒ်တွင် ငွေပေးချေမှုပမာဏတစ်ခုပါရှိသည်။ လက်ရှိတန်ဖိုးကို ထပ်ရေးလိုပါသလား။", "qr_payment_amount": "ဤ QR ကုဒ်တွင် ငွေပေးချေမှုပမာဏတစ်ခုပါရှိသည်။ လက်ရှိတန်ဖိုးကို ထပ်ရေးလိုပါသလား။",
"quantity": "အရေအတွက်",
"question_to_disable_2fa": "Cake 2FA ကို ပိတ်လိုသည်မှာ သေချာပါသလား။ ပိုက်ဆံအိတ်နှင့် အချို့သောလုပ်ဆောင်ချက်များကို အသုံးပြုရန်အတွက် 2FA ကုဒ်တစ်ခု မလိုအပ်တော့ပါ။", "question_to_disable_2fa": "Cake 2FA ကို ပိတ်လိုသည်မှာ သေချာပါသလား။ ပိုက်ဆံအိတ်နှင့် အချို့သောလုပ်ဆောင်ချက်များကို အသုံးပြုရန်အတွက် 2FA ကုဒ်တစ်ခု မလိုအပ်တော့ပါ။",
"receivable_balance": "လက်ကျန်ငွေ", "receivable_balance": "လက်ကျန်ငွေ",
"receive": "လက်ခံသည်။", "receive": "လက်ခံသည်။",
@ -708,6 +716,7 @@
"tokenID": "အမှတ်သညာ", "tokenID": "အမှတ်သညာ",
"tor_connection": "Tor ချိတ်ဆက်မှု", "tor_connection": "Tor ချိတ်ဆက်မှု",
"tor_only": "Tor သာ", "tor_only": "Tor သာ",
"total": "လုံးဝသော",
"total_saving": "စုစုပေါင်းစုဆောင်းငွေ", "total_saving": "စုစုပေါင်းစုဆောင်းငွေ",
"totp_2fa_failure": "ကုဒ်မမှန်ပါ။ ကျေးဇူးပြု၍ အခြားကုဒ်တစ်ခုကို စမ်းကြည့်ပါ သို့မဟုတ် လျှို့ဝှက်သော့အသစ်တစ်ခု ဖန်တီးပါ။ ဂဏန်း ၈ လုံးကုဒ်များနှင့် SHA512 ကို ပံ့ပိုးပေးသည့် တွဲဖက်အသုံးပြုနိုင်သော 2FA အက်ပ်ကို အသုံးပြုပါ။", "totp_2fa_failure": "ကုဒ်မမှန်ပါ။ ကျေးဇူးပြု၍ အခြားကုဒ်တစ်ခုကို စမ်းကြည့်ပါ သို့မဟုတ် လျှို့ဝှက်သော့အသစ်တစ်ခု ဖန်တီးပါ။ ဂဏန်း ၈ လုံးကုဒ်များနှင့် SHA512 ကို ပံ့ပိုးပေးသည့် တွဲဖက်အသုံးပြုနိုင်သော 2FA အက်ပ်ကို အသုံးပြုပါ။",
"totp_2fa_success": "အောင်မြင် ဤပိုက်ဆံအိတ်အတွက် ကိတ်မုန့် 2FA ကို ဖွင့်ထားသည်။ ပိုက်ဆံအိတ်ဝင်ရောက်ခွင့်ဆုံးရှုံးသွားသောအခါတွင် သင်၏ mnemonic မျိုးစေ့များကို သိမ်းဆည်းရန် မမေ့ပါနှင့်။", "totp_2fa_success": "အောင်မြင် ဤပိုက်ဆံအိတ်အတွက် ကိတ်မုန့် 2FA ကို ဖွင့်ထားသည်။ ပိုက်ဆံအိတ်ဝင်ရောက်ခွင့်ဆုံးရှုံးသွားသောအခါတွင် သင်၏ mnemonic မျိုးစေ့များကို သိမ်းဆည်းရန် မမေ့ပါနှင့်။",
@ -798,6 +807,8 @@
"use_ssl": "SSL ကိုသုံးပါ။", "use_ssl": "SSL ကိုသုံးပါ။",
"use_suggested": "အကြံပြုထားသည်ကို အသုံးပြုပါ။", "use_suggested": "အကြံပြုထားသည်ကို အသုံးပြုပါ။",
"use_testnet": "testnet ကိုသုံးပါ", "use_testnet": "testnet ကိုသုံးပါ",
"value": "အဘိုး",
"value_type": "Value အမျိုးအစား",
"variable_pair_not_supported": "ရွေးချယ်ထားသော ဖလှယ်မှုများဖြင့် ဤပြောင်းလဲနိုင်သောအတွဲကို ပံ့ပိုးမထားပါ။", "variable_pair_not_supported": "ရွေးချယ်ထားသော ဖလှယ်မှုများဖြင့် ဤပြောင်းလဲနိုင်သောအတွဲကို ပံ့ပိုးမထားပါ။",
"verification": "စိစစ်ခြင်း။", "verification": "စိစစ်ခြင်း။",
"verify_with_2fa": "Cake 2FA ဖြင့် စစ်ဆေးပါ။", "verify_with_2fa": "Cake 2FA ဖြင့် စစ်ဆေးပါ။",

View file

@ -87,6 +87,7 @@
"buy": "Kopen", "buy": "Kopen",
"buy_alert_content": "Momenteel ondersteunen we alleen de aankoop van Bitcoin, Ethereum, Litecoin en Monero. Maak of schakel over naar uw Bitcoin-, Ethereum-, Litecoin- of Monero-portemonnee.", "buy_alert_content": "Momenteel ondersteunen we alleen de aankoop van Bitcoin, Ethereum, Litecoin en Monero. Maak of schakel over naar uw Bitcoin-, Ethereum-, Litecoin- of Monero-portemonnee.",
"buy_bitcoin": "Koop Bitcoin", "buy_bitcoin": "Koop Bitcoin",
"buy_now": "Koop nu",
"buy_provider_unavailable": "Provider momenteel niet beschikbaar.", "buy_provider_unavailable": "Provider momenteel niet beschikbaar.",
"buy_with": "Koop met", "buy_with": "Koop met",
"by_cake_pay": "door Cake Pay", "by_cake_pay": "door Cake Pay",
@ -94,8 +95,7 @@
"cake_dark_theme": "Cake Dark Theme", "cake_dark_theme": "Cake Dark Theme",
"cake_pay_account_note": "Meld u aan met alleen een e-mailadres om kaarten te bekijken en te kopen. Sommige zijn zelfs met korting verkrijgbaar!", "cake_pay_account_note": "Meld u aan met alleen een e-mailadres om kaarten te bekijken en te kopen. Sommige zijn zelfs met korting verkrijgbaar!",
"cake_pay_learn_more": "Koop en wissel cadeaubonnen direct in de app in!\nSwipe van links naar rechts voor meer informatie.", "cake_pay_learn_more": "Koop en wissel cadeaubonnen direct in de app in!\nSwipe van links naar rechts voor meer informatie.",
"cake_pay_subtitle": "Koop cadeaubonnen met korting (alleen VS)", "cake_pay_subtitle": "Koop wereldwijde prepaid -kaarten en cadeaubonnen",
"cake_pay_title": "Cake Pay-cadeaubonnen",
"cake_pay_web_cards_subtitle": "Koop wereldwijd prepaidkaarten en cadeaubonnen", "cake_pay_web_cards_subtitle": "Koop wereldwijd prepaidkaarten en cadeaubonnen",
"cake_pay_web_cards_title": "Cake Pay-webkaarten", "cake_pay_web_cards_title": "Cake Pay-webkaarten",
"cake_wallet": "Cake Wallet", "cake_wallet": "Cake Wallet",
@ -123,6 +123,7 @@
"change_wallet_alert_title": "Wijzig huidige portemonnee", "change_wallet_alert_title": "Wijzig huidige portemonnee",
"choose_account": "Kies account", "choose_account": "Kies account",
"choose_address": "\n\nKies het adres:", "choose_address": "\n\nKies het adres:",
"choose_card_value": "Kies een kaartwaarde",
"choose_derivation": "Kies portemonnee -afleiding", "choose_derivation": "Kies portemonnee -afleiding",
"choose_from_available_options": "Kies uit de beschikbare opties:", "choose_from_available_options": "Kies uit de beschikbare opties:",
"choose_one": "Kies er een", "choose_one": "Kies er een",
@ -166,6 +167,7 @@
"copy_address": "Adres kopiëren", "copy_address": "Adres kopiëren",
"copy_id": "ID kopiëren", "copy_id": "ID kopiëren",
"copyWalletConnectLink": "Kopieer de WalletConnect-link van dApp en plak deze hier", "copyWalletConnectLink": "Kopieer de WalletConnect-link van dApp en plak deze hier",
"countries": "Landen",
"create_account": "Account aanmaken", "create_account": "Account aanmaken",
"create_backup": "Maak een back-up", "create_backup": "Maak een back-up",
"create_donation_link": "Maak een donatielink aan", "create_donation_link": "Maak een donatielink aan",
@ -178,6 +180,7 @@
"custom": "aangepast", "custom": "aangepast",
"custom_drag": "Custom (vasthouden en slepen)", "custom_drag": "Custom (vasthouden en slepen)",
"custom_redeem_amount": "Aangepast inwisselbedrag", "custom_redeem_amount": "Aangepast inwisselbedrag",
"custom_value": "Aangepaste waarde",
"dark_theme": "Donker", "dark_theme": "Donker",
"debit_card": "Debetkaart", "debit_card": "Debetkaart",
"debit_card_terms": "De opslag en het gebruik van uw betaalkaartnummer (en inloggegevens die overeenkomen met uw betaalkaartnummer) in deze digitale portemonnee zijn onderworpen aan de Algemene voorwaarden van de toepasselijke kaarthouderovereenkomst met de uitgever van de betaalkaart, zoals van kracht vanaf tijd tot tijd.", "debit_card_terms": "De opslag en het gebruik van uw betaalkaartnummer (en inloggegevens die overeenkomen met uw betaalkaartnummer) in deze digitale portemonnee zijn onderworpen aan de Algemene voorwaarden van de toepasselijke kaarthouderovereenkomst met de uitgever van de betaalkaart, zoals van kracht vanaf tijd tot tijd.",
@ -190,6 +193,7 @@
"delete_wallet": "Portemonnee verwijderen", "delete_wallet": "Portemonnee verwijderen",
"delete_wallet_confirm_message": "Weet u zeker dat u de portemonnee van ${wallet_name} wilt verwijderen?", "delete_wallet_confirm_message": "Weet u zeker dat u de portemonnee van ${wallet_name} wilt verwijderen?",
"deleteConnectionConfirmationPrompt": "Weet u zeker dat u de verbinding met", "deleteConnectionConfirmationPrompt": "Weet u zeker dat u de verbinding met",
"denominations": "Denominaties",
"descending": "Aflopend", "descending": "Aflopend",
"description": "Beschrijving", "description": "Beschrijving",
"destination_tag": "Bestemmingstag:", "destination_tag": "Bestemmingstag:",
@ -277,6 +281,7 @@
"expired": "Verlopen", "expired": "Verlopen",
"expires": "Verloopt", "expires": "Verloopt",
"expiresOn": "Verloopt op", "expiresOn": "Verloopt op",
"expiry_and_validity": "Vervallen en geldigheid",
"export_backup": "Back-up exporteren", "export_backup": "Back-up exporteren",
"extra_id": "Extra ID:", "extra_id": "Extra ID:",
"extracted_address_content": "U stuurt geld naar\n${recipient_name}", "extracted_address_content": "U stuurt geld naar\n${recipient_name}",
@ -384,6 +389,7 @@
"new_template": "Nieuwe sjabloon", "new_template": "Nieuwe sjabloon",
"new_wallet": "Nieuwe portemonnee", "new_wallet": "Nieuwe portemonnee",
"newConnection": "Nieuwe verbinding", "newConnection": "Nieuwe verbinding",
"no_cards_found": "Geen kaarten gevonden",
"no_id_needed": "Geen ID nodig!", "no_id_needed": "Geen ID nodig!",
"no_id_required": "Geen ID vereist. Opwaarderen en overal uitgeven", "no_id_required": "Geen ID vereist. Opwaarderen en overal uitgeven",
"no_relay_on_domain": "Er is geen relay voor het domein van de gebruiker of de relay is niet beschikbaar. Kies een relais dat u wilt gebruiken.", "no_relay_on_domain": "Er is geen relay voor het domein van de gebruiker of de relay is niet beschikbaar. Kies een relais dat u wilt gebruiken.",
@ -452,6 +458,7 @@
"pre_seed_button_text": "Ik begrijp het. Laat me mijn zaad zien", "pre_seed_button_text": "Ik begrijp het. Laat me mijn zaad zien",
"pre_seed_description": "Op de volgende pagina ziet u een reeks van ${words} woorden. Dit is uw unieke en persoonlijke zaadje en het is de ENIGE manier om uw portemonnee te herstellen in geval van verlies of storing. Het is JOUW verantwoordelijkheid om het op te schrijven en op een veilige plaats op te slaan buiten de Cake Wallet app.", "pre_seed_description": "Op de volgende pagina ziet u een reeks van ${words} woorden. Dit is uw unieke en persoonlijke zaadje en het is de ENIGE manier om uw portemonnee te herstellen in geval van verlies of storing. Het is JOUW verantwoordelijkheid om het op te schrijven en op een veilige plaats op te slaan buiten de Cake Wallet app.",
"pre_seed_title": "BELANGRIJK", "pre_seed_title": "BELANGRIJK",
"prepaid_cards": "Prepaid-kaarten",
"prevent_screenshots": "Voorkom screenshots en schermopname", "prevent_screenshots": "Voorkom screenshots en schermopname",
"privacy": "Privacy", "privacy": "Privacy",
"privacy_policy": "Privacybeleid", "privacy_policy": "Privacybeleid",
@ -467,6 +474,7 @@
"purple_dark_theme": "Paars donker thema", "purple_dark_theme": "Paars donker thema",
"qr_fullscreen": "Tik om de QR-code op volledig scherm te openen", "qr_fullscreen": "Tik om de QR-code op volledig scherm te openen",
"qr_payment_amount": "This QR code contains a payment amount. Do you want to overwrite the current value?", "qr_payment_amount": "This QR code contains a payment amount. Do you want to overwrite the current value?",
"quantity": "Hoeveelheid",
"question_to_disable_2fa": "Weet je zeker dat je Cake 2FA wilt uitschakelen? Er is geen 2FA-code meer nodig om toegang te krijgen tot de portemonnee en bepaalde functies.", "question_to_disable_2fa": "Weet je zeker dat je Cake 2FA wilt uitschakelen? Er is geen 2FA-code meer nodig om toegang te krijgen tot de portemonnee en bepaalde functies.",
"receivable_balance": "Het saldo", "receivable_balance": "Het saldo",
"receive": "Krijgen", "receive": "Krijgen",
@ -708,6 +716,7 @@
"tokenID": "ID kaart", "tokenID": "ID kaart",
"tor_connection": "Tor-verbinding", "tor_connection": "Tor-verbinding",
"tor_only": "Alleen Tor", "tor_only": "Alleen Tor",
"total": "Totaal",
"total_saving": "Totale besparingen", "total_saving": "Totale besparingen",
"totp_2fa_failure": "Foute code. Probeer een andere code of genereer een nieuwe geheime sleutel. Gebruik een compatibele 2FA-app die 8-cijferige codes en SHA512 ondersteunt.", "totp_2fa_failure": "Foute code. Probeer een andere code of genereer een nieuwe geheime sleutel. Gebruik een compatibele 2FA-app die 8-cijferige codes en SHA512 ondersteunt.",
"totp_2fa_success": "Succes! Cake 2FA ingeschakeld voor deze portemonnee. Vergeet niet om uw geheugensteuntje op te slaan voor het geval u de toegang tot de portemonnee kwijtraakt.", "totp_2fa_success": "Succes! Cake 2FA ingeschakeld voor deze portemonnee. Vergeet niet om uw geheugensteuntje op te slaan voor het geval u de toegang tot de portemonnee kwijtraakt.",
@ -798,6 +807,8 @@
"use_ssl": "Gebruik SSL", "use_ssl": "Gebruik SSL",
"use_suggested": "Gebruik aanbevolen", "use_suggested": "Gebruik aanbevolen",
"use_testnet": "Gebruik testnet", "use_testnet": "Gebruik testnet",
"value": "Waarde",
"value_type": "Waarde type",
"variable_pair_not_supported": "Dit variabelenpaar wordt niet ondersteund met de geselecteerde uitwisselingen", "variable_pair_not_supported": "Dit variabelenpaar wordt niet ondersteund met de geselecteerde uitwisselingen",
"verification": "Verificatie", "verification": "Verificatie",
"verify_with_2fa": "Controleer met Cake 2FA", "verify_with_2fa": "Controleer met Cake 2FA",

View file

@ -87,6 +87,7 @@
"buy": "Kup", "buy": "Kup",
"buy_alert_content": "Obecnie obsługujemy tylko zakup Bitcoin, Ethereum, Litecoin i Monero. Utwórz lub przełącz się na swój portfel Bitcoin, Ethereum, Litecoin lub Monero.", "buy_alert_content": "Obecnie obsługujemy tylko zakup Bitcoin, Ethereum, Litecoin i Monero. Utwórz lub przełącz się na swój portfel Bitcoin, Ethereum, Litecoin lub Monero.",
"buy_bitcoin": "Kup Bitcoin", "buy_bitcoin": "Kup Bitcoin",
"buy_now": "Kup Teraz",
"buy_provider_unavailable": "Dostawca obecnie niedostępny.", "buy_provider_unavailable": "Dostawca obecnie niedostępny.",
"buy_with": "Kup za pomocą", "buy_with": "Kup za pomocą",
"by_cake_pay": "przez Cake Pay", "by_cake_pay": "przez Cake Pay",
@ -94,8 +95,7 @@
"cake_dark_theme": "Cake Dark Temat", "cake_dark_theme": "Cake Dark Temat",
"cake_pay_account_note": "Zarejestruj się, używając tylko adresu e-mail, aby przeglądać i kupować karty. Niektóre są nawet dostępne ze zniżką!", "cake_pay_account_note": "Zarejestruj się, używając tylko adresu e-mail, aby przeglądać i kupować karty. Niektóre są nawet dostępne ze zniżką!",
"cake_pay_learn_more": "Kupuj i wykorzystuj karty podarunkowe od razu w aplikacji!\nPrzesuń od lewej do prawej, aby dowiedzieć się więcej.", "cake_pay_learn_more": "Kupuj i wykorzystuj karty podarunkowe od razu w aplikacji!\nPrzesuń od lewej do prawej, aby dowiedzieć się więcej.",
"cake_pay_subtitle": "Kup karty upominkowe ze zniżką (tylko USA)", "cake_pay_subtitle": "Kup na całym świecie karty przedpłacone i karty podarunkowe",
"cake_pay_title": "Karty podarunkowe Cake Pay",
"cake_pay_web_cards_subtitle": "Kupuj na całym świecie karty przedpłacone i karty podarunkowe", "cake_pay_web_cards_subtitle": "Kupuj na całym świecie karty przedpłacone i karty podarunkowe",
"cake_pay_web_cards_title": "Cake Pay Web Cards", "cake_pay_web_cards_title": "Cake Pay Web Cards",
"cake_wallet": "Cake Wallet", "cake_wallet": "Cake Wallet",
@ -123,6 +123,7 @@
"change_wallet_alert_title": "Zmień obecny portfel", "change_wallet_alert_title": "Zmień obecny portfel",
"choose_account": "Wybierz konto", "choose_account": "Wybierz konto",
"choose_address": "\n\nWybierz adres:", "choose_address": "\n\nWybierz adres:",
"choose_card_value": "Wybierz wartość karty",
"choose_derivation": "Wybierz wyprowadzenie portfela", "choose_derivation": "Wybierz wyprowadzenie portfela",
"choose_from_available_options": "Wybierz z dostępnych opcji:", "choose_from_available_options": "Wybierz z dostępnych opcji:",
"choose_one": "Wybierz jeden", "choose_one": "Wybierz jeden",
@ -166,6 +167,7 @@
"copy_address": "Skopiuj adress", "copy_address": "Skopiuj adress",
"copy_id": "skopiuj ID", "copy_id": "skopiuj ID",
"copyWalletConnectLink": "Skopiuj link do WalletConnect z dApp i wklej tutaj", "copyWalletConnectLink": "Skopiuj link do WalletConnect z dApp i wklej tutaj",
"countries": "Kraje",
"create_account": "Utwórz konto", "create_account": "Utwórz konto",
"create_backup": "Utwórz kopię zapasową", "create_backup": "Utwórz kopię zapasową",
"create_donation_link": "Utwórz link do darowizny", "create_donation_link": "Utwórz link do darowizny",
@ -178,6 +180,7 @@
"custom": "niestandardowy", "custom": "niestandardowy",
"custom_drag": "Niestandardowe (trzymaj i przeciągnij)", "custom_drag": "Niestandardowe (trzymaj i przeciągnij)",
"custom_redeem_amount": "Niestandardowa kwota wykorzystania", "custom_redeem_amount": "Niestandardowa kwota wykorzystania",
"custom_value": "Wartość niestandardowa",
"dark_theme": "Ciemny", "dark_theme": "Ciemny",
"debit_card": "Karta debetowa", "debit_card": "Karta debetowa",
"debit_card_terms": "Przechowywanie i używanie numeru karty płatniczej (oraz danych uwierzytelniających odpowiadających numerowi karty płatniczej) w tym portfelu cyfrowym podlega Warunkom odpowiedniej umowy posiadacza karty z wydawcą karty płatniczej, zgodnie z obowiązującym od od czasu do czasu.", "debit_card_terms": "Przechowywanie i używanie numeru karty płatniczej (oraz danych uwierzytelniających odpowiadających numerowi karty płatniczej) w tym portfelu cyfrowym podlega Warunkom odpowiedniej umowy posiadacza karty z wydawcą karty płatniczej, zgodnie z obowiązującym od od czasu do czasu.",
@ -190,6 +193,7 @@
"delete_wallet": "Usuń portfel", "delete_wallet": "Usuń portfel",
"delete_wallet_confirm_message": "Czy na pewno chcesz usunąć portfel ${wallet_name}?", "delete_wallet_confirm_message": "Czy na pewno chcesz usunąć portfel ${wallet_name}?",
"deleteConnectionConfirmationPrompt": "Czy na pewno chcesz usunąć połączenie z", "deleteConnectionConfirmationPrompt": "Czy na pewno chcesz usunąć połączenie z",
"denominations": "Wyznaczenia",
"descending": "Schodzenie", "descending": "Schodzenie",
"description": "Opis", "description": "Opis",
"destination_tag": "Tag docelowy:", "destination_tag": "Tag docelowy:",
@ -277,6 +281,7 @@
"expired": "Przedawniony", "expired": "Przedawniony",
"expires": "Wygasa", "expires": "Wygasa",
"expiresOn": "Upływa w dniu", "expiresOn": "Upływa w dniu",
"expiry_and_validity": "Wygaśnięcie i ważność",
"export_backup": "Eksportuj kopię zapasową", "export_backup": "Eksportuj kopię zapasową",
"extra_id": "Dodatkowy ID:", "extra_id": "Dodatkowy ID:",
"extracted_address_content": "Wysyłasz środki na\n${recipient_name}", "extracted_address_content": "Wysyłasz środki na\n${recipient_name}",
@ -384,6 +389,7 @@
"new_template": "Nowy szablon", "new_template": "Nowy szablon",
"new_wallet": "Nowy portfel", "new_wallet": "Nowy portfel",
"newConnection": "Nowe połączenie", "newConnection": "Nowe połączenie",
"no_cards_found": "Nie znaleziono żadnych kart",
"no_id_needed": "Nie potrzeba Dowodu!", "no_id_needed": "Nie potrzeba Dowodu!",
"no_id_required": "Nie wymagamy Dowodu. Doładuj i wydawaj gdziekolwiek", "no_id_required": "Nie wymagamy Dowodu. Doładuj i wydawaj gdziekolwiek",
"no_relay_on_domain": "Brak przekaźnika dla domeny użytkownika lub przekaźnik jest niedostępny. Wybierz przekaźnik, którego chcesz użyć.", "no_relay_on_domain": "Brak przekaźnika dla domeny użytkownika lub przekaźnik jest niedostępny. Wybierz przekaźnik, którego chcesz użyć.",
@ -452,6 +458,7 @@
"pre_seed_button_text": "Rozumiem. Pokaż mi moją fraze seed", "pre_seed_button_text": "Rozumiem. Pokaż mi moją fraze seed",
"pre_seed_description": "Na następnej stronie zobaczysz serię ${words} słów. To jest Twoja unikalna i prywatna fraza seed i jest to JEDYNY sposób na odzyskanie portfela w przypadku utraty lub awarii telefonu. Twoim obowiązkiem jest zapisanie go i przechowywanie w bezpiecznym miejscu (np. na kartce w SEJFIE).", "pre_seed_description": "Na następnej stronie zobaczysz serię ${words} słów. To jest Twoja unikalna i prywatna fraza seed i jest to JEDYNY sposób na odzyskanie portfela w przypadku utraty lub awarii telefonu. Twoim obowiązkiem jest zapisanie go i przechowywanie w bezpiecznym miejscu (np. na kartce w SEJFIE).",
"pre_seed_title": "WAŻNY", "pre_seed_title": "WAŻNY",
"prepaid_cards": "Karty przedpłacone",
"prevent_screenshots": "Zapobiegaj zrzutom ekranu i nagrywaniu ekranu", "prevent_screenshots": "Zapobiegaj zrzutom ekranu i nagrywaniu ekranu",
"privacy": "Prywatność", "privacy": "Prywatność",
"privacy_policy": "Polityka prywatności", "privacy_policy": "Polityka prywatności",
@ -467,6 +474,7 @@
"purple_dark_theme": "Purple Dark Temat", "purple_dark_theme": "Purple Dark Temat",
"qr_fullscreen": "Dotknij, aby otworzyć pełnoekranowy kod QR", "qr_fullscreen": "Dotknij, aby otworzyć pełnoekranowy kod QR",
"qr_payment_amount": "Ten kod QR zawiera kwotę do zapłaty. Czy chcesz nadpisać obecną wartość?", "qr_payment_amount": "Ten kod QR zawiera kwotę do zapłaty. Czy chcesz nadpisać obecną wartość?",
"quantity": "Ilość",
"question_to_disable_2fa": "Czy na pewno chcesz wyłączyć Cake 2FA? Kod 2FA nie będzie już potrzebny do uzyskania dostępu do portfela i niektórych funkcji.", "question_to_disable_2fa": "Czy na pewno chcesz wyłączyć Cake 2FA? Kod 2FA nie będzie już potrzebny do uzyskania dostępu do portfela i niektórych funkcji.",
"receivable_balance": "Saldo należności", "receivable_balance": "Saldo należności",
"receive": "Otrzymaj", "receive": "Otrzymaj",
@ -708,6 +716,7 @@
"tokenID": "ID", "tokenID": "ID",
"tor_connection": "Połączenie Torem", "tor_connection": "Połączenie Torem",
"tor_only": "Tylko sieć Tor", "tor_only": "Tylko sieć Tor",
"total": "Całkowity",
"total_saving": "Całkowite oszczędności", "total_saving": "Całkowite oszczędności",
"totp_2fa_failure": "Błędny kod. Spróbuj użyć innego kodu lub wygeneruj nowy tajny klucz. Użyj kompatybilnej aplikacji 2FA, która obsługuje 8-cyfrowe kody i SHA512.", "totp_2fa_failure": "Błędny kod. Spróbuj użyć innego kodu lub wygeneruj nowy tajny klucz. Użyj kompatybilnej aplikacji 2FA, która obsługuje 8-cyfrowe kody i SHA512.",
"totp_2fa_success": "Powodzenie! Cake 2FA włączony dla tego portfela. Pamiętaj, aby zapisać swoje mnemoniczne ziarno na wypadek utraty dostępu do portfela.", "totp_2fa_success": "Powodzenie! Cake 2FA włączony dla tego portfela. Pamiętaj, aby zapisać swoje mnemoniczne ziarno na wypadek utraty dostępu do portfela.",
@ -798,6 +807,8 @@
"use_ssl": "Użyj SSL", "use_ssl": "Użyj SSL",
"use_suggested": "Użyj sugerowane", "use_suggested": "Użyj sugerowane",
"use_testnet": "Użyj testne", "use_testnet": "Użyj testne",
"value": "Wartość",
"value_type": "Typ wartości",
"variable_pair_not_supported": "Ta para zmiennych nie jest obsługiwana na wybranych giełdach", "variable_pair_not_supported": "Ta para zmiennych nie jest obsługiwana na wybranych giełdach",
"verification": "Weryfikacja", "verification": "Weryfikacja",
"verify_with_2fa": "Sprawdź za pomocą Cake 2FA", "verify_with_2fa": "Sprawdź za pomocą Cake 2FA",

View file

@ -87,6 +87,7 @@
"buy": "Comprar", "buy": "Comprar",
"buy_alert_content": "Atualmente, oferecemos suporte apenas à compra de Bitcoin, Ethereum, Litecoin e Monero. Crie ou troque para sua carteira Bitcoin, Ethereum, Litecoin ou Monero.", "buy_alert_content": "Atualmente, oferecemos suporte apenas à compra de Bitcoin, Ethereum, Litecoin e Monero. Crie ou troque para sua carteira Bitcoin, Ethereum, Litecoin ou Monero.",
"buy_bitcoin": "Compre Bitcoin", "buy_bitcoin": "Compre Bitcoin",
"buy_now": "Comprar agora",
"buy_provider_unavailable": "Provedor atualmente indisponível.", "buy_provider_unavailable": "Provedor atualmente indisponível.",
"buy_with": "Compre com", "buy_with": "Compre com",
"by_cake_pay": "por Cake Pay", "by_cake_pay": "por Cake Pay",
@ -94,8 +95,7 @@
"cake_dark_theme": "Bolo tema escuro", "cake_dark_theme": "Bolo tema escuro",
"cake_pay_account_note": "Inscreva-se com apenas um endereço de e-mail para ver e comprar cartões. Alguns estão até com desconto!", "cake_pay_account_note": "Inscreva-se com apenas um endereço de e-mail para ver e comprar cartões. Alguns estão até com desconto!",
"cake_pay_learn_more": "Compre e resgate vales-presente instantaneamente no app!\nDeslize da esquerda para a direita para saber mais.", "cake_pay_learn_more": "Compre e resgate vales-presente instantaneamente no app!\nDeslize da esquerda para a direita para saber mais.",
"cake_pay_subtitle": "Compre vales-presente com desconto (somente nos EUA)", "cake_pay_subtitle": "Compre cartões pré -pagos em todo o mundo e cartões -presente",
"cake_pay_title": "Cartões de presente de CakePay",
"cake_pay_web_cards_subtitle": "Compre cartões pré-pagos e cartões-presente em todo o mundo", "cake_pay_web_cards_subtitle": "Compre cartões pré-pagos e cartões-presente em todo o mundo",
"cake_pay_web_cards_title": "Cartões Cake Pay Web", "cake_pay_web_cards_title": "Cartões Cake Pay Web",
"cake_wallet": "Cake Wallet", "cake_wallet": "Cake Wallet",
@ -123,6 +123,7 @@
"change_wallet_alert_title": "Alterar carteira atual", "change_wallet_alert_title": "Alterar carteira atual",
"choose_account": "Escolha uma conta", "choose_account": "Escolha uma conta",
"choose_address": "\n\nEscolha o endereço:", "choose_address": "\n\nEscolha o endereço:",
"choose_card_value": "Escolha um valor de cartão",
"choose_derivation": "Escolha a derivação da carteira", "choose_derivation": "Escolha a derivação da carteira",
"choose_from_available_options": "Escolha entre as opções disponíveis:", "choose_from_available_options": "Escolha entre as opções disponíveis:",
"choose_one": "Escolha um", "choose_one": "Escolha um",
@ -166,6 +167,7 @@
"copy_address": "Copiar endereço", "copy_address": "Copiar endereço",
"copy_id": "Copiar ID", "copy_id": "Copiar ID",
"copyWalletConnectLink": "Copie o link WalletConnect do dApp e cole aqui", "copyWalletConnectLink": "Copie o link WalletConnect do dApp e cole aqui",
"countries": "Países",
"create_account": "Criar conta", "create_account": "Criar conta",
"create_backup": "Criar backup", "create_backup": "Criar backup",
"create_donation_link": "Criar link de doação", "create_donation_link": "Criar link de doação",
@ -178,6 +180,7 @@
"custom": "personalizado", "custom": "personalizado",
"custom_drag": "Personalizado (segure e arraste)", "custom_drag": "Personalizado (segure e arraste)",
"custom_redeem_amount": "Valor de resgate personalizado", "custom_redeem_amount": "Valor de resgate personalizado",
"custom_value": "Valor customizado",
"dark_theme": "Sombria", "dark_theme": "Sombria",
"debit_card": "Cartão de débito", "debit_card": "Cartão de débito",
"debit_card_terms": "O armazenamento e uso do número do cartão de pagamento (e credenciais correspondentes ao número do cartão de pagamento) nesta carteira digital estão sujeitos aos Termos e Condições do contrato do titular do cartão aplicável com o emissor do cartão de pagamento, em vigor a partir de tempo ao tempo.", "debit_card_terms": "O armazenamento e uso do número do cartão de pagamento (e credenciais correspondentes ao número do cartão de pagamento) nesta carteira digital estão sujeitos aos Termos e Condições do contrato do titular do cartão aplicável com o emissor do cartão de pagamento, em vigor a partir de tempo ao tempo.",
@ -190,6 +193,7 @@
"delete_wallet": "Excluir carteira", "delete_wallet": "Excluir carteira",
"delete_wallet_confirm_message": "Tem certeza de que deseja excluir a carteira ${wallet_name}?", "delete_wallet_confirm_message": "Tem certeza de que deseja excluir a carteira ${wallet_name}?",
"deleteConnectionConfirmationPrompt": "Tem certeza de que deseja excluir a conexão com", "deleteConnectionConfirmationPrompt": "Tem certeza de que deseja excluir a conexão com",
"denominations": "Denominações",
"descending": "descendente", "descending": "descendente",
"description": "Descrição", "description": "Descrição",
"destination_tag": "Tag de destino:", "destination_tag": "Tag de destino:",
@ -277,6 +281,7 @@
"expired": "Expirada", "expired": "Expirada",
"expires": "Expira", "expires": "Expira",
"expiresOn": "Expira em", "expiresOn": "Expira em",
"expiry_and_validity": "Expiração e validade",
"export_backup": "Backup de exportação", "export_backup": "Backup de exportação",
"extra_id": "ID extra:", "extra_id": "ID extra:",
"extracted_address_content": "Você enviará fundos para\n${recipient_name}", "extracted_address_content": "Você enviará fundos para\n${recipient_name}",
@ -385,6 +390,7 @@
"new_template": "Novo modelo", "new_template": "Novo modelo",
"new_wallet": "Nova carteira", "new_wallet": "Nova carteira",
"newConnection": "Nova conexão", "newConnection": "Nova conexão",
"no_cards_found": "Nenhum cartão encontrado",
"no_id_needed": "Nenhum ID necessário!", "no_id_needed": "Nenhum ID necessário!",
"no_id_required": "Não é necessário ID. Recarregue e gaste em qualquer lugar", "no_id_required": "Não é necessário ID. Recarregue e gaste em qualquer lugar",
"no_relay_on_domain": "Não há uma retransmissão para o domínio do usuário ou a retransmissão está indisponível. Escolha um relé para usar.", "no_relay_on_domain": "Não há uma retransmissão para o domínio do usuário ou a retransmissão está indisponível. Escolha um relé para usar.",
@ -454,6 +460,7 @@
"pre_seed_button_text": "Compreendo. Me mostre minha semente", "pre_seed_button_text": "Compreendo. Me mostre minha semente",
"pre_seed_description": "Na próxima página, você verá uma série de ${words} palavras. Esta é a sua semente única e privada e é a ÚNICA maneira de recuperar sua carteira em caso de perda ou mau funcionamento. É SUA responsabilidade anotá-lo e armazená-lo em um local seguro fora do aplicativo Cake Wallet.", "pre_seed_description": "Na próxima página, você verá uma série de ${words} palavras. Esta é a sua semente única e privada e é a ÚNICA maneira de recuperar sua carteira em caso de perda ou mau funcionamento. É SUA responsabilidade anotá-lo e armazená-lo em um local seguro fora do aplicativo Cake Wallet.",
"pre_seed_title": "IMPORTANTE", "pre_seed_title": "IMPORTANTE",
"prepaid_cards": "Cartões pré-pagos",
"prevent_screenshots": "Evite capturas de tela e gravação de tela", "prevent_screenshots": "Evite capturas de tela e gravação de tela",
"privacy": "Privacidade", "privacy": "Privacidade",
"privacy_policy": "Política de privacidade", "privacy_policy": "Política de privacidade",
@ -469,6 +476,7 @@
"purple_dark_theme": "Tema escuro roxo", "purple_dark_theme": "Tema escuro roxo",
"qr_fullscreen": "Toque para abrir o código QR em tela cheia", "qr_fullscreen": "Toque para abrir o código QR em tela cheia",
"qr_payment_amount": "This QR code contains a payment amount. Do you want to overwrite the current value?", "qr_payment_amount": "This QR code contains a payment amount. Do you want to overwrite the current value?",
"quantity": "Quantidade",
"question_to_disable_2fa": "Tem certeza de que deseja desativar o Cake 2FA? Um código 2FA não será mais necessário para acessar a carteira e certas funções.", "question_to_disable_2fa": "Tem certeza de que deseja desativar o Cake 2FA? Um código 2FA não será mais necessário para acessar a carteira e certas funções.",
"receivable_balance": "Saldo a receber", "receivable_balance": "Saldo a receber",
"receive": "Receber", "receive": "Receber",
@ -710,6 +718,7 @@
"tokenID": "EU IA", "tokenID": "EU IA",
"tor_connection": "Conexão Tor", "tor_connection": "Conexão Tor",
"tor_only": "Tor apenas", "tor_only": "Tor apenas",
"total": "Total",
"total_saving": "Economia total", "total_saving": "Economia total",
"totp_2fa_failure": "Código incorreto. Tente um código diferente ou gere uma nova chave secreta. Use um aplicativo 2FA compatível com códigos de 8 dígitos e SHA512.", "totp_2fa_failure": "Código incorreto. Tente um código diferente ou gere uma nova chave secreta. Use um aplicativo 2FA compatível com códigos de 8 dígitos e SHA512.",
"totp_2fa_success": "Sucesso! Cake 2FA ativado para esta carteira. Lembre-se de salvar sua semente mnemônica caso perca o acesso à carteira.", "totp_2fa_success": "Sucesso! Cake 2FA ativado para esta carteira. Lembre-se de salvar sua semente mnemônica caso perca o acesso à carteira.",
@ -800,6 +809,8 @@
"use_ssl": "Use SSL", "use_ssl": "Use SSL",
"use_suggested": "Uso sugerido", "use_suggested": "Uso sugerido",
"use_testnet": "Use testNet", "use_testnet": "Use testNet",
"value": "Valor",
"value_type": "Tipo de valor",
"variable_pair_not_supported": "Este par de variáveis não é compatível com as trocas selecionadas", "variable_pair_not_supported": "Este par de variáveis não é compatível com as trocas selecionadas",
"verification": "Verificação", "verification": "Verificação",
"verify_with_2fa": "Verificar com Cake 2FA", "verify_with_2fa": "Verificar com Cake 2FA",
@ -864,4 +875,4 @@
"you_will_get": "Converter para", "you_will_get": "Converter para",
"you_will_send": "Converter de", "you_will_send": "Converter de",
"yy": "aa" "yy": "aa"
} }

View file

@ -87,6 +87,7 @@
"buy": "Купить", "buy": "Купить",
"buy_alert_content": "В настоящее время мы поддерживаем только покупку биткойнов, Ethereum, Litecoin и Monero. Пожалуйста, создайте или переключитесь на свой кошелек Bitcoin, Ethereum, Litecoin или Monero.", "buy_alert_content": "В настоящее время мы поддерживаем только покупку биткойнов, Ethereum, Litecoin и Monero. Пожалуйста, создайте или переключитесь на свой кошелек Bitcoin, Ethereum, Litecoin или Monero.",
"buy_bitcoin": "Купить Bitcoin", "buy_bitcoin": "Купить Bitcoin",
"buy_now": "Купить сейчас",
"buy_provider_unavailable": "Поставщик в настоящее время недоступен.", "buy_provider_unavailable": "Поставщик в настоящее время недоступен.",
"buy_with": "Купить с помощью", "buy_with": "Купить с помощью",
"by_cake_pay": "от Cake Pay", "by_cake_pay": "от Cake Pay",
@ -94,8 +95,7 @@
"cake_dark_theme": "Тейт темная тема", "cake_dark_theme": "Тейт темная тема",
"cake_pay_account_note": "Зарегистрируйтесь, указав только адрес электронной почты, чтобы просматривать и покупать карты. Некоторые даже доступны со скидкой!", "cake_pay_account_note": "Зарегистрируйтесь, указав только адрес электронной почты, чтобы просматривать и покупать карты. Некоторые даже доступны со скидкой!",
"cake_pay_learn_more": "Мгновенно покупайте и используйте подарочные карты в приложении!\nПроведите по экрану слева направо, чтобы узнать больше.", "cake_pay_learn_more": "Мгновенно покупайте и используйте подарочные карты в приложении!\nПроведите по экрану слева направо, чтобы узнать больше.",
"cake_pay_subtitle": "Покупайте подарочные карты со скидкой (только для США)", "cake_pay_subtitle": "Купить карты с предоплатой и подарочными картами по всему миру",
"cake_pay_title": "Подарочные карты Cake Pay",
"cake_pay_web_cards_subtitle": "Покупайте карты предоплаты и подарочные карты по всему миру", "cake_pay_web_cards_subtitle": "Покупайте карты предоплаты и подарочные карты по всему миру",
"cake_pay_web_cards_title": "Веб-карты Cake Pay", "cake_pay_web_cards_title": "Веб-карты Cake Pay",
"cake_wallet": "Cake Wallet", "cake_wallet": "Cake Wallet",
@ -123,6 +123,7 @@
"change_wallet_alert_title": "Изменить текущий кошелек", "change_wallet_alert_title": "Изменить текущий кошелек",
"choose_account": "Выберите аккаунт", "choose_account": "Выберите аккаунт",
"choose_address": "\n\nПожалуйста, выберите адрес:", "choose_address": "\n\nПожалуйста, выберите адрес:",
"choose_card_value": "Выберите значение карты",
"choose_derivation": "Выберите вывод кошелька", "choose_derivation": "Выберите вывод кошелька",
"choose_from_available_options": "Выберите из доступных вариантов:", "choose_from_available_options": "Выберите из доступных вариантов:",
"choose_one": "Выбери один", "choose_one": "Выбери один",
@ -166,6 +167,7 @@
"copy_address": "Cкопировать адрес", "copy_address": "Cкопировать адрес",
"copy_id": "Скопировать ID", "copy_id": "Скопировать ID",
"copyWalletConnectLink": "Скопируйте ссылку WalletConnect из dApp и вставьте сюда.", "copyWalletConnectLink": "Скопируйте ссылку WalletConnect из dApp и вставьте сюда.",
"countries": "Страны",
"create_account": "Создать аккаунт", "create_account": "Создать аккаунт",
"create_backup": "Создать резервную копию", "create_backup": "Создать резервную копию",
"create_donation_link": "Создать ссылку для пожертвований", "create_donation_link": "Создать ссылку для пожертвований",
@ -178,6 +180,7 @@
"custom": "обычай", "custom": "обычай",
"custom_drag": "Пользователь (удерживайте и перетаскивайте)", "custom_drag": "Пользователь (удерживайте и перетаскивайте)",
"custom_redeem_amount": "Пользовательская сумма погашения", "custom_redeem_amount": "Пользовательская сумма погашения",
"custom_value": "Пользовательское значение",
"dark_theme": "Темная", "dark_theme": "Темная",
"debit_card": "Дебетовая карта", "debit_card": "Дебетовая карта",
"debit_card_terms": "Хранение и использование номера вашей платежной карты (и учетных данных, соответствующих номеру вашей платежной карты) в этом цифровом кошельке регулируются положениями и условиями применимого соглашения держателя карты с эмитентом платежной карты, действующим с время от времени.", "debit_card_terms": "Хранение и использование номера вашей платежной карты (и учетных данных, соответствующих номеру вашей платежной карты) в этом цифровом кошельке регулируются положениями и условиями применимого соглашения держателя карты с эмитентом платежной карты, действующим с время от времени.",
@ -190,6 +193,7 @@
"delete_wallet": "Удалить кошелек", "delete_wallet": "Удалить кошелек",
"delete_wallet_confirm_message": "Вы уверены, что хотите удалить кошелек ${wallet_name}?", "delete_wallet_confirm_message": "Вы уверены, что хотите удалить кошелек ${wallet_name}?",
"deleteConnectionConfirmationPrompt": "Вы уверены, что хотите удалить подключение к", "deleteConnectionConfirmationPrompt": "Вы уверены, что хотите удалить подключение к",
"denominations": "Деноминации",
"descending": "Нисходящий", "descending": "Нисходящий",
"description": "Описание", "description": "Описание",
"destination_tag": "Целевой тег:", "destination_tag": "Целевой тег:",
@ -277,6 +281,7 @@
"expired": "Истекает", "expired": "Истекает",
"expires": "Истекает", "expires": "Истекает",
"expiresOn": "Годен до", "expiresOn": "Годен до",
"expiry_and_validity": "Истечение и достоверность",
"export_backup": "Экспорт резервной копии", "export_backup": "Экспорт резервной копии",
"extra_id": "Дополнительный ID:", "extra_id": "Дополнительный ID:",
"extracted_address_content": "Вы будете отправлять средства\n${recipient_name}", "extracted_address_content": "Вы будете отправлять средства\n${recipient_name}",
@ -384,6 +389,7 @@
"new_template": "Новый шаблон", "new_template": "Новый шаблон",
"new_wallet": "Новый кошелёк", "new_wallet": "Новый кошелёк",
"newConnection": "Новое соединение", "newConnection": "Новое соединение",
"no_cards_found": "Карт не найдено",
"no_id_needed": "Идентификатор не нужен!", "no_id_needed": "Идентификатор не нужен!",
"no_id_required": "Идентификатор не требуется. Пополняйте и тратьте где угодно", "no_id_required": "Идентификатор не требуется. Пополняйте и тратьте где угодно",
"no_relay_on_domain": "Для домена пользователя реле не существует или реле недоступно. Пожалуйста, выберите реле для использования.", "no_relay_on_domain": "Для домена пользователя реле не существует или реле недоступно. Пожалуйста, выберите реле для использования.",
@ -453,6 +459,7 @@
"pre_seed_button_text": "Понятно. Покажите мнемоническую фразу", "pre_seed_button_text": "Понятно. Покажите мнемоническую фразу",
"pre_seed_description": "На следующей странице вы увидите серию из ${words} слов. Это ваша уникальная и личная мнемоническая фраза, и это ЕДИНСТВЕННЫЙ способ восстановить свой кошелек в случае потери или неисправности. ВАМ необходимо записать ее и хранить в надежном месте вне приложения Cake Wallet.", "pre_seed_description": "На следующей странице вы увидите серию из ${words} слов. Это ваша уникальная и личная мнемоническая фраза, и это ЕДИНСТВЕННЫЙ способ восстановить свой кошелек в случае потери или неисправности. ВАМ необходимо записать ее и хранить в надежном месте вне приложения Cake Wallet.",
"pre_seed_title": "ВАЖНО", "pre_seed_title": "ВАЖНО",
"prepaid_cards": "Предоплаченные карты",
"prevent_screenshots": "Предотвратить скриншоты и запись экрана", "prevent_screenshots": "Предотвратить скриншоты и запись экрана",
"privacy": "Конфиденциальность", "privacy": "Конфиденциальность",
"privacy_policy": "Политика конфиденциальности", "privacy_policy": "Политика конфиденциальности",
@ -468,6 +475,7 @@
"purple_dark_theme": "Пурпурная темная тема", "purple_dark_theme": "Пурпурная темная тема",
"qr_fullscreen": "Нажмите, чтобы открыть полноэкранный QR-код", "qr_fullscreen": "Нажмите, чтобы открыть полноэкранный QR-код",
"qr_payment_amount": "This QR code contains a payment amount. Do you want to overwrite the current value?", "qr_payment_amount": "This QR code contains a payment amount. Do you want to overwrite the current value?",
"quantity": "Количество",
"question_to_disable_2fa": "Вы уверены, что хотите отключить Cake 2FA? Код 2FA больше не потребуется для доступа к кошельку и некоторым функциям.", "question_to_disable_2fa": "Вы уверены, что хотите отключить Cake 2FA? Код 2FA больше не потребуется для доступа к кошельку и некоторым функциям.",
"receivable_balance": "Баланс дебиторской задолженности", "receivable_balance": "Баланс дебиторской задолженности",
"receive": "Получить", "receive": "Получить",
@ -709,6 +717,7 @@
"tokenID": "ИДЕНТИФИКАТОР", "tokenID": "ИДЕНТИФИКАТОР",
"tor_connection": "Тор соединение", "tor_connection": "Тор соединение",
"tor_only": "Только Tor", "tor_only": "Только Tor",
"total": "Общий",
"total_saving": "Общая экономия", "total_saving": "Общая экономия",
"totp_2fa_failure": "Неверный код. Пожалуйста, попробуйте другой код или создайте новый секретный ключ. Используйте совместимое приложение 2FA, которое поддерживает 8-значные коды и SHA512.", "totp_2fa_failure": "Неверный код. Пожалуйста, попробуйте другой код или создайте новый секретный ключ. Используйте совместимое приложение 2FA, которое поддерживает 8-значные коды и SHA512.",
"totp_2fa_success": "Успех! Для этого кошелька включена двухфакторная аутентификация Cake. Не забудьте сохранить мнемоническое семя на случай, если вы потеряете доступ к кошельку.", "totp_2fa_success": "Успех! Для этого кошелька включена двухфакторная аутентификация Cake. Не забудьте сохранить мнемоническое семя на случай, если вы потеряете доступ к кошельку.",
@ -799,6 +808,8 @@
"use_ssl": "Использовать SSL", "use_ssl": "Использовать SSL",
"use_suggested": "Использовать предложенный", "use_suggested": "Использовать предложенный",
"use_testnet": "Используйте Testnet", "use_testnet": "Используйте Testnet",
"value": "Ценить",
"value_type": "Тип значения",
"variable_pair_not_supported": "Эта пара переменных не поддерживается выбранными биржами.", "variable_pair_not_supported": "Эта пара переменных не поддерживается выбранными биржами.",
"verification": "Проверка", "verification": "Проверка",
"verify_with_2fa": "Подтвердить с помощью Cake 2FA", "verify_with_2fa": "Подтвердить с помощью Cake 2FA",

Some files were not shown because too many files have changed in this diff Show more