Merge branch 'main' of https://github.com/cake-tech/cake_wallet into CW-118-Allow-disabling-of-fiat

 Conflicts:
	res/values/strings_de.arb
	res/values/strings_en.arb
	res/values/strings_es.arb
	res/values/strings_fr.arb
	res/values/strings_hi.arb
	res/values/strings_hr.arb
	res/values/strings_it.arb
	res/values/strings_ja.arb
	res/values/strings_ko.arb
	res/values/strings_nl.arb
	res/values/strings_pl.arb
	res/values/strings_pt.arb
	res/values/strings_ru.arb
	res/values/strings_uk.arb
	res/values/strings_zh.arb
This commit is contained in:
OmarHatem 2022-12-08 14:01:20 +02:00
commit fddac23b94
33 changed files with 508 additions and 254 deletions

View file

@ -35,6 +35,7 @@ import 'package:cake_wallet/view_model/settings/display_settings_view_model.dart
import 'package:cake_wallet/view_model/settings/other_settings_view_model.dart';
import 'package:cake_wallet/view_model/settings/privacy_settings_view_model.dart';
import 'package:cake_wallet/view_model/settings/security_settings_view_model.dart';
import 'package:cake_wallet/view_model/advanced_privacy_settings_view_model.dart';
import 'package:cw_core/unspent_coins_info.dart';
import 'package:cake_wallet/core/backup_service.dart';
import 'package:cw_core/wallet_service.dart';
@ -159,6 +160,7 @@ import 'package:cake_wallet/anypay/any_pay_payment_committed_info.dart';
import 'package:cake_wallet/ionia/ionia_any_pay_payment_info.dart';
import 'package:cake_wallet/src/screens/receive/fullscreen_qr_page.dart';
import 'package:cake_wallet/core/wallet_loading_service.dart';
import 'package:cw_core/crypto_currency.dart';
final getIt = GetIt.instance;
@ -349,7 +351,7 @@ Future setup(
onAuthenticationFinished: onAuthFinished,
closable: closable ?? false));
getIt.registerFactory(() =>
getIt.registerFactory(() =>
BalancePage(dashboardViewModel: getIt.get<DashboardViewModel>(), settingsStore: getIt.get<SettingsStore>()));
getIt.registerFactory<DashboardPage>(() => DashboardPage( balancePage: getIt.get<BalancePage>(), walletViewModel: getIt.get<DashboardViewModel>(), addressListViewModel: getIt.get<WalletAddressListViewModel>()));
@ -471,12 +473,11 @@ Future setup(
(ContactRecord? contact, _) =>
ContactViewModel(_contactSource, contact: contact));
getIt.registerFactory(
() => ContactListViewModel(_contactSource, _walletInfoSource));
getIt.registerFactoryParam<ContactListViewModel, CryptoCurrency?, void>(
(CryptoCurrency? cur, _) => ContactListViewModel(_contactSource, _walletInfoSource, cur));
getIt.registerFactoryParam<ContactListPage, bool, void>(
(bool isEditable, _) => ContactListPage(getIt.get<ContactListViewModel>(),
isEditable: isEditable));
getIt.registerFactoryParam<ContactListPage, CryptoCurrency?, void>((CryptoCurrency? cur, _)
=> ContactListPage(getIt.get<ContactListViewModel>(param1: cur)));
getIt.registerFactoryParam<ContactPage, ContactRecord?, void>(
(ContactRecord? contact, _) =>
@ -498,8 +499,12 @@ Future setup(
getIt.registerFactory(() => OtherSettingsPage(getIt.get<OtherSettingsViewModel>()));
getIt.registerFactory(() =>
NodeCreateOrEditViewModel(_nodeSource, getIt.get<AppStore>().wallet!));
getIt.registerFactoryParam<NodeCreateOrEditViewModel, WalletType?, void>(
(WalletType? type, _) => NodeCreateOrEditViewModel(
_nodeSource,
type ?? getIt.get<AppStore>().wallet!.type,
getIt.get<SettingsStore>(),
));
getIt.registerFactory(
() => NodeCreateOrEditPage(getIt.get<NodeCreateOrEditViewModel>()));
@ -698,7 +703,7 @@ Future setup(
getIt.registerFactoryParam<FullscreenQRPage, String, bool>(
(String qrData, bool isLight) => FullscreenQRPage(qrData: qrData, isLight: isLight,));
getIt.registerFactory(() => IoniaApi());
getIt.registerFactory(() => AnyPayApi());
@ -718,7 +723,7 @@ Future setup(
getIt.registerFactoryParam<IoniaMerchPurchaseViewModel, double, IoniaMerchant>((double amount, merchant) {
return IoniaMerchPurchaseViewModel(
ioniaAnyPayService: getIt.get<IoniaAnyPay>(),
ioniaAnyPayService: getIt.get<IoniaAnyPay>(),
amount: amount,
ioniaMerchant: merchant,
sendViewModel: getIt.get<SendViewModel>()
@ -761,31 +766,31 @@ Future setup(
ioniaService: getIt.get<IoniaService>(),
giftCard: giftCard);
});
getIt.registerFactoryParam<IoniaCustomTipViewModel, List, void>((List args, _) {
final amount = args[0] as double;
final merchant = args[1] as IoniaMerchant;
final tip = args[2] as IoniaTip;
return IoniaCustomTipViewModel(amount: amount, tip: tip, ioniaMerchant: merchant);
});
getIt.registerFactoryParam<IoniaGiftCardDetailPage, IoniaGiftCard, void>((IoniaGiftCard giftCard, _) {
return IoniaGiftCardDetailPage(getIt.get<IoniaGiftCardDetailsViewModel>(param1: giftCard));
});
getIt.registerFactoryParam<IoniaMoreOptionsPage, List, void>((List args, _){
final giftCard = args.first as IoniaGiftCard;
return IoniaMoreOptionsPage(giftCard);
return IoniaMoreOptionsPage(giftCard);
});
getIt.registerFactoryParam<IoniaCustomRedeemViewModel, IoniaGiftCard, void>((IoniaGiftCard giftCard, _) => IoniaCustomRedeemViewModel(giftCard));
getIt.registerFactoryParam<IoniaCustomRedeemPage, List, void>((List args, _){
final giftCard = args.first as IoniaGiftCard;
return IoniaCustomRedeemPage(getIt.get<IoniaCustomRedeemViewModel>(param1: giftCard) );
return IoniaCustomRedeemPage(getIt.get<IoniaCustomRedeemViewModel>(param1: giftCard) );
});
@ -814,5 +819,8 @@ Future setup(
(IoniaAnyPayPaymentInfo paymentInfo, AnyPayPaymentCommittedInfo committedInfo)
=> IoniaPaymentStatusPage(getIt.get<IoniaPaymentStatusViewModel>(param1: paymentInfo, param2: committedInfo)));
getIt.registerFactoryParam<AdvancedPrivacySettingsViewModel, WalletType, void>((type, _) =>
AdvancedPrivacySettingsViewModel(type, getIt.get<SettingsStore>()));
_isSetupFinished = true;
}

View file

@ -261,7 +261,7 @@ class AppState extends State<App> with SingleTickerProviderStateMixin {
final statusBarColor = Colors.transparent;
final authenticationStore = getIt.get<AuthenticationStore>();
final initialRoute =
authenticationStore.state == AuthenticationState.denied
authenticationStore.state == AuthenticationState.uninitialized
? Routes.disclaimer
: Routes.login;
final currentTheme = settingsStore.currentTheme;

View file

@ -22,9 +22,9 @@ Future<void> bootstrap(GlobalKey<NavigatorState> navigatorKey) async {
final currentWalletName = getIt
.get<SharedPreferences>()
.getString(PreferencesKey.currentWalletName);
authenticationStore.state = currentWalletName == null
? AuthenticationState.denied
: AuthenticationState.installed;
if (currentWalletName != null) {
authenticationStore.state = AuthenticationState.installed;
}
startAuthenticationStateChange(authenticationStore, navigatorKey);
startCurrentWalletChangeReaction(

View file

@ -26,10 +26,5 @@ void startAuthenticationStateChange(AuthenticationStore authenticationStore,
await navigatorKey.currentState!.pushNamedAndRemoveUntil(Routes.dashboard, (route) => false);
return;
}
if (state == AuthenticationState.denied) {
await navigatorKey.currentState!.pushNamedAndRemoveUntil(Routes.welcome, (_) => false);
return;
}
});
}

View file

@ -15,6 +15,7 @@ import 'package:cake_wallet/src/screens/ionia/cards/ionia_custom_redeem_page.dar
import 'package:cake_wallet/src/screens/ionia/cards/ionia_custom_tip_page.dart';
import 'package:cake_wallet/src/screens/ionia/cards/ionia_gift_card_detail_page.dart';
import 'package:cake_wallet/src/screens/ionia/cards/ionia_more_options_page.dart';
import 'package:cake_wallet/src/screens/new_wallet/advanced_privacy_settings_page.dart';
import 'package:cake_wallet/src/screens/order_details/order_details_page.dart';
import 'package:cake_wallet/src/screens/pin_code/pin_code_widget.dart';
import 'package:cake_wallet/src/screens/restore/restore_from_backup_page.dart';
@ -25,6 +26,8 @@ import 'package:cake_wallet/src/screens/support/support_page.dart';
import 'package:cake_wallet/src/screens/unspent_coins/unspent_coins_details_page.dart';
import 'package:cake_wallet/src/screens/unspent_coins/unspent_coins_list_page.dart';
import 'package:cake_wallet/view_model/monero_account_list/account_list_item.dart';
import 'package:cake_wallet/view_model/node_list/node_create_or_edit_view_model.dart';
import 'package:cake_wallet/view_model/advanced_privacy_settings_view_model.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:cake_wallet/routes.dart';
@ -77,6 +80,7 @@ import 'package:cake_wallet/src/screens/ionia/ionia.dart';
import 'package:cake_wallet/src/screens/ionia/cards/ionia_payment_status_page.dart';
import 'package:cake_wallet/anypay/any_pay_payment_committed_info.dart';
import 'package:cake_wallet/ionia/ionia_any_pay_payment_info.dart';
import 'package:cw_core/crypto_currency.dart';
late RouteSettings currentRouteSettings;
@ -317,11 +321,13 @@ Route<dynamic> createRoute(RouteSettings settings) {
case Routes.addressBook:
return MaterialPageRoute<void>(
builder: (_) => getIt.get<ContactListPage>(param1: true));
builder: (_) =>
getIt.get<ContactListPage>());
case Routes.pickerAddressBook:
final selectedCurrency = settings.arguments as CryptoCurrency;
return MaterialPageRoute<void>(
builder: (_) => getIt.get<ContactListPage>(param1: false));
builder: (_) => getIt.get<ContactListPage>(param1: selectedCurrency));
case Routes.addressBookAddContact:
return CupertinoPageRoute<void>(
@ -491,6 +497,15 @@ Route<dynamic> createRoute(RouteSettings settings) {
case Routes.onramperPage:
return CupertinoPageRoute<void>(builder: (_) => getIt.get<OnRamperPage>());
case Routes.advancedPrivacySettings:
final type = settings.arguments as WalletType;
return CupertinoPageRoute<void>(
builder: (_) => AdvancedPrivacySettingsPage(
getIt.get<AdvancedPrivacySettingsViewModel>(param1: type),
getIt.get<NodeCreateOrEditViewModel>(param1: type),
));
default:
return MaterialPageRoute<void>(
builder: (_) => Scaffold(

View file

@ -81,4 +81,5 @@ class Routes {
static const privacyPage = '/privacy_page';
static const displaySettingsPage = '/display_settings_page';
static const otherSettingsPage = '/other_settings_page';
static const advancedPrivacySettings = '/advanced_privacy_settings';
}

View file

@ -9,24 +9,22 @@ import 'package:flutter_mobx/flutter_mobx.dart';
import 'package:flutter_slidable/flutter_slidable.dart';
import 'package:cake_wallet/routes.dart';
import 'package:cake_wallet/generated/i18n.dart';
import 'package:cw_core/crypto_currency.dart';
import 'package:cake_wallet/src/screens/base_page.dart';
import 'package:cake_wallet/src/widgets/alert_with_two_actions.dart';
import 'package:cake_wallet/view_model/contact_list/contact_list_view_model.dart';
import 'package:cake_wallet/src/widgets/collapsible_standart_list.dart';
class ContactListPage extends BasePage {
ContactListPage(this.contactListViewModel, {this.isEditable = true});
ContactListPage(this.contactListViewModel);
final ContactListViewModel contactListViewModel;
final bool isEditable;
@override
String get title => S.current.address_book;
@override
Widget? trailing(BuildContext context) {
if (!isEditable) {
if (!contactListViewModel.isEditable) {
return null;
}
@ -60,11 +58,14 @@ class ContactListPage extends BasePage {
@override
Widget body(BuildContext context) {
return Container(
padding: EdgeInsets.only(top: 20.0, bottom: 20.0),
child: Observer(
builder: (_) {
return CollapsibleSectionList(
builder: (_) {
final contacts = contactListViewModel.contactsToShow;
final walletContacts = contactListViewModel.walletContactsToShow;
return CollapsibleSectionList(
context: context,
sectionCount: 2,
themeColor: Theme.of(context).primaryTextTheme.headline6!.color!,
@ -82,35 +83,37 @@ class ContactListPage extends BasePage {
child: Text(title, style: TextStyle(fontSize: 36)));
},
itemCounter: (int sectionIndex) => sectionIndex == 0
? contactListViewModel.walletContacts.length
: contactListViewModel.contacts.length,
? walletContacts.length
: contacts.length,
itemBuilder: (_, sectionIndex, index) {
if (sectionIndex == 0) {
final walletInfo = contactListViewModel.walletContacts[index];
final walletInfo = walletContacts[index];
return generateRaw(context, walletInfo);
}
final contact = contactListViewModel.contacts[index];
final contact = contacts[index];
final content = generateRaw(context, contact);
return !isEditable
? content
: Slidable(
return contactListViewModel.isEditable
? Slidable(
key: Key('${contact.key}'),
endActionPane: _actionPane(context, contact),
child: content,
);
)
: content;
},
);
},
));
);})
);
}
Widget generateRaw(BuildContext context, ContactBase contact) {
final image = _getCurrencyImage(contact.type);
final image = contact.type.iconPath;
final currencyIcon = image != null ? Image.asset(image, height: 24, width: 24)
: const SizedBox(height: 24, width: 24);
return GestureDetector(
onTap: () async {
if (!isEditable) {
if (!contactListViewModel.isEditable) {
Navigator.of(context).pop(contact);
return;
}
@ -131,12 +134,10 @@ class ContactListPage extends BasePage {
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
image ?? Offstage(),
currencyIcon,
Expanded(
child: Padding(
padding: image != null
? EdgeInsets.only(left: 12)
: EdgeInsets.only(left: 0),
padding: EdgeInsets.only(left: 12),
child: Text(
contact.name,
style: TextStyle(
@ -152,69 +153,6 @@ class ContactListPage extends BasePage {
);
}
Image? _getCurrencyImage(CryptoCurrency currency) {
Image? image;
switch (currency) {
case CryptoCurrency.xmr:
image =
Image.asset('assets/images/monero_logo.png', height: 24, width: 24);
break;
case CryptoCurrency.ada:
image = Image.asset('assets/images/ada.png', height: 24, width: 24);
break;
case CryptoCurrency.bch:
image = Image.asset('assets/images/bch.png', height: 24, width: 24);
break;
case CryptoCurrency.bnb:
image = Image.asset('assets/images/bnb.png', height: 24, width: 24);
break;
case CryptoCurrency.btc:
image = Image.asset('assets/images/bitcoin.png', height: 24, width: 24);
break;
case CryptoCurrency.dai:
image = Image.asset('assets/images/dai.png', height: 24, width: 24);
break;
case CryptoCurrency.dash:
image = Image.asset('assets/images/dash.png', height: 24, width: 24);
break;
case CryptoCurrency.eos:
image = Image.asset('assets/images/eos.png', height: 24, width: 24);
break;
case CryptoCurrency.eth:
image = Image.asset('assets/images/eth.png', height: 24, width: 24);
break;
case CryptoCurrency.ltc:
image =
Image.asset('assets/images/litecoin.png', height: 24, width: 24);
break;
case CryptoCurrency.nano:
image = Image.asset('assets/images/nano.png', height: 24, width: 24);
break;
case CryptoCurrency.trx:
image = Image.asset('assets/images/trx.png', height: 24, width: 24);
break;
case CryptoCurrency.usdt:
image = Image.asset('assets/images/usdt.png', height: 24, width: 24);
break;
case CryptoCurrency.usdterc20:
image = Image.asset('assets/images/usdterc.png', height: 24, width: 24);
break;
case CryptoCurrency.xlm:
image = Image.asset('assets/images/xlm.png', height: 24, width: 24);
break;
case CryptoCurrency.xrp:
image = Image.asset('assets/images/xrp.png', height: 24, width: 24);
break;
case CryptoCurrency.xhv:
image = Image.asset('assets/images/haven_logo.png', height: 24, width: 24);
break;
default:
image = null;
}
return image;
}
Future<bool> showAlertDialog(BuildContext context) async {
return await showPopUp<bool>(
context: context,

View file

@ -395,7 +395,8 @@ class ExchangeCardState extends State<ExchangeCard> {
buttonColor: widget.addressButtonsColor,
validator: widget.addressTextFieldValidator,
onPushPasteButton: widget.onPushPasteButton,
onPushAddressBookButton: widget.onPushAddressBookButton
onPushAddressBookButton: widget.onPushAddressBookButton,
selectedCurrency: _selectedCurrency
),
)

View file

@ -0,0 +1,104 @@
import 'package:cake_wallet/src/screens/nodes/widgets/node_form.dart';
import 'package:cake_wallet/src/screens/settings/widgets/settings_switcher_cell.dart';
import 'package:cake_wallet/view_model/node_list/node_create_or_edit_view_model.dart';
import 'package:cake_wallet/view_model/advanced_privacy_settings_view_model.dart';
import 'package:flutter_mobx/flutter_mobx.dart';
import 'package:flutter/material.dart';
import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/src/screens/base_page.dart';
import 'package:cake_wallet/src/widgets/primary_button.dart';
import 'package:cake_wallet/src/widgets/scollable_with_bottom_section.dart';
class AdvancedPrivacySettingsPage extends BasePage {
AdvancedPrivacySettingsPage(this.advancedPrivacySettingsViewModel, this.nodeViewModel);
final AdvancedPrivacySettingsViewModel advancedPrivacySettingsViewModel;
final NodeCreateOrEditViewModel nodeViewModel;
@override
String get title => S.current.privacy_settings;
@override
Widget body(BuildContext context) =>
AdvancedPrivacySettingsBody(advancedPrivacySettingsViewModel, nodeViewModel);
}
class AdvancedPrivacySettingsBody extends StatefulWidget {
const AdvancedPrivacySettingsBody(this.privacySettingsViewModel, this.nodeViewModel, {Key? key})
: super(key: key);
final AdvancedPrivacySettingsViewModel privacySettingsViewModel;
final NodeCreateOrEditViewModel nodeViewModel;
@override
_AdvancedPrivacySettingsBodyState createState() => _AdvancedPrivacySettingsBodyState();
}
class _AdvancedPrivacySettingsBodyState extends State<AdvancedPrivacySettingsBody> {
_AdvancedPrivacySettingsBodyState();
final _formKey = GlobalKey<FormState>();
@override
Widget build(BuildContext context) {
return Container(
padding: EdgeInsets.only(top: 24),
child: ScrollableWithBottomSection(
contentPadding: EdgeInsets.only(bottom: 24),
content: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
...widget.privacySettingsViewModel.settings.map(
(item) => Observer(
builder: (_) => SettingsSwitcherCell(
title: item.title,
value: item.value(),
onValueChange: item.onValueChange,
),
),
),
Observer(
builder: (_) {
if (widget.privacySettingsViewModel.addCustomNode) {
return Padding(
padding: EdgeInsets.only(left: 24, right: 24, top: 24),
child: NodeForm(
formKey: _formKey,
nodeViewModel: widget.nodeViewModel,
),
);
}
return const SizedBox();
},
),
],
),
bottomSectionPadding: EdgeInsets.all(24),
bottomSection: Column(
children: [
LoadingPrimaryButton(
onPressed: () {
widget.nodeViewModel.save(saveAsCurrent: true);
Navigator.pop(context);
},
text: S.of(context).continue_text,
color: Theme.of(context).accentTextTheme.bodyText1!.color!,
textColor: Colors.white,
),
const SizedBox(height: 25),
Padding(
padding: EdgeInsets.symmetric(horizontal: MediaQuery.of(context).size.width * 0.15),
child: Text(
S.of(context).settings_can_be_changed_later,
textAlign: TextAlign.center,
style: TextStyle(
color: Theme.of(context).accentTextTheme.headline2?.color,
),
),
),
],
),
),
);
}
}

View file

@ -200,18 +200,30 @@ class _WalletNameFormState extends State<WalletNameForm> {
]
]),
bottomSectionPadding:
EdgeInsets.only(left: 24, right: 24, bottom: 24),
bottomSection: Observer(
builder: (context) {
return LoadingPrimaryButton(
onPressed: _confirmForm,
text: S.of(context).seed_language_next,
color: Colors.green,
textColor: Colors.white,
isLoading: _walletNewVM.state is IsExecutingState,
isDisabled: _walletNewVM.name.isEmpty,
);
},
EdgeInsets.all(24),
bottomSection: Column(
children: [
Observer(
builder: (context) {
return LoadingPrimaryButton(
onPressed: _confirmForm,
text: S.of(context).seed_language_next,
color: Colors.green,
textColor: Colors.white,
isLoading: _walletNewVM.state is IsExecutingState,
isDisabled: _walletNewVM.name.isEmpty,
);
},
),
const SizedBox(height: 25),
GestureDetector(
onTap: () {
Navigator.of(context)
.pushNamed(Routes.advancedPrivacySettings, arguments: _walletNewVM.type);
},
child: Text(S.of(context).advanced_privacy_settings),
),
],
)),
);
}

View file

@ -1,16 +1,13 @@
import 'package:cake_wallet/core/execution_state.dart';
import 'package:cake_wallet/src/screens/nodes/widgets/node_form.dart';
import 'package:cake_wallet/src/widgets/alert_with_one_action.dart';
import 'package:cake_wallet/src/widgets/standard_checkbox.dart';
import 'package:cake_wallet/utils/show_pop_up.dart';
import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter_mobx/flutter_mobx.dart';
import 'package:mobx/mobx.dart';
import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/core/node_address_validator.dart';
import 'package:cake_wallet/core/node_port_validator.dart';
import 'package:cake_wallet/src/widgets/primary_button.dart';
import 'package:cake_wallet/src/widgets/base_text_form_field.dart';
import 'package:cake_wallet/src/screens/base_page.dart';
import 'package:cake_wallet/src/widgets/scollable_with_bottom_section.dart';
import 'package:cake_wallet/view_model/node_list/node_create_or_edit_view_model.dart';
@ -108,91 +105,10 @@ class NodeCreateOrEditPage extends BasePage {
padding: EdgeInsets.only(left: 24, right: 24),
child: ScrollableWithBottomSection(
contentPadding: EdgeInsets.only(bottom: 24.0),
content: Form(
key: _formKey,
child: Column(
children: <Widget>[
Row(
children: <Widget>[
Expanded(
child: BaseTextFormField(
controller: _addressController,
hintText: S.of(context).node_address,
validator: NodeAddressValidator(),
)
)
],
),
SizedBox(height: 10.0),
Row(
children: <Widget>[
Expanded(
child: BaseTextFormField(
controller: _portController,
hintText: S.of(context).node_port,
keyboardType: TextInputType.numberWithOptions(
signed: false, decimal: false),
validator: NodePortValidator(),
)
)
],
),
SizedBox(height: 10.0),
if (nodeCreateOrEditViewModel.hasAuthCredentials) ...[
Row(
children: <Widget>[
Expanded(
child: BaseTextFormField(
controller: _loginController,
hintText: S.of(context).login,
)
)
],
),
SizedBox(height: 10.0),
Row(
children: <Widget>[
Expanded(
child: BaseTextFormField(
controller: _passwordController,
hintText: S.of(context).password,
)
)
],
),
Padding(
padding: EdgeInsets.only(top: 20),
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
mainAxisSize: MainAxisSize.max,
children: [
Observer(
builder: (_) => StandardCheckbox(
value: nodeCreateOrEditViewModel.useSSL,
onChanged: (value) =>
nodeCreateOrEditViewModel.useSSL = value,
caption: S.of(context).use_ssl,
))
],
)),
Padding(
padding: EdgeInsets.only(top: 20),
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
mainAxisSize: MainAxisSize.max,
children: [
Observer(
builder: (_) => StandardCheckbox(
value: nodeCreateOrEditViewModel.trusted,
onChanged: (value) =>
nodeCreateOrEditViewModel.trusted = value,
caption: S.of(context).trusted,
))
],
)),
]
],
)),
content: NodeForm(
formKey: _formKey,
nodeViewModel: nodeCreateOrEditViewModel,
),
bottomSectionPadding: EdgeInsets.only(bottom: 24),
bottomSection: Observer(
builder: (_) => Row(

View file

@ -0,0 +1,151 @@
import 'package:cake_wallet/core/node_address_validator.dart';
import 'package:cake_wallet/core/node_port_validator.dart';
import 'package:cake_wallet/src/widgets/base_text_form_field.dart';
import 'package:cake_wallet/src/widgets/standard_checkbox.dart';
import 'package:cake_wallet/view_model/node_list/node_create_or_edit_view_model.dart';
import 'package:flutter/material.dart';
import 'package:flutter_mobx/flutter_mobx.dart';
import 'package:cake_wallet/generated/i18n.dart';
import 'package:mobx/mobx.dart';
class NodeForm extends StatelessWidget {
NodeForm({
required this.nodeViewModel,
required this.formKey,
}) : _addressController = TextEditingController(),
_portController = TextEditingController(),
_loginController = TextEditingController(),
_passwordController = TextEditingController() {
reaction((_) => nodeViewModel.address, (String address) {
if (address != _addressController.text) {
_addressController.text = address;
}
});
reaction((_) => nodeViewModel.port, (String port) {
if (port != _portController.text) {
_portController.text = port;
}
});
if (nodeViewModel.hasAuthCredentials) {
reaction((_) => nodeViewModel.login, (String login) {
if (login != _loginController.text) {
_loginController.text = login;
}
});
reaction((_) => nodeViewModel.password, (String password) {
if (password != _passwordController.text) {
_passwordController.text = password;
}
});
}
_addressController
.addListener(() => nodeViewModel.address = _addressController.text);
_portController
.addListener(() => nodeViewModel.port = _portController.text);
_loginController
.addListener(() => nodeViewModel.login = _loginController.text);
_passwordController
.addListener(() => nodeViewModel.password = _passwordController.text);
}
final NodeCreateOrEditViewModel nodeViewModel;
final GlobalKey<FormState> formKey;
final TextEditingController _addressController;
final TextEditingController _portController;
final TextEditingController _loginController;
final TextEditingController _passwordController;
@override
Widget build(BuildContext context) {
return Form(
key: formKey,
child: Column(
children: <Widget>[
Row(
children: <Widget>[
Expanded(
child: BaseTextFormField(
controller: _addressController,
hintText: S.of(context).node_address,
validator: NodeAddressValidator(),
),
)
],
),
SizedBox(height: 10.0),
Row(
children: <Widget>[
Expanded(
child: BaseTextFormField(
controller: _portController,
hintText: S.of(context).node_port,
keyboardType: TextInputType.numberWithOptions(
signed: false, decimal: false),
validator: NodePortValidator(),
))
],
),
SizedBox(height: 10.0),
if (nodeViewModel.hasAuthCredentials) ...[
Row(
children: <Widget>[
Expanded(
child: BaseTextFormField(
controller: _loginController,
hintText: S.of(context).login,
))
],
),
SizedBox(height: 10.0),
Row(
children: <Widget>[
Expanded(
child: BaseTextFormField(
controller: _passwordController,
hintText: S.of(context).password,
))
],
),
Padding(
padding: EdgeInsets.only(top: 20),
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
mainAxisSize: MainAxisSize.max,
children: [
Observer(
builder: (_) => StandardCheckbox(
value: nodeViewModel.useSSL,
onChanged: (value) => nodeViewModel.useSSL = value,
caption: S.of(context).use_ssl,
),
)
],
),
),
Padding(
padding: EdgeInsets.only(top: 20),
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
mainAxisSize: MainAxisSize.max,
children: [
Observer(
builder: (_) => StandardCheckbox(
value: nodeViewModel.trusted,
onChanged: (value) => nodeViewModel.trusted = value,
caption: S.of(context).trusted,
),
),
],
),
),
]
],
),
);
}
}

View file

@ -154,6 +154,7 @@ class SendCardState extends State<SendCard>
await output.fetchParsedAddress(context);
},
validator: validator,
selectedCurrency: sendViewModel.currency,
);
}),
if (output.isParsedAddress) Padding(

View file

@ -4,6 +4,7 @@ import 'package:cake_wallet/routes.dart';
import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/entities/qr_scanner.dart';
import 'package:cake_wallet/entities/contact_base.dart';
import 'package:cw_core/crypto_currency.dart';
enum AddressTextFieldOption { paste, qrCode, addressBook }
@ -26,7 +27,8 @@ class AddressTextField extends StatelessWidget {
this.hintStyle,
this.validator,
this.onPushPasteButton,
this.onPushAddressBookButton});
this.onPushAddressBookButton,
this.selectedCurrency});
static const prefixIconWidth = 34.0;
static const prefixIconHeight = 34.0;
@ -47,6 +49,7 @@ class AddressTextField extends StatelessWidget {
final FocusNode? focusNode;
final Function(BuildContext context)? onPushPasteButton;
final Function(BuildContext context)? onPushAddressBookButton;
final CryptoCurrency? selectedCurrency;
@override
Widget build(BuildContext context) {
@ -207,7 +210,7 @@ class AddressTextField extends StatelessWidget {
Future<void> _presetAddressBookPicker(BuildContext context) async {
final contact = await Navigator.of(context, rootNavigator: true)
.pushNamed(Routes.pickerAddressBook);
.pushNamed(Routes.pickerAddressBook,arguments: selectedCurrency);
if (contact is ContactBase && contact.address != null) {
controller?.text = contact.address;

View file

@ -4,7 +4,7 @@ part 'authentication_store.g.dart';
class AuthenticationStore = AuthenticationStoreBase with _$AuthenticationStore;
enum AuthenticationState { uninitialized, installed, allowed, denied }
enum AuthenticationState { uninitialized, installed, allowed }
abstract class AuthenticationStoreBase with Store {
AuthenticationStoreBase() : state = AuthenticationState.uninitialized;
@ -17,7 +17,4 @@ abstract class AuthenticationStoreBase with Store {
@action
void allowed() => state = AuthenticationState.allowed;
@action
void denied() => state = AuthenticationState.denied;
}

View file

@ -0,0 +1,51 @@
import 'package:cake_wallet/store/settings_store.dart';
import 'package:cake_wallet/view_model/settings/switcher_list_item.dart';
import 'package:cw_core/wallet_type.dart';
import 'package:mobx/mobx.dart';
import 'package:cake_wallet/generated/i18n.dart';
part 'advanced_privacy_settings_view_model.g.dart';
class AdvancedPrivacySettingsViewModel = AdvancedPrivacySettingsViewModelBase
with _$AdvancedPrivacySettingsViewModel;
abstract class AdvancedPrivacySettingsViewModelBase with Store {
AdvancedPrivacySettingsViewModelBase(this.type, this._settingsStore)
: _disableFiat = false,
_addCustomNode = false {
settings = [
// TODO: uncomment when Disable Fiat PR is merged
// SwitcherListItem(
// title: S.current.disable_fiat,
// value: () => _disableFiat,
// onValueChange: (_, bool value) => _disableFiat = value,
// ),
SwitcherListItem(
title: S.current.disable_exchange,
value: () => _settingsStore.disableExchange,
onValueChange: (_, bool value) {
_settingsStore.disableExchange = value;
},
),
SwitcherListItem(
title: S.current.add_custom_node,
value: () => _addCustomNode,
onValueChange: (_, bool value) => _addCustomNode = value,
),
];
}
late List<SwitcherListItem> settings;
@observable
bool _disableFiat = false;
@observable
bool _addCustomNode = false;
final WalletType type;
final SettingsStore _settingsStore;
@computed
bool get addCustomNode => _addCustomNode;
}

View file

@ -7,27 +7,26 @@ import 'package:mobx/mobx.dart';
import 'package:cake_wallet/entities/contact_record.dart';
import 'package:cake_wallet/entities/contact.dart';
import 'package:cake_wallet/utils/mobx.dart';
import 'package:cw_core/crypto_currency.dart';
part 'contact_list_view_model.g.dart';
class ContactListViewModel = ContactListViewModelBase
with _$ContactListViewModel;
class ContactListViewModel = ContactListViewModelBase with _$ContactListViewModel;
abstract class ContactListViewModelBase with Store {
ContactListViewModelBase(this.contactSource, this.walletInfoSource)
ContactListViewModelBase(this.contactSource, this.walletInfoSource, this._currency)
: contacts = ObservableList<ContactRecord>(),
walletContacts = [] {
walletInfoSource.values.forEach((info) {
if (info.addresses?.isNotEmpty ?? false) {
info.addresses?.forEach((address, label) {
final name = label.isNotEmpty
? info.name + ' ($label)'
: info.name;
final name = label.isNotEmpty ? info.name + ' ($label)' : info.name;
walletContacts.add(WalletContact(
address,
name,
walletTypeToCryptoCurrency(info.type)));
address,
name,
walletTypeToCryptoCurrency(info.type),
));
});
}
});
@ -41,7 +40,18 @@ abstract class ContactListViewModelBase with Store {
final Box<WalletInfo> walletInfoSource;
final ObservableList<ContactRecord> contacts;
final List<WalletContact> walletContacts;
final CryptoCurrency? _currency;
StreamSubscription<BoxEvent>? _subscription;
bool get isEditable => _currency == null;
Future<void> delete(ContactRecord contact) async => contact.original.delete();
@computed
List<ContactRecord> get contactsToShow =>
contacts.where((element) => _currency == null || element.type == _currency).toList();
@computed
List<WalletContact> get walletContactsToShow =>
walletContacts.where((element) => _currency == null || element.type == _currency).toList();
}

View file

@ -1,7 +1,7 @@
import 'package:cake_wallet/core/execution_state.dart';
import 'package:cake_wallet/store/settings_store.dart';
import 'package:hive/hive.dart';
import 'package:mobx/mobx.dart';
import 'package:cw_core/wallet_base.dart';
import 'package:cw_core/node.dart';
import 'package:cw_core/wallet_type.dart';
@ -11,7 +11,7 @@ class NodeCreateOrEditViewModel = NodeCreateOrEditViewModelBase
with _$NodeCreateOrEditViewModel;
abstract class NodeCreateOrEditViewModelBase with Store {
NodeCreateOrEditViewModelBase(this._nodeSource, this._wallet)
NodeCreateOrEditViewModelBase(this._nodeSource, this._walletType, this._settingsStore)
: state = InitialExecutionState(),
connectionState = InitialExecutionState(),
useSSL = false,
@ -49,8 +49,8 @@ abstract class NodeCreateOrEditViewModelBase with Store {
bool get isReady =>
address.isNotEmpty && port.isNotEmpty;
bool get hasAuthCredentials => _wallet.type == WalletType.monero ||
_wallet.type == WalletType.haven;
bool get hasAuthCredentials => _walletType == WalletType.monero ||
_walletType == WalletType.haven;
String get uri {
var uri = address;
@ -62,8 +62,9 @@ abstract class NodeCreateOrEditViewModelBase with Store {
return uri;
}
final WalletBase _wallet;
final WalletType _walletType;
final Box<Node> _nodeSource;
final SettingsStore _settingsStore;
@action
void reset() {
@ -76,13 +77,18 @@ abstract class NodeCreateOrEditViewModelBase with Store {
}
@action
Future<void> save() async {
Future<void> save({bool saveAsCurrent = false}) async {
try {
state = IsExecutingState();
final node =
Node(uri: uri, type: _wallet.type, login: login, password: password,
Node(uri: uri, type: _walletType, login: login, password: password,
useSSL: useSSL, trusted: trusted);
await _nodeSource.add(node);
if (saveAsCurrent) {
_settingsStore.nodes[_walletType] = node;
}
state = ExecutedSuccessfullyState();
} catch (e) {
state = FailureState(e.toString());
@ -94,7 +100,7 @@ abstract class NodeCreateOrEditViewModelBase with Store {
try {
connectionState = IsExecutingState();
final node =
Node(uri: uri, type: _wallet.type, login: login, password: password);
Node(uri: uri, type: _walletType, login: login, password: password);
final isAlive = await node.requestNode();
connectionState = ExecutedSuccessfullyState(payload: isAlive);
} catch (e) {

View file

@ -654,7 +654,6 @@
"use_suggested": "Vorgeschlagen verwenden",
"do_not_share_warning_text" : "Teilen Sie diese nicht mit anderen, einschließlich des Supports.\n\nSie werden Ihr Geld stehlen!",
"help": "hilfe",
"disable_exchange": "Exchange deaktivieren",
"connection_sync": "Verbindung und Synchronisierung",
"security_and_backup": "Sicherheit und Datensicherung",
"create_backup": "Backup erstellen",
@ -662,6 +661,10 @@
"privacy": "Datenschutz",
"display_settings": "Anzeigeeinstellungen",
"other_settings": "Andere Einstellungen",
"disable_exchange": "Exchange deaktivieren",
"advanced_privacy_settings": "Erweiterte Datenschutzeinstellungen",
"settings_can_be_changed_later": "Diese Einstellungen können später in den App-Einstellungen geändert werden",
"add_custom_node": "Neuen benutzerdefinierten Knoten hinzufügen",
"disable_fiat": "Fiat deaktivieren",
"fiat_api": "Fiat API",
"disabled": "Deaktiviert",

View file

@ -654,7 +654,6 @@
"use_suggested": "Use Suggested",
"do_not_share_warning_text" : "Do not share these with anyone else, including support.\n\nThey will steal your money!",
"help": "help",
"disable_exchange": "Disable exchange",
"connection_sync": "Connection and sync",
"security_and_backup": "Security and backup",
"create_backup": "Create backup",
@ -662,6 +661,10 @@
"privacy": "Privacy",
"display_settings": "Display settings",
"other_settings": "Other settings",
"disable_exchange": "Disable exchange",
"advanced_privacy_settings": "Advanced Privacy Settings",
"settings_can_be_changed_later": "These settings can be changed later in the app settings",
"add_custom_node": "Add New Custom Node",
"disable_fiat": "Disable fiat",
"fiat_api": "Fiat API",
"disabled": "Disabled",

View file

@ -654,7 +654,6 @@
"use_suggested": "Usar sugerido",
"do_not_share_warning_text" : "No comparta estos con nadie más, incluido el soporte.\n\n¡Te robarán tu dinero!",
"help": "ayuda",
"disable_exchange": "Deshabilitar intercambio",
"connection_sync": "Conexión y sincronización",
"security_and_backup": "Seguridad y respaldo",
"create_backup": "Crear copia de seguridad",
@ -662,6 +661,10 @@
"privacy": "Privacidad",
"display_settings": "Configuración de pantalla",
"other_settings": "Otras configuraciones",
"disable_exchange": "Deshabilitar intercambio",
"advanced_privacy_settings": "Configuración avanzada de privacidad",
"settings_can_be_changed_later": "Estas configuraciones se pueden cambiar más tarde en la configuración de la aplicación",
"add_custom_node": "Agregar nuevo nodo personalizado",
"disable_fiat": "Deshabilitar fiat",
"fiat_api": "Fiat API",
"disabled": "Desactivado",

View file

@ -652,7 +652,6 @@
"use_suggested": "Utilisation suggérée",
"do_not_share_warning_text" : "Ne les partagez avec personne d'autre, y compris avec l'assistance.\n\nIls vont voler votre argent!",
"help": "aider",
"disable_exchange": "Désactiver l'échange",
"connection_sync": "Connexion et synchronisation",
"security_and_backup": "Sécurité et sauvegarde",
"create_backup": "Créer une sauvegarde",
@ -660,6 +659,10 @@
"privacy": "Confidentialité",
"display_settings": "Paramètres d'affichage",
"other_settings": "Autres paramètres",
"disable_exchange": "Désactiver l'échange",
"advanced_privacy_settings": "Paramètres de confidentialité avancés",
"settings_can_be_changed_later": "Ces paramètres peuvent être modifiés ultérieurement dans les paramètres de l'application",
"add_custom_node": "Ajouter un nouveau nœud personnalisé",
"disable_fiat": "Désactiver fiat",
"fiat_api": "Fiat API",
"disabled": "Handicapé",

View file

@ -654,7 +654,6 @@
"use_suggested": "सुझाए गए का प्रयोग करें",
"do_not_share_warning_text" : "इन्हें समर्थन सहित किसी और के साथ साझा न करें।\n\nवे आपका पैसा चुरा लेंगे!",
"help": "मदद करना",
"disable_fiat": "िएट अक्षम करें",
"connection_sync": "कनेक्शन और सिंक",
"security_and_backup": "सुरक्षा और बैकअप",
"create_backup": "बैकअप बनाएँ",
@ -663,6 +662,10 @@
"display_settings": "प्रदर्शन सेटिंग्स",
"other_settings": "अन्य सेटिंग्स",
"disable_exchange": "एक्सचेंज अक्षम करें",
"advanced_privacy_settings": "उन्नत गोपनीयता सेटिंग्स",
"settings_can_be_changed_later": "इन सेटिंग्स को बाद में ऐप सेटिंग में बदला जा सकता है",
"add_custom_node": "नया कस्टम नोड जोड़ें",
"disable_exchange": "एक्सचेंज अक्षम करें",
"fiat_api": "फिएट पैसे API",
"disabled": "अक्षम",
"enabled": "सक्रिय",

View file

@ -654,7 +654,6 @@
"use_suggested": "Koristite predloženo",
"do_not_share_warning_text" : "Nemojte ih dijeliti ni s kim, uključujući podršku.\n\nUkrast će vam novac!",
"help": "pomozite",
"disable_exchange": "Onemogući exchange",
"connection_sync": "Povezivanje i sinkronizacija",
"security_and_backup": "Sigurnost i sigurnosna kopija",
"create_backup": "Stvori sigurnosnu kopiju",
@ -662,6 +661,10 @@
"privacy": "Privatnost",
"display_settings": "Postavke zaslona",
"other_settings": "Ostale postavke",
"disable_exchange": "Onemogući exchange",
"advanced_privacy_settings": "Napredne postavke privatnosti",
"settings_can_be_changed_later": "Te se postavke mogu promijeniti kasnije u postavkama aplikacije",
"add_custom_node": "Dodaj novi prilagođeni čvor",
"disable_fiat": "Isključi, fiat",
"fiat_api": "Fiat API",
"disabled": "Onemogućeno",

View file

@ -654,7 +654,6 @@
"use_suggested": "Usa suggerito",
"do_not_share_warning_text" : "Non condividerli con nessun altro, incluso il supporto.\n\nTi ruberanno i soldi!",
"help": "aiuto",
"disable_exchange": "Disabilita scambio",
"connection_sync": "Connessione e sincronizzazione",
"security_and_backup": "Sicurezza e backup",
"create_backup": "Crea backup",
@ -662,6 +661,10 @@
"privacy": "Privacy",
"display_settings": "Impostazioni di visualizzazione",
"other_settings": "Altre impostazioni",
"disable_exchange": "Disabilita scambio",
"advanced_privacy_settings": "Impostazioni avanzate sulla privacy",
"settings_can_be_changed_later": "Queste impostazioni possono essere modificate in seguito nelle impostazioni dell'app",
"add_custom_node": "Aggiungi nuovo nodo personalizzato",
"disable_fiat": "Disabilita fiat",
"fiat_api": "Fiat API",
"disabled": "Disabilitato",

View file

@ -654,7 +654,6 @@
"use_suggested": "推奨を使用",
"do_not_share_warning_text" : "サポートを含め、これらを他の誰とも共有しないでください。\n\n彼らはあなたのお金を盗みます",
"help": "ヘルプ",
"disable_exchange": "交換を無効にする",
"connection_sync": "接続と同期",
"security_and_backup": "セキュリティとバックアップ",
"create_backup": "バックアップを作成",
@ -662,6 +661,10 @@
"privacy": "プライバシー",
"display_settings": "表示設定",
"other_settings": "その他の設定",
"disable_exchange": "交換を無効にする",
"advanced_privacy_settings": "高度なプライバシー設定",
"settings_can_be_changed_later": "これらの設定は、後でアプリの設定で変更できます",
"add_custom_node": "新しいカスタム ノードを追加",
"disable_fiat": "フィアットを無効にする",
"fiat_api": "不換紙幣 API",
"disabled": "無効",

View file

@ -654,7 +654,6 @@
"use_suggested": "추천 사용",
"do_not_share_warning_text" : "지원을 포함하여 다른 사람과 이러한 정보를 공유하지 마십시오.\n\n그들은 당신의 돈을 훔칠 것입니다!",
"help": "돕다",
"disable_exchange": "교환 비활성화",
"connection_sync": "연결 및 동기화",
"security_and_backup": "보안 및 백업",
"create_backup": "백업 생성",
@ -662,6 +661,10 @@
"privacy": "프라이버시",
"display_settings": "디스플레이 설정",
"other_settings": "기타 설정",
"disable_exchange": "교환 비활성화",
"advanced_privacy_settings": "고급 개인 정보 설정",
"settings_can_be_changed_later": "이 설정은 나중에 앱 설정에서 변경할 수 있습니다.",
"add_custom_node": "새 사용자 정의 노드 추가",
"disable_fiat": "법정화폐 비활성화",
"fiat_api": "명목 화폐 API",
"disabled": "장애가 있는",

View file

@ -654,7 +654,6 @@
"use_suggested": "Gebruik aanbevolen",
"do_not_share_warning_text" : "Deel deze met niemand anders, ook niet met support.\n\nZe zullen je geld stelen!",
"help": "helpen",
"disable_exchange": "Uitwisseling uitschakelen",
"connection_sync": "Verbinding en synchronisatie",
"security_and_backup": "Beveiliging en back-up",
"create_backup": "Maak een back-up",
@ -662,6 +661,10 @@
"privacy": "Privacy",
"display_settings": "Weergave-instellingen",
"other_settings": "Andere instellingen",
"disable_exchange": "Uitwisseling uitschakelen",
"advanced_privacy_settings": "Geavanceerde privacy-instellingen",
"settings_can_be_changed_later": "Deze instellingen kunnen later worden gewijzigd in de app-instellingen",
"add_custom_node": "Voeg een nieuw aangepast knooppunt toe",
"disable_fiat": "Schakel Fiat uit",
"fiat_api": "Fiat API",
"disabled": "Gehandicapt",

View file

@ -654,7 +654,6 @@
"use_suggested": "Użyj sugerowane",
"do_not_share_warning_text" : "Nie udostępniaj ich nikomu innemu, w tym wsparcia.\n\nUkradną twoje pieniądze!",
"help": "pomoc",
"disable_exchange": "Wyłącz wymianę",
"connection_sync": "Połączenie i synchronizacja",
"security_and_backup": "Bezpieczeństwo i kopia zapasowa",
"create_backup": "Utwórz kopię zapasową",
@ -662,6 +661,10 @@
"privacy": "Prywatność",
"display_settings": "Ustawienia wyświetlania",
"other_settings": "Inne ustawienia",
"disable_exchange": "Wyłącz wymianę",
"advanced_privacy_settings": "Zaawansowane ustawienia prywatności",
"settings_can_be_changed_later": "Te ustawienia można później zmienić w ustawieniach aplikacji",
"add_custom_node": "Dodaj nowy węzeł niestandardowy",
"disable_fiat": "Wyłącz fiat",
"fiat_api": "API Fiata",
"disabled": "Wyłączone",

View file

@ -653,7 +653,6 @@
"use_suggested": "Uso sugerido",
"do_not_share_warning_text" : "Não os compartilhe com mais ninguém, incluindo suporte.\n\nEles vão roubar seu dinheiro!",
"help": "ajuda",
"disable_exchange": "Desativar troca",
"connection_sync": "Conexão e sincronização",
"security_and_backup": "Segurança e backup",
"create_backup": "Criar backup",
@ -661,6 +660,10 @@
"privacy": "Privacidade",
"display_settings": "Configurações de exibição",
"other_settings": "Outras configurações",
"disable_exchange": "Desativar troca",
"advanced_privacy_settings": "Configurações de privacidade avançadas",
"settings_can_be_changed_later": "Essas configurações podem ser alteradas posteriormente nas configurações do aplicativo",
"add_custom_node": "Adicionar novo nó personalizado",
"disable_fiat": "Desativar fiat",
"fiat_api": "API da Fiat",
"disabled": "Desabilitado",

View file

@ -654,7 +654,6 @@
"use_suggested": "Использовать предложенный",
"do_not_share_warning_text" : "Не делитесь ими с кем-либо еще, в том числе со службой поддержки.\n\nОни украдут ваши деньги!",
"help": "помощь",
"disable_exchange": "Отключить обмен",
"connection_sync": "Подключение и синхронизация",
"security_and_backup": "Безопасность и резервное копирование",
"create_backup": "Создать резервную копию",
@ -662,6 +661,10 @@
"privacy": "Конфиденциальность",
"display_settings": "Настройки отображения",
"other_settings": "Другие настройки",
"disable_exchange": "Отключить обмен",
"advanced_privacy_settings": "Расширенные настройки конфиденциальности",
"settings_can_be_changed_later": "Эти настройки можно изменить позже в настройках приложения.",
"add_custom_node": "Добавить новый пользовательский узел",
"disable_fiat": "Отключить фиат",
"fiat_api": "Фиат API",
"disabled": "Отключено",

View file

@ -653,7 +653,6 @@
"use_suggested": "Використати запропоноване",
"do_not_share_warning_text" : "Не повідомляйте їх нікому, включно зі службою підтримки.\n\nВони вкрадуть ваші гроші!",
"help": "допомога",
"disable_exchange": "Вимкнути exchange",
"connection_sync": "Підключення та синхронізація",
"security_and_backup": "Безпека та резервне копіювання",
"create_backup": "Створити резервну копію",
@ -661,6 +660,10 @@
"privacy": "Конфіденційність",
"display_settings": "Налаштування дисплея",
"other_settings": "Інші налаштування",
"disable_exchange": "Вимкнути exchange",
"advanced_privacy_settings": "Розширені налаштування конфіденційності",
"settings_can_be_changed_later": "Ці параметри можна змінити пізніше в налаштуваннях програми",
"add_custom_node": "Додати новий спеціальний вузол",
"disable_fiat": "Вимкнути фиат",
"fiat_api": "Фіат API",
"disabled": "Вимкнено",

View file

@ -652,7 +652,6 @@
"use_suggested": "使用建议",
"do_not_share_warning_text" : "不要與其他任何人分享這些內容,包括支持。\n\n他們會偷你的錢",
"help": "帮助",
"disable_exchange": "禁用交换",
"connection_sync": "连接和同步",
"security_and_backup": "安全和备份",
"create_backup": "创建备份",
@ -660,6 +659,10 @@
"privacy":"隐私",
"display_settings": "显示设置",
"other_settings": "其他设置",
"disable_exchange": "禁用交换",
"advanced_privacy_settings": "高级隐私设置",
"settings_can_be_changed_later": "稍后可以在应用设置中更改这些设置",
"add_custom_node": "添加新的自定义节点",
"disable_fiat": "禁用法令",
"fiat_api": "法币API",
"disabled": "禁用",