Merge branch 'main' of https://github.com/cake-tech/cake_wallet into CW-328-Restore-wallet-from-QRCode-and-sweep-all-funds-in-a-new-wallet

This commit is contained in:
Blazebrain 2023-07-11 09:00:48 +01:00
commit 245e52792f
60 changed files with 11789 additions and 14193 deletions

View file

@ -1,6 +1,3 @@
Opt-in to Cake 2FA for security. More info: https://guides.cakewallet.com/docs/advanced-features/authentication/#cake-2fa Enable iPad/Tablet separate layout from mobile UI
Auto generate restore height for Monero restore QR codes SideShift update and fixes
Hausa and Yoruba languages Bug Fixes
Additional privacy settings
Update Monero to 0.18.2.2
Refactoring and bug fixes

View file

@ -1,6 +1,4 @@
Opt-in to Cake 2FA for security. More info: https://guides.cakewallet.com/docs/advanced-features/authentication/#cake-2fa Enable iPad/Tablet separate layout from mobile UI
Auto generate restore height for Monero restore QR codes SideShift update and fixes
Hausa and Yoruba languages Add MoonPay sell
Additional privacy settings Bug Fixes
Update Monero to 0.18.2.2
Refactoring and bug fixes

View file

@ -26,7 +26,7 @@ enum WalletType {
litecoin, litecoin,
@HiveField(4) @HiveField(4)
haven haven,
} }
int serializeToInt(WalletType type) { int serializeToInt(WalletType type) {
@ -77,13 +77,13 @@ String walletTypeToString(WalletType type) {
String walletTypeToDisplayName(WalletType type) { String walletTypeToDisplayName(WalletType type) {
switch (type) { switch (type) {
case WalletType.monero: case WalletType.monero:
return 'Monero'; return 'Monero (XMR)';
case WalletType.bitcoin: case WalletType.bitcoin:
return 'Bitcoin (Electrum)'; return 'Bitcoin (BTC)';
case WalletType.litecoin: case WalletType.litecoin:
return 'Litecoin (Electrum)'; return 'Litecoin (LTC)';
case WalletType.haven: case WalletType.haven:
return 'Haven'; return 'Haven (XHV)';
default: default:
return ''; return '';
} }

View file

@ -64,7 +64,6 @@ class OnRamperBuyProvider {
return Uri.https(_baseUrl, '', <String, dynamic>{ return Uri.https(_baseUrl, '', <String, dynamic>{
'apiKey': _apiKey, 'apiKey': _apiKey,
'defaultCrypto': _normalizeCryptoCurrency, 'defaultCrypto': _normalizeCryptoCurrency,
'defaultFiat': _settingsStore.fiatCurrency.title,
'wallets': '${_wallet.currency.title}:${_wallet.walletAddresses.address}', 'wallets': '${_wallet.currency.title}:${_wallet.walletAddresses.address}',
'supportSell': "false", 'supportSell': "false",
'supportSwap': "false", 'supportSwap': "false",

View file

@ -1,7 +1,6 @@
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/buy/moonpay/moonpay_buy_provider.dart';
import 'package:cake_wallet/buy/onramper/onramper_buy_provider.dart'; import 'package:cake_wallet/buy/onramper/onramper_buy_provider.dart';
import 'package:cake_wallet/buy/payfura/payfura_buy_provider.dart'; import 'package:cake_wallet/buy/payfura/payfura_buy_provider.dart';
import 'package:cake_wallet/core/yat_service.dart'; import 'package:cake_wallet/core/yat_service.dart';
@ -14,7 +13,6 @@ import 'package:cake_wallet/ionia/ionia_tip.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/buy/webview_page.dart'; import 'package:cake_wallet/src/screens/buy/webview_page.dart';
import 'package:cake_wallet/src/screens/buy/payfura_page.dart';
import 'package:cake_wallet/src/screens/dashboard/desktop_dashboard_page.dart'; import 'package:cake_wallet/src/screens/dashboard/desktop_dashboard_page.dart';
import 'package:cake_wallet/src/screens/dashboard/desktop_widgets/desktop_sidebar_wrapper.dart'; import 'package:cake_wallet/src/screens/dashboard/desktop_widgets/desktop_sidebar_wrapper.dart';
import 'package:cake_wallet/src/screens/dashboard/desktop_widgets/desktop_wallet_selection_dropdown.dart'; import 'package:cake_wallet/src/screens/dashboard/desktop_widgets/desktop_wallet_selection_dropdown.dart';
@ -702,8 +700,6 @@ Future setup({
wallet: getIt.get<AppStore>().wallet!, wallet: getIt.get<AppStore>().wallet!,
)); ));
getIt.registerFactory(() => PayFuraPage(getIt.get<PayfuraBuyProvider>()));
getIt.registerFactory(() => ExchangeViewModel( getIt.registerFactory(() => ExchangeViewModel(
getIt.get<AppStore>().wallet!, getIt.get<AppStore>().wallet!,
_tradesSource, _tradesSource,

View file

@ -1,12 +1,10 @@
import 'package:cake_wallet/buy/moonpay/moonpay_buy_provider.dart'; import 'package:cake_wallet/buy/moonpay/moonpay_buy_provider.dart';
import 'package:cake_wallet/buy/onramper/onramper_buy_provider.dart'; import 'package:cake_wallet/buy/onramper/onramper_buy_provider.dart';
import 'package:cake_wallet/buy/payfura/payfura_buy_provider.dart';
import 'package:cake_wallet/di.dart'; import 'package:cake_wallet/di.dart';
import 'package:cake_wallet/generated/i18n.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/widgets/alert_with_one_action.dart'; import 'package:cake_wallet/src/widgets/alert_with_one_action.dart';
import 'package:cake_wallet/utils/device_info.dart'; import 'package:cake_wallet/utils/device_info.dart';
import 'package:cake_wallet/utils/responsive_layout_util.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/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:cw_core/wallet_type.dart';
@ -60,12 +58,9 @@ class MainActions {
break; break;
case WalletType.monero: case WalletType.monero:
if (viewModel.isEnabledBuyAction) { if (viewModel.isEnabledBuyAction) {
if (DeviceInfo.instance.isMobile) { // final uri = getIt.get<PayfuraBuyProvider>().requestUrl();
Navigator.of(context).pushNamed(Routes.payfuraPage); final uri = Uri.parse("https://monero.com/trade");
} else { await launchUrl(uri);
final uri = getIt.get<PayfuraBuyProvider>().requestUrl();
await launchUrl(uri);
}
} }
break; break;
default: default:

View file

@ -1,6 +1,10 @@
import 'dart:convert'; import 'dart:convert';
import 'dart:io';
import 'package:cake_wallet/exchange/trade_not_found_exeption.dart'; import 'package:cake_wallet/exchange/trade_not_found_exeption.dart';
import 'package:cake_wallet/store/settings_store.dart';
import 'package:cake_wallet/utils/device_info.dart'; import 'package:cake_wallet/utils/device_info.dart';
import 'package:cake_wallet/utils/distribution_info.dart';
import 'package:cake_wallet/wallet_type_utils.dart';
import 'package:http/http.dart'; import 'package:http/http.dart';
import 'package:cake_wallet/.secrets.g.dart' as secrets; import 'package:cake_wallet/.secrets.g.dart' as secrets;
import 'package:cw_core/crypto_currency.dart'; import 'package:cw_core/crypto_currency.dart';
@ -14,7 +18,7 @@ import 'package:cake_wallet/exchange/changenow/changenow_request.dart';
import 'package:cake_wallet/exchange/exchange_provider_description.dart'; import 'package:cake_wallet/exchange/exchange_provider_description.dart';
class ChangeNowExchangeProvider extends ExchangeProvider { class ChangeNowExchangeProvider extends ExchangeProvider {
ChangeNowExchangeProvider() ChangeNowExchangeProvider({required this.settingsStore})
: _lastUsedRateId = '', : _lastUsedRateId = '',
super( super(
pairList: CryptoCurrency.all pairList: CryptoCurrency.all
@ -25,7 +29,8 @@ class ChangeNowExchangeProvider extends ExchangeProvider {
.expand((i) => i) .expand((i) => i)
.toList()); .toList());
static final apiKey = DeviceInfo.instance.isMobile ? secrets.changeNowApiKey : secrets.changeNowApiKeyDesktop; static final apiKey =
DeviceInfo.instance.isMobile ? secrets.changeNowApiKey : secrets.changeNowApiKeyDesktop;
static const apiAuthority = 'api.changenow.io'; static const apiAuthority = 'api.changenow.io';
static const createTradePath = '/v2/exchange'; static const createTradePath = '/v2/exchange';
static const findTradeByIdPath = '/v2/exchange/by-id'; static const findTradeByIdPath = '/v2/exchange/by-id';
@ -46,21 +51,22 @@ class ChangeNowExchangeProvider extends ExchangeProvider {
bool get supportsFixedRate => true; bool get supportsFixedRate => true;
@override @override
ExchangeProviderDescription get description => ExchangeProviderDescription get description => ExchangeProviderDescription.changeNow;
ExchangeProviderDescription.changeNow;
@override @override
Future<bool> checkIsAvailable() async => true; Future<bool> checkIsAvailable() async => true;
final SettingsStore settingsStore;
String _lastUsedRateId; String _lastUsedRateId;
static String getFlow(bool isFixedRate) => isFixedRate ? 'fixed-rate' : 'standard'; static String getFlow(bool isFixedRate) => isFixedRate ? 'fixed-rate' : 'standard';
@override @override
Future<Limits> fetchLimits({ Future<Limits> fetchLimits(
required CryptoCurrency from, {required CryptoCurrency from,
required CryptoCurrency to, required CryptoCurrency to,
required bool isFixedRateMode}) async { required bool isFixedRateMode}) async {
final headers = {apiHeaderKey: apiKey}; final headers = {apiHeaderKey: apiKey};
final normalizedFrom = normalizeCryptoCurrency(from); final normalizedFrom = normalizeCryptoCurrency(from);
final normalizedTo = normalizeCryptoCurrency(to); final normalizedTo = normalizeCryptoCurrency(to);
@ -70,10 +76,11 @@ class ChangeNowExchangeProvider extends ExchangeProvider {
'toCurrency': normalizedTo, 'toCurrency': normalizedTo,
'fromNetwork': networkFor(from), 'fromNetwork': networkFor(from),
'toNetwork': networkFor(to), 'toNetwork': networkFor(to),
'flow': flow}; 'flow': flow
};
final uri = Uri.https(apiAuthority, rangePath, params); final uri = Uri.https(apiAuthority, rangePath, params);
final response = await get(uri, headers: headers); final response = await get(uri, headers: headers);
if (response.statusCode == 400) { if (response.statusCode == 400) {
final responseJSON = json.decode(response.body) as Map<String, dynamic>; final responseJSON = json.decode(response.body) as Map<String, dynamic>;
final error = responseJSON['error'] as String; final error = responseJSON['error'] as String;
@ -87,19 +94,24 @@ class ChangeNowExchangeProvider extends ExchangeProvider {
final responseJSON = json.decode(response.body) as Map<String, dynamic>; final responseJSON = json.decode(response.body) as Map<String, dynamic>;
return Limits( return Limits(
min: responseJSON['minAmount'] as double?, min: responseJSON['minAmount'] as double?, max: responseJSON['maxAmount'] as double?);
max: responseJSON['maxAmount'] as double?);
} }
@override @override
Future<Trade> createTrade({required TradeRequest request, required bool isFixedRateMode}) async { Future<Trade> createTrade({required TradeRequest request, required bool isFixedRateMode}) async {
final _request = request as ChangeNowRequest; final _request = request as ChangeNowRequest;
final headers = { final distributionPath = await DistributionInfo.instance.getDistributionPath();
apiHeaderKey: apiKey, final formattedAppVersion = int.tryParse(settingsStore.appVersion.replaceAll('.', '')) ?? 0;
'Content-Type': 'application/json'}; final payload = {
'app': isMoneroOnly ? 'monerocom' : 'cakewallet',
'device': Platform.operatingSystem,
'distribution': distributionPath,
'version': formattedAppVersion
};
final headers = {apiHeaderKey: apiKey, 'Content-Type': 'application/json'};
final flow = getFlow(isFixedRateMode); final flow = getFlow(isFixedRateMode);
final type = isFixedRateMode ? 'reverse' : 'direct'; final type = isFixedRateMode ? 'reverse' : 'direct';
final body = <String, String>{ final body = <String, dynamic>{
'fromCurrency': normalizeCryptoCurrency(_request.from), 'fromCurrency': normalizeCryptoCurrency(_request.from),
'toCurrency': normalizeCryptoCurrency(_request.to), 'toCurrency': normalizeCryptoCurrency(_request.to),
'fromNetwork': networkFor(_request.from), 'fromNetwork': networkFor(_request.from),
@ -109,7 +121,8 @@ class ChangeNowExchangeProvider extends ExchangeProvider {
'address': _request.address, 'address': _request.address,
'flow': flow, 'flow': flow,
'type': type, 'type': type,
'refundAddress': _request.refundAddress 'refundAddress': _request.refundAddress,
'payload': payload,
}; };
if (isFixedRateMode) { if (isFixedRateMode) {
@ -164,7 +177,7 @@ class ChangeNowExchangeProvider extends ExchangeProvider {
Future<Trade> findTradeById({required String id}) async { Future<Trade> findTradeById({required String id}) async {
final headers = {apiHeaderKey: apiKey}; final headers = {apiHeaderKey: apiKey};
final params = <String, String>{'id': id}; final params = <String, String>{'id': id};
final uri = Uri.https(apiAuthority,findTradeByIdPath, params); final uri = Uri.https(apiAuthority, findTradeByIdPath, params);
final response = await get(uri, headers: headers); final response = await get(uri, headers: headers);
if (response.statusCode == 404) { if (response.statusCode == 404) {
@ -175,8 +188,7 @@ class ChangeNowExchangeProvider extends ExchangeProvider {
final responseJSON = json.decode(response.body) as Map<String, dynamic>; final responseJSON = json.decode(response.body) as Map<String, dynamic>;
final error = responseJSON['message'] as String; final error = responseJSON['message'] as String;
throw TradeNotFoundException(id, throw TradeNotFoundException(id, provider: description, description: error);
provider: description, description: error);
} }
if (response.statusCode != 200) { if (response.statusCode != 200) {
@ -234,19 +246,20 @@ class ChangeNowExchangeProvider extends ExchangeProvider {
'fromNetwork': networkFor(from), 'fromNetwork': networkFor(from),
'toNetwork': networkFor(to), 'toNetwork': networkFor(to),
'type': type, 'type': type,
'flow': flow}; 'flow': flow
};
if (isReverse) { if (isReverse) {
params['toAmount'] = amount.toString(); params['toAmount'] = amount.toString();
} else { } else {
params['fromAmount'] = amount.toString(); params['fromAmount'] = amount.toString();
} }
final uri = Uri.https(apiAuthority, estimatedAmountPath, params); final uri = Uri.https(apiAuthority, estimatedAmountPath, params);
final response = await get(uri, headers: headers); final response = await get(uri, headers: headers);
final responseJSON = json.decode(response.body) as Map<String, dynamic>; final responseJSON = json.decode(response.body) as Map<String, dynamic>;
final fromAmount = double.parse(responseJSON['fromAmount'].toString()); final fromAmount = double.parse(responseJSON['fromAmount'].toString());
final toAmount = double.parse(responseJSON['toAmount'].toString()); final toAmount = double.parse(responseJSON['toAmount'].toString());
final rateId = responseJSON['rateId'] as String? ?? ''; final rateId = responseJSON['rateId'] as String? ?? '';
if (rateId.isNotEmpty) { if (rateId.isNotEmpty) {
@ -254,35 +267,31 @@ class ChangeNowExchangeProvider extends ExchangeProvider {
} }
return isReverse ? (amount / fromAmount) : (toAmount / amount); return isReverse ? (amount / fromAmount) : (toAmount / amount);
} catch(e) { } catch (e) {
print(e.toString()); print(e.toString());
return 0.0; return 0.0;
} }
} }
String networkFor(CryptoCurrency currency) { String networkFor(CryptoCurrency currency) {
switch (currency) { switch (currency) {
case CryptoCurrency.usdt: case CryptoCurrency.usdt:
return CryptoCurrency.btc.title.toLowerCase(); return CryptoCurrency.btc.title.toLowerCase();
default: default:
return currency.tag != null return currency.tag != null ? currency.tag!.toLowerCase() : currency.title.toLowerCase();
? currency.tag!.toLowerCase()
: currency.title.toLowerCase();
}
} }
} }
}
String normalizeCryptoCurrency(CryptoCurrency currency) { String normalizeCryptoCurrency(CryptoCurrency currency) {
switch(currency) { switch (currency) {
case CryptoCurrency.zec: case CryptoCurrency.zec:
return 'zec'; return 'zec';
case CryptoCurrency.usdcpoly: case CryptoCurrency.usdcpoly:
return 'usdcmatic'; return 'usdcmatic';
case CryptoCurrency.maticpoly: case CryptoCurrency.maticpoly:
return 'maticmainnet'; return 'maticmainnet';
default: default:
return currency.title.toLowerCase(); return currency.title.toLowerCase();
}
} }
}

View file

@ -9,7 +9,6 @@ import 'package:cake_wallet/src/screens/backup/backup_page.dart';
import 'package:cake_wallet/src/screens/backup/edit_backup_password_page.dart'; import 'package:cake_wallet/src/screens/backup/edit_backup_password_page.dart';
import 'package:cake_wallet/src/screens/buy/buy_webview_page.dart'; import 'package:cake_wallet/src/screens/buy/buy_webview_page.dart';
import 'package:cake_wallet/src/screens/buy/webview_page.dart'; import 'package:cake_wallet/src/screens/buy/webview_page.dart';
import 'package:cake_wallet/src/screens/buy/payfura_page.dart';
import 'package:cake_wallet/src/screens/buy/pre_order_page.dart'; import 'package:cake_wallet/src/screens/buy/pre_order_page.dart';
import 'package:cake_wallet/src/screens/restore/sweeping_wallet_page.dart'; import 'package:cake_wallet/src/screens/restore/sweeping_wallet_page.dart';
import 'package:cake_wallet/src/screens/receive/anonpay_invoice_page.dart'; import 'package:cake_wallet/src/screens/receive/anonpay_invoice_page.dart';
@ -97,8 +96,6 @@ import 'package:cake_wallet/ionia/ionia_any_pay_payment_info.dart';
import 'package:cw_core/crypto_currency.dart'; import 'package:cw_core/crypto_currency.dart';
import 'package:cw_core/node.dart'; import 'package:cw_core/node.dart';
import 'buy/moonpay/moonpay_buy_provider.dart';
late RouteSettings currentRouteSettings; late RouteSettings currentRouteSettings;
Route<dynamic> createRoute(RouteSettings settings) { Route<dynamic> createRoute(RouteSettings settings) {
@ -528,9 +525,6 @@ Route<dynamic> createRoute(RouteSettings settings) {
param1: title, param1: title,
param2: url)); param2: url));
case Routes.payfuraPage:
return CupertinoPageRoute<void>(builder: (_) => getIt.get<PayFuraPage>());
case Routes.advancedPrivacySettings: case Routes.advancedPrivacySettings:
final type = settings.arguments as WalletType; final type = settings.arguments as WalletType;

View file

@ -81,7 +81,6 @@ class Routes {
static const anonPayInvoicePage = '/anon_pay_invoice_page'; static const anonPayInvoicePage = '/anon_pay_invoice_page';
static const anonPayReceivePage = '/anon_pay_receive_page'; static const anonPayReceivePage = '/anon_pay_receive_page';
static const anonPayDetailsPage = '/anon_pay_details_page'; static const anonPayDetailsPage = '/anon_pay_details_page';
static const payfuraPage = '/pay_fura_page';
static const desktop_actions = '/desktop_actions'; static const desktop_actions = '/desktop_actions';
static const transactionsPage = '/transactions_page'; static const transactionsPage = '/transactions_page';
static const setup_2faPage = '/setup_2fa_page'; static const setup_2faPage = '/setup_2fa_page';

View file

@ -1,58 +0,0 @@
import 'package:cake_wallet/buy/payfura/payfura_buy_provider.dart';
import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/src/screens/base_page.dart';
import 'package:flutter/material.dart';
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
import 'package:permission_handler/permission_handler.dart';
class PayFuraPage extends BasePage {
PayFuraPage(this._PayfuraBuyProvider);
final PayfuraBuyProvider _PayfuraBuyProvider;
@override
String get title => S.current.buy;
@override
Widget body(BuildContext context) {
return PayFuraPageBody(_PayfuraBuyProvider);
}
}
class PayFuraPageBody extends StatefulWidget {
PayFuraPageBody(this._PayfuraBuyProvider);
final PayfuraBuyProvider _PayfuraBuyProvider;
Uri get uri => _PayfuraBuyProvider.requestUrl();
@override
PayFuraPageBodyState createState() => PayFuraPageBodyState();
}
class PayFuraPageBodyState extends State<PayFuraPageBody> {
PayFuraPageBodyState();
@override
Widget build(BuildContext context) {
return InAppWebView(
initialOptions: InAppWebViewGroupOptions(
crossPlatform: InAppWebViewOptions(transparentBackground: true),
),
initialUrlRequest: URLRequest(url: widget.uri),
androidOnPermissionRequest: (_, __, resources) async {
bool permissionGranted = await Permission.camera.status == PermissionStatus.granted;
if (!permissionGranted) {
permissionGranted = await Permission.camera.request().isGranted;
}
return PermissionRequestResponse(
resources: resources,
action: permissionGranted
? PermissionRequestResponseAction.GRANT
: PermissionRequestResponseAction.DENY,
);
},
);
}
}

View file

@ -1,6 +1,8 @@
import 'package:cake_wallet/src/screens/exchange_trade/information_page.dart';
import 'package:cake_wallet/store/settings_store.dart'; import 'package:cake_wallet/store/settings_store.dart';
import 'package:cake_wallet/themes/theme_base.dart'; import 'package:cake_wallet/themes/theme_base.dart';
import 'package:cake_wallet/utils/responsive_layout_util.dart'; import 'package:cake_wallet/utils/responsive_layout_util.dart';
import 'package:cake_wallet/utils/show_pop_up.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.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:flutter_mobx/flutter_mobx.dart'; import 'package:flutter_mobx/flutter_mobx.dart';
@ -104,63 +106,86 @@ class BalancePage extends StatelessWidget {
color: Theme.of(context).textTheme!.titleLarge!.backgroundColor!), color: Theme.of(context).textTheme!.titleLarge!.backgroundColor!),
child: Container( child: Container(
margin: const EdgeInsets.only(top: 16, left: 24, right: 24, bottom: 24), margin: const EdgeInsets.only(top: 16, left: 24, right: 24, bottom: 24),
child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [ child: Column(
SizedBox( crossAxisAlignment: CrossAxisAlignment.start,
height: 4, children: [
),
Text('${availableBalanceLabel}',
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 12,
fontFamily: 'Lato',
fontWeight: FontWeight.w400,
color: Theme.of(context)
.accentTextTheme!
.displaySmall!
.backgroundColor!,
height: 1)),
SizedBox(height: 5),
Row( Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ mainAxisAlignment: MainAxisAlignment.spaceBetween,
Expanded( crossAxisAlignment: CrossAxisAlignment.start,
child: AutoSizeText(availableBalance, children: [
GestureDetector(
behavior: HitTestBehavior.opaque,
onTap: () => _showBalanceDescription(context),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Text('${availableBalanceLabel}',
style: TextStyle(
fontSize: 12,
fontFamily: 'Lato',
fontWeight: FontWeight.w400,
color: Theme.of(context)
.accentTextTheme!
.displaySmall!
.backgroundColor!,
height: 1)),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 4),
child: Icon(Icons.help_outline,
size: 16,
color: Theme.of(context)
.accentTextTheme!
.displaySmall!
.backgroundColor!),
)
],
),SizedBox(
height: 6,
),
AutoSizeText(availableBalance,
style: TextStyle(
fontSize: 24,
fontFamily: 'Lato',
fontWeight: FontWeight.w900,
color: Theme.of(context)
.accentTextTheme!
.displayMedium!
.backgroundColor!,
height: 1),
maxLines: 1,
textAlign: TextAlign.start),
SizedBox(
height: 6,
),
Text('${availableFiatBalance}',
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 16,
fontFamily: 'Lato',
fontWeight: FontWeight.w500,
color: Theme.of(context)
.accentTextTheme!
.displayMedium!
.backgroundColor!,
height: 1)),
],
),
),
Text(currency,
style: TextStyle( style: TextStyle(
fontSize: 24, fontSize: 28,
fontFamily: 'Lato', fontFamily: 'Lato',
fontWeight: FontWeight.w900, fontWeight: FontWeight.w800,
color: Theme.of(context) color: Theme.of(context)
.accentTextTheme! .accentTextTheme!
.displayMedium! .displayMedium!
.backgroundColor!, .backgroundColor!,
height: 1), height: 1)),
maxLines: 1, ],
textAlign: TextAlign.start),
),
Text(currency,
style: TextStyle(
fontSize: 28,
fontFamily: 'Lato',
fontWeight: FontWeight.w800,
color: Theme.of(context)
.accentTextTheme!
.displayMedium!
.backgroundColor!,
height: 1)),
]),
SizedBox(
height: 4,
), ),
Text('${availableFiatBalance}',
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 16,
fontFamily: 'Lato',
fontWeight: FontWeight.w500,
color: Theme.of(context)
.accentTextTheme!
.displayMedium!
.backgroundColor!,
height: 1)),
SizedBox(height: 26), SizedBox(height: 26),
if (frozenBalance.isNotEmpty) if (frozenBalance.isNotEmpty)
Column(crossAxisAlignment: CrossAxisAlignment.start, children: [ Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
@ -247,4 +272,10 @@ class BalancePage extends StatelessWidget {
])), ])),
); );
} }
void _showBalanceDescription(BuildContext context) {
showPopUp<void>(
context: context,
builder: (_) => InformationPage(information: S.current.available_balance_description));
}
} }

View file

@ -1,6 +1,6 @@
import 'package:cake_wallet/routes.dart'; import 'package:cake_wallet/routes.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/market_place_item.dart'; import 'package:cake_wallet/src/widgets/dashboard_card_widget.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/dashboard/dashboard_view_model.dart'; import 'package:cake_wallet/view_model/dashboard/dashboard_view_model.dart';
import 'package:cake_wallet/view_model/dashboard/market_place_view_model.dart'; import 'package:cake_wallet/view_model/dashboard/market_place_view_model.dart';
@ -51,13 +51,13 @@ class MarketPlacePage extends StatelessWidget {
controller: _scrollController, controller: _scrollController,
children: <Widget>[ children: <Widget>[
SizedBox(height: 20), SizedBox(height: 20),
MarketPlaceItem( DashBoardRoundedCardWidget(
onTap: () => _navigatorToGiftCardsPage(context), onTap: () => _navigatorToGiftCardsPage(context),
title: S.of(context).cake_pay_title, title: S.of(context).cake_pay_title,
subTitle: S.of(context).cake_pay_subtitle, subTitle: S.of(context).cake_pay_subtitle,
), ),
SizedBox(height: 20), SizedBox(height: 20),
MarketPlaceItem( DashBoardRoundedCardWidget(
onTap: () => launchUrl( onTap: () => launchUrl(
Uri.https("buy.cakepay.com"), Uri.https("buy.cakepay.com"),
mode: LaunchMode.externalApplication, mode: LaunchMode.externalApplication,

View file

@ -1,9 +1,11 @@
import 'package:cake_wallet/src/screens/dashboard/widgets/anonpay_transaction_row.dart'; import 'package:cake_wallet/src/screens/dashboard/widgets/anonpay_transaction_row.dart';
import 'package:cake_wallet/src/screens/dashboard/widgets/order_row.dart'; import 'package:cake_wallet/src/screens/dashboard/widgets/order_row.dart';
import 'package:cake_wallet/src/widgets/dashboard_card_widget.dart';
import 'package:cake_wallet/utils/responsive_layout_util.dart'; import 'package:cake_wallet/utils/responsive_layout_util.dart';
import 'package:cake_wallet/view_model/dashboard/anonpay_transaction_list_item.dart'; import 'package:cake_wallet/view_model/dashboard/anonpay_transaction_list_item.dart';
import 'package:cake_wallet/view_model/dashboard/order_list_item.dart'; import 'package:cake_wallet/view_model/dashboard/order_list_item.dart';
import 'package:cw_core/crypto_currency.dart'; import 'package:cw_core/crypto_currency.dart';
import 'package:cw_core/sync_status.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.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:flutter_mobx/flutter_mobx.dart'; import 'package:flutter_mobx/flutter_mobx.dart';
@ -37,6 +39,23 @@ class TransactionsPage extends StatelessWidget {
padding: EdgeInsets.only(top: 24, bottom: 24), padding: EdgeInsets.only(top: 24, bottom: 24),
child: Column( child: Column(
children: <Widget>[ children: <Widget>[
Observer(builder: (_) {
final status = dashboardViewModel.status;
if (status is SyncingSyncStatus) {
return Padding(
padding: const EdgeInsets.fromLTRB(24, 0, 24, 8),
child: DashBoardRoundedCardWidget(
onTap: () => Navigator.of(context).pushNamed(
Routes.webViewPage,
arguments: ['', Uri.parse('https://guides.cakewallet.com/docs/bugs-service-status/why_are_my_funds_not_appearing/')]),
title: S.of(context).syncing_wallet_alert_title,
subTitle: S.of(context).syncing_wallet_alert_content,
),
);
} else {
return Container();
}
}),
HeaderRow(dashboardViewModel: dashboardViewModel), HeaderRow(dashboardViewModel: dashboardViewModel),
Expanded(child: Observer(builder: (_) { Expanded(child: Observer(builder: (_) {
final items = dashboardViewModel.items; final items = dashboardViewModel.items;

View file

@ -359,7 +359,7 @@ class ExchangeTradeState extends State<ExchangeTradeForm> {
Navigator.of(popupContext).pop(); Navigator.of(popupContext).pop();
RequestReviewHandler.requestReview(); RequestReviewHandler.requestReview();
}, },
text: S.of(popupContext).send_got_it, text: S.of(popupContext).got_it,
color: Theme.of(popupContext) color: Theme.of(popupContext)
.accentTextTheme! .accentTextTheme!
.bodyLarge! .bodyLarge!

View file

@ -30,6 +30,7 @@ class InformationPage extends StatelessWidget {
padding: EdgeInsets.fromLTRB(24, 28, 24, 24), padding: EdgeInsets.fromLTRB(24, 28, 24, 24),
child: Text( child: Text(
information, information,
textAlign: TextAlign.center,
style: TextStyle( style: TextStyle(
fontSize: 14, fontSize: 14,
fontWeight: FontWeight.normal, fontWeight: FontWeight.normal,
@ -43,7 +44,7 @@ class InformationPage extends StatelessWidget {
padding: EdgeInsets.fromLTRB(10, 0, 10, 10), padding: EdgeInsets.fromLTRB(10, 0, 10, 10),
child: PrimaryButton( child: PrimaryButton(
onPressed: () => Navigator.of(context).pop(), onPressed: () => Navigator.of(context).pop(),
text: S.of(context).send_got_it, text: S.of(context).got_it,
color: Theme.of(context).accentTextTheme!.bodySmall!.backgroundColor!, color: Theme.of(context).accentTextTheme!.bodySmall!.backgroundColor!,
textColor: Theme.of(context).primaryTextTheme!.titleLarge!.color! textColor: Theme.of(context).primaryTextTheme!.titleLarge!.color!
), ),

View file

@ -283,7 +283,7 @@ class IoniaBuyGiftCardDetailPage extends BasePage {
}) })
.expand((e) => e) .expand((e) => e)
.toList()), .toList()),
actionTitle: S.current.send_got_it, actionTitle: S.current.got_it,
); );
}); });
} }

View file

@ -216,7 +216,7 @@ class IoniaDebitCardPage extends BasePage {
onPressed: () => activate onPressed: () => activate
? Navigator.pushNamed(context, Routes.ioniaActivateDebitCardPage) ? Navigator.pushNamed(context, Routes.ioniaActivateDebitCardPage)
: Navigator.pop(context), : Navigator.pop(context),
text: S.of(context).send_got_it, text: S.of(context).got_it,
color: Color.fromRGBO(233, 242, 252, 1), color: Color.fromRGBO(233, 242, 252, 1),
textColor: textColor:
Theme.of(context).textTheme!.displaySmall!.color!, Theme.of(context).textTheme!.displaySmall!.color!,

View file

@ -214,7 +214,7 @@ class IoniaGiftCardDetailPage extends BasePage {
}) })
.expand((e) => e) .expand((e) => e)
.toList()), .toList()),
actionTitle: S.of(context).send_got_it, actionTitle: S.of(context).got_it,
); );
}); });
} }

View file

@ -1,176 +1,94 @@
import 'package:cake_wallet/src/widgets/picker_inner_wrapper_widget.dart';
import 'package:cake_wallet/src/widgets/section_divider.dart'; import 'package:cake_wallet/src/widgets/section_divider.dart';
import 'package:cake_wallet/utils/responsive_layout_util.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_mobx/flutter_mobx.dart'; import 'package:flutter_mobx/flutter_mobx.dart';
import 'package:cake_wallet/routes.dart'; import 'package:cake_wallet/routes.dart';
import 'package:cake_wallet/generated/i18n.dart'; import 'package:cake_wallet/generated/i18n.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/src/screens/monero_accounts/widgets/account_tile.dart'; import 'package:cake_wallet/src/screens/monero_accounts/widgets/account_tile.dart';
import 'package:cake_wallet/src/widgets/alert_background.dart';
import 'package:cake_wallet/src/widgets/cake_scrollbar.dart';
import 'package:cake_wallet/src/widgets/alert_close_button.dart';
class MoneroAccountListPage extends StatelessWidget { class MoneroAccountListPage extends StatelessWidget {
MoneroAccountListPage({required this.accountListViewModel}) MoneroAccountListPage({required this.accountListViewModel});
: backgroundHeight = 194,
thumbHeight = 72,
isAlwaysShowScrollThumb = false,
controller = ScrollController() {
controller.addListener(() {
final scrollOffsetFromTop = controller.hasClients
? (controller.offset / controller.position.maxScrollExtent * (backgroundHeight - thumbHeight))
: 0.0;
accountListViewModel.setScrollOffsetFromTop(scrollOffsetFromTop);
});
}
final MoneroAccountListViewModel accountListViewModel; final MoneroAccountListViewModel accountListViewModel;
final ScrollController controller = ScrollController();
ScrollController controller;
double backgroundHeight;
double thumbHeight;
bool isAlwaysShowScrollThumb;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return AlertBackground( double itemHeight = 80;
child: Column( double buttonHeight = 62;
return Observer(builder: (_) {
final accounts = accountListViewModel.accounts;
return PickerInnerWrapperWidget(
title: S.of(context).choose_account,
itemsHeight: (itemHeight * accounts.length) + buttonHeight,
children: [ children: [
Expanded( Expanded(
child: Stack( child: Scrollbar(
alignment: Alignment.center, controller: controller,
children: <Widget>[ child: ListView.separated(
Column( padding: EdgeInsets.zero,
controller: controller,
separatorBuilder: (context, index) => const SectionDivider(),
itemCount: accounts.length,
itemBuilder: (context, index) {
final account = accounts[index];
return AccountTile(
isCurrent: account.isSelected,
accountName: account.label,
accountBalance: account.balance ?? '0.00',
currency: accountListViewModel.currency.toString(),
onTap: () {
if (account.isSelected) {
return;
}
accountListViewModel.select(account);
Navigator.of(context).pop();
},
onEdit: () async => await Navigator.of(context)
.pushNamed(Routes.accountCreation, arguments: account));
},
),
)),
GestureDetector(
onTap: () async =>
await Navigator.of(context).pushNamed(Routes.accountCreation),
child: Container(
height: buttonHeight,
color: Theme.of(context).cardColor,
padding: EdgeInsets.symmetric(horizontal: 24),
child: Center(
child: Row(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: <Widget>[ children: <Widget>[
Container( Icon(
padding: EdgeInsets.only(left: 24, right: 24), Icons.add,
child: Text( color: Colors.white,
S.of(context).choose_account,
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
fontFamily: 'Lato',
decoration: TextDecoration.none,
color: Colors.white
),
),
), ),
Padding( Padding(
padding: EdgeInsets.only(left: 24, right: 24, top: 24), padding: EdgeInsets.only(left: 5),
child: GestureDetector( child: Text(
onTap: () => null, S.of(context).create_new_account,
child: ClipRRect( style: TextStyle(
borderRadius: BorderRadius.all(Radius.circular(14)), fontSize: 15,
child: Container( fontWeight: FontWeight.w600,
height: 296, fontFamily: 'Lato',
color: Theme.of(context).textTheme!.displayLarge!.decorationColor!, color: Colors.white,
child: Column( decoration: TextDecoration.none,
children: <Widget>[
Expanded(
child: Observer(
builder: (_) {
final accounts = accountListViewModel.accounts;
isAlwaysShowScrollThumb = accounts == null
? false
: accounts.length > 3;
return Stack(
alignment: Alignment.center,
children: <Widget>[
ListView.separated(
padding: EdgeInsets.zero,
controller: controller,
separatorBuilder: (context, index) =>
const SectionDivider(),
itemCount: accounts.length ?? 0,
itemBuilder: (context, index) {
final account = accounts[index];
return AccountTile(
isCurrent: account.isSelected,
accountName: account.label,
accountBalance: account.balance ?? '0.00',
currency: accountListViewModel
.currency.toString(),
onTap: () {
if (account.isSelected) {
return;
}
accountListViewModel
.select(account);
Navigator.of(context).pop();
},
onEdit: () async =>
await Navigator.of(context)
.pushNamed(
Routes.accountCreation,
arguments: account));
},
),
isAlwaysShowScrollThumb
? CakeScrollbar(
backgroundHeight: backgroundHeight,
thumbHeight: thumbHeight,
fromTop: accountListViewModel
.scrollOffsetFromTop
)
: Offstage(),
],
);
}
)
),
GestureDetector(
onTap: () async => await Navigator.of(context)
.pushNamed(Routes.accountCreation),
child: Container(
height: 62,
color: Theme.of(context).cardColor,
padding: EdgeInsets.only(left: 24, right: 24),
child: Center(
child: Row(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Icon(
Icons.add,
color: Colors.white,
),
Padding(
padding: EdgeInsets.only(left: 5),
child: Text(
S.of(context).create_new_account,
style: TextStyle(
fontSize: 15,
fontWeight: FontWeight.w600,
fontFamily: 'Lato',
color: Colors.white,
decoration: TextDecoration.none,
),
),
)
],
),
),
),
)
],
),
),
), ),
), ),
) )
], ],
), ),
SizedBox(height: ResponsiveLayoutUtil.kPopupSpaceHeight), ),
AlertCloseButton()
],
), ),
), )
], ],
), );
); });
} }
} }

View file

@ -1,14 +1,13 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
class AccountTile extends StatelessWidget { class AccountTile extends StatelessWidget {
AccountTile({ AccountTile(
required this.isCurrent, {required this.isCurrent,
required this.accountName, required this.accountName,
this.accountBalance, this.accountBalance,
required this.currency, required this.currency,
required this.onTap, required this.onTap,
required this.onEdit required this.onEdit});
});
final bool isCurrent; final bool isCurrent;
final String accountName; final String accountName;
@ -32,11 +31,13 @@ class AccountTile extends StatelessWidget {
height: 77, height: 77,
padding: EdgeInsets.only(left: 24, right: 24), padding: EdgeInsets.only(left: 24, right: 24),
color: color, color: color,
child: Row( child: Wrap(
mainAxisAlignment: MainAxisAlignment.spaceBetween, direction: Axis.horizontal,
alignment: WrapAlignment.spaceBetween,
runAlignment: WrapAlignment.center,
crossAxisAlignment: WrapCrossAlignment.center,
children: [ children: [
Expanded( Container(
flex: 2,
child: Text( child: Text(
accountName, accountName,
style: TextStyle( style: TextStyle(
@ -49,19 +50,19 @@ class AccountTile extends StatelessWidget {
), ),
), ),
if (accountBalance != null) if (accountBalance != null)
Expanded( Container(
child: Text( child: Text(
'${accountBalance.toString()} $currency', '${accountBalance.toString()} $currency',
textAlign: TextAlign.end, textAlign: TextAlign.end,
style: TextStyle( style: TextStyle(
fontSize: 15, fontSize: 15,
fontWeight: FontWeight.w600, fontWeight: FontWeight.w600,
fontFamily: 'Lato', fontFamily: 'Lato',
color: Theme.of(context).textTheme!.headlineMedium!.color!, color: Theme.of(context).textTheme!.headlineMedium!.color!,
decoration: TextDecoration.none, decoration: TextDecoration.none,
),
), ),
), ),
),
], ],
), ),
), ),
@ -80,4 +81,4 @@ class AccountTile extends StatelessWidget {
// onTap: () => onEdit?.call()) // onTap: () => onEdit?.call())
// ]); // ]);
} }
} }

View file

@ -1,13 +1,14 @@
import 'package:cake_wallet/utils/responsive_layout_util.dart';
import 'package:cw_core/wallet_type.dart';
import 'package:cake_wallet/themes/theme_base.dart';
import 'package:flutter/material.dart';
import 'package:cake_wallet/generated/i18n.dart'; import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/src/screens/base_page.dart'; import 'package:cake_wallet/src/screens/base_page.dart';
import 'package:cake_wallet/src/screens/new_wallet/widgets/select_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/src/screens/new_wallet/widgets/select_button.dart'; import 'package:cake_wallet/src/widgets/search_bar_widget.dart';
import 'package:cake_wallet/themes/theme_base.dart';
import 'package:cake_wallet/utils/responsive_layout_util.dart';
import 'package:cake_wallet/wallet_types.g.dart'; import 'package:cake_wallet/wallet_types.g.dart';
import 'package:cw_core/wallet_type.dart';
import 'package:flutter/material.dart';
class NewWalletTypePage extends BasePage { class NewWalletTypePage extends BasePage {
NewWalletTypePage({required this.onTypeSelected}); NewWalletTypePage({required this.onTypeSelected});
@ -40,92 +41,82 @@ class WalletTypeFormState extends State<WalletTypeForm> {
static const aspectRatioImage = 1.22; static const aspectRatioImage = 1.22;
final moneroIcon = Image.asset('assets/images/monero_logo.png', height: 24, width: 24); final TextEditingController searchController = TextEditingController();
final bitcoinIcon = Image.asset('assets/images/bitcoin.png', height: 24, width: 24);
final litecoinIcon = Image.asset('assets/images/litecoin_icon.png', height: 24, width: 24);
final walletTypeImage = Image.asset('assets/images/wallet_type.png');
final walletTypeLightImage = Image.asset('assets/images/wallet_type_light.png');
final havenIcon = Image.asset('assets/images/haven_logo.png', height: 24, width: 24);
WalletType? selected; WalletType? selected;
List<WalletType> types; List<WalletType> types;
List<WalletType> filteredTypes = [];
@override @override
void initState() { void initState() {
types = availableWalletTypes; types = filteredTypes = availableWalletTypes;
super.initState(); super.initState();
searchController.addListener(() {
setState(() {
filteredTypes = List.from(types.where((type) => walletTypeToDisplayName(type)
.toLowerCase()
.contains(searchController.text.toLowerCase())));
return;
});
});
} }
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return ScrollableWithBottomSection( return Center(
contentPadding: EdgeInsets.only(left: 24, right: 24, bottom: 24),
content: Center(
child: ConstrainedBox( child: ConstrainedBox(
constraints: BoxConstraints(maxWidth: ResponsiveLayoutUtil.kDesktopMaxWidthConstraint), constraints: BoxConstraints(maxWidth: ResponsiveLayoutUtil.kDesktopMaxWidthConstraint),
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.center, children: [
children: <Widget>[ Padding(
Padding( padding: EdgeInsets.only(top: 48),
padding: EdgeInsets.only(left: 12, right: 12), child: Text(
child: AspectRatio( S.of(context).choose_wallet_currency,
aspectRatio: aspectRatioImage, textAlign: TextAlign.center,
child: FittedBox(child: widget.walletImage, fit: BoxFit.fill)), style: TextStyle(
), fontSize: 16,
Padding( fontWeight: FontWeight.w500,
padding: EdgeInsets.only(top: 48), color: Theme.of(context).primaryTextTheme!.titleLarge!.color!),
child: Text( ),
S.of(context).choose_wallet_currency,
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.w500,
color: Theme.of(context)
.primaryTextTheme!
.titleLarge!
.color!),
), ),
), Padding(
...types.map((type) => Padding( padding: const EdgeInsets.fromLTRB(24, 24, 24, 12),
padding: EdgeInsets.only(top: 24), child: SearchBarWidget(searchController: searchController, borderRadius: 24),
child: SelectButton( ),
image: _iconFor(type), Expanded(
text: walletTypeToDisplayName(type), child: ScrollableWithBottomSection(
isSelected: selected == type, contentPadding: EdgeInsets.only(left: 24, right: 24, bottom: 24),
onTap: () => setState(() => selected = type)), content: Column(
)) crossAxisAlignment: CrossAxisAlignment.center,
], children: <Widget>[
), ...filteredTypes.map((type) => Padding(
), padding: EdgeInsets.only(top: 12),
), child: SelectButton(
bottomSectionPadding: EdgeInsets.only(left: 24, right: 24, bottom: 24), image: Image.asset(
bottomSection: PrimaryButton( walletTypeToCryptoCurrency(type).iconPath ?? '',
onPressed: () => onTypeSelected(), height: 24,
text: S.of(context).seed_language_next, width: 24),
color: Theme.of(context) text: walletTypeToDisplayName(type),
.accentTextTheme! showTrailingIcon: false,
.bodyLarge! height: 54,
.color!, isSelected: selected == type,
textColor: Colors.white, onTap: () => setState(() => selected = type)),
isDisabled: selected == null, ))
), ],
); ),
} bottomSectionPadding: EdgeInsets.only(left: 24, right: 24, bottom: 24),
bottomSection: PrimaryButton(
Image _iconFor(WalletType type) { onPressed: () => onTypeSelected(),
switch (type) { text: S.of(context).seed_language_next,
case WalletType.monero: color: Theme.of(context).accentTextTheme!.bodyLarge!.color!,
return moneroIcon; textColor: Colors.white,
case WalletType.bitcoin: isDisabled: selected == null,
return bitcoinIcon; ),
case WalletType.litecoin: ),
return litecoinIcon; ),
case WalletType.haven: ],
return havenIcon; )));
default:
throw Exception(
'_iconFor: Incorrect Wallet Type. Cannot find icon for Wallet Type: ${type.toString()}');
}
} }
Future<void> onTypeSelected() async { Future<void> onTypeSelected() async {

View file

@ -6,12 +6,16 @@ class SelectButton extends StatelessWidget {
required this.onTap, required this.onTap,
this.image, this.image,
this.isSelected = false, this.isSelected = false,
this.showTrailingIcon = true,
this.height = 60,
}); });
final Image? image; final Image? image;
final String text; final String text;
final bool isSelected; final bool isSelected;
final VoidCallback onTap; final VoidCallback onTap;
final bool showTrailingIcon;
final double height;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -44,7 +48,7 @@ class SelectButton extends StatelessWidget {
onTap: onTap, onTap: onTap,
child: Container( child: Container(
width: double.infinity, width: double.infinity,
height: 60, height: height,
padding: EdgeInsets.only(left: 30, right: 30), padding: EdgeInsets.only(left: 30, right: 30),
alignment: Alignment.center, alignment: Alignment.center,
decoration: BoxDecoration( decoration: BoxDecoration(
@ -76,7 +80,7 @@ class SelectButton extends StatelessWidget {
) )
], ],
), ),
selectArrowImage if (showTrailingIcon) selectArrowImage
], ],
), ),
), ),

