diff --git a/lib/core/backup_service.dart b/lib/core/backup_service.dart index 999b67120..46868cf1a 100644 --- a/lib/core/backup_service.dart +++ b/lib/core/backup_service.dart @@ -214,6 +214,7 @@ class BackupService { final currentBitcoinElectrumSererId = data[PreferencesKey.currentBitcoinElectrumSererIdKey] as int?; final currentLanguageCode = data[PreferencesKey.currentLanguageCode] as String?; final displayActionListMode = data[PreferencesKey.displayActionListModeKey] as int?; + final fiatApiMode = data[PreferencesKey.currentFiatApiModeKey] as int?; final currentPinLength = data[PreferencesKey.currentPinLength] as int?; final currentTheme = data[PreferencesKey.currentTheme] as int?; final currentDefaultSettingsMigrationVersion = data[PreferencesKey.currentDefaultSettingsMigrationVersion] as int?; @@ -266,6 +267,10 @@ class BackupService { await _sharedPreferences.setInt(PreferencesKey.displayActionListModeKey, displayActionListMode); + if (fiatApiMode != null) + await _sharedPreferences.setInt(PreferencesKey.currentFiatApiModeKey, + fiatApiMode); + if (currentPinLength != null) await _sharedPreferences.setInt(PreferencesKey.currentPinLength, currentPinLength); @@ -427,6 +432,8 @@ class BackupService { _sharedPreferences.getInt(PreferencesKey.bitcoinTransactionPriority), PreferencesKey.moneroTransactionPriority: _sharedPreferences.getInt(PreferencesKey.moneroTransactionPriority), + PreferencesKey.currentFiatApiModeKey: + _sharedPreferences.getInt(PreferencesKey.currentFiatApiModeKey), }; return json.encode(preferences); diff --git a/lib/entities/default_settings_migration.dart b/lib/entities/default_settings_migration.dart index 40d26b93f..d65b4401d 100644 --- a/lib/entities/default_settings_migration.dart +++ b/lib/entities/default_settings_migration.dart @@ -20,6 +20,8 @@ import 'package:cake_wallet/exchange/trade.dart'; import 'package:encrypt/encrypt.dart' as encrypt; import 'package:collection/collection.dart'; +import 'fiat_api_mode.dart'; + const newCakeWalletMoneroUri = 'xmr-node.cakewallet.com:18081'; const cakeWalletBitcoinElectrumUri = 'electrum.cakewallet.com:50002'; const cakeWalletLitecoinElectrumUri = 'ltc-electrum.cakewallet.com:50002'; @@ -61,7 +63,9 @@ Future defaultSettingsMigration( await sharedPreferences.setInt( PreferencesKey.currentBalanceDisplayModeKey, BalanceDisplayMode.availableBalance.raw); - await sharedPreferences.setBool('disable_fiat', false); + await sharedPreferences.setInt( + PreferencesKey.currentFiatApiModeKey, + FiatApiMode.enabled.raw); await sharedPreferences.setBool('save_recipient_address', true); await resetToDefault(nodes); await changeMoneroCurrentNodeToDefault( @@ -140,6 +144,10 @@ Future defaultSettingsMigration( await addOnionNode(nodes); break; + case 19: + await updateFiatApiModes(sharedPreferences); + break; + default: break; } @@ -350,6 +358,14 @@ Future updateDisplayModes(SharedPreferences sharedPreferences) async { PreferencesKey.currentBalanceDisplayModeKey, balanceDisplayMode); } +Future updateFiatApiModes(SharedPreferences sharedPreferences) async { + final currentFiatApiMode = + sharedPreferences.getInt(PreferencesKey.currentFiatApiModeKey) ?? -1; + final fiatApiMode = currentFiatApiMode < 1 ? 2 : 1; + await sharedPreferences.setInt( + PreferencesKey.currentFiatApiModeKey, fiatApiMode); +} + Future generateBackupPassword(FlutterSecureStorage secureStorage) async { final key = generateStoreKeyFor(key: SecretStoreKey.backupPassword); diff --git a/lib/entities/fiat_api_mode.dart b/lib/entities/fiat_api_mode.dart new file mode 100644 index 000000000..615784986 --- /dev/null +++ b/lib/entities/fiat_api_mode.dart @@ -0,0 +1,39 @@ +import 'package:cake_wallet/generated/i18n.dart'; +import 'package:cw_core/enumerable_item.dart'; + +class FiatApiMode extends EnumerableItem with Serializable { + const FiatApiMode({required String title, required int raw}) : super(title: title, raw: raw); + + static const all = [FiatApiMode.enabled, FiatApiMode.torOnly, FiatApiMode.disabled]; + + static const enabled = FiatApiMode(raw: 0, title: 'Enabled'); + static const torOnly = FiatApiMode(raw: 1, title: 'Tor only'); + static const disabled = FiatApiMode(raw: 2, title: 'Disabled'); + + static FiatApiMode deserialize({required int raw}) { + switch (raw) { + case 0: + return enabled; + case 1: + return torOnly; + case 2: + return disabled; + default: + throw Exception('Unexpected token: $raw for FiatApiMode deserialize'); + } + } + + @override + String toString() { + switch (this) { + case FiatApiMode.enabled: + return 'enable'; + case FiatApiMode.torOnly: + return 'torOnly'; + case FiatApiMode.disabled: + return 'disable'; + default: + return ''; + } + } +} diff --git a/lib/entities/preferences_key.dart b/lib/entities/preferences_key.dart index 0df7981bd..7d1d75000 100644 --- a/lib/entities/preferences_key.dart +++ b/lib/entities/preferences_key.dart @@ -9,7 +9,7 @@ class PreferencesKey { static const currentTransactionPriorityKeyLegacy = 'current_fee_priority'; static const currentBalanceDisplayModeKey = 'current_balance_display_mode'; static const shouldSaveRecipientAddressKey = 'save_recipient_address'; - static const shouldDisableFiatKey = 'disable_fiat'; + static const currentFiatApiModeKey = 'current_fiat_api_mode'; static const allowBiometricalAuthenticationKey = 'allow_biometrical_authentication'; static const disableExchangeKey = 'disable_exchange'; diff --git a/lib/src/screens/send/widgets/send_card.dart b/lib/src/screens/send/widgets/send_card.dart index 60da5a8ea..503494c92 100644 --- a/lib/src/screens/send/widgets/send_card.dart +++ b/lib/src/screens/send/widgets/send_card.dart @@ -331,7 +331,7 @@ class SendCardState extends State ], ), )), - if (sendViewModel.balanceViewModel.disableFiat) + if (!sendViewModel.balanceViewModel.disableFiat) Padding( padding: const EdgeInsets.only(top: 20), child: BaseTextFormField( diff --git a/lib/src/screens/settings/privacy_page.dart b/lib/src/screens/settings/privacy_page.dart index 128d864f4..34957fa4a 100644 --- a/lib/src/screens/settings/privacy_page.dart +++ b/lib/src/screens/settings/privacy_page.dart @@ -1,9 +1,12 @@ import 'package:cake_wallet/generated/i18n.dart'; import 'package:cake_wallet/src/screens/base_page.dart'; +import 'package:cake_wallet/src/screens/settings/widgets/settings_choices_cell.dart'; import 'package:cake_wallet/src/screens/settings/widgets/settings_switcher_cell.dart'; import 'package:cake_wallet/view_model/settings/privacy_settings_view_model.dart'; import 'package:flutter/material.dart'; import 'package:flutter_mobx/flutter_mobx.dart'; +import 'package:cake_wallet/view_model/settings/choices_list_item.dart'; +import 'package:cake_wallet/entities/fiat_api_mode.dart'; class PrivacyPage extends BasePage { PrivacyPage(this._privacySettingsViewModel); @@ -18,10 +21,17 @@ class PrivacyPage extends BasePage { return Container( padding: EdgeInsets.only(top: 10), child: Observer(builder: (_) { - return Observer(builder: (_) { return Column( mainAxisSize: MainAxisSize.min, children: [ + SettingsChoicesCell( + ChoicesListItem( + title: 'Fiat api', + items: FiatApiMode.all, + selectedItem: _privacySettingsViewModel.fiatApiMode, + onItemSelected: (FiatApiMode mode) => _privacySettingsViewModel.setFiatMode(mode), + ), + ), SettingsSwitcherCell( title: S.current.disable_exchange, value: _privacySettingsViewModel.disableExchange, @@ -36,7 +46,6 @@ class PrivacyPage extends BasePage { }) ], ); - }); }), ); } diff --git a/lib/store/settings_store.dart b/lib/store/settings_store.dart index 1f49be479..419b03e49 100644 --- a/lib/store/settings_store.dart +++ b/lib/store/settings_store.dart @@ -17,8 +17,10 @@ import 'package:cake_wallet/entities/fiat_currency.dart'; import 'package:cw_core/node.dart'; import 'package:cake_wallet/monero/monero.dart'; import 'package:cake_wallet/entities/action_list_display_mode.dart'; +import 'package:cake_wallet/entities/fiat_api_mode.dart'; import 'package:cake_wallet/.secrets.g.dart' as secrets; + part 'settings_store.g.dart'; class SettingsStore = SettingsStoreBase with _$SettingsStore; @@ -29,7 +31,7 @@ abstract class SettingsStoreBase with Store { required FiatCurrency initialFiatCurrency, required BalanceDisplayMode initialBalanceDisplayMode, required bool initialSaveRecipientAddress, - required bool initialDisableFiat, + required FiatApiMode initialFiatMode, required bool initialAllowBiometricalAuthentication, required bool initialExchangeEnabled, required ThemeBase initialTheme, @@ -48,7 +50,7 @@ abstract class SettingsStoreBase with Store { fiatCurrency = initialFiatCurrency, balanceDisplayMode = initialBalanceDisplayMode, shouldSaveRecipientAddress = initialSaveRecipientAddress, - shouldDisableFiat = initialDisableFiat, + fiatApiMode = initialFiatMode, allowBiometricalAuthentication = initialAllowBiometricalAuthentication, disableExchange = initialExchangeEnabled, currentTheme = initialTheme, @@ -92,10 +94,9 @@ abstract class SettingsStoreBase with Store { shouldSaveRecipientAddress)); reaction( - (_) => shouldDisableFiat, - (bool shouldDisableFiat) => sharedPreferences.setBool( - PreferencesKey.shouldDisableFiatKey, - shouldDisableFiat)); + (_) => fiatApiMode, + (FiatApiMode mode) => sharedPreferences.setInt( + PreferencesKey.currentFiatApiModeKey, mode.serialize())); reaction( (_) => currentTheme, @@ -148,10 +149,10 @@ abstract class SettingsStoreBase with Store { BalanceDisplayMode balanceDisplayMode; @observable - bool shouldSaveRecipientAddress; + FiatApiMode fiatApiMode; @observable - bool shouldDisableFiat; + bool shouldSaveRecipientAddress; @observable bool allowBiometricalAuthentication; @@ -234,8 +235,9 @@ abstract class SettingsStoreBase with Store { // FIX-ME: Check for which default value we should have here final shouldSaveRecipientAddress = sharedPreferences.getBool(PreferencesKey.shouldSaveRecipientAddressKey) ?? false; - final shouldDisableFiat = - sharedPreferences.getBool(PreferencesKey.shouldDisableFiatKey) ?? false; + final currentFiatApiMode = FiatApiMode.deserialize( + raw: sharedPreferences + .getInt(PreferencesKey.currentFiatApiModeKey)!); final allowBiometricalAuthentication = sharedPreferences .getBool(PreferencesKey.allowBiometricalAuthenticationKey) ?? false; @@ -303,7 +305,7 @@ abstract class SettingsStoreBase with Store { initialFiatCurrency: currentFiatCurrency, initialBalanceDisplayMode: currentBalanceDisplayMode, initialSaveRecipientAddress: shouldSaveRecipientAddress, - initialDisableFiat: shouldDisableFiat, + initialFiatMode: currentFiatApiMode, initialAllowBiometricalAuthentication: allowBiometricalAuthentication, initialExchangeEnabled: disableExchange, initialTheme: savedTheme, diff --git a/lib/view_model/dashboard/balance_view_model.dart b/lib/view_model/dashboard/balance_view_model.dart index 40502bb84..6728859da 100644 --- a/lib/view_model/dashboard/balance_view_model.dart +++ b/lib/view_model/dashboard/balance_view_model.dart @@ -1,3 +1,4 @@ +import 'package:cake_wallet/entities/fiat_api_mode.dart'; import 'package:cw_core/transaction_history.dart'; import 'package:cw_core/wallet_base.dart'; import 'package:cw_core/balance.dart'; @@ -10,7 +11,6 @@ import 'package:cake_wallet/entities/calculate_fiat_amount.dart'; import 'package:cake_wallet/store/app_store.dart'; import 'package:cake_wallet/store/settings_store.dart'; import 'package:cake_wallet/store/dashboard/fiat_conversion_store.dart'; -import 'package:flutter/cupertino.dart'; import 'package:mobx/mobx.dart'; part 'balance_view_model.g.dart'; @@ -72,7 +72,7 @@ abstract class BalanceViewModelBase with Store { BalanceDisplayMode get savedDisplayMode => settingsStore.balanceDisplayMode; @computed - bool get disableFiat => settingsStore.shouldDisableFiat; + bool get disableFiat => settingsStore.fiatApiMode == FiatApiMode.disabled; @computed String get asset { diff --git a/lib/view_model/settings/privacy_settings_view_model.dart b/lib/view_model/settings/privacy_settings_view_model.dart index 88311bf1f..2d8418d11 100644 --- a/lib/view_model/settings/privacy_settings_view_model.dart +++ b/lib/view_model/settings/privacy_settings_view_model.dart @@ -1,5 +1,6 @@ import 'package:cake_wallet/store/settings_store.dart'; import 'package:mobx/mobx.dart'; +import 'package:cake_wallet/entities/fiat_api_mode.dart'; part 'privacy_settings_view_model.g.dart'; @@ -16,9 +17,15 @@ abstract class PrivacySettingsViewModelBase with Store { @computed bool get shouldSaveRecipientAddress => _settingsStore.shouldSaveRecipientAddress; + @computed + FiatApiMode get fiatApiMode => _settingsStore.fiatApiMode; + @action void setShouldSaveRecipientAddress(bool value) => _settingsStore.shouldSaveRecipientAddress = value; @action void setEnableExchange(bool value) => _settingsStore.disableExchange = value; + + @action + void setFiatMode(FiatApiMode mode) => _settingsStore.fiatApiMode = mode; }