From 9a7c9853568ce9068fd9602a77802240272e168d Mon Sep 17 00:00:00 2001 From: Marcos Rodriguez Velez Date: Wed, 17 Apr 2024 21:05:48 -0400 Subject: [PATCH] REF: SettingsContext --- WatchConnectivity.ios.js | 5 +- android/.project | 11 + .../org.eclipse.buildship.core.prefs | 11 + android/app/.classpath | 2 +- android/app/.project | 11 + blue_modules/storage-context.tsx | 100 +------- class/quick-actions.tsx | 6 +- components/Context/SettingsContext.tsx | 214 ++++++++++++++++++ components/HandOffComponent.ios.tsx | 6 +- components/TransactionListItem.js | 4 +- components/TransactionsNavigationHeader.tsx | 6 +- components/WalletsCarousel.js | 3 +- components/WidgetCommunication.ios.tsx | 71 +++--- components/WidgetCommunication.tsx | 3 + hooks/usePrivacy.android.tsx | 6 +- hooks/usePrivacy.ios.tsx | 6 +- index.js | 5 +- screen/settings/Currency.tsx | 8 +- screen/settings/GeneralSettings.tsx | 44 ++-- screen/settings/Settings.js | 6 +- screen/settings/SettingsPrivacy.js | 48 ++-- screen/settings/language.tsx | 17 +- screen/wallets/ViewEditMultisigCosigners.tsx | 14 +- screen/wallets/add.tsx | 10 +- screen/wallets/addMultisig.js | 14 +- screen/wallets/addMultisigStep2.js | 13 +- screen/wallets/details.js | 12 +- screen/wallets/import.js | 10 +- 28 files changed, 398 insertions(+), 268 deletions(-) create mode 100644 components/Context/SettingsContext.tsx diff --git a/WatchConnectivity.ios.js b/WatchConnectivity.ios.js index b2085fa46..98a268201 100644 --- a/WatchConnectivity.ios.js +++ b/WatchConnectivity.ios.js @@ -13,10 +13,11 @@ import { BlueStorageContext } from './blue_modules/storage-context'; import Notifications from './blue_modules/notifications'; import { FiatUnit } from './models/fiatUnit'; import { MultisigHDWallet } from './class'; +import { useSettings } from './components/Context/SettingsContext'; function WatchConnectivity() { - const { walletsInitialized, wallets, fetchWalletTransactions, saveToDisk, txMetadata, preferredFiatCurrency } = - useContext(BlueStorageContext); + const { walletsInitialized, wallets, fetchWalletTransactions, saveToDisk, txMetadata } = useContext(BlueStorageContext); + const { preferredFiatCurrency } = useSettings(); const isReachable = useReachability(); const isInstalled = useInstalled(); // true | false const messagesListenerActive = useRef(false); diff --git a/android/.project b/android/.project index d22beed79..ac42b2132 100644 --- a/android/.project +++ b/android/.project @@ -14,4 +14,15 @@ org.eclipse.buildship.core.gradleprojectnature + + + 1713398970188 + + 30 + + org.eclipse.core.resources.regexFilterMatcher + node_modules|\.git|__CREATED_BY_JAVA_LANGUAGE_SERVER__ + + + diff --git a/android/.settings/org.eclipse.buildship.core.prefs b/android/.settings/org.eclipse.buildship.core.prefs index e8895216f..caff9d179 100644 --- a/android/.settings/org.eclipse.buildship.core.prefs +++ b/android/.settings/org.eclipse.buildship.core.prefs @@ -1,2 +1,13 @@ +arguments=--init-script /var/folders/wp/mctylz615p727_90j3yv0vnc0000gn/T/d146c9752a26f79b52047fb6dc6ed385d064e120494f96f08ca63a317c41f94c.gradle --init-script /var/folders/wp/mctylz615p727_90j3yv0vnc0000gn/T/52cde0cfcf3e28b8b7510e992210d9614505e0911af0c190bd590d7158574963.gradle +auto.sync=false +build.scans.enabled=false +connection.gradle.distribution=GRADLE_DISTRIBUTION(WRAPPER) connection.project.dir= eclipse.preferences.version=1 +gradle.user.home= +java.home=/Library/Java/JavaVirtualMachines/temurin-21.jdk/Contents/Home +jvm.arguments= +offline.mode=false +override.workspace.settings=true +show.console.view=true +show.executions.view=true diff --git a/android/app/.classpath b/android/app/.classpath index eb19361b5..0a3280e2a 100644 --- a/android/app/.classpath +++ b/android/app/.classpath @@ -1,6 +1,6 @@ - + diff --git a/android/app/.project b/android/app/.project index ac485d7c3..784693d9d 100644 --- a/android/app/.project +++ b/android/app/.project @@ -20,4 +20,15 @@ org.eclipse.jdt.core.javanature org.eclipse.buildship.core.gradleprojectnature + + + 1713398970196 + + 30 + + org.eclipse.core.resources.regexFilterMatcher + node_modules|\.git|__CREATED_BY_JAVA_LANGUAGE_SERVER__ + + + diff --git a/blue_modules/storage-context.tsx b/blue_modules/storage-context.tsx index 1e2ddd53d..43b049358 100644 --- a/blue_modules/storage-context.tsx +++ b/blue_modules/storage-context.tsx @@ -1,15 +1,11 @@ -import React, { createContext, useEffect, useState } from 'react'; -import { useAsyncStorage } from '@react-native-async-storage/async-storage'; - +import React, { createContext, useContext, useEffect, useState } from 'react'; import { startAndDecrypt } from './start-and-decrypt'; import Notifications from '../blue_modules/notifications'; import { LegacyWallet, TTXMetadata, WatchOnlyWallet, BlueApp as BlueAppClass } from '../class'; import type { TWallet } from '../class/wallets/types'; import presentAlert from '../components/Alert'; -import loc, { STORAGE_KEY as LOC_STORAGE_KEY } from '../loc'; -import { FiatUnit, TFiatUnit } from '../models/fiatUnit'; +import loc from '../loc'; import * as BlueElectrum from './BlueElectrum'; -import { initCurrencyDaemon, PREFERRED_CURRENCY_STORAGE_KEY } from './currency'; import triggerHapticFeedback, { HapticFeedbackTypes } from './hapticFeedback'; import A from '../blue_modules/analytics'; @@ -35,23 +31,13 @@ interface BlueStorageContextType { setWalletsInitialized: (initialized: boolean) => void; refreshAllWalletTransactions: (lastSnappedTo?: number, showUpdateStatusIndicator?: boolean) => Promise; resetWallets: () => void; - setPreferredFiatCurrency: () => void; - preferredFiatCurrency: TFiatUnit; - setLanguage: () => void; - language: string | undefined; - isHandOffUseEnabled: boolean; - setIsHandOffUseEnabledAsyncStorage: (value: boolean) => Promise; walletTransactionUpdateStatus: WalletTransactionsStatus | string; setWalletTransactionUpdateStatus: (status: WalletTransactionsStatus | string) => void; isElectrumDisabled: boolean; setIsElectrumDisabled: (value: boolean) => void; - isPrivacyBlurEnabled: boolean; - setIsPrivacyBlurEnabled: (value: boolean) => void; reloadTransactionsMenuActionFunction: () => void; setReloadTransactionsMenuActionFunction: (func: () => void) => void; - getTransactions: typeof BlueApp.getTransactions; - isAdvancedModeEnabled: typeof BlueApp.isAdvancedModeEnabled; fetchWalletBalances: typeof BlueApp.fetchWalletBalances; fetchWalletTransactions: typeof BlueApp.fetchWalletTransactions; getBalance: typeof BlueApp.getBalance; @@ -63,9 +49,6 @@ interface BlueStorageContextType { decryptStorage: typeof BlueApp.decryptStorage; isPasswordInUse: typeof BlueApp.isPasswordInUse; cachedPassword: typeof BlueApp.cachedPassword; - setIsAdvancedModeEnabled: typeof BlueApp.setIsAdvancedModeEnabled; - setDoNotTrack: typeof BlueApp.setDoNotTrack; - isDoNotTrackEnabled: typeof BlueApp.isDoNotTrackEnabled; getItem: typeof BlueApp.getItem; setItem: typeof BlueApp.setItem; } @@ -83,14 +66,8 @@ export const BlueStorageProvider = ({ children }: { children: React.ReactNode }) WalletTransactionsStatus.NONE, ); const [walletsInitialized, setWalletsInitialized] = useState(false); - const [preferredFiatCurrency, _setPreferredFiatCurrency] = useState(FiatUnit.USD); - const [language, _setLanguage] = useState(); - const [isHandOffUseEnabled, setIsHandOffUseEnabled] = useState(false); const [isElectrumDisabled, setIsElectrumDisabled] = useState(true); - const [isPrivacyBlurEnabled, setIsPrivacyBlurEnabled] = useState(true); const [currentSharedCosigner, setCurrentSharedCosigner] = useState(''); - const getPreferredCurrencyAsyncStorage = useAsyncStorage(PREFERRED_CURRENCY_STORAGE_KEY).getItem; - const getLanguageAsyncStorage = useAsyncStorage(LOC_STORAGE_KEY).getItem; const [reloadTransactionsMenuActionFunction, setReloadTransactionsMenuActionFunction] = useState<() => void>(() => {}); useEffect(() => { @@ -99,23 +76,10 @@ export const BlueStorageProvider = ({ children }: { children: React.ReactNode }) useEffect(() => { if (walletsInitialized) { - initCurrencyDaemon(); BlueElectrum.connectMain(); } }, [walletsInitialized]); - useEffect(() => { - console.log(`Privacy blur: ${isPrivacyBlurEnabled}`); - if (!isPrivacyBlurEnabled) { - presentAlert({ message: 'Privacy blur has been disabled.' }); - } - }, [isPrivacyBlurEnabled]); - - const setIsHandOffUseEnabledAsyncStorage = (value: boolean) => { - setIsHandOffUseEnabled(value); - return BlueApp.setIsHandoffEnabled(value); - }; - const saveToDisk = async (force: boolean = false) => { if (BlueApp.getWallets().length === 0 && !force) { console.log('not saving empty wallets array'); @@ -131,47 +95,6 @@ export const BlueStorageProvider = ({ children }: { children: React.ReactNode }) setWallets(BlueApp.getWallets()); }, []); - useEffect(() => { - (async () => { - try { - const enabledHandoff = await BlueApp.isHandoffEnabled(); - setIsHandOffUseEnabled(!!enabledHandoff); - } catch (_e) { - setIsHandOffUseEnabledAsyncStorage(false); - setIsHandOffUseEnabled(false); - } - })(); - }, []); - - const getPreferredCurrency = async () => { - // @ts-ignore TODO: fix this - const item = JSON.parse(await getPreferredCurrencyAsyncStorage()) ?? FiatUnit.USD; - _setPreferredFiatCurrency(item); - return item; - }; - - const setPreferredFiatCurrency = () => { - getPreferredCurrency(); - }; - - const getLanguage = async () => { - const item = await getLanguageAsyncStorage(); - if (item === null) { - return; - } - _setLanguage(item); - }; - - const setLanguage = () => { - getLanguage(); - }; - - useEffect(() => { - getPreferredCurrency(); - getLanguageAsyncStorage(); - // eslint-disable-next-line react-hooks/exhaustive-deps - }, []); - const resetWallets = () => { setWallets(BlueApp.getWallets()); }; @@ -272,7 +195,6 @@ export const BlueStorageProvider = ({ children }: { children: React.ReactNode }) let txMetadata = BlueApp.tx_metadata; const getTransactions = BlueApp.getTransactions; - const isAdvancedModeEnabled = BlueApp.isAdvancedModeEnabled; const fetchWalletBalances = BlueApp.fetchWalletBalances; const fetchWalletTransactions = BlueApp.fetchWalletTransactions; const getBalance = BlueApp.getBalance; @@ -283,9 +205,7 @@ export const BlueStorageProvider = ({ children }: { children: React.ReactNode }) const decryptStorage = BlueApp.decryptStorage; const isPasswordInUse = BlueApp.isPasswordInUse; const cachedPassword = BlueApp.cachedPassword; - const setIsAdvancedModeEnabled = BlueApp.setIsAdvancedModeEnabled; - const setDoNotTrack = BlueApp.setDoNotTrack; - const isDoNotTrackEnabled = BlueApp.isDoNotTrackEnabled; + const getItem = BlueApp.getItem; const setItem = BlueApp.setItem; @@ -304,7 +224,6 @@ export const BlueStorageProvider = ({ children }: { children: React.ReactNode }) addAndSaveWallet, setItem, getItem, - isAdvancedModeEnabled, fetchWalletBalances, fetchWalletTransactions, fetchAndSaveWalletTransactions, @@ -321,24 +240,15 @@ export const BlueStorageProvider = ({ children }: { children: React.ReactNode }) resetWallets, decryptStorage, isPasswordInUse, - setIsAdvancedModeEnabled, - setPreferredFiatCurrency, - preferredFiatCurrency, - setLanguage, - language, - isHandOffUseEnabled, - setIsHandOffUseEnabledAsyncStorage, walletTransactionUpdateStatus, setWalletTransactionUpdateStatus, - setDoNotTrack, - isDoNotTrackEnabled, isElectrumDisabled, setIsElectrumDisabled, - isPrivacyBlurEnabled, - setIsPrivacyBlurEnabled, reloadTransactionsMenuActionFunction, setReloadTransactionsMenuActionFunction, }; return {children}; }; + +export const useStorage = () => useContext(BlueStorageContext); diff --git a/class/quick-actions.tsx b/class/quick-actions.tsx index 56e0a236a..f6222d14d 100644 --- a/class/quick-actions.tsx +++ b/class/quick-actions.tsx @@ -9,12 +9,14 @@ import { formatBalance } from '../loc'; import DeeplinkSchemaMatch from './deeplink-schema-match'; import { TWallet } from './wallets/types'; import useOnAppLaunch from '../hooks/useOnAppLaunch'; +import { useSettings } from '../components/Context/SettingsContext'; const DeviceQuickActionsStorageKey = 'DeviceQuickActionsEnabled'; function DeviceQuickActions(): JSX.Element | null { - const { wallets, walletsInitialized, isStorageEncrypted, preferredFiatCurrency, addWallet, saveToDisk, setSharedCosigner } = - useContext(BlueStorageContext); + const { wallets, walletsInitialized, isStorageEncrypted, addWallet, saveToDisk, setSharedCosigner } = useContext(BlueStorageContext); + const { preferredFiatCurrency } = useSettings(); + const { isViewAllWalletsEnabled, getSelectedDefaultWallet } = useOnAppLaunch(); useEffect(() => { diff --git a/components/Context/SettingsContext.tsx b/components/Context/SettingsContext.tsx new file mode 100644 index 000000000..be4a3de35 --- /dev/null +++ b/components/Context/SettingsContext.tsx @@ -0,0 +1,214 @@ +import React, { createContext, useState, useContext, useEffect } from 'react'; +import { useAsyncStorage } from '@react-native-async-storage/async-storage'; +import { FiatUnit, TFiatUnit } from '../../models/fiatUnit'; +import { getPreferredCurrency, initCurrencyDaemon } from '../../blue_modules/currency'; +import { BlueApp } from '../../class'; +import presentAlert from '../Alert'; +import { STORAGE_KEY, saveLanguage } from '../../loc'; +import { useStorage } from '../../blue_modules/storage-context'; +import { isBalanceDisplayAllowed, setBalanceDisplayAllowed } from '../WidgetCommunication'; +import { clearUseURv1, isURv1Enabled, setUseURv1 } from '../../blue_modules/ur'; +import BlueClipboard from '../../blue_modules/clipboard'; +import DeviceQuickActions from '../../class/quick-actions'; + +interface SettingsContextType { + preferredFiatCurrency: TFiatUnit; + setPreferredFiatCurrencyStorage: (currency: TFiatUnit) => Promise; + language: string | undefined; + setLanguageStorage: (language: string) => Promise; + isHandOffUseEnabled: boolean; + setIsHandOffUseEnabledAsyncStorage: (value: boolean) => Promise; + isPrivacyBlurEnabled: boolean; + setIsPrivacyBlurEnabled: (value: boolean) => void; + isAdvancedModeEnabled: boolean; + setIsAdvancedModeEnabledStorage: (value: boolean) => Promise; + isDoNotTrackEnabled: boolean; + setDoNotTrackStorage: (value: boolean) => Promise; + isWidgetBalanceDisplayAllowed: boolean; + setIsWidgetBalanceDisplayAllowedStorage: (value: boolean) => Promise; + isLegacyURv1Enabled: boolean; + setIsLegacyURv1EnabledStorage: (value: boolean) => Promise; + isClipboardGetContentEnabled: boolean; + setIsClipboardGetContentEnabledStorage: (value: boolean) => Promise; + isQuickActionsEnabled: boolean; + setIsQuickActionsEnabledStorage: (value: boolean) => Promise; +} + +const defaultSettingsContext: SettingsContextType = { + preferredFiatCurrency: FiatUnit.USD, + setPreferredFiatCurrencyStorage: async () => {}, + language: 'en', + setLanguageStorage: async () => {}, + isHandOffUseEnabled: false, + setIsHandOffUseEnabledAsyncStorage: async () => {}, + isPrivacyBlurEnabled: true, + setIsPrivacyBlurEnabled: () => {}, + isAdvancedModeEnabled: false, + setIsAdvancedModeEnabledStorage: async () => {}, + isDoNotTrackEnabled: false, + setDoNotTrackStorage: async () => {}, + isWidgetBalanceDisplayAllowed: true, + setIsWidgetBalanceDisplayAllowedStorage: async () => {}, + setIsLegacyURv1EnabledStorage: async () => {}, + isLegacyURv1Enabled: false, + isClipboardGetContentEnabled: true, + setIsClipboardGetContentEnabledStorage: async () => {}, + isQuickActionsEnabled: true, + setIsQuickActionsEnabledStorage: async () => {}, +}; + +export const SettingsContext = createContext(defaultSettingsContext); + +export const SettingsProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => { + // FiatCurrency + const [preferredFiatCurrency, setPreferredFiatCurrency] = useState(FiatUnit.USD); + // Language + const [language, setLanguage] = useState(); + // HandOff + const [isHandOffUseEnabled, setIsHandOffUseEnabled] = useState(false); + // PrivacyBlur + const [isPrivacyBlurEnabled, setIsPrivacyBlurEnabled] = useState(true); + // AdvancedMode + const [isAdvancedModeEnabled, setIsAdvancedModeEnabled] = useState(false); + // DoNotTrack + const [isDoNotTrackEnabled, setIsDoNotTrackEnabled] = useState(false); + // WidgetCommunication + const [isWidgetBalanceDisplayAllowed, setIsWidgetBalanceDisplayAllowed] = useState(true); + // LegacyURv1 + const [isLegacyURv1Enabled, setIsLegacyURv1Enabled] = useState(false); + // Clipboard + const [isClipboardGetContentEnabled, setIsClipboardGetContentEnabled] = useState(false); + // Quick Actions + const [isQuickActionsEnabled, setIsQuickActionsEnabled] = useState(true); + + const advancedModeStorage = useAsyncStorage(BlueApp.ADVANCED_MODE_ENABLED); + const doNotTrackStorage = useAsyncStorage(BlueApp.DO_NOT_TRACK); + const isHandOffUseEnabledStorage = useAsyncStorage(BlueApp.HANDOFF_STORAGE_KEY); + const languageStorage = useAsyncStorage(STORAGE_KEY); + + const { walletsInitialized } = useStorage(); + + useEffect(() => { + const fetchSettings = async () => { + const advMode = await advancedModeStorage.getItem(); + console.log('SettingsContext advMode:', advMode); + const handOff = await isHandOffUseEnabledStorage.getItem(); + console.log('SettingsContext handOff:', handOff); + const lang = (await languageStorage.getItem()) ?? 'en'; + console.log('SettingsContext lang:', lang); + setIsAdvancedModeEnabled(advMode ? JSON.parse(advMode) : false); + setIsHandOffUseEnabled(handOff ? JSON.parse(handOff) : false); + const isBalanceDisplayAllowedStorage = await isBalanceDisplayAllowed(); + console.log('SettingsContext isBalanceDisplayAllowed:', isBalanceDisplayAllowedStorage); + setIsWidgetBalanceDisplayAllowed(isBalanceDisplayAllowedStorage); + setLanguage(lang); + + const isURv1EnabledStorage = await isURv1Enabled(); + console.log('SettingsContext isURv1Enabled:', isURv1EnabledStorage); + setIsLegacyURv1EnabledStorage(isURv1EnabledStorage); + + const isClipboardGetContentEnabledStorage = await BlueClipboard().isReadClipboardAllowed(); + console.log('SettingsContext isClipboardGetContentEnabled:', isClipboardGetContentEnabledStorage); + setIsClipboardGetContentEnabledStorage(isClipboardGetContentEnabledStorage); + + // @ts-ignore: Fix later + const isQuickActionsEnabledStorage = await DeviceQuickActions.getEnabled(); + console.log('SettingsContext isQuickActionsEnabled:', isQuickActionsEnabledStorage); + setIsQuickActionsEnabledStorage(isQuickActionsEnabledStorage); + }; + + fetchSettings(); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); + + useEffect(() => { + if (walletsInitialized) { + initCurrencyDaemon().finally(() => { + getPreferredCurrency().then(currency => { + console.log('SettingsContext currency:', currency); + setPreferredFiatCurrency(FiatUnit[currency.endPointKey]); + }); + }); + } + }, [walletsInitialized]); + + const setPreferredFiatCurrencyStorage = async (currency: TFiatUnit) => { + await setPreferredFiatCurrency(currency); + setPreferredFiatCurrency(currency); + }; + + const setLanguageStorage = async (newLanguage: string) => { + await saveLanguage(newLanguage); + setLanguage(newLanguage); + }; + + const setIsAdvancedModeEnabledStorage = async (value: boolean) => { + await advancedModeStorage.setItem(JSON.stringify(value)); + setIsAdvancedModeEnabled(value); + }; + + const setDoNotTrackStorage = async (value: boolean) => { + await doNotTrackStorage.setItem(JSON.stringify(value)); + setIsDoNotTrackEnabled(value); + }; + + const setIsHandOffUseEnabledAsyncStorage = async (value: boolean) => { + setIsHandOffUseEnabled(value); + await isHandOffUseEnabledStorage.setItem; + }; + + const setIsWidgetBalanceDisplayAllowedStorage = async (value: boolean) => { + await setBalanceDisplayAllowed(value); + setIsWidgetBalanceDisplayAllowed(value); + }; + + const setIsLegacyURv1EnabledStorage = async (value: boolean) => { + value ? await setUseURv1() : await clearUseURv1(); + await setIsLegacyURv1Enabled(value); + }; + + const setIsClipboardGetContentEnabledStorage = async (value: boolean) => { + await BlueClipboard().setReadClipboardAllowed(value); + setIsClipboardGetContentEnabled(value); + }; + + const setIsQuickActionsEnabledStorage = async (value: boolean) => { + // @ts-ignore: Fix later + await DeviceQuickActions.setEnabled(value); + setIsQuickActionsEnabled(value); + }; + + useEffect(() => { + console.log(`Privacy blur: ${isPrivacyBlurEnabled}`); + if (!isPrivacyBlurEnabled) { + presentAlert({ message: 'Privacy blur has been disabled.' }); + } + }, [isPrivacyBlurEnabled]); + + const value: SettingsContextType = { + preferredFiatCurrency, + setPreferredFiatCurrencyStorage, + language, + setLanguageStorage, + isHandOffUseEnabled, + setIsHandOffUseEnabledAsyncStorage, + isPrivacyBlurEnabled, + setIsPrivacyBlurEnabled, + isAdvancedModeEnabled, + setIsAdvancedModeEnabledStorage, + isDoNotTrackEnabled, + setDoNotTrackStorage, + isWidgetBalanceDisplayAllowed, + setIsWidgetBalanceDisplayAllowedStorage, + isLegacyURv1Enabled, + setIsLegacyURv1EnabledStorage, + isClipboardGetContentEnabled, + setIsClipboardGetContentEnabledStorage, + isQuickActionsEnabled, + setIsQuickActionsEnabledStorage, + }; + + return {children}; +}; + +export const useSettings = () => useContext(SettingsContext); diff --git a/components/HandOffComponent.ios.tsx b/components/HandOffComponent.ios.tsx index 174965be5..739ec9c6b 100644 --- a/components/HandOffComponent.ios.tsx +++ b/components/HandOffComponent.ios.tsx @@ -1,7 +1,7 @@ -import React, { useContext } from 'react'; +import React from 'react'; // @ts-ignore: react-native-handoff is not in the type definition import Handoff from 'react-native-handoff'; -import { BlueStorageContext } from '../blue_modules/storage-context'; +import { useSettings } from './Context/SettingsContext'; interface HandOffComponentProps { url?: string; @@ -19,7 +19,7 @@ interface HandOffComponentWithActivityTypes extends React.FC { - const { isHandOffUseEnabled } = useContext(BlueStorageContext); + const { isHandOffUseEnabled } = useSettings(); if (process.env.NODE_ENV === 'development') { console.log('HandOffComponent: props', props); diff --git a/components/TransactionListItem.js b/components/TransactionListItem.js index c30ce20f2..a7f897257 100644 --- a/components/TransactionListItem.js +++ b/components/TransactionListItem.js @@ -19,13 +19,15 @@ import TransactionOutgoingIcon from '../components/icons/TransactionOutgoingIcon import TransactionPendingIcon from '../components/icons/TransactionPendingIcon'; import { useTheme } from './themes'; import ListItem from './ListItem'; +import { useSettings } from './Context/SettingsContext'; export const TransactionListItem = React.memo(({ item, itemPriceUnit = BitcoinUnit.BTC, walletID }) => { const [subtitleNumberOfLines, setSubtitleNumberOfLines] = useState(1); const { colors } = useTheme(); const { navigate } = useNavigation(); const menuRef = useRef(); - const { txMetadata, wallets, preferredFiatCurrency, language } = useContext(BlueStorageContext); + const { txMetadata, wallets } = useContext(BlueStorageContext); + const { preferredFiatCurrency, language } = useSettings(); const containerStyle = useMemo( () => ({ backgroundColor: 'transparent', diff --git a/components/TransactionsNavigationHeader.tsx b/components/TransactionsNavigationHeader.tsx index 5c15e3398..3c2533b58 100644 --- a/components/TransactionsNavigationHeader.tsx +++ b/components/TransactionsNavigationHeader.tsx @@ -1,4 +1,4 @@ -import React, { useState, useEffect, useRef, useContext, useCallback, useMemo } from 'react'; +import React, { useState, useEffect, useRef, useCallback, useMemo } from 'react'; import { Image, Text, TouchableOpacity, View, I18nManager, StyleSheet, LayoutAnimation } from 'react-native'; import Clipboard from '@react-native-clipboard/clipboard'; import LinearGradient from 'react-native-linear-gradient'; @@ -6,11 +6,11 @@ import { HDSegwitBech32Wallet, LightningCustodianWallet, LightningLdkWallet, Mul import { BitcoinUnit } from '../models/bitcoinUnits'; import WalletGradient from '../class/wallet-gradient'; import loc, { formatBalance, formatBalanceWithoutSuffix } from '../loc'; -import { BlueStorageContext } from '../blue_modules/storage-context'; import ToolTipMenu from './TooltipMenu'; import { FiatUnit } from '../models/fiatUnit'; import { TWallet } from '../class/wallets/types'; import { BlurredBalanceView } from './BlurredBalanceView'; +import { useSettings } from './Context/SettingsContext'; interface TransactionsNavigationHeaderProps { wallet: TWallet; @@ -43,8 +43,8 @@ const TransactionsNavigationHeader: React.FC }) => { const [wallet, setWallet] = useState(initialWallet); const [allowOnchainAddress, setAllowOnchainAddress] = useState(false); + const { preferredFiatCurrency } = useSettings(); - const { preferredFiatCurrency } = useContext(BlueStorageContext); const menuRef = useRef(null); const verifyIfWalletAllowsOnchainAddress = useCallback(() => { diff --git a/components/WalletsCarousel.js b/components/WalletsCarousel.js index 7f7c9db7d..2624344a7 100644 --- a/components/WalletsCarousel.js +++ b/components/WalletsCarousel.js @@ -24,6 +24,7 @@ import { BlueStorageContext, WalletTransactionsStatus } from '../blue_modules/st import { isTablet, isDesktop } from '../blue_modules/environment'; import { useTheme } from './themes'; import { BlurredBalanceView } from './BlurredBalanceView'; +import { useSettings } from './Context/SettingsContext'; const nStyles = StyleSheet.create({ container: { @@ -271,7 +272,7 @@ const cStyles = StyleSheet.create({ const ListHeaderComponent = () => ; const WalletsCarousel = forwardRef((props, ref) => { - const { preferredFiatCurrency, language } = useContext(BlueStorageContext); + const { preferredFiatCurrency, language } = useSettings(); const { horizontal, data, handleLongPress, onPress, selectedWallet } = props; const renderItem = useCallback( ({ item, index }) => diff --git a/components/WidgetCommunication.ios.tsx b/components/WidgetCommunication.ios.tsx index 2954071fa..fa95b198b 100644 --- a/components/WidgetCommunication.ios.tsx +++ b/components/WidgetCommunication.ios.tsx @@ -1,9 +1,10 @@ import React, { useContext, useEffect } from 'react'; import DefaultPreference from 'react-native-default-preference'; -// @ts-ignore: fix later +// @ts-ignore: no type definitions import RNWidgetCenter from 'react-native-widget-center'; import { BlueStorageContext } from '../blue_modules/storage-context'; import { TWallet } from '../class/wallets/types'; +import { useSettings } from './Context/SettingsContext'; enum WidgetCommunicationKeys { AllWalletsSatoshiBalance = 'WidgetCommunicationAllWalletsSatoshiBalance', @@ -18,6 +19,7 @@ export const reloadAllTimelines = (): void => { export const isBalanceDisplayAllowed = async (): Promise => { try { + await DefaultPreference.setName('group.io.bluewallet.bluewallet'); const displayBalance = await DefaultPreference.get(WidgetCommunicationKeys.DisplayBalanceAllowed); return displayBalance === '1'; } catch { @@ -26,6 +28,7 @@ export const isBalanceDisplayAllowed = async (): Promise => { }; export const setBalanceDisplayAllowed = async (value: boolean): Promise => { + await DefaultPreference.setName('group.io.bluewallet.bluewallet'); if (value) { await DefaultPreference.set(WidgetCommunicationKeys.DisplayBalanceAllowed, '1'); } else { @@ -34,45 +37,45 @@ export const setBalanceDisplayAllowed = async (value: boolean): Promise => reloadAllTimelines(); }; +export const syncWidgetBalanceWithWallets = async (wallets: TWallet[], walletsInitialized: boolean): Promise => { + await DefaultPreference.setName('group.io.bluewallet.bluewallet'); + const { allWalletsBalance, latestTransactionTime } = await allWalletsBalanceAndTransactionTime(wallets, walletsInitialized); + await DefaultPreference.set(WidgetCommunicationKeys.AllWalletsSatoshiBalance, String(allWalletsBalance)); + await DefaultPreference.set(WidgetCommunicationKeys.AllWalletsLatestTransactionTime, String(latestTransactionTime)); + reloadAllTimelines(); +}; + +const allWalletsBalanceAndTransactionTime = async ( + wallets: TWallet[], + walletsInitialized: boolean, +): Promise<{ allWalletsBalance: number; latestTransactionTime: number | string }> => { + if (!walletsInitialized || !(await isBalanceDisplayAllowed())) { + return { allWalletsBalance: 0, latestTransactionTime: 0 }; + } + let balance = 0; + let latestTransactionTime: number | string = 0; + wallets.forEach((wallet: TWallet) => { + if (wallet.hideBalance) return; + balance += wallet.getBalance(); + const walletLatestTime = wallet.getLatestTransactionTimeEpoch(); + if (typeof latestTransactionTime === 'number' && walletLatestTime > latestTransactionTime) { + latestTransactionTime = + wallet.getTransactions()[0]?.confirmations === 0 ? WidgetCommunicationKeys.LatestTransactionIsUnconfirmed : walletLatestTime; + } + }); + + return { allWalletsBalance: balance, latestTransactionTime }; +}; + const WidgetCommunication: React.FC = () => { const { wallets, walletsInitialized } = useContext(BlueStorageContext); + const { isWidgetBalanceDisplayAllowed } = useSettings(); useEffect(() => { - const allWalletsBalanceAndTransactionTime = async (): Promise<{ - allWalletsBalance: number; - latestTransactionTime: number | string; - }> => { - if (!walletsInitialized || !(await isBalanceDisplayAllowed())) { - return { allWalletsBalance: 0, latestTransactionTime: 0 }; - } else { - let balance = 0; - let latestTransactionTime: number | string = 0; - wallets.forEach((wallet: TWallet) => { - if (wallet.hideBalance) return; - balance += wallet.getBalance(); - const walletLatestTime = wallet.getLatestTransactionTimeEpoch(); - - if (typeof latestTransactionTime === 'number' && walletLatestTime > latestTransactionTime) { - latestTransactionTime = - wallet.getTransactions()[0]?.confirmations === 0 ? WidgetCommunicationKeys.LatestTransactionIsUnconfirmed : walletLatestTime; - } - }); - return { allWalletsBalance: balance, latestTransactionTime }; - } - }; - - const setValues = async (): Promise => { - await DefaultPreference.setName('group.io.bluewallet.bluewallet'); - const { allWalletsBalance, latestTransactionTime } = await allWalletsBalanceAndTransactionTime(); - await DefaultPreference.set(WidgetCommunicationKeys.AllWalletsSatoshiBalance, String(allWalletsBalance)); - await DefaultPreference.set(WidgetCommunicationKeys.AllWalletsLatestTransactionTime, String(latestTransactionTime)); - reloadAllTimelines(); - }; - if (walletsInitialized) { - setValues(); + syncWidgetBalanceWithWallets(wallets, walletsInitialized); } - }, [wallets, walletsInitialized]); + }, [wallets, walletsInitialized, isWidgetBalanceDisplayAllowed]); return null; }; diff --git a/components/WidgetCommunication.tsx b/components/WidgetCommunication.tsx index 05b768147..0afb6dbc4 100644 --- a/components/WidgetCommunication.tsx +++ b/components/WidgetCommunication.tsx @@ -1,4 +1,5 @@ import React from 'react'; +import { TWallet } from '../class/wallets/types'; export const isBalanceDisplayAllowed = async (): Promise => { return true; @@ -8,6 +9,8 @@ export const setBalanceDisplayAllowed = async (value: boolean): Promise => export const reloadAllTimelines = (): void => {}; +export const syncWidgetBalanceWithWallets = async (_wallets: TWallet[], _walletsInitialized: boolean): Promise => {}; + const WidgetCommunication: React.FC = () => { return null; // This component does not render anything. }; diff --git a/hooks/usePrivacy.android.tsx b/hooks/usePrivacy.android.tsx index 9b92fd1cc..f8c6f81b0 100644 --- a/hooks/usePrivacy.android.tsx +++ b/hooks/usePrivacy.android.tsx @@ -1,10 +1,10 @@ -import { useContext, useEffect, useCallback } from 'react'; +import { useEffect, useCallback } from 'react'; // @ts-ignore: react-native-obscure is not in the type definition import Obscure from 'react-native-obscure'; -import { BlueStorageContext } from '../blue_modules/storage-context'; +import { useSettings } from '../components/Context/SettingsContext'; export const usePrivacy = () => { - const { isPrivacyBlurEnabled } = useContext(BlueStorageContext); + const { isPrivacyBlurEnabled } = useSettings(); const enableBlur = useCallback(() => { if (!isPrivacyBlurEnabled) return; diff --git a/hooks/usePrivacy.ios.tsx b/hooks/usePrivacy.ios.tsx index 581cbbb94..f2812880f 100644 --- a/hooks/usePrivacy.ios.tsx +++ b/hooks/usePrivacy.ios.tsx @@ -1,10 +1,10 @@ -import { useContext, useEffect, useCallback } from 'react'; +import { useEffect, useCallback } from 'react'; // @ts-ignore: react-native-obscure is not in the type definition import { enabled } from 'react-native-privacy-snapshot'; -import { BlueStorageContext } from '../blue_modules/storage-context'; +import { useSettings } from '../components/Context/SettingsContext'; export const usePrivacy = () => { - const { isPrivacyBlurEnabled } = useContext(BlueStorageContext); + const { isPrivacyBlurEnabled } = useSettings(); const enableBlur = useCallback(() => { if (!isPrivacyBlurEnabled) return; diff --git a/index.js b/index.js index 35517fc0e..db9ff2f8d 100644 --- a/index.js +++ b/index.js @@ -6,6 +6,7 @@ import { AppRegistry } from 'react-native'; import App from './App'; import { BlueStorageProvider } from './blue_modules/storage-context'; import A from './blue_modules/analytics'; +import { SettingsProvider } from './components/Context/SettingsContext'; if (!Error.captureStackTrace) { // captureStackTrace is only available when debugging @@ -19,7 +20,9 @@ const BlueAppComponent = () => { return ( - + + + ); }; diff --git a/screen/settings/Currency.tsx b/screen/settings/Currency.tsx index 9ab8e86a5..f36a3930e 100644 --- a/screen/settings/Currency.tsx +++ b/screen/settings/Currency.tsx @@ -1,6 +1,6 @@ import { useNavigation } from '@react-navigation/native'; import dayjs from 'dayjs'; -import React, { useContext, useLayoutEffect, useState } from 'react'; +import React, { useLayoutEffect, useState } from 'react'; import { FlatList, NativeSyntheticEvent, StyleSheet, View } from 'react-native'; import { BlueCard, BlueSpacing10, BlueText } from '../../BlueComponents'; import { @@ -10,16 +10,16 @@ import { mostRecentFetchedRate, setPreferredCurrency, } from '../../blue_modules/currency'; -import { BlueStorageContext } from '../../blue_modules/storage-context'; import presentAlert from '../../components/Alert'; import ListItem from '../../components/ListItem'; import { useTheme } from '../../components/themes'; import loc from '../../loc'; import { FiatUnit, FiatUnitSource, FiatUnitType, getFiatRate } from '../../models/fiatUnit'; +import { useSettings } from '../../components/Context/SettingsContext'; dayjs.extend(require('dayjs/plugin/calendar')); const Currency = () => { - const { setPreferredFiatCurrency } = useContext(BlueStorageContext); + const { setPreferredFiatCurrencyStorage } = useSettings(); const [isSavingNewPreferredCurrency, setIsSavingNewPreferredCurrency] = useState(false); const [selectedCurrency, setSelectedCurrency] = useState(FiatUnit.USD); const [currencyRate, setCurrencyRate] = useState({ LastUpdated: null, Rate: null }); @@ -74,7 +74,7 @@ const Currency = () => { await initCurrencyDaemon(true); await fetchCurrency(); setSelectedCurrency(item); - setPreferredFiatCurrency(); + setPreferredFiatCurrencyStorage(FiatUnit[item.endPointKey]); } catch (error: any) { console.log(error); presentAlert({ diff --git a/screen/settings/GeneralSettings.tsx b/screen/settings/GeneralSettings.tsx index af7b8dfde..323713de8 100644 --- a/screen/settings/GeneralSettings.tsx +++ b/screen/settings/GeneralSettings.tsx @@ -1,13 +1,13 @@ -import React, { useContext, useEffect, useState } from 'react'; +import React, { useContext } from 'react'; import { Platform, ScrollView, StyleSheet } from 'react-native'; import { useNavigation } from '@react-navigation/native'; -import { BlueCard, BlueLoading, BlueSpacing20, BlueText } from '../../BlueComponents'; +import { BlueCard, BlueSpacing20, BlueText } from '../../BlueComponents'; import { BlueStorageContext } from '../../blue_modules/storage-context'; -import { clearUseURv1, isURv1Enabled, setUseURv1 } from '../../blue_modules/ur'; import ListItem, { PressableWrapper } from '../../components/ListItem'; import { useTheme } from '../../components/themes'; import loc from '../../loc'; +import { useSettings } from '../../components/Context/SettingsContext'; const styles = StyleSheet.create({ root: { @@ -16,29 +16,17 @@ const styles = StyleSheet.create({ }); const GeneralSettings: React.FC = () => { - const { isAdvancedModeEnabled, setIsAdvancedModeEnabled, wallets, isHandOffUseEnabled, setIsHandOffUseEnabledAsyncStorage } = - useContext(BlueStorageContext); - const [isLoading, setIsLoading] = useState(true); - const [isAdvancedModeSwitchEnabled, setIsAdvancedModeSwitchEnabled] = useState(false); - const [isURv1SwitchEnabled, setIsURv1SwitchEnabled] = useState(false); + const { wallets } = useContext(BlueStorageContext); + const { + isAdvancedModeEnabled, + setIsAdvancedModeEnabledStorage, + isHandOffUseEnabled, + setIsHandOffUseEnabledAsyncStorage, + isLegacyURv1Enabled, + setIsLegacyURv1EnabledStorage, + } = useSettings(); const { navigate } = useNavigation(); const { colors } = useTheme(); - const onAdvancedModeSwitch = async (value: boolean) => { - await setIsAdvancedModeEnabled(value); - setIsAdvancedModeSwitchEnabled(value); - }; - const onLegacyURv1Switch = async (value: boolean) => { - setIsURv1SwitchEnabled(value); - return value ? setUseURv1() : clearUseURv1(); - }; - - useEffect(() => { - (async () => { - setIsAdvancedModeSwitchEnabled(await isAdvancedModeEnabled()); - setIsURv1SwitchEnabled(await isURv1Enabled()); - setIsLoading(false); - })(); - }); const navigateToPrivacy = () => { // @ts-ignore: Fix later @@ -51,9 +39,7 @@ const GeneralSettings: React.FC = () => { }, }; - return isLoading ? ( - - ) : ( + return ( {wallets.length > 1 && ( <> @@ -79,7 +65,7 @@ const GeneralSettings: React.FC = () => { {loc.settings.general_adv_mode_e} @@ -88,7 +74,7 @@ const GeneralSettings: React.FC = () => { diff --git a/screen/settings/Settings.js b/screen/settings/Settings.js index b0fef5451..5b46936a4 100644 --- a/screen/settings/Settings.js +++ b/screen/settings/Settings.js @@ -1,10 +1,10 @@ -import React, { useContext } from 'react'; +import React from 'react'; import { ScrollView, StyleSheet, Platform } from 'react-native'; import { BlueHeaderDefaultSub } from '../../BlueComponents'; import loc from '../../loc'; -import { BlueStorageContext } from '../../blue_modules/storage-context'; import ListItem from '../../components/ListItem'; import { useExtendedNavigation } from '../../hooks/useExtendedNavigation'; +import { useSettings } from '../../components/Context/SettingsContext'; const styles = StyleSheet.create({ root: { @@ -22,7 +22,7 @@ const Settings = () => { const { navigate } = useExtendedNavigation(); // By simply having it here, it'll re-render the UI if language is changed // eslint-disable-next-line @typescript-eslint/no-unused-vars - const { language } = useContext(BlueStorageContext); + const { language } = useSettings(); return ( { const { colors } = useTheme(); - const { isStorageEncrypted, isDoNotTrackEnabled, setDoNotTrack, setIsPrivacyBlurEnabled } = useContext(BlueStorageContext); + const { isStorageEncrypted } = useContext(BlueStorageContext); + const { + isDoNotTrackEnabled, + setDoNotTrackStorage, + setIsPrivacyBlurEnabled, + isWidgetBalanceDisplayAllowed, + setIsWidgetBalanceDisplayAllowedStorage, + isClipboardGetContentEnabled, + setIsClipboardGetContentEnabledStorage, + } = useSettings(); const sections = Object.freeze({ ALL: 0, CLIPBOARDREAD: 1, QUICKACTION: 2, WIDGETS: 3 }); const [isLoading, setIsLoading] = useState(sections.ALL); - const [isReadClipboardAllowed, setIsReadClipboardAllowed] = useState(false); - const [doNotTrackSwitchValue, setDoNotTrackSwitchValue] = useState(false); - const [isDisplayWidgetBalanceAllowed, setIsDisplayWidgetBalanceAllowed] = useState(false); const [isQuickActionsEnabled, setIsQuickActionsEnabled] = useState(false); const [storageIsEncrypted, setStorageIsEncrypted] = useState(true); const [isPrivacyBlurEnabledTapped, setIsPrivacyBlurEnabledTapped] = useState(0); @@ -34,11 +39,8 @@ const SettingsPrivacy = () => { useEffect(() => { (async () => { try { - isDoNotTrackEnabled().then(setDoNotTrackSwitchValue); - setIsReadClipboardAllowed(await BlueClipboard().isReadClipboardAllowed()); setStorageIsEncrypted(await isStorageEncrypted()); setIsQuickActionsEnabled(await DeviceQuickActions.getEnabled()); - setIsDisplayWidgetBalanceAllowed(await isBalanceDisplayAllowed()); } catch (e) { console.log(e); } @@ -47,23 +49,11 @@ const SettingsPrivacy = () => { // eslint-disable-next-line react-hooks/exhaustive-deps }, []); - const onValueChange = async value => { - setIsLoading(sections.CLIPBOARDREAD); - try { - await BlueClipboard().setReadClipboardAllowed(value); - setIsReadClipboardAllowed(value); - } catch (e) { - console.log(e); - } - setIsLoading(false); - }; - const onDoNotTrackValueChange = async value => { setIsLoading(sections.ALL); try { - await setDoNotTrack(value); + setDoNotTrackStorage(value); A.setOptOut(value); - setDoNotTrackSwitchValue(value); } catch (e) { console.log(e); } @@ -84,8 +74,7 @@ const SettingsPrivacy = () => { const onWidgetsTotalBalanceValueChange = async value => { setIsLoading(sections.WIDGETS); try { - await setBalanceDisplayAllowed(value); - setIsDisplayWidgetBalanceAllowed(value); + setIsWidgetBalanceDisplayAllowedStorage(value); } catch (e) { console.log(e); } @@ -116,7 +105,12 @@ const SettingsPrivacy = () => { hideChevron title={loc.settings.privacy_read_clipboard} Component={TouchableWithoutFeedback} - switch={{ onValueChange, value: isReadClipboardAllowed, disabled: isLoading === sections.ALL, testID: 'ClipboardSwitch' }} + switch={{ + onValueChange: setIsClipboardGetContentEnabledStorage, + value: isClipboardGetContentEnabled, + disabled: isLoading === sections.ALL, + testID: 'ClipboardSwitch', + }} /> {loc.settings.privacy_clipboard_explanation} @@ -144,7 +138,7 @@ const SettingsPrivacy = () => { hideChevron title={loc.settings.privacy_do_not_track} Component={TouchableWithoutFeedback} - switch={{ onValueChange: onDoNotTrackValueChange, value: doNotTrackSwitchValue, disabled: isLoading === sections.ALL }} + switch={{ onValueChange: onDoNotTrackValueChange, value: isDoNotTrackEnabled, disabled: isLoading === sections.ALL }} /> {loc.settings.privacy_do_not_track_explanation} @@ -161,7 +155,7 @@ const SettingsPrivacy = () => { Component={TouchableWithoutFeedback} switch={{ onValueChange: onWidgetsTotalBalanceValueChange, - value: isDisplayWidgetBalanceAllowed, + value: isWidgetBalanceDisplayAllowed, disabled: isLoading === sections.ALL, }} /> diff --git a/screen/settings/language.tsx b/screen/settings/language.tsx index 595f55e47..d9c80ac95 100644 --- a/screen/settings/language.tsx +++ b/screen/settings/language.tsx @@ -1,14 +1,14 @@ import { useNavigation } from '@react-navigation/native'; -import React, { useContext, useEffect, useState } from 'react'; +import React, { useEffect } from 'react'; import { FlatList, StyleSheet } from 'react-native'; import { useSafeAreaInsets } from 'react-native-safe-area-context'; -import { BlueStorageContext } from '../../blue_modules/storage-context'; import presentAlert from '../../components/Alert'; import ListItem from '../../components/ListItem'; import { useTheme } from '../../components/themes'; -import loc, { saveLanguage } from '../../loc'; +import loc from '../../loc'; import { AvailableLanguages, TLanguage } from '../../loc/languages'; +import { useSettings } from '../../components/Context/SettingsContext'; const styles = StyleSheet.create({ flex: { @@ -17,8 +17,7 @@ const styles = StyleSheet.create({ }); const Language = () => { - const { setLanguage, language } = useContext(BlueStorageContext); - const [selectedLanguage, setSelectedLanguage] = useState(loc.getLanguage()); + const { setLanguageStorage, language } = useSettings(); const { setOptions } = useNavigation(); const { colors } = useTheme(); const insets = useSafeAreaInsets(); @@ -37,10 +36,8 @@ const Language = () => { }, [language]); const onLanguageSelect = (item: TLanguage) => { - const currentLanguage = AvailableLanguages.find(l => l.value === selectedLanguage); - saveLanguage(item.value).then(() => { - setSelectedLanguage(item.value); - setLanguage(); + const currentLanguage = AvailableLanguages.find(l => l.value === language); + setLanguageStorage(item.value).then(() => { if (currentLanguage?.isRTL !== item.isRTL) { presentAlert({ message: loc.settings.language_isRTL }); } @@ -48,7 +45,7 @@ const Language = () => { }; const renderItem = ({ item }: { item: TLanguage }) => { - return onLanguageSelect(item)} />; + return onLanguageSelect(item)} />; }; return ( diff --git a/screen/wallets/ViewEditMultisigCosigners.tsx b/screen/wallets/ViewEditMultisigCosigners.tsx index 1e50074a2..5b018c822 100644 --- a/screen/wallets/ViewEditMultisigCosigners.tsx +++ b/screen/wallets/ViewEditMultisigCosigners.tsx @@ -1,6 +1,6 @@ import { useFocusEffect } from '@react-navigation/native'; import { NativeStackScreenProps } from '@react-navigation/native-stack'; -import React, { useCallback, useContext, useEffect, useRef, useState } from 'react'; +import React, { useCallback, useContext, useRef, useState } from 'react'; import { ActivityIndicator, Alert, @@ -55,13 +55,15 @@ import ActionSheet from '../ActionSheet'; import SaveFileButton from '../../components/SaveFileButton'; import { useExtendedNavigation } from '../../hooks/useExtendedNavigation'; import prompt from '../../helpers/prompt'; +import { useSettings } from '../../components/Context/SettingsContext'; type Props = NativeStackScreenProps; const ViewEditMultisigCosigners = ({ route }: Props) => { const hasLoaded = useRef(false); const { colors } = useTheme(); - const { wallets, setWalletsWithNewOrder, isElectrumDisabled, isAdvancedModeEnabled } = useContext(BlueStorageContext); + const { wallets, setWalletsWithNewOrder, isElectrumDisabled } = useContext(BlueStorageContext); + const { isAdvancedModeEnabled } = useSettings(); const { navigate, dispatch, addListener } = useExtendedNavigation(); const openScannerButtonRef = useRef(); const { walletId } = route.params; @@ -80,7 +82,6 @@ const ViewEditMultisigCosigners = ({ route }: Props) => { const [exportFilename, setExportFilename] = useState('bw-cosigner.json'); const [vaultKeyData, setVaultKeyData] = useState({ keyIndex: 1, xpub: '', seed: '', passphrase: '', path: '', fp: '', isLoading: false }); // string rendered in modal const [askPassphrase, setAskPassphrase] = useState(false); - const [isAdvancedModeEnabledRender, setIsAdvancedModeEnabledRender] = useState(false); const data = useRef(); /* discardChangesRef is only so the action sheet can be shown on mac catalyst when a user tries to leave the screen with unsaved changes. @@ -167,11 +168,6 @@ const ViewEditMultisigCosigners = ({ route }: Props) => { }, [isSaveButtonDisabled, addListener, dispatch]), ); - useEffect(() => { - isAdvancedModeEnabled().then(setIsAdvancedModeEnabledRender); - // eslint-disable-next-line react-hooks/exhaustive-deps - }, []); - const saveFileButtonAfterOnPress = () => { setIsShareModalVisible(false); }; @@ -546,7 +542,7 @@ const ViewEditMultisigCosigners = ({ route }: Props) => { {loc.multisig.type_your_mnemonics} - {isAdvancedModeEnabledRender && ( + {isAdvancedModeEnabled && ( <> diff --git a/screen/wallets/add.tsx b/screen/wallets/add.tsx index e9ba682e5..62e5482ab 100644 --- a/screen/wallets/add.tsx +++ b/screen/wallets/add.tsx @@ -31,11 +31,11 @@ import Button from '../../components/Button'; import { LdkButton } from '../../components/LdkButton'; import ListItem from '../../components/ListItem'; import { useTheme } from '../../components/themes'; -import useAsyncPromise from '../../hooks/useAsyncPromise'; import loc from '../../loc'; import { Chain } from '../../models/bitcoinUnits'; import WalletButton from '../../components/WalletButton'; import A from '../../blue_modules/analytics'; +import { useSettings } from '../../components/Context/SettingsContext'; enum ButtonSelected { // @ts-ignore: Return later to update @@ -123,8 +123,8 @@ const WalletsAdd: React.FC = () => { const entropyButtonText = state.entropyButtonText; // const colorScheme = useColorScheme(); - const { addWallet, saveToDisk, isAdvancedModeEnabled, wallets } = useContext(BlueStorageContext); - const isAdvancedOptionsEnabled = useAsyncPromise(isAdvancedModeEnabled); + const { addWallet, saveToDisk, wallets } = useContext(BlueStorageContext); + const { isAdvancedModeEnabled } = useSettings(); const { navigate, goBack, setOptions } = useNavigation(); const stylesHook = { advancedText: { @@ -423,7 +423,7 @@ const WalletsAdd: React.FC = () => { {(() => { - if (selectedWalletType === ButtonSelected.ONCHAIN && isAdvancedOptionsEnabled.data) { + if (selectedWalletType === ButtonSelected.ONCHAIN && isAdvancedModeEnabled) { return ( @@ -478,7 +478,7 @@ const WalletsAdd: React.FC = () => { ); } })()} - {isAdvancedOptionsEnabled.data === true && selectedWalletType === ButtonSelected.ONCHAIN && !isLoading && ( + {isAdvancedModeEnabled === true && selectedWalletType === ButtonSelected.ONCHAIN && !isLoading && ( )} diff --git a/screen/wallets/addMultisig.js b/screen/wallets/addMultisig.js index ba0096178..507874d71 100644 --- a/screen/wallets/addMultisig.js +++ b/screen/wallets/addMultisig.js @@ -1,4 +1,4 @@ -import React, { useState, useRef, useEffect, useContext } from 'react'; +import React, { useState, useRef, useEffect } from 'react'; import { Keyboard, ScrollView, StyleSheet, Text, TouchableOpacity, View } from 'react-native'; import LottieView from 'lottie-react-native'; import { Icon } from 'react-native-elements'; @@ -8,11 +8,11 @@ import navigationStyle from '../../components/navigationStyle'; import BottomModal from '../../components/BottomModal'; import { MultisigHDWallet } from '../../class'; import loc from '../../loc'; -import { BlueStorageContext } from '../../blue_modules/storage-context'; import { useTheme } from '../../components/themes'; import Button from '../../components/Button'; import ListItem from '../../components/ListItem'; import SafeArea from '../../components/SafeArea'; +import { useSettings } from '../../components/Context/SettingsContext'; const WalletsAddMultisig = () => { const { colors } = useTheme(); @@ -23,8 +23,7 @@ const WalletsAddMultisig = () => { const [n, setN] = useState(3); const [isModalVisible, setIsModalVisible] = useState(false); const [format, setFormat] = useState(MultisigHDWallet.FORMAT_P2WSH); - const { isAdvancedModeEnabled } = useContext(BlueStorageContext); - const [isAdvancedModeEnabledRender, setIsAdvancedModeEnabledRender] = useState(false); + const { isAdvancedModeEnabled } = useSettings(); const stylesHook = StyleSheet.create({ root: { @@ -65,11 +64,6 @@ const WalletsAddMultisig = () => { } }, []); - useEffect(() => { - isAdvancedModeEnabled().then(setIsAdvancedModeEnabledRender); - // eslint-disable-next-line react-hooks/exhaustive-deps - }, []); - const onLetsStartPress = () => { navigate('WalletsAddMultisigStep2', { m, n, format, walletLabel }); }; @@ -227,7 +221,7 @@ const WalletsAddMultisig = () => { - {isAdvancedModeEnabledRender && ( + {isAdvancedModeEnabled && ( { - const { addWallet, saveToDisk, isElectrumDisabled, isAdvancedModeEnabled, sleep, currentSharedCosigner, setSharedCosigner } = - useContext(BlueStorageContext); + const { addWallet, saveToDisk, isElectrumDisabled, sleep, currentSharedCosigner, setSharedCosigner } = useContext(BlueStorageContext); + const { isAdvancedModeEnabled } = useSettings(); const { colors } = useTheme(); const navigation = useNavigation(); @@ -62,16 +63,10 @@ const WalletsAddMultisigStep2 = () => { const [vaultKeyData, setVaultKeyData] = useState({ keyIndex: 1, xpub: '', seed: '', isLoading: false }); // string rendered in modal const [importText, setImportText] = useState(''); const [askPassphrase, setAskPassphrase] = useState(false); - const [isAdvancedModeEnabledRender, setIsAdvancedModeEnabledRender] = useState(false); const openScannerButton = useRef(); const data = useRef(new Array(n)); const { enableBlur, disableBlur } = usePrivacy(); - useEffect(() => { - isAdvancedModeEnabled().then(setIsAdvancedModeEnabledRender); - // eslint-disable-next-line react-hooks/exhaustive-deps - }, []); - useFocusEffect( useCallback(() => { enableBlur(); @@ -607,7 +602,7 @@ const WalletsAddMultisigStep2 = () => { {loc.multisig.type_your_mnemonics} - {isAdvancedModeEnabledRender && ( + {isAdvancedModeEnabled && ( <> diff --git a/screen/wallets/details.js b/screen/wallets/details.js index 828e29a9f..1f283b1f4 100644 --- a/screen/wallets/details.js +++ b/screen/wallets/details.js @@ -50,6 +50,7 @@ import { useExtendedNavigation } from '../../hooks/useExtendedNavigation'; import loc, { formatBalanceWithoutSuffix } from '../../loc'; import { BitcoinUnit, Chain } from '../../models/bitcoinUnits'; import SaveFileButton from '../../components/SaveFileButton'; +import { useSettings } from '../../components/Context/SettingsContext'; const styles = StyleSheet.create({ scrollViewContent: { @@ -129,8 +130,7 @@ const WalletDetails = () => { const wallet = useRef(wallets.find(w => w.getID() === walletID)).current; const [walletName, setWalletName] = useState(wallet.getLabel()); const [useWithHardwareWallet, setUseWithHardwareWallet] = useState(wallet.useWithHardwareWalletEnabled()); - const { isAdvancedModeEnabled } = useContext(BlueStorageContext); - const [isAdvancedModeEnabledRender, setIsAdvancedModeEnabledRender] = useState(false); + const { isAdvancedModeEnabled } = useSettings(); const [isBIP47Enabled, setIsBIP47Enabled] = useState(wallet.isBIP47Enabled()); const [hideTransactionsInWalletsList, setHideTransactionsInWalletsList] = useState(!wallet.getHideTransactionsInWalletsList()); const { goBack, setOptions, popToTop, navigate } = useExtendedNavigation(); @@ -152,12 +152,12 @@ const WalletDetails = () => { const onMenuWillHide = () => setIsToolTipMenuVisible(false); useEffect(() => { - if (isAdvancedModeEnabledRender && wallet.allowMasterFingerprint()) { + if (isAdvancedModeEnabled && wallet.allowMasterFingerprint()) { InteractionManager.runAfterInteractions(() => { setMasterFingerprint(wallet.getMasterFingerprintHex()); }); } - }, [isAdvancedModeEnabledRender, wallet]); + }, [isAdvancedModeEnabled, wallet]); const stylesHook = StyleSheet.create({ textLabel1: { color: colors.feeText, @@ -214,8 +214,6 @@ const WalletDetails = () => { }; useLayoutEffect(() => { - isAdvancedModeEnabled().then(setIsAdvancedModeEnabledRender); - setOptions({ // eslint-disable-next-line react/no-unstable-nested-components headerRight: () => ( @@ -635,7 +633,7 @@ const WalletDetails = () => { )} - {isAdvancedModeEnabledRender && ( + {isAdvancedModeEnabled && ( {wallet.allowMasterFingerprint() && ( diff --git a/screen/wallets/import.js b/screen/wallets/import.js index 8ed7e571c..371269954 100644 --- a/screen/wallets/import.js +++ b/screen/wallets/import.js @@ -1,4 +1,4 @@ -import React, { useEffect, useState, useContext } from 'react'; +import React, { useEffect, useState } from 'react'; import { Platform, View, Keyboard, StyleSheet, Switch, TouchableWithoutFeedback } from 'react-native'; import { useNavigation, useRoute } from '@react-navigation/native'; import { @@ -11,12 +11,12 @@ import { } from '../../BlueComponents'; import navigationStyle from '../../components/navigationStyle'; import loc from '../../loc'; -import { BlueStorageContext } from '../../blue_modules/storage-context'; import { requestCameraAuthorization } from '../../helpers/scan-qr'; import { useTheme } from '../../components/themes'; import Button from '../../components/Button'; import SafeArea from '../../components/SafeArea'; import usePrivacy from '../../hooks/usePrivacy'; +import { useSettings } from '../../components/Context/SettingsContext'; const WalletsImport = () => { const navigation = useNavigation(); @@ -24,11 +24,10 @@ const WalletsImport = () => { const route = useRoute(); const label = route?.params?.label ?? ''; const triggerImport = route?.params?.triggerImport ?? false; - const { isAdvancedModeEnabled } = useContext(BlueStorageContext); + const { isAdvancedModeEnabled } = useSettings(); const [importText, setImportText] = useState(label); const [isToolbarVisibleForAndroid, setIsToolbarVisibleForAndroid] = useState(false); const [, setSpeedBackdoor] = useState(0); - const [isAdvancedModeEnabledRender, setIsAdvancedModeEnabledRender] = useState(false); const [searchAccounts, setSearchAccounts] = useState(false); const [askPassphrase, setAskPassphrase] = useState(false); const { enableBlur, disableBlur } = usePrivacy(); @@ -70,7 +69,6 @@ const WalletsImport = () => { }, [disableBlur, enableBlur]); useEffect(() => { - isAdvancedModeEnabled().then(setIsAdvancedModeEnabledRender); if (triggerImport) importButtonPressed(); // eslint-disable-next-line react-hooks/exhaustive-deps }, []); @@ -117,7 +115,7 @@ const WalletsImport = () => { const renderOptionsAndImportButton = ( <> - {isAdvancedModeEnabledRender && ( + {isAdvancedModeEnabled && ( <> {loc.wallets.import_passphrase}