View file

@ -149,26 +149,12 @@ class WalletListBodyState extends State<WalletListBody> {
return wallet.isCurrent return wallet.isCurrent
? row ? row
: Row(children: [ : Slidable(
Expanded(child: row), key: Key('${wallet.key}'),
GestureDetector( startActionPane: _actionPane(wallet),
onTap: () => _removeWallet(wallet), endActionPane: _actionPane(wallet),
child: Container( child: row,
height: 40, );
width: 44,
padding: EdgeInsets.only(right: 20),
child: Center(
child: Image.asset('assets/images/trash.png',
height: 16,
width: 16,
color: Theme.of(context)
.primaryTextTheme
.titleLarge!
.color),
),
),
)
]);
}), }),
), ),
), ),
@ -291,4 +277,18 @@ class WalletListBodyState extends State<WalletListBody> {
_progressBar = null; _progressBar = null;
}); });
} }
ActionPane _actionPane(WalletListItem wallet) => ActionPane(
motion: const ScrollMotion(),
extentRatio: 0.3,
children: [
SlidableAction(
onPressed: (_) => _removeWallet(wallet),
backgroundColor: Colors.red,
foregroundColor: Colors.white,
icon: CupertinoIcons.delete,
label: S.of(context).delete,
),
],
);
} }

