Skip to content

Commit

Permalink
refactor: re-org and renames
Browse files Browse the repository at this point in the history
  • Loading branch information
Ross Bulat committed Mar 12, 2024
1 parent e4b05bb commit 0607354
Show file tree
Hide file tree
Showing 51 changed files with 158 additions and 167 deletions.
2 changes: 1 addition & 1 deletion src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { AppErrorBoundary } from 'library/ErrorBoundaries/AppErrorBoundary';
import { performLocalIntegrityChecks } from 'IntegrityChecks/Local';

// The currently supported pages.
export type PageId = 'default' | 'settings';
export type Route = 'default' | 'settings';

export const App = () => (
<Entry mode="light" accent={`developer-console`}>
Expand Down
2 changes: 1 addition & 1 deletion src/IntegrityChecks/Local.ts
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ export const removeLocalStorageState = (includeTags = false) => {
localStorage.removeItem('searchTerms');
localStorage.removeItem('customEndpoints');
localStorage.removeItem('appliedTags');
localStorage.removeItem('pageSections');
localStorage.removeItem('activePages');
localStorage.removeItem('pageRedirects');

if (includeTags) {
Expand Down
4 changes: 2 additions & 2 deletions src/Router.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
// SPDX-License-Identifier: GPL-3.0-only

import { Navigate, Route, Routes } from 'react-router-dom';
import { DefaultRoute } from 'screens/Default/Route';
import { SettingsRoute } from 'screens/Settings/Route';
import { DefaultRoute } from 'routes/Default/Route';
import { SettingsRoute } from 'routes/Settings/Route';
import { Header } from 'library/Header';
import { ContextMenu } from 'library/ContextMenu';
import { Tabs } from 'library/Tabs';
Expand Down
46 changes: 19 additions & 27 deletions src/library/Page/provider/Local.ts → src/contexts/Route/Local.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,53 +2,53 @@
// SPDX-License-Identifier: GPL-3.0-only

import { localStorageOrDefault } from '@w3ux/utils';
import type { PageId } from 'App';
import type { Route } from 'App';

// ------------------------------------------------------
// Getters.
// ------------------------------------------------------

// Gets saved page section from local storage, or returns undefined otherwise.
export const getActiveSection = (
pageId: PageId,
// Gets saved active page from local storage, or returns undefined otherwise.
export const getActivePage = (
route: Route,
tabId: number
): number | undefined => {
const result = localStorageOrDefault(`pageSections`, undefined, true) as
const result = localStorageOrDefault(`activePages`, undefined, true) as
| Record<string, number>
| undefined;

if (result) {
const maybePageSection = result[`${tabId}:${pageId}`];
if (maybePageSection) {
return maybePageSection as number;
const value = result[`${tabId}:${route}`];
if (value) {
return value as number;
}
}
};

// Gets a temporary redirect from local storage, or returns undefined otherwise. If a redirect is
// found it is immediately removed from local storage.
export const getSectionRedirect = (
pageId: PageId,
route: Route,
tabId: number
): number | undefined => {
const result = localStorageOrDefault(`pageRedirects`, undefined, true) as
| Record<string, number>
| undefined;

if (result) {
const maybePageRedirect = result[`${tabId}:${pageId}`];
const value = result[`${tabId}:${route}`];
// If page redirect exists, remove it before returning.
if (maybePageRedirect) {
if (value) {
const updated = { ...result };
delete updated[`${tabId}:${pageId}`];
delete updated[`${tabId}:${route}`];

if (Object.keys(updated).length === 0) {
localStorage.removeItem(`pageRedirects`);
} else {
localStorage.setItem(`pageRedirects`, JSON.stringify(updated));
}

return maybePageRedirect as number;
return value as number;
}
}
};
Expand All @@ -58,37 +58,29 @@ export const getSectionRedirect = (
// ------------------------------------------------------

// Sets page section to local storage.
export const setActiveSection = (
pageId: PageId,
tabId: number,
value: number
) => {
export const setActivePage = (route: Route, tabId: number, value: number) => {
const current =
(localStorageOrDefault(`pageSections`, undefined, true) as
(localStorageOrDefault(`activePages`, undefined, true) as
| Record<string, number>
| undefined) || {};

const updated = {
...current,
[`${tabId}:${pageId}`]: value,
[`${tabId}:${route}`]: value,
};
localStorage.setItem(`pageSections`, JSON.stringify(updated));
localStorage.setItem(`activePages`, JSON.stringify(updated));
};

// Sets a temporary redirect to local storage.
export const setSectionRedirect = (
pageId: PageId,
tabId: number,
value: number
) => {
export const setPageRedirect = (route: Route, tabId: number, value: number) => {
const current =
(localStorageOrDefault(`pageRedirects`, undefined, true) as
| Record<string, number>
| undefined) || {};

const updated = {
...current,
[`${tabId}:${pageId}`]: value,
[`${tabId}:${route}`]: value,
};
localStorage.setItem(`pageRedirects`, JSON.stringify(updated));
};
12 changes: 12 additions & 0 deletions src/contexts/Route/defaults.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// Copyright 2024 @rossbulat/console authors & contributors
// SPDX-License-Identifier: GPL-3.0-only
/* eslint-disable @typescript-eslint/no-unused-vars, @typescript-eslint/no-empty-function */

import type { RouteContextInterface } from './types';

export const defaultActivePage = 0;

export const defaultRouteContext: RouteContextInterface = {
activePage: defaultActivePage,
setActivePage: (section, persist) => {},
};
66 changes: 66 additions & 0 deletions src/contexts/Route/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
// Copyright 2024 @rossbulat/console authors & contributors
// SPDX-License-Identifier: GPL-3.0-only

import { createContext, useContext, useState } from 'react';
import { defaultActivePage, defaultRouteContext } from './defaults';
import type { RouteContextInterface, RouteContextProps } from './types';
import * as local from './Local';
import { useEffectIgnoreInitial } from '@w3ux/hooks';
import { useTabs } from 'contexts/Tabs';
import { useApi } from 'contexts/Api';

export const RouteContext =
createContext<RouteContextInterface>(defaultRouteContext);

export const useRoute = () => useContext(RouteContext);

export const RouteProvider = ({ route, children }: RouteContextProps) => {
const { activeTabId } = useTabs();
const { redirectCounter } = useTabs();
const { getApiActive, getApiStatus } = useApi();

const apiStatus = getApiStatus(activeTabId);
const apiActive = getApiActive(activeTabId);

// The active section of the page. Falls back to default section if not connected.
const [activePage, setActivePageState] = useState<number>(
!apiActive
? defaultActivePage
: local.getActivePage(route, activeTabId) || defaultActivePage
);

// Sets active section, and updates local storage if persisted.
const setActivePage = (section: number, persist = true) => {
if (persist) {
local.setActivePage(route, activeTabId, section);
}
setActivePageState(section);
};

// Handle redirects from local storage, if present. Also redirects back to default section if api
// is not active.
useEffectIgnoreInitial(() => {
const redirect = local.getSectionRedirect(route, activeTabId);
const localActive = local.getActivePage(route, activeTabId);

if (redirect) {
setActivePage(redirect || localActive || defaultActivePage, false);
} else {
setActivePage(
!apiActive ? defaultActivePage : localActive || defaultActivePage,
false
);
}
}, [route, activeTabId, redirectCounter, apiActive, apiStatus]);

return (
<RouteContext.Provider
value={{
activePage,
setActivePage,
}}
>
{children}
</RouteContext.Provider>
);
};
15 changes: 15 additions & 0 deletions src/contexts/Route/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// Copyright 2024 @rossbulat/console authors & contributors
// SPDX-License-Identifier: GPL-3.0-only

import type { Route } from 'App';
import type { ReactNode } from 'react';

export interface RouteContextInterface {
activePage: number;
setActivePage: (section: number, persist?: boolean) => void;
}

export interface RouteContextProps {
route: Route;
children: ReactNode;
}
8 changes: 4 additions & 4 deletions src/hooks/useRedirectOnInactive/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@

import { useApi } from 'contexts/Api';
import { useTabs } from 'contexts/Tabs';
import { useSection } from 'library/Page/provider';
import { useRoute } from 'contexts/Route';
import { useEffect } from 'react';

// NOTE: This hook can only be used within <Page> components, depending on SectionProvider.
// NOTE: This hook can only be used within <Page> components, depending on RouteProvider.
export const useRedirectOnInactive = (tabId: number) => {
const { activeTabId } = useTabs();
const { getApiStatus } = useApi();
const { setActiveSection } = useSection();
const { setActivePage } = useRoute();

const apiStatus = getApiStatus(tabId);
const INACTIVE_API_STATUSES = ['connected', 'disconnected', 'error'];
Expand All @@ -21,7 +21,7 @@ export const useRedirectOnInactive = (tabId: number) => {
// different section.
useEffect(() => {
if (apiInactive) {
setActiveSection(0, false);
setActivePage(0, false);
}
}, [apiStatus, activeTabId]);
};
12 changes: 0 additions & 12 deletions src/library/Page/provider/defaults.ts

This file was deleted.

67 changes: 0 additions & 67 deletions src/library/Page/provider/index.tsx

This file was deleted.

15 changes: 0 additions & 15 deletions src/library/Page/provider/types.ts

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

import { Body } from 'library/Body';
import { Page as PageWrapper } from 'library/Page';
import { SectionProvider } from 'library/Page/provider';
import { RouteProvider } from 'contexts/Route';
import type { PageWithMenuProps } from './types';
import { NetworkDirectory, type DirectoryId } from 'config/networks';
import { useTabs } from 'contexts/Tabs';
Expand All @@ -12,9 +12,9 @@ import { useApi } from 'contexts/Api';
import { useSettings } from 'contexts/Settings';

// Renders a page and menu, with state controlling the active section of the page.
export const PageWithMenu = ({ pageId, Page, Menu }: PageWithMenuProps) => {
const { chainColorEnabled } = useSettings();
export const PageWithMenu = ({ route, Page, Menu }: PageWithMenuProps) => {
const { getApiStatus } = useApi();
const { chainColorEnabled } = useSettings();
const { getActiveTab, activeTabId } = useTabs();

const tab = getActiveTab();
Expand Down Expand Up @@ -43,14 +43,14 @@ export const PageWithMenu = ({ pageId, Page, Menu }: PageWithMenuProps) => {
: undefined
}
>
<SectionProvider pageId={pageId}>
<RouteProvider route={route}>
<Menu />
<Body>
<PageWrapper>
<Page />
</PageWrapper>
</Body>
</SectionProvider>
</RouteProvider>
</div>
);
};
Loading

0 comments on commit 0607354

Please sign in to comment.