diff --git a/src/IntegrityChecks/Local.ts b/src/IntegrityChecks/Local.ts index 345820d1..85b1b542 100644 --- a/src/IntegrityChecks/Local.ts +++ b/src/IntegrityChecks/Local.ts @@ -14,7 +14,7 @@ import { defaultTabs } from 'contexts/Tabs/defaults'; import { defaultTags, defaultTagsConfig } from 'contexts/Tags/defaults'; import { defaultAppliedTags, - defaultCustomNodeUrls, + defaultCustomEndpoints, defaultSearchTerms, } from 'contexts/ChainFilter/defaults'; import type { RemoveOrSetInput } from './types'; @@ -84,8 +84,8 @@ export const checkLocalChainFilter = () => { const activeTabs = localTabs.getTabs() || defaultTabs; const tags = localTags.getTags() || defaultTags; const searchTerms = localChainFilter.getSearchTerms() || defaultSearchTerms; - const customNodeUrls = - localChainFilter.getCustomNodeUrls() || defaultCustomNodeUrls; + const customEndpoints = + localChainFilter.getCustomEndpoints() || defaultCustomEndpoints; const appliedTags = localChainFilter.getAppliedTags() || defaultAppliedTags; // Check if tabs exist for each search term, and remove the entry otherwise. @@ -94,10 +94,10 @@ export const checkLocalChainFilter = () => { sanitizeKeysForTabExistence(activeTabs, searchTerms) ); - // Check if tabs exist for each custom node url, and remove the entry otherwise. + // Check if tabs exist for each custom endpoint, and remove the entry otherwise. removeOrSetLocalData( - 'customNodeUrls', - sanitizeKeysForTabExistence(activeTabs, customNodeUrls) + 'customEndpoints', + sanitizeKeysForTabExistence(activeTabs, customEndpoints) ); // Check if tab index exists for each applied tag key, and that the corresponding tag entry also @@ -125,7 +125,7 @@ export const removeOrSetLocalData = ( localStorage.removeItem(key); } else { if (updated) { - localChainFilter.setCustomNodeUrls(result); + localChainFilter.setCustomEndpoints(result); } } }; @@ -144,7 +144,7 @@ export const removeLocalStorageState = (includeTags = false) => { localStorage.removeItem('activeTabId'); localStorage.removeItem('activeTabIndex'); localStorage.removeItem('searchTerms'); - localStorage.removeItem('customNodeUrls'); + localStorage.removeItem('customEndpoints'); localStorage.removeItem('appliedTags'); localStorage.removeItem('pageSections'); localStorage.removeItem('pageRedirects'); diff --git a/src/contexts/ChainFilter/Local.ts b/src/contexts/ChainFilter/Local.ts index 202aa8b8..e519597d 100644 --- a/src/contexts/ChainFilter/Local.ts +++ b/src/contexts/ChainFilter/Local.ts @@ -2,7 +2,7 @@ // SPDX-License-Identifier: GPL-3.0-only import { localStorageOrDefault } from '@w3ux/utils'; -import type { AppliedTags, CustomNodeUrls, SearchTerms } from './types'; +import type { AppliedTags, CustomEndpoints, SearchTerms } from './types'; // ------------------------------------------------------ // Getters. @@ -19,14 +19,14 @@ export const getSearchTerms = (): SearchTerms | undefined => { } }; -// Gets saved custom node urls from local storage, or returns undefined otherwise. -export const getCustomNodeUrls = (): CustomNodeUrls | undefined => { - const result = localStorageOrDefault('customNodeUrls', undefined, true) as - | CustomNodeUrls +// Gets saved custom endpoints from local storage, or returns undefined otherwise. +export const getCustomEndpoints = (): CustomEndpoints | undefined => { + const result = localStorageOrDefault('customEndpoints', undefined, true) as + | CustomEndpoints | undefined; if (result) { - return result as CustomNodeUrls; + return result as CustomEndpoints; } }; @@ -50,9 +50,9 @@ export const setSearchTerms = (value: SearchTerms) => { localStorage.setItem('searchTerms', JSON.stringify(value)); }; -// Sets custom node urls to local storage. -export const setCustomNodeUrls = (value: CustomNodeUrls) => { - localStorage.setItem('customNodeUrls', JSON.stringify(value)); +// Sets custom endpoints to local storage. +export const setCustomEndpoints = (value: CustomEndpoints) => { + localStorage.setItem('customEndpoints', JSON.stringify(value)); }; // Sets applied tags to local storage. diff --git a/src/contexts/ChainFilter/defaults.ts b/src/contexts/ChainFilter/defaults.ts index 60a3489f..b0e3211a 100644 --- a/src/contexts/ChainFilter/defaults.ts +++ b/src/contexts/ChainFilter/defaults.ts @@ -5,7 +5,7 @@ import type { AppliedTags, ChainFilterInterface, - CustomNodeUrls, + CustomEndpoints, SearchTerms, } from './types'; @@ -13,9 +13,9 @@ export const defaultChainFilter: ChainFilterInterface = { searchTerms: {}, getSearchTerm: (tabId) => '', setSearchTerm: (tabId, searchTerm) => {}, - customNodeUrls: {}, - getCustomNodeUrl: (tabId) => '', - setCustomNodeUrl: (tabId, url) => {}, + customEndpoints: {}, + getCustomEndpoint: (tabId) => '', + setCustomEndpoint: (tabId, url) => {}, appliedTags: {}, getAppliedTags: (tabId) => [], applyTags: (tabId, tagIds) => {}, @@ -36,4 +36,4 @@ export const defaultSearchTerms: SearchTerms = { 4: 'Westend', }; -export const defaultCustomNodeUrls: CustomNodeUrls = {}; +export const defaultCustomEndpoints: CustomEndpoints = {}; diff --git a/src/contexts/ChainFilter/index.tsx b/src/contexts/ChainFilter/index.tsx index 15c87b7c..bd085b1e 100644 --- a/src/contexts/ChainFilter/index.tsx +++ b/src/contexts/ChainFilter/index.tsx @@ -6,13 +6,13 @@ import { createContext, useContext, useRef, useState } from 'react'; import type { AppliedTags, ChainFilterInterface, - CustomNodeUrls, + CustomEndpoints, SearchTerms, } from './types'; import { defaultAppliedTags, defaultChainFilter, - defaultCustomNodeUrls, + defaultCustomEndpoints, defaultSearchTerms, } from './defaults'; import { useTags } from 'contexts/Tags'; @@ -36,9 +36,9 @@ export const ChainFilterProvider = ({ children }: { children: ReactNode }) => { local.getSearchTerms() || defaultSearchTerms ); - // The current custom node urls. - const [customNodeUrls, setCustomNodeUrlsState] = useState( - local.getCustomNodeUrls() || defaultCustomNodeUrls + // The current custom endpoints. + const [customEndpoints, setCustomEndpointsState] = useState( + local.getCustomEndpoints() || defaultCustomEndpoints ); // The current applied tags to a given key. NOTE: needs a ref for up to date state updates in @@ -54,10 +54,10 @@ export const ChainFilterProvider = ({ children }: { children: ReactNode }) => { setSearchTermsState(value); }; - // Sets custom node urls state, and updates local storage. - const setCustomNodeUrls = (value: CustomNodeUrls) => { - local.setCustomNodeUrls(value); - setCustomNodeUrlsState(value); + // Sets custom endpoints state, and updates local storage. + const setCustomEndpoints = (value: CustomEndpoints) => { + local.setCustomEndpoints(value); + setCustomEndpointsState(value); }; // Sets applied tags state, and updates local storage. @@ -70,17 +70,17 @@ export const ChainFilterProvider = ({ children }: { children: ReactNode }) => { // Gets a search term for a given key. const getSearchTerm = (tabId: number) => searchTerms[tabId] || ''; - // Gets a custom node url for a given key. - const getCustomNodeUrl = (tabId: number) => customNodeUrls[tabId] || ''; + // Gets a custom endpoint for a given key. + const getCustomEndpoint = (tabId: number) => customEndpoints[tabId] || ''; // Sets a search term for a given key. const setSearchTerm = (tabId: number, value: string) => { setSearchTerms({ ...searchTerms, [tabId]: value }); }; - // Sets a custom node url for a given key. - const setCustomNodeUrl = (tabId: number, value: string) => { - setCustomNodeUrls({ ...customNodeUrls, [tabId]: value }); + // Sets a custom endpoint for a given key. + const setCustomEndpoint = (tabId: number, value: string) => { + setCustomEndpoints({ ...customEndpoints, [tabId]: value }); }; // Gets the applied tags for a given key. @@ -119,9 +119,9 @@ export const ChainFilterProvider = ({ children }: { children: ReactNode }) => { searchTerms, getSearchTerm, setSearchTerm, - customNodeUrls, - getCustomNodeUrl, - setCustomNodeUrl, + customEndpoints, + getCustomEndpoint, + setCustomEndpoint, getAppliedTags, appliedTags, applyTags, diff --git a/src/contexts/ChainFilter/types.ts b/src/contexts/ChainFilter/types.ts index d498d02e..b97c71af 100644 --- a/src/contexts/ChainFilter/types.ts +++ b/src/contexts/ChainFilter/types.ts @@ -8,9 +8,9 @@ export interface ChainFilterInterface { searchTerms: SearchTerms; getSearchTerm: (tabId: number) => string; setSearchTerm: (tabId: number, searchTerm: string) => void; - customNodeUrls: CustomNodeUrls; - getCustomNodeUrl: (tabId: number) => string; - setCustomNodeUrl: (tabId: number, url: string) => void; + customEndpoints: CustomEndpoints; + getCustomEndpoint: (tabId: number) => string; + setCustomEndpoint: (tabId: number, url: string) => void; appliedTags: AppliedTags; getAppliedTags: (tabId: number) => [DirectoryId, TagItem][]; applyTags: (tabId: number, tagIds: TagId[]) => void; @@ -19,6 +19,6 @@ export interface ChainFilterInterface { export type SearchTerms = Record; -export type CustomNodeUrls = Record; +export type CustomEndpoints = Record; export type AppliedTags = Record; diff --git a/src/contexts/Tabs/types.ts b/src/contexts/Tabs/types.ts index 2b0c800e..572d3d06 100644 --- a/src/contexts/Tabs/types.ts +++ b/src/contexts/Tabs/types.ts @@ -19,7 +19,7 @@ export interface Tab { autoConnect: boolean; } -export type ConnectFrom = 'directory' | 'customNode'; +export type ConnectFrom = 'directory' | 'customEndpoint'; export interface TabsContextInterface { tabs: Tabs; diff --git a/src/library/Page/provider/index.tsx b/src/library/Page/provider/index.tsx index 71ca111e..5fef51e5 100644 --- a/src/library/Page/provider/index.tsx +++ b/src/library/Page/provider/index.tsx @@ -16,15 +16,18 @@ export const SectionContext = createContext( export const useSection = () => useContext(SectionContext); export const SectionProvider = ({ pageId, children }: SectionContextProps) => { - const { getApiActive } = useApi(); const { activeTabId } = useTabs(); const { redirectCounter } = useTabs(); + const { getApiActive, getApiStatus } = useApi(); + const apiStatus = getApiStatus(activeTabId); const apiActive = getApiActive(activeTabId); - // The active section of the page. + // The active section of the page. Falls back to default section if not connected. const [activeSection, setActiveSectionState] = useState( - local.getActiveSection(pageId, activeTabId) || defaultActiveSection + !apiActive + ? defaultActiveSection + : local.getActiveSection(pageId, activeTabId) || defaultActiveSection ); // Sets active section, and updates local storage if persisted. @@ -35,16 +38,21 @@ export const SectionProvider = ({ pageId, children }: SectionContextProps) => { setActiveSectionState(section); }; - // Handle redirects from local storage, if present. + // Handle redirects from local storage, if present. Also redirects back to default section if api + // is not active. useEffectIgnoreInitial(() => { const redirect = local.getSectionRedirect(pageId, activeTabId); const localActive = local.getActiveSection(pageId, activeTabId); + if (redirect) { setActiveSection(redirect || localActive || defaultActiveSection, false); } else { - setActiveSection(localActive || defaultActiveSection); + setActiveSection( + !apiActive ? defaultActiveSection : localActive || defaultActiveSection, + false + ); } - }, [pageId, activeTabId, redirectCounter, apiActive]); + }, [pageId, activeTabId, redirectCounter, apiActive, apiStatus]); return ( { Directory diff --git a/src/screens/Default/Connect/LocaNodeInput.tsx b/src/screens/Default/Connect/CustomEndpointInput.tsx similarity index 75% rename from src/screens/Default/Connect/LocaNodeInput.tsx rename to src/screens/Default/Connect/CustomEndpointInput.tsx index cf87b83b..6fe374d3 100644 --- a/src/screens/Default/Connect/LocaNodeInput.tsx +++ b/src/screens/Default/Connect/CustomEndpointInput.tsx @@ -11,18 +11,18 @@ import { import { useTabs } from 'contexts/Tabs'; import { useChainFilter } from 'contexts/ChainFilter'; -export const LocalNodeInput = () => { +export const CustomEndpointInput = () => { const { activeTabId, connectTab } = useTabs(); - const { getCustomNodeUrl, setCustomNodeUrl } = useChainFilter(); + const { getCustomEndpoint, setCustomEndpoint } = useChainFilter(); // The editable value of the input. - const customNodeUrl = getCustomNodeUrl(activeTabId); + const customEndpoint = getCustomEndpoint(activeTabId); // Handle input change. const onChange = (value: string) => { // If trimmed value and the current value is empty, don't update. - if (!(!value.trim().length && customNodeUrl === '')) { - setCustomNodeUrl(activeTabId, value); + if (!(!value.trim().length && customEndpoint === '')) { + setCustomEndpoint(activeTabId, value); } }; @@ -30,7 +30,7 @@ export const LocalNodeInput = () => { {
{ - connectTab(activeTabId, 'custom', customNodeUrl); + connectTab(activeTabId, 'custom', customEndpoint); }} > Connect diff --git a/src/screens/Default/Connect/index.tsx b/src/screens/Default/Connect/index.tsx index 0f257743..6f424e19 100644 --- a/src/screens/Default/Connect/index.tsx +++ b/src/screens/Default/Connect/index.tsx @@ -7,7 +7,7 @@ import { PageContentWrapper } from 'library/Page/Wrapper'; import { RecentChain } from './RecentChain'; import { ConnectHeader } from './ConnectHeader'; import { useTabs } from 'contexts/Tabs'; -import { LocalNodeInput } from './LocaNodeInput'; +import { CustomEndpointInput } from './CustomEndpointInput'; export const Connect = () => { const { getActiveTab } = useTabs(); @@ -17,7 +17,7 @@ export const Connect = () => { return ( - {connectFrom === 'customNode' && } + {connectFrom === 'customEndpoint' && } {connectFrom === 'directory' && ( <> diff --git a/src/screens/Settings/WorkspaceSettings/Utils.ts b/src/screens/Settings/WorkspaceSettings/Utils.ts index 1fe35471..42c30794 100644 --- a/src/screens/Settings/WorkspaceSettings/Utils.ts +++ b/src/screens/Settings/WorkspaceSettings/Utils.ts @@ -19,7 +19,7 @@ const SUPPORTED_WORKSPACE_LOCAL_STORAGE_KEYS = [ 'tags', 'tagsConfig', 'searchTerms', - 'customNodeUrls', + 'customEndpoints', 'appliedTags', ]; @@ -105,15 +105,15 @@ export const importWorkspace = (file: File) => { ); json = deleteKeyOrOverwrite('searchTerms', searchTermsResult, json); - // Check if imported custom node urls are valid. - const customNodeUrls = json.customNodeUrls || {}; - const { result: customNodeUrlsResult } = sanitizeKeysForTabExistence( + // Check if imported custom endpoints are valid. + const customEndpoints = json.customEndpoints || {}; + const { result: customEndpointsResult } = sanitizeKeysForTabExistence( activeTabs || defaultTabs, - customNodeUrls + customEndpoints ); json = deleteKeyOrOverwrite( - 'customNodeUrls', - customNodeUrlsResult, + 'customEndpoints', + customEndpointsResult, json );