diff --git a/app/components/Views/Settings/DisplayNFTMediaSettings/__snapshots__/index.test.tsx.snap b/app/components/Views/Settings/DisplayNFTMediaSettings/__snapshots__/index.test.tsx.snap new file mode 100644 index 00000000000..a76d061844e --- /dev/null +++ b/app/components/Views/Settings/DisplayNFTMediaSettings/__snapshots__/index.test.tsx.snap @@ -0,0 +1,89 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`DisplayNFTMediaSettings should render correctly 1`] = ` + + + + Display NFT Media + + + + + + + Displaying NFT media and data exposes your IP address to OpenSea or other third parties. NFT autodetection relies on this feature, and won't be available when turned off. If NFT media is fully located on IPFS, it can still be displayed even when this feature is turned off. + + +`; diff --git a/app/components/Views/Settings/DisplayNFTMediaSettings/index.constants.ts b/app/components/Views/Settings/DisplayNFTMediaSettings/index.constants.ts new file mode 100644 index 00000000000..e4e04eae3b5 --- /dev/null +++ b/app/components/Views/Settings/DisplayNFTMediaSettings/index.constants.ts @@ -0,0 +1 @@ +export const NFT_DISPLAY_MEDIA_MODE_SECTION = 'nft-display-media-mode-section'; diff --git a/app/components/Views/Settings/DisplayNFTMediaSettings/index.styles.ts b/app/components/Views/Settings/DisplayNFTMediaSettings/index.styles.ts new file mode 100644 index 00000000000..a0252e30b0c --- /dev/null +++ b/app/components/Views/Settings/DisplayNFTMediaSettings/index.styles.ts @@ -0,0 +1,26 @@ +import { StyleSheet } from 'react-native'; + +const styleSheet = () => + StyleSheet.create({ + titleContainer: { + flexDirection: 'row', + alignItems: 'center', + }, + title: { + flex: 1, + }, + switchElement: { + marginLeft: 16, + }, + switch: { + alignSelf: 'flex-start', + }, + halfSetting: { + marginTop: 16, + }, + desc: { + marginTop: 8, + }, + }); + +export default styleSheet; diff --git a/app/components/Views/Settings/DisplayNFTMediaSettings/index.test.tsx b/app/components/Views/Settings/DisplayNFTMediaSettings/index.test.tsx new file mode 100644 index 00000000000..830474e13d6 --- /dev/null +++ b/app/components/Views/Settings/DisplayNFTMediaSettings/index.test.tsx @@ -0,0 +1,74 @@ +import React from 'react'; +import { fireEvent } from '@testing-library/react-native'; +import Engine from '../../../../core/Engine'; +import renderWithProvider from '../../../../util/test/renderWithProvider'; +import { backgroundState } from '../../../../util/test/initial-root-state'; +import DisplayNFTMediaSettings from '.'; +import { NFT_DISPLAY_MEDIA_MODE_SECTION } from './index.constants'; + +let mockSetDisplayNftMedia: jest.Mock; +let mockSetUseNftDetection: jest.Mock; + +beforeEach(() => { + mockSetDisplayNftMedia.mockClear(); + mockSetUseNftDetection.mockClear(); +}); + +const mockEngine = Engine; + +jest.mock('../../../../core/Engine', () => { + mockSetDisplayNftMedia = jest.fn(); + mockSetUseNftDetection = jest.fn(); + return { + init: () => mockEngine.init({}), + context: { + PreferencesController: { + setDisplayNftMedia: mockSetDisplayNftMedia, + setUseNftDetection: mockSetUseNftDetection, + }, + }, + }; +}); + +describe('DisplayNFTMediaSettings', () => { + beforeEach(() => { + jest.clearAllMocks(); + }); + + const initialState = { + engine: { + backgroundState: { + ...backgroundState, + PreferencesController: { + ...backgroundState.PreferencesController, + displayNftMedia: false, + useNftDetection: false, + }, + }, + }, + }; + + it('should render correctly', () => { + const tree = renderWithProvider(, { + state: initialState, + }); + expect(tree).toMatchSnapshot(); + }); + + describe('Display NFT Media', () => { + it('should toggle display NFT media when switch is pressed', () => { + const { getByTestId } = renderWithProvider(, { + state: initialState, + }); + const toggleSwitch = getByTestId(NFT_DISPLAY_MEDIA_MODE_SECTION); + + fireEvent(toggleSwitch, 'onValueChange', true); + expect(mockSetDisplayNftMedia).toHaveBeenCalledWith(true); + expect(mockSetUseNftDetection).not.toHaveBeenCalled(); + + fireEvent(toggleSwitch, 'onValueChange', false); + expect(mockSetDisplayNftMedia).toHaveBeenCalledWith(false); + expect(mockSetUseNftDetection).toHaveBeenCalledWith(false); + }); + }); +}); diff --git a/app/components/Views/Settings/DisplayNFTMediaSettings/index.tsx b/app/components/Views/Settings/DisplayNFTMediaSettings/index.tsx new file mode 100644 index 00000000000..00f35360306 --- /dev/null +++ b/app/components/Views/Settings/DisplayNFTMediaSettings/index.tsx @@ -0,0 +1,61 @@ +import React from 'react'; +import { View, Switch } from 'react-native'; +import { useSelector } from 'react-redux'; +import { useStyles } from '../../../../component-library/hooks'; +import Engine from '../../../../core/Engine'; +import { selectDisplayNftMedia } from '../../../../selectors/preferencesController'; +import { useTheme } from '../../../../util/theme'; +import { strings } from '../../../../../locales/i18n'; +import Text, { + TextVariant, + TextColor, +} from '../../../../component-library/components/Texts/Text'; +import styleSheet from './index.styles'; +import { NFT_DISPLAY_MEDIA_MODE_SECTION } from './index.constants'; + +const DisplayNFTMediaSettings = () => { + const theme = useTheme(); + const { colors } = theme; + const { styles } = useStyles(styleSheet, {}); + + const displayNftMedia = useSelector(selectDisplayNftMedia); + + const toggleDisplayNftMedia = (value: boolean) => { + const { PreferencesController } = Engine.context; + PreferencesController?.setDisplayNftMedia(value); + if (!value) PreferencesController?.setUseNftDetection(value); + }; + + return ( + + + + {strings('app_settings.display_nft_media')} + + + + + + + {strings('app_settings.display_nft_media_desc_new')} + + + ); +}; + +export default DisplayNFTMediaSettings; diff --git a/app/components/Views/Settings/IPFSGatewaySettings/__snapshots__/index.test.tsx.snap b/app/components/Views/Settings/IPFSGatewaySettings/__snapshots__/index.test.tsx.snap new file mode 100644 index 00000000000..33852107326 --- /dev/null +++ b/app/components/Views/Settings/IPFSGatewaySettings/__snapshots__/index.test.tsx.snap @@ -0,0 +1,129 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`IPFSGatewaySettings should render correctly 1`] = ` + + + + IPFS Gateway + + + + + + + MetaMask uses third-party services to show images of your NFTs stored on IPFS, display information related to ENS addresses entered in your browser's address bar, and fetch icons for different tokens. Your IP address may be exposed to these services when you’re using them. + + + + Choose your preferred IPFS gateway. + + + + + + + + +`; diff --git a/app/components/Views/Settings/IPFSGatewaySettings/index.constants.ts b/app/components/Views/Settings/IPFSGatewaySettings/index.constants.ts new file mode 100644 index 00000000000..b00da328346 --- /dev/null +++ b/app/components/Views/Settings/IPFSGatewaySettings/index.constants.ts @@ -0,0 +1,4 @@ +export const IPFS_GATEWAY_SECTION = 'IPFS_GATEWAY_SECTION'; +export const HASH_TO_TEST = 'Qmaisz6NMhDB51cCvNWa1GMS7LU1pAxdF4Ld6Ft9kZEP2a'; +export const HASH_STRING = 'Hello from IPFS Gateway Checker'; +export const IPFS_GATEWAY_SELECTED = 'ipfs-gateway-selected'; diff --git a/app/components/Views/Settings/IPFSGatewaySettings/index.styles.ts b/app/components/Views/Settings/IPFSGatewaySettings/index.styles.ts new file mode 100644 index 00000000000..efafda4de0a --- /dev/null +++ b/app/components/Views/Settings/IPFSGatewaySettings/index.styles.ts @@ -0,0 +1,42 @@ +import { StyleSheet } from 'react-native'; +import { Theme } from '../../../../util/theme/models'; + +const styleSheet = (params: { theme: Theme }) => { + const { theme } = params; + const { colors } = theme; + return StyleSheet.create({ + titleContainer: { + flexDirection: 'row', + alignItems: 'center', + }, + title: { + flex: 1, + }, + switchElement: { + marginLeft: 16, + }, + switch: { + alignSelf: 'flex-start', + }, + halfSetting: { + marginTop: 16, + }, + desc: { + marginTop: 8, + }, + setting: { + marginTop: 32, + }, + accessory: { + marginTop: 16, + }, + picker: { + borderColor: colors.border.default, + borderRadius: 5, + borderWidth: 2, + marginTop: 16, + }, + }); +}; + +export default styleSheet; diff --git a/app/components/Views/Settings/IPFSGatewaySettings/index.test.tsx b/app/components/Views/Settings/IPFSGatewaySettings/index.test.tsx new file mode 100644 index 00000000000..0a5bb500ab5 --- /dev/null +++ b/app/components/Views/Settings/IPFSGatewaySettings/index.test.tsx @@ -0,0 +1,120 @@ +import React from 'react'; +import { fireEvent } from '@testing-library/react-native'; +import Engine from '../../../../core/Engine'; +import renderWithProvider from '../../../../util/test/renderWithProvider'; +import { backgroundState } from '../../../../util/test/initial-root-state'; +import IPFSGatewaySettings from './'; +import { IPFS_GATEWAY_SECTION, IPFS_GATEWAY_SELECTED } from './index.constants'; + +let mockSetIsIpfsGatewayEnabled: jest.Mock; +let mockSetIpfsGateway: jest.Mock; + +beforeEach(() => { + mockSetIsIpfsGatewayEnabled.mockClear(); + mockSetIpfsGateway.mockClear(); +}); + +const mockEngine = Engine; + +jest.mock('../../../../core/Engine', () => { + mockSetIsIpfsGatewayEnabled = jest.fn(); + mockSetIpfsGateway = jest.fn(); + return { + init: () => mockEngine.init({}), + context: { + PreferencesController: { + setIsIpfsGatewayEnabled: mockSetIsIpfsGatewayEnabled, + setIpfsGateway: mockSetIpfsGateway, + }, + }, + }; +}); + +jest.mock('../../../../util/general', () => ({ + timeoutFetch: jest.fn(), +})); + +describe('IPFSGatewaySettings', () => { + beforeEach(() => { + jest.clearAllMocks(); + }); + + const initialState = { + engine: { + backgroundState: { + ...backgroundState, + PreferencesController: { + ...backgroundState.PreferencesController, + useTokenDetection: true, + displayNftMedia: false, + useNftDetection: false, + }, + }, + }, + network: { + provider: { + chainId: '1', + }, + }, + }; + + it('should render correctly', () => { + const tree = renderWithProvider(, { + state: initialState, + }); + expect(tree).toMatchSnapshot(); + }); + + describe('IPFS Gateway', () => { + it('should render IPFS gateway toggle', () => { + const { getByTestId } = renderWithProvider(, { + state: initialState, + }); + const ipfsGatewayToggle = getByTestId(IPFS_GATEWAY_SECTION); + expect(ipfsGatewayToggle).toBeTruthy(); + }); + + it('should toggle IPFS gateway when switch is pressed', () => { + const { getByTestId } = renderWithProvider(, { + state: initialState, + }); + const ipfsGatewayToggle = getByTestId(IPFS_GATEWAY_SECTION); + + fireEvent(ipfsGatewayToggle, 'onValueChange', true); + expect(mockSetIsIpfsGatewayEnabled).toHaveBeenCalledWith(true); + + fireEvent(ipfsGatewayToggle, 'onValueChange', false); + expect(mockSetIsIpfsGatewayEnabled).toHaveBeenCalledWith(false); + }); + + it('should render IPFS gateway selector when enabled', async () => { + const { queryByTestId } = renderWithProvider(, { + state: { + ...initialState, + engine: { + backgroundState: { + ...initialState.engine.backgroundState, + PreferencesController: { + ...initialState.engine.backgroundState.PreferencesController, + isIpfsGatewayEnabled: true, + }, + }, + }, + }, + }); + + await new Promise((resolve) => setTimeout(resolve, 0)); + + const ipfsGatewaySelector = queryByTestId(IPFS_GATEWAY_SELECTED); + expect(ipfsGatewaySelector).toBeNull(); + }); + + it('should not render IPFS gateway selector when disabled', () => { + const { queryByTestId } = renderWithProvider(, { + state: initialState, + }); + const ipfsGatewaySelector = queryByTestId(IPFS_GATEWAY_SELECTED); + expect(ipfsGatewaySelector).toBeNull(); + }); + }); +}); diff --git a/app/components/Views/Settings/IPFSGatewaySettings/index.tsx b/app/components/Views/Settings/IPFSGatewaySettings/index.tsx new file mode 100644 index 00000000000..86ffa296036 --- /dev/null +++ b/app/components/Views/Settings/IPFSGatewaySettings/index.tsx @@ -0,0 +1,138 @@ +import React, { useCallback, useEffect, useState } from 'react'; +import { View, Switch, ActivityIndicator } from 'react-native'; +import { useSelector } from 'react-redux'; +import Engine from '../../../../core/Engine'; +import { useStyles } from '../../../../component-library/hooks'; +import { + selectIsIpfsGatewayEnabled, + selectIpfsGateway, +} from '../../../../selectors/preferencesController'; +import { useTheme } from '../../../../util/theme'; +import { strings } from '../../../../../locales/i18n'; +import Text, { + TextVariant, + TextColor, +} from '../../../../component-library/components/Texts/Text'; +import ipfsGateways from '../../../../util/ipfs-gateways.json'; +import { timeoutFetch } from '../../../../util/general'; +import SelectComponent from '../../../UI/SelectComponent'; +import styleSheet from './index.styles'; +import { + IPFS_GATEWAY_SECTION, + HASH_TO_TEST, + HASH_STRING, + IPFS_GATEWAY_SELECTED, +} from './index.constants'; +import { Gateway } from './index.types'; + +const IPFSGatewaySettings = () => { + const { PreferencesController } = Engine.context; + const theme = useTheme(); + const { colors } = theme; + const { styles } = useStyles(styleSheet, colors); + + const [onlineIpfsGateways, setOnlineIpfsGateways] = useState([]); + const [gotAvailableGateways, setGotAvailableGateways] = useState(false); + + const ipfsGateway = useSelector(selectIpfsGateway); + const isIpfsGatewayEnabled = useSelector(selectIsIpfsGatewayEnabled); + + const handleAvailableIpfsGateways = useCallback(async () => { + if (!isIpfsGatewayEnabled) return; + const ipfsGatewaysPromises = ipfsGateways.map(async (gateway: Gateway) => { + const testUrl = + gateway.value + HASH_TO_TEST + '#x-ipfs-companion-no-redirect'; + try { + const res = await timeoutFetch(testUrl, 1200); + const text = await res.text(); + const available = text.trim() === HASH_STRING.trim(); + return { ...gateway, available }; + } catch (e) { + return { ...gateway, available: false }; + } + }); + const ipfsGatewaysAvailability = await Promise.all(ipfsGatewaysPromises); + const onlineGateways = ipfsGatewaysAvailability.filter( + (gateway) => gateway.available, + ); + + const sortedOnlineIpfsGateways = [...onlineGateways].sort( + (a, b) => a.key - b.key, + ); + + setGotAvailableGateways(true); + setOnlineIpfsGateways(sortedOnlineIpfsGateways); + }, [isIpfsGatewayEnabled]); + + const setIsIpfsGatewayEnabled = (isIpfsGatewatEnabled: boolean) => { + PreferencesController.setIsIpfsGatewayEnabled(isIpfsGatewatEnabled); + }; + + const setIpfsGateway = (gateway: string) => { + PreferencesController.setIpfsGateway(gateway); + }; + + useEffect(() => { + handleAvailableIpfsGateways(); + }, [handleAvailableIpfsGateways]); + + return ( + + + + {strings('app_settings.ipfs_gateway')} + + + + + + + {strings('app_settings.ipfs_gateway_content')} + + {isIpfsGatewayEnabled && ( + + + {strings('app_settings.ipfs_gateway_desc')} + + + {gotAvailableGateways ? ( + + ) : ( + + + + )} + + + )} + + ); +}; + +export default IPFSGatewaySettings; diff --git a/app/components/Views/Settings/IPFSGatewaySettings/index.types.ts b/app/components/Views/Settings/IPFSGatewaySettings/index.types.ts new file mode 100644 index 00000000000..fb5d63031d2 --- /dev/null +++ b/app/components/Views/Settings/IPFSGatewaySettings/index.types.ts @@ -0,0 +1,12 @@ +/** + * Represents an IPFS gateway configuration. + * @interface Gateway + * @property {number} key - Unique identifier for the gateway. + * @property {string} value - URL or address of the IPFS gateway. + * @property {string} label - Human-readable name or description for the gateway, used in the UI. + */ +export interface Gateway { + key: number; + value: string; + label: string; +} diff --git a/app/components/Views/Settings/SecuritySettings/SecuritySettings.constants.ts b/app/components/Views/Settings/SecuritySettings/SecuritySettings.constants.ts index e91280b6d85..6c35ca96127 100644 --- a/app/components/Views/Settings/SecuritySettings/SecuritySettings.constants.ts +++ b/app/components/Views/Settings/SecuritySettings/SecuritySettings.constants.ts @@ -1,7 +1,5 @@ export const PASSCODE_CHOICE_STRING = 'passcodeChoice'; export const BIOMETRY_CHOICE_STRING = 'biometryChoice'; -export const HASH_TO_TEST = 'Qmaisz6NMhDB51cCvNWa1GMS7LU1pAxdF4Ld6Ft9kZEP2a'; -export const HASH_STRING = 'Hello from IPFS Gateway Checker'; export const LOGIN_OPTIONS = 'login-options'; export const TURN_ON_REMEMBER_ME = 'turn-on-remember-me'; export const REVEAL_PRIVATE_KEY_SECTION = 'reveal-private-key-section'; @@ -15,10 +13,8 @@ export const DELETE_METRICS_BUTTON = 'delete-metrics-button'; export const SECURITY_SETTINGS_DELETE_WALLET_BUTTON = 'security-settings-delete-wallet-buttons'; export const THIRD_PARTY_SECTION = 'third-party-section'; -export const NFT_DISPLAY_MEDIA_MODE_SECTION = 'nft-display-media-mode-section'; export const NFT_AUTO_DETECT_MODE_SECTION = 'nft-opensea-autodetect-mode-section'; -export const IPFS_GATEWAY_SECTION = 'ipfs-gateway-section'; export const USE_SAFE_CHAINS_LIST_VALIDATION = 'use-chains-list-validation'; export const DISPLAY_SAFE_CHAINS_LIST_VALIDATION = 'display-use-safe-list-validation'; diff --git a/app/components/Views/Settings/SecuritySettings/SecuritySettings.test.tsx b/app/components/Views/Settings/SecuritySettings/SecuritySettings.test.tsx index 955cc9a9eea..b1eb8415adb 100644 --- a/app/components/Views/Settings/SecuritySettings/SecuritySettings.test.tsx +++ b/app/components/Views/Settings/SecuritySettings/SecuritySettings.test.tsx @@ -8,12 +8,10 @@ import { CLEAR_BROWSER_HISTORY_SECTION, CLEAR_PRIVACY_SECTION, DELETE_METRICS_BUTTON, - IPFS_GATEWAY_SECTION, LOGIN_OPTIONS, META_METRICS_DATA_MARKETING_SECTION, META_METRICS_SECTION, NFT_AUTO_DETECT_MODE_SECTION, - NFT_DISPLAY_MEDIA_MODE_SECTION, REVEAL_PRIVATE_KEY_SECTION, SDK_SECTION, SECURITY_SETTINGS_DELETE_WALLET_BUTTON, @@ -108,9 +106,7 @@ describe('SecuritySettings', () => { expect(getByTestId(META_METRICS_DATA_MARKETING_SECTION)).toBeTruthy(); expect(getByTestId(SECURITY_SETTINGS_DELETE_WALLET_BUTTON)).toBeTruthy(); expect(SecurityPrivacyViewSelectorsIDs.INCOMING_TRANSACTIONS).toBeTruthy(); - expect(getByTestId(NFT_DISPLAY_MEDIA_MODE_SECTION)).toBeTruthy(); expect(getByTestId(NFT_AUTO_DETECT_MODE_SECTION)).toBeTruthy(); - expect(getByTestId(IPFS_GATEWAY_SECTION)).toBeTruthy(); expect(getByText('Automatic security checks')).toBeTruthy(); expect(getByTestId(USE_SAFE_CHAINS_LIST_VALIDATION)).toBeTruthy(); }); diff --git a/app/components/Views/Settings/SecuritySettings/SecuritySettings.tsx b/app/components/Views/Settings/SecuritySettings/SecuritySettings.tsx index 73eba5fc828..9a5a131f742 100644 --- a/app/components/Views/Settings/SecuritySettings/SecuritySettings.tsx +++ b/app/components/Views/Settings/SecuritySettings/SecuritySettings.tsx @@ -53,21 +53,14 @@ import { selectNetworkConfigurations, } from '../../../../selectors/networkController'; import { - selectIpfsGateway, - selectIsIpfsGatewayEnabled, - selectDisplayNftMedia, selectShowIncomingTransactionNetworks, selectShowTestNetworks, selectUseSafeChainsListValidation, selectUseTransactionSimulations, } from '../../../../selectors/preferencesController'; import { SECURITY_PRIVACY_VIEW_ID } from '../../../../../wdio/screen-objects/testIDs/Screens/SecurityPrivacy.testIds'; -import ipfsGateways from '../../../../util/ipfs-gateways.json'; -import SelectComponent from '../../../UI/SelectComponent'; -import { timeoutFetch } from '../../../../util/general'; import createStyles from './SecuritySettings.styles'; import { - Gateway, HeadingProps, NetworksI, SecuritySettingsParams, @@ -78,10 +71,6 @@ import { BIOMETRY_CHOICE_STRING, CLEAR_BROWSER_HISTORY_SECTION, DISPLAY_SAFE_CHAINS_LIST_VALIDATION, - HASH_STRING, - HASH_TO_TEST, - IPFS_GATEWAY_SECTION, - NFT_DISPLAY_MEDIA_MODE_SECTION, PASSCODE_CHOICE_STRING, SDK_SECTION, USE_SAFE_CHAINS_LIST_VALIDATION, @@ -122,6 +111,8 @@ import { RootState } from '../../../../reducers'; import { EtherscanSupportedHexChainId } from '@metamask/preferences-controller'; import { useDisableNotifications } from '../../../../util/notifications/hooks/useNotifications'; import { isNotificationsFeatureEnabled } from '../../../../util/notifications'; +import DisplayNFTMediaSettings from '../../Settings/DisplayNFTMediaSettings'; +import IPFSGatewaySettings from '../../Settings/IPFSGatewaySettings'; import BatchAccountBalanceSettings from '../BatchAccountBalanceSettings'; import AutoDetectNFTSettings from '../../Settings/AutoDetectNFTSettings'; @@ -151,8 +142,6 @@ const Settings: React.FC = () => { const [analyticsEnabled, setAnalyticsEnabled] = useState(false); const [showHint, setShowHint] = useState(false); const [hintText, setHintText] = useState(''); - const [onlineIpfsGateways, setOnlineIpfsGateways] = useState([]); - const [gotAvailableGateways, setGotAvailableGateways] = useState(false); const isProfileSyncingEnabled = useSelector(selectIsProfileSyncingEnabled); const isBasicFunctionalityEnabled = useSelector( (state: RootState) => state?.settings?.basicFunctionalityEnabled, @@ -183,7 +172,6 @@ const Settings: React.FC = () => { selectShowIncomingTransactionNetworks, ); const networkConfigurations = useSelector(selectNetworkConfigurations); - const displayNftMedia = useSelector(selectDisplayNftMedia); const useSafeChainsListValidation = useSelector( selectUseSafeChainsListValidation, ); @@ -201,8 +189,6 @@ const Settings: React.FC = () => { (state: any) => state.user.seedphraseBackedUp, ); const type = useSelector(selectProviderType); - const ipfsGateway = useSelector(selectIpfsGateway); - const isIpfsGatewayEnabled = useSelector(selectIsIpfsGatewayEnabled); const myNetworks = ETHERSCAN_SUPPORTED_NETWORKS; const isMainnet = type === MAINNET; @@ -218,34 +204,6 @@ const Settings: React.FC = () => { ); }, [colors, navigation]); - const handleAvailableIpfsGateways = useCallback(async () => { - if (!isIpfsGatewayEnabled) return; - const ipfsGatewaysPromises = ipfsGateways.map(async (gateway: Gateway) => { - const testUrl = - gateway.value + HASH_TO_TEST + '#x-ipfs-companion-no-redirect'; - try { - const res = await timeoutFetch(testUrl, 1200); - const text = await res.text(); - const available = text.trim() === HASH_STRING.trim(); - return { ...gateway, available }; - } catch (e) { - const available = false; - return { ...gateway, available }; - } - }); - const ipfsGatewaysAvailability = await Promise.all(ipfsGatewaysPromises); - const onlineGateways = ipfsGatewaysAvailability.filter( - (gateway) => gateway.available, - ); - - const sortedOnlineIpfsGateways = [...onlineGateways].sort( - (a, b) => a.key - b.key, - ); - - setGotAvailableGateways(true); - setOnlineIpfsGateways(sortedOnlineIpfsGateways); - }, [isIpfsGatewayEnabled]); - const handleHintText = useCallback(async () => { const currentSeedphraseHints = await StorageWrapper.getItem( SEED_PHRASE_HINTS, @@ -319,10 +277,6 @@ const Settings: React.FC = () => { }, [waitForRenderDetectNftComponentRef]), ); - useEffect(() => { - handleAvailableIpfsGateways(); - }, [handleAvailableIpfsGateways]); - const toggleHint = () => { setShowHint(!showHint); }; @@ -526,46 +480,6 @@ const Settings: React.FC = () => { ); - const toggleDisplayNftMedia = (value: boolean) => { - const { PreferencesController } = Engine.context; - PreferencesController?.setDisplayNftMedia(value); - if (!value) PreferencesController?.setUseNftDetection(value); - }; - - const renderDisplayNftMedia = useCallback( - () => ( - - - - {strings('app_settings.display_nft_media')} - - - - - - - {strings('app_settings.display_nft_media_desc_new')} - - - ), - [colors, styles, displayNftMedia, theme], - ); - const renderUseSafeChainsListValidation = useCallback( () => ( @@ -657,72 +571,6 @@ const Settings: React.FC = () => { [colors, styles, useTransactionSimulations, theme.brandColors.white], ); - const setIpfsGateway = (gateway: string) => { - const { PreferencesController } = Engine.context; - PreferencesController.setIpfsGateway(gateway); - }; - - const setIsIpfsGatewayEnabled = (isIpfsGatewatEnabled: boolean) => { - const { PreferencesController } = Engine.context; - PreferencesController.setIsIpfsGatewayEnabled(isIpfsGatewatEnabled); - }; - - const renderIpfsGateway = () => ( - - - - {strings('app_settings.ipfs_gateway')} - - - - - - - {strings('app_settings.ipfs_gateway_content')} - - {isIpfsGatewayEnabled && ( - - - {strings('app_settings.ipfs_gateway_desc')} - - - {gotAvailableGateways ? ( - - ) : ( - - - - )} - - - )} - - ); - const handleChangeText = (text: string) => setHintText(text); const renderHint = () => ( @@ -1041,13 +889,13 @@ const Settings: React.FC = () => { > {strings('app_settings.token_nft_ens_subheading')} - {renderDisplayNftMedia()} + {isMainnet && ( )} - {renderIpfsGateway()} +