View file

@ -1,9 +1,9 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
class MarketPlaceItem extends StatelessWidget { class DashBoardRoundedCardWidget extends StatelessWidget {
MarketPlaceItem({ DashBoardRoundedCardWidget({
required this.onTap, required this.onTap,
required this.title, required this.title,
required this.subTitle, required this.subTitle,

View file

@ -1,5 +1,6 @@
// ignore_for_file: deprecated_member_use // ignore_for_file: deprecated_member_use
import 'package:cake_wallet/src/widgets/search_bar_widget.dart';
import 'package:cake_wallet/utils/responsive_layout_util.dart'; import 'package:cake_wallet/utils/responsive_layout_util.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:cw_core/currency.dart'; import 'package:cw_core/currency.dart';
@ -158,37 +159,7 @@ class _PickerState<Item> extends State<Picker<Item>> {
if (widget.hintText != null) if (widget.hintText != null)
Padding( Padding(
padding: const EdgeInsets.all(16), padding: const EdgeInsets.all(16),
child: TextFormField( child: SearchBarWidget(searchController: searchController),
controller: searchController,
style: TextStyle(
color: Theme.of(context)
.primaryTextTheme!
.titleLarge!
.color!),
decoration: InputDecoration(
hintText: widget.hintText,
prefixIcon:
Image.asset("assets/images/search_icon.png"),
filled: true,
fillColor: Theme.of(context)
.accentTextTheme!
.displaySmall!
.color!,
alignLabelWithHint: false,
contentPadding: const EdgeInsets.symmetric(
vertical: 4, horizontal: 16),
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(14),
borderSide: const BorderSide(
color: Colors.transparent,
)),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(14),
borderSide: const BorderSide(
color: Colors.transparent,
)),
),
),
), ),
Divider( Divider(
color: Theme.of(context) color: Theme.of(context)

View file

@ -0,0 +1,91 @@
import 'package:cake_wallet/utils/responsive_layout_util.dart';
import 'package:flutter/material.dart';
import 'package:cake_wallet/src/widgets/picker_wrapper_widget.dart';
class PickerInnerWrapperWidget extends StatelessWidget {
PickerInnerWrapperWidget(
{required this.children, this.title, this.itemsHeight});
final List<Widget> children;
final String? title;
final double? itemsHeight;
@override
Widget build(BuildContext context) {
final mq = MediaQuery.of(context);
final bottom = mq.viewInsets.bottom;
final height = mq.size.height - bottom;
double containerHeight = height * 0.65;
if (bottom > 0) {
// increase a bit or it gets too squished in the top
containerHeight = height * 0.75;
}
if (title != null) {
return PickerWrapperWidget(
hasTitle: true,
children: <Widget>[
Container(
padding: EdgeInsets.symmetric(horizontal: 24),
child: Text(
title!,
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
fontFamily: 'Lato',
decoration: TextDecoration.none,
color: Colors.white),
),
),
Padding(
padding: EdgeInsets.symmetric(horizontal: 24),
child: ClipRRect(
borderRadius: BorderRadius.all(Radius.circular(14)),
child: Container(
color: Theme.of(context).textTheme.displayLarge!.decorationColor!,
child: ConstrainedBox(
constraints: BoxConstraints(
maxHeight:
itemsHeight != null && itemsHeight! <= containerHeight
? itemsHeight!
: containerHeight,
maxWidth: ResponsiveLayoutUtil.kPopupWidth,
),
child: Column(
children: children,
),
),
),
),
)
],
);
}
return PickerWrapperWidget(
hasTitle: false,
children: <Widget>[
Padding(
padding: EdgeInsets.symmetric(horizontal: 24),
child: ClipRRect(
borderRadius: BorderRadius.all(Radius.circular(14)),
child: Container(
color: Theme.of(context).textTheme.displayLarge!.decorationColor!,
child: ConstrainedBox(
constraints: BoxConstraints(
maxHeight: containerHeight,
maxWidth: ResponsiveLayoutUtil.kPopupWidth,
),
child: Column(
children: children,
),
),
),
),
)
],
);
}
}

View file

@ -0,0 +1,40 @@
import 'package:flutter/material.dart';
import 'package:cake_wallet/generated/i18n.dart';
class SearchBarWidget extends StatelessWidget {
const SearchBarWidget({
required this.searchController,
this.hintText,
this.borderRadius = 14,
});
final TextEditingController searchController;
final String? hintText;
final double borderRadius;
@override
Widget build(BuildContext context) {
return TextFormField(
controller: searchController,
style: TextStyle(color: Theme.of(context).primaryTextTheme!.titleLarge!.color!),
decoration: InputDecoration(
hintText: hintText ?? S.of(context).search_currency,
prefixIcon: Image.asset("assets/images/search_icon.png"),
filled: true,
fillColor: Theme.of(context).accentTextTheme!.displaySmall!.color!,
alignLabelWithHint: false,
contentPadding: const EdgeInsets.symmetric(vertical: 4, horizontal: 16),
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(borderRadius),
borderSide: const BorderSide(
color: Colors.transparent,
)),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(borderRadius),
borderSide: const BorderSide(
color: Colors.transparent,
)),
),
);
}
}

View file

@ -0,0 +1,39 @@
import 'dart:io';
import 'package:package_info/package_info.dart';
enum DistributionType { googleplay, github, appstore, fdroid }
class DistributionInfo {
DistributionInfo._();
static DistributionInfo get instance => DistributionInfo._();
Future<String> getDistributionPath() async {
final isPlayStore = await isInstalledFromPlayStore();
final distributionPath = _getDistributionPath(isPlayStore);
return distributionPath.name;
}
DistributionType _getDistributionPath(bool isPlayStore) {
if (isPlayStore) {
return DistributionType.googleplay;
} else if (Platform.isAndroid) {
return DistributionType.github;
} else if (Platform.isIOS) {
return DistributionType.appstore;
} else {
return DistributionType.github;
}
}
Future<bool> isInstalledFromPlayStore() async {
try {
final packageInfo = await PackageInfo.fromPlatform();
return packageInfo.packageName == 'com.android.vending';
} catch (e) {
print('Error: $e');
return false;
}
}
}

View file

@ -36,7 +36,8 @@ abstract class ExchangeTradeViewModelBase with Store {
_provider = XMRTOExchangeProvider(); _provider = XMRTOExchangeProvider();
break; break;
case ExchangeProviderDescription.changeNow: case ExchangeProviderDescription.changeNow:
_provider = ChangeNowExchangeProvider(); _provider =
ChangeNowExchangeProvider(settingsStore: sendViewModel.balanceViewModel.settingsStore);
break; break;
case ExchangeProviderDescription.morphToken: case ExchangeProviderDescription.morphToken:
_provider = MorphTokenExchangeProvider(trades: trades); _provider = MorphTokenExchangeProvider(trades: trades);

View file

@ -130,7 +130,7 @@ abstract class ExchangeViewModelBase with Store {
final SharedPreferences sharedPreferences; final SharedPreferences sharedPreferences;
List<ExchangeProvider> get _allProviders => [ List<ExchangeProvider> get _allProviders => [
ChangeNowExchangeProvider(), ChangeNowExchangeProvider(settingsStore: _settingsStore),
SideShiftExchangeProvider(), SideShiftExchangeProvider(),
SimpleSwapExchangeProvider(), SimpleSwapExchangeProvider(),
TrocadorExchangeProvider(useTorOnly: _useTorOnly), TrocadorExchangeProvider(useTorOnly: _useTorOnly),
@ -221,7 +221,7 @@ abstract class ExchangeViewModelBase with Store {
bool get hasAllAmount => bool get hasAllAmount =>
wallet.type == WalletType.bitcoin && depositCurrency == wallet.currency; (wallet.type == WalletType.bitcoin || wallet.type == WalletType.litecoin) && depositCurrency == wallet.currency;
bool get isMoneroWallet => wallet.type == WalletType.monero; bool get isMoneroWallet => wallet.type == WalletType.monero;
@ -566,7 +566,7 @@ abstract class ExchangeViewModelBase with Store {
@action @action
void calculateDepositAllAmount() { void calculateDepositAllAmount() {
if (wallet.type == WalletType.bitcoin) { if (wallet.type == WalletType.bitcoin || wallet.type == WalletType.litecoin) {
final availableBalance = wallet.balance[wallet.currency]!.available; final availableBalance = wallet.balance[wallet.currency]!.available;
final priority = _settingsStore.priority[wallet.type]!; final priority = _settingsStore.priority[wallet.type]!;
final fee = wallet.calculateEstimatedFee(priority, null); final fee = wallet.calculateEstimatedFee(priority, null);

View file

@ -40,7 +40,7 @@ abstract class TradeDetailsViewModelBase with Store {
_provider = XMRTOExchangeProvider(); _provider = XMRTOExchangeProvider();
break; break;
case ExchangeProviderDescription.changeNow: case ExchangeProviderDescription.changeNow:
_provider = ChangeNowExchangeProvider(); _provider = ChangeNowExchangeProvider(settingsStore: settingsStore);
break; break;
case ExchangeProviderDescription.morphToken: case ExchangeProviderDescription.morphToken:
_provider = MorphTokenExchangeProvider(trades: trades); _provider = MorphTokenExchangeProvider(trades: trades);

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -5,19 +5,14 @@
"please_make_selection": "Don Allah zaɓi ƙasa don ƙirƙira ko dawo da kwalinku.", "please_make_selection": "Don Allah zaɓi ƙasa don ƙirƙira ko dawo da kwalinku.",
"create_new": "Ƙirƙira Sabon Kwalinku", "create_new": "Ƙirƙira Sabon Kwalinku",
"restore_wallet": "Dawo da Kwalinku", "restore_wallet": "Dawo da Kwalinku",
"monero_com": "Monero.com ta Cake Wallet", "monero_com": "Monero.com ta Cake Wallet",
"monero_com_wallet_text": "Aikace-aikacen e-wallet ga Monero", "monero_com_wallet_text": "Aikace-aikacen e-wallet ga Monero",
"haven_app": "Haven da Cake Wallet", "haven_app": "Haven da Cake Wallet",
"haven_app_wallet_text": "Aikace-aikacen e-wallet ga Haven", "haven_app_wallet_text": "Aikace-aikacen e-wallet ga Haven",
"accounts": "Lissafi", "accounts": "Lissafi",
"edit": "Gyara", "edit": "Gyara",
"account": "Asusu", "account": "Asusu",
"add": "Ƙara", "add": "Ƙara",
"address_book": "Littafin adireshi", "address_book": "Littafin adireshi",
"contact": "Tuntuɓar", "contact": "Tuntuɓar",
"please_select": "Don Allah zaɓi:", "please_select": "Don Allah zaɓi:",
@ -28,13 +23,9 @@
"save": "Ajiye", "save": "Ajiye",
"address_remove_contact": "Cire lamba", "address_remove_contact": "Cire lamba",
"address_remove_content": "Kuna tabbatar kuna so ku cire wannan Contact?", "address_remove_content": "Kuna tabbatar kuna so ku cire wannan Contact?",
"authenticated": "Ingantacce", "authenticated": "Ingantacce",
"authentication": "Tabbatarwa", "authentication": "Tabbatarwa",
"failed_authentication": "Binne wajen shiga. ${state_error}", "failed_authentication": "Binne wajen shiga. ${state_error}",
"wallet_menu": "Menu", "wallet_menu": "Menu",
"Blocks_remaining": "${status} Katanga ya rage", "Blocks_remaining": "${status} Katanga ya rage",
"please_try_to_connect_to_another_node": "Don Allah yi ƙoƙarin haɗa da wani node", "please_try_to_connect_to_another_node": "Don Allah yi ƙoƙarin haɗa da wani node",
@ -62,8 +53,6 @@
"address_book_menu": "Littafin adireshi", "address_book_menu": "Littafin adireshi",
"reconnection": "Sake haɗawa", "reconnection": "Sake haɗawa",
"reconnect_alert_text": "Shin kun tabbata kuna son sake haɗawa?", "reconnect_alert_text": "Shin kun tabbata kuna son sake haɗawa?",
"exchange": "Exchange", "exchange": "Exchange",
"clear": "Share", "clear": "Share",
"refund_address": "Adireshin maidowa", "refund_address": "Adireshin maidowa",
@ -80,7 +69,6 @@
"change_currency": "Canja Kuɗi", "change_currency": "Canja Kuɗi",
"overwrite_amount": "Rubuta adadin", "overwrite_amount": "Rubuta adadin",
"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?",
"copy_id": "Kwafi ID", "copy_id": "Kwafi ID",
"exchange_result_write_down_trade_id": "Da fatan za a kwafa ko rubuta ID ɗin ciniki don ci gaba.", "exchange_result_write_down_trade_id": "Da fatan za a kwafa ko rubuta ID ɗin ciniki don ci gaba.",
"trade_id": "ID na kasuwanci:", "trade_id": "ID na kasuwanci:",
@ -106,20 +94,13 @@
"time": "${minutes}m ${seconds}s", "time": "${minutes}m ${seconds}s",
"send_xmr": "Aika XMR", "send_xmr": "Aika XMR",
"exchange_new_template": "Sabon template", "exchange_new_template": "Sabon template",
"faq": "FAQ", "faq": "FAQ",
"enter_your_pin": "Shigar da PIN", "enter_your_pin": "Shigar da PIN",
"loading_your_wallet": "Ana loda walat ɗin ku", "loading_your_wallet": "Ana loda walat ɗin ku",
"new_wallet": "Sabuwar Wallet", "new_wallet": "Sabuwar Wallet",
"wallet_name": "Sunan walat", "wallet_name": "Sunan walat",
"continue_text": "Ci gaba", "continue_text": "Ci gaba",
"choose_wallet_currency": "Da fatan za a zaɓi kuɗin walat:", "choose_wallet_currency": "Da fatan za a zaɓi kuɗin walat:",
"node_new": "Sabon Node", "node_new": "Sabon Node",
"node_address": "Address Node", "node_address": "Address Node",
"node_port": "Node tashar jiragen ruwa", "node_port": "Node tashar jiragen ruwa",
@ -140,24 +121,18 @@
"node_connection_successful": "Haɗin ya yi nasara", "node_connection_successful": "Haɗin ya yi nasara",
"node_connection_failed": "Haɗin ya gaza", "node_connection_failed": "Haɗin ya gaza",
"new_node_testing": "Sabbin gwajin kumburi", "new_node_testing": "Sabbin gwajin kumburi",
"use": "Canja zuwa", "use": "Canja zuwa",
"digit_pin": "-lambar PIN", "digit_pin": "-lambar PIN",
"share_address": "Raba adireshin", "share_address": "Raba adireshin",
"receive_amount": "Adadi", "receive_amount": "Adadi",
"subaddresses": "Subaddresses", "subaddresses": "Subaddresses",
"addresses": "Addresses", "addresses": "Addresses",
"scan_qr_code": "Duba lambar QR don samun adireshin", "scan_qr_code": "Gani QR kodin",
"qr_fullscreen": "Matsa don buɗe lambar QR na cikakken allo", "qr_fullscreen": "Matsa don buɗe lambar QR na cikakken allo",
"rename": "Sake suna", "rename": "Sake suna",
"choose_account": "Zaɓi asusu", "choose_account": "Zaɓi asusu",
"create_new_account": "Ƙirƙiri sabon asusu", "create_new_account": "Ƙirƙiri sabon asusu",
"accounts_subaddresses": "Accounts da subaddresses", "accounts_subaddresses": "Accounts da subaddresses",
"restore_restore_wallet": "Maida Wallet", "restore_restore_wallet": "Maida Wallet",
"restore_title_from_seed_keys": "Dawo da iri/maɓallai", "restore_title_from_seed_keys": "Dawo da iri/maɓallai",
"restore_description_from_seed_keys": "Maido da walat ɗin ku daga iri/maɓallan da kuka adana don amintaccen wuri", "restore_description_from_seed_keys": "Maido da walat ɗin ku daga iri/maɓallan da kuka adana don amintaccen wuri",
@ -181,14 +156,10 @@
"restore_bitcoin_description_from_keys": "Dawo da kwalinku daga WIF string dake generate daga maɓallan sirri", "restore_bitcoin_description_from_keys": "Dawo da kwalinku daga WIF string dake generate daga maɓallan sirri",
"restore_bitcoin_title_from_keys": "Dawo daga WIF", "restore_bitcoin_title_from_keys": "Dawo daga WIF",
"restore_from_date_or_blockheight": "Don Allah shigar da wata kwanan a kafin ku ƙirƙirar wannan kwalinku. Ko idan kun san blockheight, don Allah shigar da shi", "restore_from_date_or_blockheight": "Don Allah shigar da wata kwanan a kafin ku ƙirƙirar wannan kwalinku. Ko idan kun san blockheight, don Allah shigar da shi",
"seed_reminder": "Don Allah rubuta wadannan in case ka manta ko ka sake kwallon wayarka", "seed_reminder": "Don Allah rubuta wadannan in case ka manta ko ka sake kwallon wayarka",
"seed_title": "iri", "seed_title": "iri",
"seed_share": "Raba iri", "seed_share": "Raba iri",
"copy": "Kwafi", "copy": "Kwafi",
"seed_language_choose": "Don Allah zaɓi harshen seed:", "seed_language_choose": "Don Allah zaɓi harshen seed:",
"seed_choose": "Zaɓi harshen seed", "seed_choose": "Zaɓi harshen seed",
"seed_language_next": "Na gaba", "seed_language_next": "Na gaba",
@ -202,8 +173,6 @@
"seed_language_spanish": "Spanish", "seed_language_spanish": "Spanish",
"seed_language_french": "Faransanci", "seed_language_french": "Faransanci",
"seed_language_italian": "Italiyanci", "seed_language_italian": "Italiyanci",
"send_title": "Aika", "send_title": "Aika",
"send_your_wallet": "Walat ɗin ku", "send_your_wallet": "Walat ɗin ku",
"send_address": "${cryptoCurrency} address", "send_address": "${cryptoCurrency} address",
@ -219,11 +188,9 @@
"send_amount": "Adadi:", "send_amount": "Adadi:",
"send_fee": "Kudin:", "send_fee": "Kudin:",
"send_name": "Sunan", "send_name": "Sunan",
"send_got_it": "Gama", "got_it": "Gama",
"send_sending": "Aika...", "send_sending": "Aika...",
"send_success": "${crypto} kwalinku ya aika da nasara", "send_success": "${crypto} kwalinku ya aika da nasara",
"settings_title": "Saitunan", "settings_title": "Saitunan",
"settings_nodes": "Nodes", "settings_nodes": "Nodes",
"settings_current_node": "Node yanzu", "settings_current_node": "Node yanzu",
@ -247,13 +214,9 @@
"settings_support": "Taimako", "settings_support": "Taimako",
"settings_terms_and_conditions": "Sharuɗɗa da Ka'idoji", "settings_terms_and_conditions": "Sharuɗɗa da Ka'idoji",
"pin_is_incorrect": "PIN ba daidai ba ne", "pin_is_incorrect": "PIN ba daidai ba ne",
"setup_pin": "Saita PIN", "setup_pin": "Saita PIN",
"enter_your_pin_again": "Shigar da PIN ɗinku na sake", "enter_your_pin_again": "Shigar da PIN ɗinku na sake",
"setup_successful": "An saita PIN ɗinku da nasara!", "setup_successful": "An saita PIN ɗinku da nasara!",
"wallet_keys": "Iri/maɓalli na walat", "wallet_keys": "Iri/maɓalli na walat",
"wallet_seed": "kalmar sirri na walat", "wallet_seed": "kalmar sirri na walat",
"private_key": "Keɓaɓɓen maɓalli", "private_key": "Keɓaɓɓen maɓalli",
@ -263,17 +226,11 @@
"spend_key_private": "makullin biya (maɓallin kalmar sirri)", "spend_key_private": "makullin biya (maɓallin kalmar sirri)",
"spend_key_public": "makullin biya (maɓallin jama'a)", "spend_key_public": "makullin biya (maɓallin jama'a)",
"copied_key_to_clipboard": "An kwafa ${key} a cikin kwafin", "copied_key_to_clipboard": "An kwafa ${key} a cikin kwafin",
"new_subaddress_title": "Adireshin sabuwa", "new_subaddress_title": "Adireshin sabuwa",
"new_subaddress_label_name": "Lakabin suna", "new_subaddress_label_name": "Lakabin suna",
"new_subaddress_create": "Ƙirƙiri", "new_subaddress_create": "Ƙirƙiri",
"address_label": "Labari adireshi", "address_label": "Labari adireshi",
"subaddress_title": "Jagorar subaddress", "subaddress_title": "Jagorar subaddress",
"trade_details_title": "Bayanai game da kasuwancin", "trade_details_title": "Bayanai game da kasuwancin",
"trade_details_id": "ID", "trade_details_id": "ID",
"trade_details_state": "Matsayi", "trade_details_state": "Matsayi",
@ -282,11 +239,7 @@
"trade_details_created_at": "An ƙirƙira a", "trade_details_created_at": "An ƙirƙira a",
"trade_details_pair": "miji da matarsa", "trade_details_pair": "miji da matarsa",
"trade_details_copied": "${title} an kwafa zuwa cikin kwafin", "trade_details_copied": "${title} an kwafa zuwa cikin kwafin",
"trade_history_title": "Tarihin kasuwancin", "trade_history_title": "Tarihin kasuwancin",
"transaction_details_title": "Bayanai game da aikace-aikacen", "transaction_details_title": "Bayanai game da aikace-aikacen",
"transaction_details_transaction_id": "ID na kasuwanci", "transaction_details_transaction_id": "ID na kasuwanci",
"transaction_details_date": "Kwanan wata", "transaction_details_date": "Kwanan wata",
@ -295,8 +248,6 @@
"transaction_details_fee": "Kudin", "transaction_details_fee": "Kudin",
"transaction_details_copied": "${title} an kwafa zuwa cikin kwafin", "transaction_details_copied": "${title} an kwafa zuwa cikin kwafin",
"transaction_details_recipient_address": "Adireshin masu amfani", "transaction_details_recipient_address": "Adireshin masu amfani",
"wallet_list_title": "Monero walat", "wallet_list_title": "Monero walat",
"wallet_list_create_new_wallet": "Ƙirƙiri Sabon Wallet", "wallet_list_create_new_wallet": "Ƙirƙiri Sabon Wallet",
"wallet_list_restore_wallet": "Maida Wallet", "wallet_list_restore_wallet": "Maida Wallet",
@ -305,18 +256,12 @@
"wallet_list_failed_to_load": "An kasa loda ${wallet_name} walat. ${error}", "wallet_list_failed_to_load": "An kasa loda ${wallet_name} walat. ${error}",
"wallet_list_removing_wallet": "Cirewa ${wallet_name} walat", "wallet_list_removing_wallet": "Cirewa ${wallet_name} walat",
"wallet_list_failed_to_remove": "Ba a iya cirewa ${wallet_name} walat. ${error}", "wallet_list_failed_to_remove": "Ba a iya cirewa ${wallet_name} walat. ${error}",
"widgets_address": "Adireshin", "widgets_address": "Adireshin",
"widgets_restore_from_blockheight": "Sake dawo da daga blockheight", "widgets_restore_from_blockheight": "Sake dawo da daga blockheight",
"widgets_restore_from_date": "Sake dawo da daga kwanan wata", "widgets_restore_from_date": "Sake dawo da daga kwanan wata",
"widgets_or": "ko", "widgets_or": "ko",
"widgets_seed": "iri", "widgets_seed": "iri",
"router_no_route": "Babu wata hanya da aka bayyana don ${name}", "router_no_route": "Babu wata hanya da aka bayyana don ${name}",
"error_text_account_name": "Sunan ajiya zai iya ɗauka ne kawai da haruffa, lambobi\nkuma ya zama tsakanin 1 zuwa 15 haruffa", "error_text_account_name": "Sunan ajiya zai iya ɗauka ne kawai da haruffa, lambobi\nkuma ya zama tsakanin 1 zuwa 15 haruffa",
"error_text_contact_name": "Sunan kira ba zai iya ɗaukar ` , ' \" haruffa\nkuma ya zama tsakanin 1 zuwa 32 haruffa", "error_text_contact_name": "Sunan kira ba zai iya ɗaukar ` , ' \" haruffa\nkuma ya zama tsakanin 1 zuwa 32 haruffa",
"error_text_address": "Adireshin hujja ya kamata ya dace da irin\nna cryptocurrency", "error_text_address": "Adireshin hujja ya kamata ya dace da irin\nna cryptocurrency",
@ -334,21 +279,15 @@
"error_text_maximum_limit": "Kasuwanci ga ${provider} ba a yi ba. Adadin shine fiye da ƙimanin: ${max} ${currency}", "error_text_maximum_limit": "Kasuwanci ga ${provider} ba a yi ba. Adadin shine fiye da ƙimanin: ${max} ${currency}",
"error_text_limits_loading_failed": "Kasuwanci ga ${provider} ba a yi ba. An kasa saukewa masanan", "error_text_limits_loading_failed": "Kasuwanci ga ${provider} ba a yi ba. An kasa saukewa masanan",
"error_text_template": "Sunan na tushe da adireshin ba zai iya ɗaukar ` , ' \" haruffa\nkuma ya zama tsakanin 1 zuwa 106 haruffa", "error_text_template": "Sunan na tushe da adireshin ba zai iya ɗaukar ` , ' \" haruffa\nkuma ya zama tsakanin 1 zuwa 106 haruffa",
"auth_store_ban_timeout": "ban_timeout", "auth_store_ban_timeout": "ban_timeout",
"auth_store_banned_for": "An haramta don", "auth_store_banned_for": "An haramta don",
"auth_store_banned_minutes": "da minti", "auth_store_banned_minutes": "da minti",
"auth_store_incorrect_password": "PIN na gaskiya", "auth_store_incorrect_password": "PIN na gaskiya",
"wallet_store_monero_wallet": "Monero walat", "wallet_store_monero_wallet": "Monero walat",
"wallet_restoration_store_incorrect_seed_length": "kalmar sirrin iri ba daidai ba", "wallet_restoration_store_incorrect_seed_length": "kalmar sirrin iri ba daidai ba",
"full_balance": "DUKAN KUDI", "full_balance": "DUKAN KUDI",
"available_balance": "KUDI", "available_balance": "KUDI",
"hidden_balance": "BOYE KUDI", "hidden_balance": "BOYE KUDI",
"sync_status_syncronizing": "KWAFI", "sync_status_syncronizing": "KWAFI",
"sync_status_syncronized": "KYAU", "sync_status_syncronized": "KYAU",
"sync_status_not_connected": "BABU INTERNET", "sync_status_not_connected": "BABU INTERNET",
@ -357,21 +296,15 @@
"sync_status_connecting": "HADA", "sync_status_connecting": "HADA",
"sync_status_connected": "HANNU", "sync_status_connected": "HANNU",
"sync_status_attempting_sync": "KWAFI", "sync_status_attempting_sync": "KWAFI",
"transaction_priority_slow": "SAURI DA SAURI", "transaction_priority_slow": "SAURI DA SAURI",
"transaction_priority_regular": "SAURI NORMAL", "transaction_priority_regular": "SAURI NORMAL",
"transaction_priority_medium": "SAURI DA DADI", "transaction_priority_medium": "SAURI DA DADI",
"transaction_priority_fast": "sauri", "transaction_priority_fast": "sauri",
"transaction_priority_fastest": "mafi sauri", "transaction_priority_fastest": "mafi sauri",
"trade_for_not_created": "Ba a ƙirƙira ciniki don ${title} ba.", "trade_for_not_created": "Ba a ƙirƙira ciniki don ${title} ba.",
"trade_not_created": "Ba a ƙirƙira ciniki ba", "trade_not_created": "Ba a ƙirƙira ciniki ba",
"trade_id_not_found": "Ba a samo cinikin ${tradeId} na ${title} ba.", "trade_id_not_found": "Ba a samo cinikin ${tradeId} na ${title} ba.",
"trade_not_found": "Ba a sami ciniki ba.", "trade_not_found": "Ba a sami ciniki ba.",
"trade_state_pending": "Jira", "trade_state_pending": "Jira",
"trade_state_confirming": "Tabbatar", "trade_state_confirming": "Tabbatar",
"trade_state_trading": "Ciniki", "trade_state_trading": "Ciniki",
@ -386,59 +319,42 @@
"trade_state_timeout": "lokacin da ya ƙare", "trade_state_timeout": "lokacin da ya ƙare",
"trade_state_created": "an halicci", "trade_state_created": "an halicci",
"trade_state_finished": "an kammala", "trade_state_finished": "an kammala",
"change_language": "canja harshen", "change_language": "canja harshen",
"change_language_to": "canja harshen zuwa ${language}?", "change_language_to": "canja harshen zuwa ${language}?",
"paste": "Manna", "paste": "Manna",
"restore_from_seed_placeholder": "Da fatan za a shigar da ko manna maɓallin ku a nan", "restore_from_seed_placeholder": "Da fatan za a shigar da ko manna maɓallin ku a nan",
"add_new_word": "Ƙara kalma sabuwa", "add_new_word": "Ƙara kalma sabuwa",
"incorrect_seed": "rubutun da aka shigar ba shi da inganci.", "incorrect_seed": "rubutun da aka shigar ba shi da inganci.",
"biometric_auth_reason": "Duba hoton yatsa don tantancewa", "biometric_auth_reason": "Duba hoton yatsa don tantancewa",
"version": "Sigar ${currentVersion}", "version": "Sigar ${currentVersion}",
"openalias_alert_title": "An gano adireshin", "openalias_alert_title": "An gano adireshin",
"openalias_alert_content": "Zaka aika kuɗi zuwa \n${recipient_name}", "openalias_alert_content": "Zaka aika kuɗi zuwa \n${recipient_name}",
"card_address": "Adireshin:", "card_address": "Adireshin:",
"buy": "Sayi", "buy": "Sayi",
"sell": "sayar", "sell": "sayar",
"placeholder_transactions": "Za a nuna ma'amalolin ku anan", "placeholder_transactions": "Za a nuna ma'amalolin ku anan",
"placeholder_contacts": "Za a nuna lambobin sadarwar ku anan", "placeholder_contacts": "Za a nuna lambobin sadarwar ku anan",
"template": "Samfura", "template": "Samfura",
"confirm_delete_template": "Wannan aikin zai share wannan samfuri. Kuna so ku ci gaba?", "confirm_delete_template": "Wannan aikin zai share wannan samfuri. Kuna so ku ci gaba?",
"confirm_delete_wallet": "Wannan aikin zai share wannan walat. Kuna so ku ci gaba?", "confirm_delete_wallet": "Wannan aikin zai share wannan walat. Kuna so ku ci gaba?",
"picker_description": "Don zaɓar ChangeNOW ko MorphToken, da farko canja kasuwancin pair din ku", "picker_description": "Don zaɓar ChangeNOW ko MorphToken, da farko canja kasuwancin pair din ku",
"change_wallet_alert_title": "Canja walat yanzu", "change_wallet_alert_title": "Canja walat yanzu",
"change_wallet_alert_content": "Kana so ka canja walat yanzu zuwa ${wallet_name}?", "change_wallet_alert_content": "Kana so ka canja walat yanzu zuwa ${wallet_name}?",
"creating_new_wallet": "Haliccin walat sabuwa", "creating_new_wallet": "Haliccin walat sabuwa",
"creating_new_wallet_error": "Kuskure: ${description}", "creating_new_wallet_error": "Kuskure: ${description}",
"seed_alert_title": "Hankali", "seed_alert_title": "Hankali",
"seed_alert_content": "Irin ita ce kawai hanya don dawo da walat ɗin ku. Kun rubuta shi?", "seed_alert_content": "Irin ita ce kawai hanya don dawo da walat ɗin ku. Kun rubuta shi?",
"seed_alert_back": "juya baya", "seed_alert_back": "juya baya",
"seed_alert_yes": "E, Na yi", "seed_alert_yes": "E, Na yi",
"exchange_sync_alert_content": "Da fatan za a jira har sai an daidaita walat ɗin ku", "exchange_sync_alert_content": "Da fatan za a jira har sai an daidaita walat ɗin ku",
"pre_seed_title": "MUHIMMANCI", "pre_seed_title": "MUHIMMANCI",
"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_button_text": "Ina fahimta. Nuna mini seed din nawa", "pre_seed_button_text": "Ina fahimta. Nuna mini seed din nawa",
"xmr_to_error": "XMR.TO kuskure", "xmr_to_error": "XMR.TO kuskure",
"xmr_to_error_description": "Adadin ba shi da inganci. Maksimum ɗaura 8 digiri bayan decimal point", "xmr_to_error_description": "Adadin ba shi da inganci. Maksimum ɗaura 8 digiri bayan decimal point",
"provider_error": "${provider} kuskure", "provider_error": "${provider} kuskure",
"use_ssl": "Yi amfani da SSL", "use_ssl": "Yi amfani da SSL",
"trusted": "Amintacce", "trusted": "Amintacce",
"color_theme": "Jigon launi", "color_theme": "Jigon launi",
"light_theme": "Haske", "light_theme": "Haske",
"bright_theme": "Mai haske", "bright_theme": "Mai haske",
@ -451,11 +367,9 @@
"transaction_key": "Aikace-aikacen key", "transaction_key": "Aikace-aikacen key",
"confirmations": "Tabbatar", "confirmations": "Tabbatar",
"recipient_address": "Adireshin mai karɓa", "recipient_address": "Adireshin mai karɓa",
"extra_id": "Karin ID:", "extra_id": "Karin ID:",
"destination_tag": "Tambarin makoma:", "destination_tag": "Tambarin makoma:",
"memo": "Memo:", "memo": "Memo:",
"backup": "Ajiyayyen", "backup": "Ajiyayyen",
"change_password": "Canza kalmar shiga", "change_password": "Canza kalmar shiga",
"backup_password": "Ajiyayyen kalmar sirri", "backup_password": "Ajiyayyen kalmar sirri",
@ -463,55 +377,40 @@
"export_backup": "Ajiyayyen fitarwa", "export_backup": "Ajiyayyen fitarwa",
"save_backup_password": "Da fatan za a tabbatar cewa kun adana kalmar sirrin ajiyar ku. Ba za ku iya shigo da fayilolin ajiyar ku ba tare da shi ba.", "save_backup_password": "Da fatan za a tabbatar cewa kun adana kalmar sirrin ajiyar ku. Ba za ku iya shigo da fayilolin ajiyar ku ba tare da shi ba.",
"backup_file": "Ajiyayyen fayil", "backup_file": "Ajiyayyen fayil",
"edit_backup_password": "Shirya Kalmar wucewa ta Ajiyayyen", "edit_backup_password": "Shirya Kalmar wucewa ta Ajiyayyen",
"save_backup_password_alert": "Ajiye kalmar sirri ta ajiya", "save_backup_password_alert": "Ajiye kalmar sirri ta ajiya",
"change_backup_password_alert": "Fayilolin madadin ku na baya ba za su kasance don shigo da sabon kalmar sirri ta madadin ba. Sabuwar kalmar sirri ta ajiya za a yi amfani da ita kawai don sabbin fayilolin madadin. Shin kun tabbata cewa kuna son canza kalmar wucewa?", "change_backup_password_alert": "Fayilolin madadin ku na baya ba za su kasance don shigo da sabon kalmar sirri ta madadin ba. Sabuwar kalmar sirri ta ajiya za a yi amfani da ita kawai don sabbin fayilolin madadin. Shin kun tabbata cewa kuna son canza kalmar wucewa?",
"enter_backup_password": "Shigar da kalmar wucewa ta madadin nan", "enter_backup_password": "Shigar da kalmar wucewa ta madadin nan",
"select_backup_file": "Zaɓi fayil ɗin madadin", "select_backup_file": "Zaɓi fayil ɗin madadin",
"import": "Shigo da", "import": "Shigo da",
"please_select_backup_file": "Da fatan za a zaɓi fayil ɗin madadin kuma shigar da kalmar wucewa ta madadin.", "please_select_backup_file": "Da fatan za a zaɓi fayil ɗin madadin kuma shigar da kalmar wucewa ta madadin.",
"fixed_rate": "Kafaffen ƙima", "fixed_rate": "Kafaffen ƙima",
"fixed_rate_alert": "Za ku iya shigar da adadin karɓa lokacin da aka duba ƙayyadadden zaɓin ƙimar kuɗi. Kuna so ku canza zuwa ƙayyadadden yanayin ƙimar kuɗi?", "fixed_rate_alert": "Za ku iya shigar da adadin karɓa lokacin da aka duba ƙayyadadden zaɓin ƙimar kuɗi. Kuna so ku canza zuwa ƙayyadadden yanayin ƙimar kuɗi?",
"xlm_extra_info": "Don Allah kar a manta da saka Memo ID yayin aika ma'amalar XLM don musayar", "xlm_extra_info": "Don Allah kar a manta da saka Memo ID yayin aika ma'amalar XLM don musayar",
"xrp_extra_info": "Don Allah kar a manta da saka alamar Ƙaddamarwa yayin aika ma'amalar XRP don musayar", "xrp_extra_info": "Don Allah kar a manta da saka alamar Ƙaddamarwa yayin aika ma'amalar XRP don musayar",
"exchange_incorrect_current_wallet_for_xmr": "Idan kana son musanya XMR daga ma'aunin Cake Wallet Monero, da fatan za a fara canza wallet ɗin Monero ɗin ku.", "exchange_incorrect_current_wallet_for_xmr": "Idan kana son musanya XMR daga ma'aunin Cake Wallet Monero, da fatan za a fara canza wallet ɗin Monero ɗin ku.",
"confirmed": "An tabbatar", "confirmed": "An tabbatar",
"unconfirmed": "Ba a tabbatar ba", "unconfirmed": "Ba a tabbatar ba",
"displayable": "Ana iya nunawa", "displayable": "Ana iya nunawa",
"submit_request": "gabatar da bukata", "submit_request": "gabatar da bukata",
"buy_alert_content": "A halin yanzu muna tallafawa kawai siyan Bitcoin da Litecoin. Don siyan Bitcoin ko Litecoin, da fatan za a ƙirƙira ko canza zuwa walat ɗin ku na Bitcoin ko Litecoin.", "buy_alert_content": "A halin yanzu muna tallafawa kawai siyan Bitcoin da Litecoin. Don siyan Bitcoin ko Litecoin, da fatan za a ƙirƙira ko canza zuwa walat ɗin ku na Bitcoin ko Litecoin.",
"sell_alert_content": "A halin yanzu muna tallafawa siyar da Bitcoin da Litecoin kawai. Da fatan za a ƙirƙira ko canza zuwa walat ɗin ku na Bitcoin ko Litecoin.", "sell_alert_content": "A halin yanzu muna tallafawa siyar da Bitcoin da Litecoin kawai. Da fatan za a ƙirƙira ko canza zuwa walat ɗin ku na Bitcoin ko Litecoin.",
"outdated_electrum_wallet_description": "Sabbin walat ɗin Bitcoin da aka kirkira a cikin Cake yanzu suna da nau'in kalma 24. Ya zama dole ka ƙirƙiri sabon walat ɗin Bitcoin kuma canza duk kuɗin ku zuwa sabon walat ɗin kalmomi 24, kuma ku daina amfani da walat tare da iri mai kalma 12. Da fatan za a yi haka nan take don samun kuɗin ku.", "outdated_electrum_wallet_description": "Sabbin walat ɗin Bitcoin da aka kirkira a cikin Cake yanzu suna da nau'in kalma 24. Ya zama dole ka ƙirƙiri sabon walat ɗin Bitcoin kuma canza duk kuɗin ku zuwa sabon walat ɗin kalmomi 24, kuma ku daina amfani da walat tare da iri mai kalma 12. Da fatan za a yi haka nan take don samun kuɗin ku.",
"understand": "na gane", "understand": "na gane",
"apk_update": "apk sabunta", "apk_update": "apk sabunta",
"buy_bitcoin": "Sayi Bitcoin", "buy_bitcoin": "Sayi Bitcoin",
"buy_with": "Saya da", "buy_with": "Saya da",
"moonpay_alert_text": "Darajar adadin dole ne ya zama fiye ko daidai da ${minAmount} ${fiatCurrency}", "moonpay_alert_text": "Darajar adadin dole ne ya zama fiye ko daidai da ${minAmount} ${fiatCurrency}",
"outdated_electrum_wallet_receive_warning": "Idan wannan walat ɗin yana da nau'in kalma 12 kuma an ƙirƙira shi a cikin Cake, KAR KA saka Bitcoin cikin wannan jakar. Duk wani BTC da aka canjawa wuri zuwa wannan walat na iya ɓacewa. Ƙirƙiri sabon walat mai kalmomi 24 (matsa menu a saman dama, zaɓi Wallets, zaɓi Ƙirƙiri Sabon Wallet, sannan zaɓi Bitcoin) kuma NAN nan take matsar da BTC ɗin ku a can. Sabbin (kalmomi 24) BTC wallets daga Cake suna da tsaro", "outdated_electrum_wallet_receive_warning": "Idan wannan walat ɗin yana da nau'in kalma 12 kuma an ƙirƙira shi a cikin Cake, KAR KA saka Bitcoin cikin wannan jakar. Duk wani BTC da aka canjawa wuri zuwa wannan walat na iya ɓacewa. Ƙirƙiri sabon walat mai kalmomi 24 (matsa menu a saman dama, zaɓi Wallets, zaɓi Ƙirƙiri Sabon Wallet, sannan zaɓi Bitcoin) kuma NAN nan take matsar da BTC ɗin ku a can. Sabbin (kalmomi 24) BTC wallets daga Cake suna da tsaro",
"do_not_show_me": "Kar ka sake nuna min wannan", "do_not_show_me": "Kar ka sake nuna min wannan",
"unspent_coins_title": "Tsabar da ba a kashe ba", "unspent_coins_title": "Tsabar da ba a kashe ba",
"unspent_coins_details_title": "Bayanan tsabar kudi da ba a kashe ba", "unspent_coins_details_title": "Bayanan tsabar kudi da ba a kashe ba",
"freeze": "Daskare", "freeze": "Daskare",
"frozen": "Daskararre", "frozen": "Daskararre",
"coin_control": "Sarrafa tsabar kuɗi (na zaɓi)", "coin_control": "Sarrafa tsabar kuɗi (na zaɓi)",
"address_detected": "An gano adireshin", "address_detected": "An gano adireshin",
"address_from_domain": "Wannan adireshin ya fito daga ${domain} akan Unstoppable Domain", "address_from_domain": "Wannan adireshin ya fito daga ${domain} akan Unstoppable Domain",
"add_receiver": "Ƙara wani mai karɓa (na zaɓi)", "add_receiver": "Ƙara wani mai karɓa (na zaɓi)",
"manage_yats": "Sarrafa Yats", "manage_yats": "Sarrafa Yats",
"yat_alert_title": "Aika da karɓar crypto cikin sauƙi tare da Yat", "yat_alert_title": "Aika da karɓar crypto cikin sauƙi tare da Yat",
"yat_alert_content": "Masu amfani da Wallet ɗin Cake yanzu za su iya aikawa da karɓar duk kuɗin da suka fi so tare da sunan mai amfani na tushen emoji iri ɗaya.", "yat_alert_content": "Masu amfani da Wallet ɗin Cake yanzu za su iya aikawa da karɓar duk kuɗin da suka fi so tare da sunan mai amfani na tushen emoji iri ɗaya.",
@ -681,11 +580,10 @@
"contact_list_contacts": "Lambobin sadarwa", "contact_list_contacts": "Lambobin sadarwa",
"contact_list_wallets": "Wallets dina", "contact_list_wallets": "Wallets dina",
"bitcoin_payments_require_1_confirmation": "Akwatin Bitcoin na buɗe 1 sambumbu, da yake za ta samu mintuna 20 ko yawa. Ina kira ga sabuwar lafiya! Zaka sanarwa ta email lokacin da aka samu akwatin samun lambar waya.", "bitcoin_payments_require_1_confirmation": "Akwatin Bitcoin na buɗe 1 sambumbu, da yake za ta samu mintuna 20 ko yawa. Ina kira ga sabuwar lafiya! Zaka sanarwa ta email lokacin da aka samu akwatin samun lambar waya.",
"send_to_this_address" : "Aiko ${currency} ${tag} zuwa adireshin wannan", "send_to_this_address": "Aiko ${currency} ${tag} zuwa adireshin wannan",
"arrive_in_this_address" : "${currency} ${tag} zai je wurin wannan adireshi", "arrive_in_this_address": "${currency} ${tag} zai je wurin wannan adireshi",
"do_not_send": "Kada ka aika", "do_not_send": "Kada ka aika",
"error_dialog_content": "Ai, yanzu muka ga alamar kuskure. \n\nDa fatan, aika rahoton kuskuren da muka kira zuwa gasar tsarinmu don gaskiyar shirya.", "error_dialog_content": "Ai, yanzu muka ga alamar kuskure. \n\nDa fatan, aika rahoton kuskuren da muka kira zuwa gasar tsarinmu don gaskiyar shirya.",
"scan_qr_code": "Gani QR kodin",
"cold_or_recover_wallet": "Samun kashi na baya ko samun kashi na kasa", "cold_or_recover_wallet": "Samun kashi na baya ko samun kashi na kasa",
"please_wait": "Don Allah a rufe", "please_wait": "Don Allah a rufe",
"sweeping_wallet": "Kashi na kasa", "sweeping_wallet": "Kashi na kasa",
@ -705,10 +603,13 @@
"frozen_balance": "Falin kuma maɓallin", "frozen_balance": "Falin kuma maɓallin",
"settings": "Saiti", "settings": "Saiti",
"sell_monero_com_alert_content": "Selling Monero bai sami ƙarshen mai bukatar samun ba", "sell_monero_com_alert_content": "Selling Monero bai sami ƙarshen mai bukatar samun ba",
"error_text_input_below_minimum_limit" : "Kudin ba a kamai", "error_text_input_below_minimum_limit": "Kudin ba a kamai",
"error_text_input_above_maximum_limit" : "Kudin da ya kamata", "error_text_input_above_maximum_limit": "Kudin da ya kamata",
"show_market_place" :"Nuna dan kasuwa", "show_market_place": "Nuna dan kasuwa",
"prevent_screenshots": "Fada lambobi da jarrabobi na kayan lambobi", "prevent_screenshots": "Fada lambobi da jarrabobi na kayan lambobi",
"disable_buy": "Kashe alama", "disable_buy": "Kashe alama",
"disable_sell": "Kashe karbuwa" "disable_sell": "Kashe karbuwa",
} "available_balance_description": "Ma'auni mai samuwa” ko ”,Tabbataccen Ma'auni”, kudade ne da za a iya kashewa nan da nan. Idan kudade sun bayyana a cikin ƙananan ma'auni amma ba babban ma'auni ba, to dole ne ku jira 'yan mintoci kaɗan don kudaden shiga don samun ƙarin tabbaci na hanyar sadarwa. Bayan sun sami ƙarin tabbaci, za a kashe su.",
"syncing_wallet_alert_title": "Walat ɗin ku yana aiki tare",
"syncing_wallet_alert_content": "Ma'aunin ku da lissafin ma'amala bazai cika ba har sai an ce \"SYNCHRONIZED\" a saman. Danna/matsa don ƙarin koyo."
}

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -14,14 +14,14 @@ TYPES=($MONERO_COM $CAKEWALLET $HAVEN)
APP_ANDROID_TYPE=$1 APP_ANDROID_TYPE=$1
MONERO_COM_NAME="Monero.com" MONERO_COM_NAME="Monero.com"
MONERO_COM_VERSION="1.3.7" MONERO_COM_VERSION="1.3.8"
MONERO_COM_BUILD_NUMBER=50 MONERO_COM_BUILD_NUMBER=51
MONERO_COM_BUNDLE_ID="com.monero.app" MONERO_COM_BUNDLE_ID="com.monero.app"
MONERO_COM_PACKAGE="com.monero.app" MONERO_COM_PACKAGE="com.monero.app"
CAKEWALLET_NAME="Cake Wallet" CAKEWALLET_NAME="Cake Wallet"
CAKEWALLET_VERSION="4.6.6" CAKEWALLET_VERSION="4.6.7"
CAKEWALLET_BUILD_NUMBER=160 CAKEWALLET_BUILD_NUMBER=161
CAKEWALLET_BUNDLE_ID="com.cakewallet.cake_wallet" CAKEWALLET_BUNDLE_ID="com.cakewallet.cake_wallet"
CAKEWALLET_PACKAGE="com.cakewallet.cake_wallet" CAKEWALLET_PACKAGE="com.cakewallet.cake_wallet"

23
scripts/append_translation.sh Executable file
View file

@ -0,0 +1,23 @@
#!/bin/bash
# to use on Mac first install the translation shell `brew install translate-shell`
# then install the jq `brew install jq`
# then run this file with the English key and value that you want to be translated
# `./append_translation.sh "greetings" "Hello World!"`
# if you get an error `command not found`
# give the correct permissions to this file using `chmod 777 append_translation.sh`
langs=("ar" "bg" "cs" "de" "en" "es" "fr" "ha" "hi" "hr" "id" "it" "ja" "ko" "my" "nl" "pl" "pt" "ru" "th" "tr" "uk" "ur" "yo" "zh")
name=$1
text=$2
for lang in "${langs[@]}"; do
translation="$(trans en:$lang --brief "$text")"
# Use jq to add the new key-value pair to the JSON object
jq_result=$(jq '. += { "'"$name"'": "'"$translation"'" }' ../res/values/strings_$lang.arb)
echo "$jq_result" > ../res/values/strings_$lang.arb
echo 'Added { "'"$name"'": "'"$translation"'" } to '"strings_$lang.arb"''
done

View file

@ -13,13 +13,13 @@ TYPES=($MONERO_COM $CAKEWALLET $HAVEN)
APP_IOS_TYPE=$1 APP_IOS_TYPE=$1
MONERO_COM_NAME="Monero.com" MONERO_COM_NAME="Monero.com"
MONERO_COM_VERSION="1.3.7" MONERO_COM_VERSION="1.3.8"
MONERO_COM_BUILD_NUMBER=48 MONERO_COM_BUILD_NUMBER=49
MONERO_COM_BUNDLE_ID="com.cakewallet.monero" MONERO_COM_BUNDLE_ID="com.cakewallet.monero"
CAKEWALLET_NAME="Cake Wallet" CAKEWALLET_NAME="Cake Wallet"
CAKEWALLET_VERSION="4.6.6" CAKEWALLET_VERSION="4.6.7"
CAKEWALLET_BUILD_NUMBER=155 CAKEWALLET_BUILD_NUMBER=159
CAKEWALLET_BUNDLE_ID="com.fotolockr.cakewallet" CAKEWALLET_BUNDLE_ID="com.fotolockr.cakewallet"
HAVEN_NAME="Haven" HAVEN_NAME="Haven"

View file

@ -15,8 +15,8 @@ if [ -n "$1" ]; then
fi fi
CAKEWALLET_NAME="Cake Wallet" CAKEWALLET_NAME="Cake Wallet"
CAKEWALLET_VERSION="1.0.5" CAKEWALLET_VERSION="1.0.6"
CAKEWALLET_BUILD_NUMBER=24 CAKEWALLET_BUILD_NUMBER=25
CAKEWALLET_BUNDLE_ID="com.fotolockr.cakewallet" CAKEWALLET_BUNDLE_ID="com.fotolockr.cakewallet"
if ! [[ " ${TYPES[*]} " =~ " ${APP_MACOS_TYPE} " ]]; then if ! [[ " ${TYPES[*]} " =~ " ${APP_MACOS_TYPE} " ]]; then