From 9dc81e5648262bcf957599fce5f26506f501e066 Mon Sep 17 00:00:00 2001 From: JC Date: Sun, 1 Mar 2026 17:30:26 -0700 Subject: [PATCH] fix: settings - new opt-in for different block explorers --- __mocks__/dataMocks/mockTranslate.ts | 16 + __tests__/Settings.snapshot.tsx | 3 + .../__snapshots__/Settings.snapshot.tsx.snap | 340 ++++++++++++++++++ app/AppState/AppContextLoaded.ts | 2 + app/AppState/AppContextLoading.ts | 4 +- app/AppState/classes/SettingsFileClass.ts | 4 + app/AppState/enums/BlockExplorerEnum.ts | 5 + app/AppState/enums/SettingsNameEnum.ts | 1 + app/LoadedApp/LoadedApp.tsx | 36 +- app/LoadingApp/LoadingApp.tsx | 24 +- app/context/contextAppLoaded.tsx | 2 + app/context/contextAppLoading.tsx | 2 + app/translations/en.json | 18 + app/translations/es.json | 18 + app/translations/pt.json | 18 + app/translations/ru.json | 18 + app/translations/tr.json | 18 + app/utils/Utils.ts | 25 +- .../components/ValueTransferDetail.tsx | 3 +- components/Settings/Settings.tsx | 37 +- components/Settings/SettingsFileImpl.ts | 5 + rust/Cargo.lock | 8 +- rust/Cargo.toml | 4 +- 23 files changed, 578 insertions(+), 33 deletions(-) create mode 100644 app/AppState/enums/BlockExplorerEnum.ts diff --git a/__mocks__/dataMocks/mockTranslate.ts b/__mocks__/dataMocks/mockTranslate.ts index 23e7f06cf..adb409373 100644 --- a/__mocks__/dataMocks/mockTranslate.ts +++ b/__mocks__/dataMocks/mockTranslate.ts @@ -1,4 +1,5 @@ import { CurrencyEnum, LanguageEnum } from '../../app/AppState'; +import { BlockExplorerEnum } from '../../app/AppState/enums/BlockExplorerEnum'; import { RPCPerformanceLevelEnum } from '../../app/rpc/enums/RPCPerformanceLevelEnum'; export const mockTranslate = (p: string) => { @@ -120,6 +121,21 @@ export const mockTranslate = (p: string) => { text: 'text medium', }, ]; + } else if (p === 'settings.blockexplorers') { + return [ + { + value: BlockExplorerEnum.Cipherscan, + text: 'text Cipherscan', + }, + { + value: BlockExplorerEnum.Zcashexplorer, + text: 'text Zcashexplorer', + }, + { + value: BlockExplorerEnum.Zypherscan, + text: 'text Zypherscan', + }, + ]; } else { return 'text translated'; } diff --git a/__tests__/Settings.snapshot.tsx b/__tests__/Settings.snapshot.tsx index c7c657573..a195bddf0 100644 --- a/__tests__/Settings.snapshot.tsx +++ b/__tests__/Settings.snapshot.tsx @@ -16,6 +16,7 @@ import { mockServer } from '../__mocks__/dataMocks/mockServer'; import { DrawerScreenProps } from '@react-navigation/drawer'; import { AppDrawerParamList } from '../app/types'; import mockNavigation from '../__mocks__/dataMocks/mockNavigation'; +import { BlockExplorerEnum } from '../app/AppState/enums/BlockExplorerEnum'; function makeDrawerProps(): DrawerScreenProps { return { @@ -38,6 +39,7 @@ describe('Component Settings - test', () => { state.currency = CurrencyEnum.USDCurrency; state.language = LanguageEnum.en; state.sendAll = false; + state.blockExplorer = BlockExplorerEnum.Zcashexplorer; state.rescanMenu = false; state.recoveryWalletInfoOnDevice = true; state.donation = false; @@ -59,6 +61,7 @@ describe('Component Settings - test', () => { setRescanMenuOption={onSetOption} setRecoveryWalletInfoOnDeviceOption={onSetOption} setPerformanceLevelOption={onSetOption} + setBlockExplorerOption={onSetOption} toggleMenuDrawer={toggle} /> , diff --git a/__tests__/__snapshots__/Settings.snapshot.tsx.snap b/__tests__/__snapshots__/Settings.snapshot.tsx.snap index 9bbc435c8..da3457280 100644 --- a/__tests__/__snapshots__/Settings.snapshot.tsx.snap +++ b/__tests__/__snapshots__/Settings.snapshot.tsx.snap @@ -1961,6 +1961,346 @@ exports[`Component Settings - test Settings - snapshot 1`] = ` text translated + + + + + < + color="#ffffff" + icon={ + { + "icon": [ + 512, + 512, + [ + 128308, + 128309, + 128992, + 128993, + 128994, + 128995, + 128996, + 9679, + 9898, + 9899, + 11044, + 61708, + 61915, + ], + "f111", + "M464 256a208 208 0 1 0 -416 0 208 208 0 1 0 416 0zM0 256a256 256 0 1 1 512 0 256 256 0 1 1 -512 0z", + ], + "iconName": "circle", + "prefix": "far", + } + } + size={20} + /> + + text translated + + + + + text Cipherscan + + + + + + < + color="#ffffff" + icon={ + { + "icon": [ + 512, + 512, + [ + 128280, + "dot-circle", + ], + "f192", + "M256 512a256 256 0 1 0 0-512 256 256 0 1 0 0 512zm0-352a96 96 0 1 1 0 192 96 96 0 1 1 0-192z", + ], + "iconName": "circle-dot", + "prefix": "fas", + } + } + size={20} + /> + + text translated + + + + + text Zcashexplorer + + + + + + < + color="#ffffff" + icon={ + { + "icon": [ + 512, + 512, + [ + 128308, + 128309, + 128992, + 128993, + 128994, + 128995, + 128996, + 9679, + 9898, + 9899, + 11044, + 61708, + 61915, + ], + "f111", + "M464 256a208 208 0 1 0 -416 0 208 208 0 1 0 416 0zM0 256a256 256 0 1 1 512 0 256 256 0 1 1 -512 0z", + ], + "iconName": "circle", + "prefix": "far", + } + } + size={20} + /> + + text translated + + + + + text Zypherscan + + + + + + text translated + + import('../../components/About')); const Seed = React.lazy(() => import('../../components/Seed')); @@ -165,6 +166,7 @@ export default function LoadedApp(props: LoadedAppProps) { const [rescanMenu, setRescanMenu] = useState(false); const [recoveryWalletInfoOnDevice, setRecoveryWalletInfoOnDevice] = useState(false); const [performanceLevel, setPerformanceLevel] = useState(RPCPerformanceLevelEnum.Medium); + const [blockExplorer, setBlockExplorer] = useState(BlockExplorerEnum.Zcashexplorer); const [zenniesDonationAddress, setZenniesDonationAddress] = useState(''); const file = useMemo( () => ({ @@ -304,6 +306,15 @@ export default function LoadedApp(props: LoadedAppProps) { } else { await SettingsFileImpl.writeSettings(SettingsNameEnum.performanceLevel, performanceLevel); } + if ( + settings.blockExplorer === BlockExplorerEnum.Cipherscan || + settings.blockExplorer === BlockExplorerEnum.Zcashexplorer || + settings.blockExplorer === BlockExplorerEnum.Zypherscan + ) { + setBlockExplorer(settings.blockExplorer); + } else { + await SettingsFileImpl.writeSettings(SettingsNameEnum.blockExplorer, blockExplorer); + } // reading background task info const backgroundSyncInfoJson = await BackgroundFileImpl.readBackground(); @@ -455,6 +466,7 @@ export default function LoadedApp(props: LoadedAppProps) { zenniesDonationAddress={zenniesDonationAddress} firstLaunchingMessage={firstLaunchingMessage} performanceLevel={performanceLevel} + blockExplorer={blockExplorer} /> ); } @@ -506,6 +518,7 @@ type LoadedAppClassProps = { zenniesDonationAddress: string; firstLaunchingMessage: LaunchingModeEnum; performanceLevel: RPCPerformanceLevelEnum; + blockExplorer: BlockExplorerEnum; }; type LoadedAppClassState = AppStateLoaded & AppContextLoaded; @@ -585,6 +598,7 @@ export class LoadedAppClass extends Component Likely Reverted by the server - // this is really confusing... - //if (vtNew.length === 0) { - // createAlert( - // this.setBackgroundError, - // this.addLastSnackbar, - // [this.screenName], - // this.state.translate('loadedapp.send-menu') as string, - // this.state.translate('loadedapp.valuetransfer-reverted') as string, - // true, - // this.state.translate, - // ); - //} }); // if some tx is confirmed the UI needs some time to // acomodate the bottom tabs. @@ -1559,6 +1560,13 @@ export class LoadedAppClass extends Component => { + await SettingsFileImpl.writeSettings(SettingsNameEnum.blockExplorer, value); + this.setState({ + blockExplorer: value as BlockExplorerEnum, + }); + }; + navigateToLoadingApp = async (state: LoadingAppNavigationState) => { await this.rpc.clearTimers(); if (!!state.screen && state.screen === 3) { @@ -1869,6 +1877,7 @@ export class LoadedAppClass extends Component { @@ -2071,6 +2080,7 @@ export class LoadedAppClass extends Component props.navigation.toggleDrawer() /* header */} /> } diff --git a/app/LoadingApp/LoadingApp.tsx b/app/LoadingApp/LoadingApp.tsx index 405b4b1bc..8bffb3c55 100644 --- a/app/LoadingApp/LoadingApp.tsx +++ b/app/LoadingApp/LoadingApp.tsx @@ -77,6 +77,7 @@ import { RPCUfvkType } from '../rpc/types/RPCUfvkType'; import { RPCPerformanceLevelEnum } from '../rpc/enums/RPCPerformanceLevelEnum'; import NewSeed from './components/NewSeed'; import { AppStackParamList } from '../types'; +import { BlockExplorerEnum } from '../AppState/enums/BlockExplorerEnum'; const en = require('../translations/en.json'); const es = require('../translations/es.json'); @@ -132,6 +133,7 @@ export default function LoadingApp(props: LoadingAppProps) { const [rescanMenu, setRescanMenu] = useState(false); const [recoveryWalletInfoOnDevice, setRecoveryWalletInfoOnDevice] = useState(false); const [performanceLevel, setPerformanceLevel] = useState(RPCPerformanceLevelEnum.Medium); + const [blockExplorer, setBlockExplorer] = useState(BlockExplorerEnum.Zcashexplorer); const file = useMemo( () => ({ en: en, @@ -287,6 +289,15 @@ export default function LoadingApp(props: LoadingAppProps) { } else { await SettingsFileImpl.writeSettings(SettingsNameEnum.performanceLevel, performanceLevel); } + if ( + settings.blockExplorer === BlockExplorerEnum.Cipherscan || + settings.blockExplorer === BlockExplorerEnum.Zcashexplorer || + settings.blockExplorer === BlockExplorerEnum.Zypherscan + ) { + setBlockExplorer(settings.blockExplorer); + } else { + await SettingsFileImpl.writeSettings(SettingsNameEnum.blockExplorer, blockExplorer); + } // if server uri is empty, fix this. // it is a weird edge case @@ -340,6 +351,7 @@ export default function LoadingApp(props: LoadingAppProps) { rescanMenu={rescanMenu} recoveryWalletInfoOnDevice={recoveryWalletInfoOnDevice} performanceLevel={performanceLevel} + blockExplorer={blockExplorer} /> ); } @@ -366,6 +378,7 @@ type LoadingAppClassProps = { rescanMenu: boolean; recoveryWalletInfoOnDevice: boolean; performanceLevel: RPCPerformanceLevelEnum; + blockExplorer: BlockExplorerEnum; }; type LoadingAppClassState = AppStateLoading & AppContextLoading; @@ -411,6 +424,7 @@ export class LoadingAppClass extends Component { if (!seedUfvk) { + // no reporting button, no needed. createAlert( this.setBackgroundError, this.addLastSnackbar, @@ -1145,8 +1160,6 @@ export class LoadingAppClass extends Component {}, + blockExplorer: BlockExplorerEnum.Zcashexplorer, }; export const ContextAppLoaded = React.createContext(defaultAppContextLoaded); diff --git a/app/context/contextAppLoading.tsx b/app/context/contextAppLoading.tsx index cb2c60795..06a7863b4 100644 --- a/app/context/contextAppLoading.tsx +++ b/app/context/contextAppLoading.tsx @@ -16,6 +16,7 @@ import { SnackbarType, } from '../AppState'; import { RPCPerformanceLevelEnum } from '../rpc/enums/RPCPerformanceLevelEnum'; +import { BlockExplorerEnum } from '../AppState/enums/BlockExplorerEnum'; export const defaultAppContextLoading: AppContextLoading = { netInfo: {} as NetInfoType, @@ -54,6 +55,7 @@ export const defaultAppContextLoading: AppContextLoading = { zingolibVersion: '', performanceLevel: RPCPerformanceLevelEnum.Medium, setPrivacyOption: async () => {}, + blockExplorer: BlockExplorerEnum.Zcashexplorer, }; export const ContextAppLoading = React.createContext(defaultAppContextLoading); diff --git a/app/translations/en.json b/app/translations/en.json index 62283661d..697e01a45 100644 --- a/app/translations/en.json +++ b/app/translations/en.json @@ -330,6 +330,20 @@ "text": "For old devices." } ], + "blockexplorers": [ + { + "value": "Zcashexplorer", + "text": "ZcashExplorer.App" + }, + { + "value": "Cipherscan", + "text": "CipherScan.App" + }, + { + "value": "Zypherscan", + "text": "ZypherScan.Com" + } + ], "nochanges": "No changes registered.", "ismemo": "You need to choose the download memos option to save.", "isthreshold": "You need to choose the transaction filter threshold option to save.", @@ -364,6 +378,7 @@ "rescanmenu-title": "THE RESCAN MENU OPTION", "recoverywalletinfoondevice-title": "Store Wallet Recovery Info in the Device", "performancelevel-title": "Zingolib Performance Level", + "blockexplorer-title": "Switch between Block Explorers", "value-currency-": "No currency", "value-currency-USD": "US Dollar", "value-currency-USDTOR": "US Dollar with Tor", @@ -391,6 +406,9 @@ "value-performancelevel-High": "High", "value-performancelevel-Medium": "Medium", "value-performancelevel-Low": "Low", + "value-blockexplorer-Zcashexplorer": "Zcashexplorer", + "value-blockexplorer-Cipherscan": "Cipherscan", + "value-blockexplorer-Zypherscan": "Zypherscan", "security-title": "APPLY DEVICE SECURITY TO SCREENS/OPTIONS", "security-startapp": "When the App starts", "security-foregroundapp": "When the App go to the Foreground", diff --git a/app/translations/es.json b/app/translations/es.json index a5cbf259e..001d3caa8 100644 --- a/app/translations/es.json +++ b/app/translations/es.json @@ -330,6 +330,20 @@ "text": "For old devices." } ], + "blockexplorers": [ + { + "value": "Zcashexplorer", + "text": "ZcashExplorer.App" + }, + { + "value": "Cipherscan", + "text": "CipherScan.App" + }, + { + "value": "Zypherscan", + "text": "ZypherScan.Com" + } + ], "nochanges": "No se han registrado cambios.", "ismemo": "Necesitas escoger una opción de Memos para poder guardar.", "isthreshold": "Necesitas escoger una opción de umbral para poder guardar.", @@ -364,6 +378,7 @@ "rescanmenu-title": "LA OPCIÓN DE MENU RE-ESCANEAR", "recoverywalletinfoondevice-title": "Almacenar la información de recuperacion del monedero en el dispositivo", "performancelevel-title": "Zingolib Performance Level", + "blockexplorer-title": "Cambiar entre Exploradores de Bloques", "value-currency-": "Sin moneda", "value-currency-USD": "US Dólares", "value-currency-USDTOR": "US Dólares con Tor", @@ -391,6 +406,9 @@ "value-performancelevel-High": "High", "value-performancelevel-Medium": "Medium", "value-performancelevel-Low": "Low", + "value-blockexplorer-Zcashexplorer": "Zcashexplorer", + "value-blockexplorer-Cipherscan": "Cipherscan", + "value-blockexplorer-Zypherscan": "Zypherscan", "security-title": "USAR LA SEGURIDAD DEL DISPOSITIVO", "security-startapp": "Al inicar la aplicación", "security-foregroundapp": "Aplicación va a Primer Plano", diff --git a/app/translations/pt.json b/app/translations/pt.json index 63ed5bb3e..8e0e7fbd6 100644 --- a/app/translations/pt.json +++ b/app/translations/pt.json @@ -330,6 +330,20 @@ "text": "For old devices." } ], + "blockexplorers": [ + { + "value": "Zcashexplorer", + "text": "ZcashExplorer.App" + }, + { + "value": "Cipherscan", + "text": "CipherScan.App" + }, + { + "value": "Zypherscan", + "text": "ZypherScan.Com" + } + ], "nochanges": "Nenhuma alteração registrada.", "ismemo": "Você precisa escolher a opção MEMO para salvar.", "isthreshold": "Você precisa escolher a opção Limite para salvar.", @@ -364,6 +378,7 @@ "rescanmenu-title": "A OPÇÃO DE MENU RESCAN", "recoverywalletinfoondevice-title": "Armazene informações de recuperação da carteira no dispositivo", "performancelevel-title": "Zingolib Performance Level", + "blockexplorer-title": "Alternar entre Exploradores de Blocos", "value-currency-": "Sem Saldo", "value-currency-USD": "US Dólares", "value-currency-USDTOR": "US Dólares com Tor", @@ -391,6 +406,9 @@ "value-performancelevel-High": "High", "value-performancelevel-Medium": "Medium", "value-performancelevel-Low": "Low", + "value-blockexplorer-Zcashexplorer": "Zcashexplorer", + "value-blockexplorer-Cipherscan": "Cipherscan", + "value-blockexplorer-Zypherscan": "Zypherscan", "security-title": "APLICAR SEGURANÇA DO DISPOSITIVO PARA AS TELAS/OPÇÕES", "security-startapp": "Quando o App inicia", "security-foregroundapp": "Quando o aplicativo vai para o primeiro plano", diff --git a/app/translations/ru.json b/app/translations/ru.json index 2d0211b05..d1b500812 100644 --- a/app/translations/ru.json +++ b/app/translations/ru.json @@ -330,6 +330,20 @@ "text": "For old devices." } ], + "blockexplorers": [ + { + "value": "Zcashexplorer", + "text": "ZcashExplorer.App" + }, + { + "value": "Cipherscan", + "text": "CipherScan.App" + }, + { + "value": "Zypherscan", + "text": "ZypherScan.Com" + } + ], "nochanges": "Изменения не зарегистрированы.", "ismemo": "Вам необходимо выбрать опцию сохранения заметок для загрузки.", "isthreshold": "Вам необходимо выбрать порог фильтрации транзакций для сохранения.", @@ -364,6 +378,7 @@ "rescanmenu-title": "ОТПРАВЛЕНИЕ РЕШЕНУ", "recoverywalletinfoondevice-title": "Сохраните данные для восстановления кошелька на устройстве", "performancelevel-title": "Zingolib Performance Level", + "blockexplorer-title": "Переключаться между обозревателями блоков", "value-currency-": "Без указания валюты", "value-currency-USD": "Доллар США", "value-currency-USDTOR": "Доллар США с Tor", @@ -391,6 +406,9 @@ "value-performancelevel-High": "High", "value-performancelevel-Medium": "Medium", "value-performancelevel-Low": "Low", + "value-blockexplorer-Zcashexplorer": "Zcashexplorer", + "value-blockexplorer-Cipherscan": "Cipherscan", + "value-blockexplorer-Zypherscan": "Zypherscan", "security-title": "ПРИМЕНИТЬ ЗАЩИТУ ДЛЯ ЭКРАНОВ И ОПЦИЙ УСТРОЙСТВА", "security-startapp": "При запуске приложения", "security-foregroundapp": "Когда приложение переходит в активный режим", diff --git a/app/translations/tr.json b/app/translations/tr.json index 46f88e0fd..bfa1b951d 100644 --- a/app/translations/tr.json +++ b/app/translations/tr.json @@ -330,6 +330,20 @@ "text": "For old devices." } ], + "blockexplorers": [ + { + "value": "Zcashexplorer", + "text": "ZcashExplorer.App" + }, + { + "value": "Cipherscan", + "text": "CipherScan.App" + }, + { + "value": "Zypherscan", + "text": "ZypherScan.Com" + } + ], "nochanges": "Herhangi bir değişiklik kaydedilmedi.", "ismemo": "Kaydetmek için notları indirme seçeneğini seçmeniz gerekiyor.", "isthreshold": "Kaydetmek için işlem filtre eşiği seçeneğini seçmeniz gerekiyor.", @@ -364,6 +378,7 @@ "rescanmenu-title": "YENİDEN TARA SEÇENEĞİ", "recoverywalletinfoondevice-title": "Cüzdan Kurtarma Bilgilerini Cihaza Kaydet", "performancelevel-title": "Zingolib Performance Level", + "blockexplorer-title": "Blok Gezgini Uygulamaları Arasında Geçiş Yap", "value-currency-": "Para birimi yok", "value-currency-USD": "Amerikan doları", "value-currency-USDTOR": "Tor ağı üzerinden ABD Doları", @@ -391,6 +406,9 @@ "value-performancelevel-High": "High", "value-performancelevel-Medium": "Medium", "value-performancelevel-Low": "Low", + "value-blockexplorer-Zcashexplorer": "Zcashexplorer", + "value-blockexplorer-Cipherscan": "Cipherscan", + "value-blockexplorer-Zypherscan": "Zypherscan", "security-title": "Ekranlara/Ayarlara Cihaz Güvenliğini Uygula", "security-startapp": "Uygulama başladığında", "security-foregroundapp": "Uygulama ön plana geçtiğinde", diff --git a/app/utils/Utils.ts b/app/utils/Utils.ts index b048847e2..b4e170183 100644 --- a/app/utils/Utils.ts +++ b/app/utils/Utils.ts @@ -26,6 +26,7 @@ import { RPCParseAddressType } from '../rpc/types/RPCParseAddressType'; import { RPCParseAddressStatusEnum } from '../rpc/enums/RPCParseAddressStatusEnum'; import { RPCAddressKindEnum } from '../rpc/enums/RPCAddressKindEnum'; import { RPCReceiversEnum } from '../rpc/enums/RPCReceiversEnum'; +import { BlockExplorerEnum } from '../AppState/enums/BlockExplorerEnum'; export default class Utils { static trimToSmall(addr?: string, numChars?: number): string { @@ -198,11 +199,27 @@ export default class Utils { return stringValue.replace(new RegExp('\\.'), `${decimalSeparator}`); } - static getBlockExplorerTxIDURL(txid: string, chainName: ChainNameEnum): string { - if (chainName === ChainNameEnum.testChainName) { - return `https://testnet.zcashexplorer.app/transactions/${txid}`; + static getBlockExplorerTxIDURL(txid: string, chainName: ChainNameEnum, blockExplorer: BlockExplorerEnum): string { + if (blockExplorer === BlockExplorerEnum.Zcashexplorer) { + if (chainName === ChainNameEnum.testChainName) { + return `https://testnet.zcashexplorer.app/transactions/${txid}`; + } else { + return `https://mainnet.zcashexplorer.app/transactions/${txid}`; + } + } else if (blockExplorer === BlockExplorerEnum.Cipherscan) { + if (chainName === ChainNameEnum.testChainName) { + return `https://testnet.cipherscan.app/tx/${txid}`; + } else { + return `https://cipherscan.app/tx/${txid}`; + } + } else if (blockExplorer === BlockExplorerEnum.Zypherscan) { + if (chainName === ChainNameEnum.testChainName) { + return `https://testnet.zypherscan.com/tx/${txid}`; + } else { + return `https://www.zypherscan.com/tx/${txid}`; + } } else { - return `https://mainnet.zcashexplorer.app/transactions/${txid}`; + return ''; } } diff --git a/components/History/components/ValueTransferDetail.tsx b/components/History/components/ValueTransferDetail.tsx index d9c984eb4..1b570f67f 100644 --- a/components/History/components/ValueTransferDetail.tsx +++ b/components/History/components/ValueTransferDetail.tsx @@ -69,6 +69,7 @@ const ValueTransferDetail: React.FunctionComponent = ( netInfo, selectServer, setPrivacyOption, + blockExplorer, } = context; const { colors } = useTheme() as ThemeType; const { clear } = useToast(); @@ -133,7 +134,7 @@ const ValueTransferDetail: React.FunctionComponent = ( return; } - const url = Utils.getBlockExplorerTxIDURL(txid, server.chainName); + const url = Utils.getBlockExplorerTxIDURL(txid, server.chainName, blockExplorer); Linking.canOpenURL(url).then(supported => { if (supported) { Linking.openURL(url); diff --git a/components/Settings/Settings.tsx b/components/Settings/Settings.tsx index e9cbed0c8..ac43e36a1 100644 --- a/components/Settings/Settings.tsx +++ b/components/Settings/Settings.tsx @@ -49,6 +49,7 @@ import { RPCPerformanceLevelEnum } from '../../app/rpc/enums/RPCPerformanceLevel import { DrawerScreenProps } from '@react-navigation/drawer'; import { createAlert } from '../../app/createAlert'; import { sendEmail } from '../../app/sendEmail'; +import { BlockExplorerEnum } from '../../app/AppState/enums/BlockExplorerEnum'; type SettingsProps = DrawerScreenProps & { setServerOption: ( @@ -67,6 +68,7 @@ type SettingsProps = DrawerScreenProps & setRescanMenuOption: (value: boolean) => Promise; setRecoveryWalletInfoOnDeviceOption: (value: boolean) => Promise; setPerformanceLevelOption: (value: RPCPerformanceLevelEnum) => Promise; + setBlockExplorerOption: (value: BlockExplorerEnum) => Promise; toggleMenuDrawer: () => void; }; @@ -88,6 +90,7 @@ const Settings: React.FunctionComponent = ({ setRescanMenuOption, setRecoveryWalletInfoOnDeviceOption, setPerformanceLevelOption, + setBlockExplorerOption, toggleMenuDrawer, }) => { const context = useContext(ContextAppLoaded); @@ -107,6 +110,7 @@ const Settings: React.FunctionComponent = ({ rescanMenu: rescanMenuContext, recoveryWalletInfoOnDevice: recoveryWalletInfoOnDeviceContext, performanceLevel: performanceLevelContext, + blockExplorer: blockExplorerContext, readOnly, snackbars, removeFirstSnackbar, @@ -171,6 +175,12 @@ const Settings: React.FunctionComponent = ({ PERFORMANCELEVELMENU = performanceLevelsArray as Options[]; } + const blockExplorersArray = translate('settings.blockexplorers'); + let BLOCKEXPLORERMENU: Options[] = []; + if (typeof blockExplorersArray === 'object') { + BLOCKEXPLORERMENU = blockExplorersArray as Options[]; + } + const { colors } = useTheme() as ThemeType; const screenName = ScreenEnum.Settings; @@ -204,6 +214,7 @@ const Settings: React.FunctionComponent = ({ recoveryWalletInfoOnDeviceContext, ); const [performanceLevel, setPerformanceLevel] = useState(performanceLevelContext); + const [blockExplorer, setBlockExplorer] = useState(blockExplorerContext); const [autoIcon, setAutoIcon] = useState(farCircle); const [listIcon, setListIcon] = useState(farCircle); @@ -324,7 +335,8 @@ const Settings: React.FunctionComponent = ({ selectServerContext === selectServer && rescanMenuContext === rescanMenu && recoveryWalletInfoOnDeviceContext === recoveryWalletInfoOnDevice && - performanceLevelContext === performanceLevel + performanceLevelContext === performanceLevel && + blockExplorerContext === blockExplorer ) { setDisabledButton(true); } else { @@ -354,6 +366,8 @@ const Settings: React.FunctionComponent = ({ rescanMenuContext, performanceLevel, performanceLevelContext, + blockExplorer, + blockExplorerContext, securityContext, selectServer, selectServerContext, @@ -395,7 +409,8 @@ const Settings: React.FunctionComponent = ({ selectServerContext === selectServer && rescanMenuContext === rescanMenu && recoveryWalletInfoOnDeviceContext === recoveryWalletInfoOnDevice && - performanceLevelContext === performanceLevel + performanceLevelContext === performanceLevel && + blockExplorerContext === blockExplorer ) { addLastSnackbar({ message: translate('settings.nochanges') as string, screenName: [screenName] }); return; @@ -507,6 +522,9 @@ const Settings: React.FunctionComponent = ({ if (performanceLevelContext !== performanceLevel) { await setPerformanceLevelOption(performanceLevel); } + if (blockExplorerContext !== blockExplorer) { + await setBlockExplorerOption(blockExplorer); + } // I need a little time in this modal because maybe the wallet cannot be open with the new server let ms = 100; @@ -558,6 +576,7 @@ const Settings: React.FunctionComponent = ({ setRestoreWalletBackupScreen(securityContext.restoreWalletBackupScreen); setRecoveryWalletInfoOnDevice(recoveryWalletInfoOnDeviceContext); setPerformanceLevel(performanceLevelContext); + setBlockExplorer(blockExplorerContext); } navigation.navigate(RouteEnum.HomeStack); }; @@ -801,6 +820,20 @@ const Settings: React.FunctionComponent = ({ )} + + {translate('settings.blockexplorer-title') as string} + + + + {optionsRadio( + BLOCKEXPLORERMENU, + setBlockExplorer as React.Dispatch>, + String, + blockExplorer, + 'blockexplorer', + )} + + {translate('settings.server-title') as string} diff --git a/components/Settings/SettingsFileImpl.ts b/components/Settings/SettingsFileImpl.ts index 1bec539aa..197816c32 100644 --- a/components/Settings/SettingsFileImpl.ts +++ b/components/Settings/SettingsFileImpl.ts @@ -14,6 +14,7 @@ import { import { serverUris } from '../../app/uris'; import { isEqual } from 'lodash'; import { RPCPerformanceLevelEnum } from '../../app/rpc/enums/RPCPerformanceLevelEnum'; +import { BlockExplorerEnum } from '../../app/AppState/enums/BlockExplorerEnum'; export default class SettingsFileImpl { static async getFileName() { @@ -202,6 +203,10 @@ export default class SettingsFileImpl { // by default medium settings.performanceLevel = RPCPerformanceLevelEnum.Medium; } + if (!settings.hasOwnProperty(SettingsNameEnum.blockExplorer)) { + // by default medium + settings.blockExplorer = BlockExplorerEnum.Zcashexplorer; + } return settings; } catch (err) { // The File doesn't exist, so return nothing diff --git a/rust/Cargo.lock b/rust/Cargo.lock index c0fc440ad..964de52e8 100644 --- a/rust/Cargo.lock +++ b/rust/Cargo.lock @@ -9212,7 +9212,7 @@ dependencies = [ [[package]] name = "zingo-price" version = "0.0.1" -source = "git+https://github.com/zingolabs/zingolib?rev=zingolib_v3.0.0-rc.5#2cd0304af0bc39678e35e594c998d85cec7f56ea" +source = "git+https://github.com/zingolabs/zingolib?rev=zingolib_v3.0.0-rc.6#127332852e47a99c350b6fb88a60d65dbcef982e" dependencies = [ "byteorder", "reqwest", @@ -9270,8 +9270,8 @@ dependencies = [ [[package]] name = "zingolib" -version = "3.0.0-rc.1" -source = "git+https://github.com/zingolabs/zingolib?rev=zingolib_v3.0.0-rc.5#2cd0304af0bc39678e35e594c998d85cec7f56ea" +version = "3.0.0-rc.6" +source = "git+https://github.com/zingolabs/zingolib?rev=zingolib_v3.0.0-rc.6#127332852e47a99c350b6fb88a60d65dbcef982e" dependencies = [ "append-only-vec", "bech32", @@ -9337,7 +9337,7 @@ dependencies = [ [[package]] name = "zingolib_testutils" version = "0.1.0" -source = "git+https://github.com/zingolabs/zingolib?rev=zingolib_v3.0.0-rc.5#2cd0304af0bc39678e35e594c998d85cec7f56ea" +source = "git+https://github.com/zingolabs/zingolib?rev=zingolib_v3.0.0-rc.6#127332852e47a99c350b6fb88a60d65dbcef982e" dependencies = [ "bip0039 0.13.4", "http", diff --git a/rust/Cargo.toml b/rust/Cargo.toml index cdbe93b26..8944b2165 100644 --- a/rust/Cargo.toml +++ b/rust/Cargo.toml @@ -3,9 +3,9 @@ members = ["lib", "android", "ios", "zingomobile_utils"] resolver = "2" [workspace.dependencies] -zingolib = { git = "https://github.com/zingolabs/zingolib", rev = "zingolib_v3.0.0-rc.5" } +zingolib = { git = "https://github.com/zingolabs/zingolib", rev = "zingolib_v3.0.0-rc.6" } pepper-sync = "0.2.0" -zingolib_testutils = { git = "https://github.com/zingolabs/zingolib", rev = "zingolib_v3.0.0-rc.5", features = [ +zingolib_testutils = { git = "https://github.com/zingolabs/zingolib", rev = "zingolib_v3.0.0-rc.6", features = [ "test_lwd_zcashd", ] } regchest_utils = { git = "https://github.com/zingolabs/zingo-regchest", branch = "dev" }