Refactor context (#427)

* Move AppContext to top level

* Refactor context
This commit is contained in:
Reckless_Satoshi 2023-04-20 14:52:03 +00:00 committed by GitHub
parent e3b7f1f268
commit 28ef253020
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
29 changed files with 168 additions and 311 deletions

View File

@ -1,9 +1,8 @@
import React, { Suspense, useState, useEffect } from 'react';
import React, { StrictMode, Suspense } from 'react';
import ReactDOM from 'react-dom/client';
import Main from './basic/Main';
import { CssBaseline } from '@mui/material';
import { AppContextProvider } from './contexts/AppContext';
import { ThemeProvider, createTheme, Theme } from '@mui/material/styles';
import { CssBaseline, ThemeProvider } from '@mui/material';
import { AppContext, useAppStore } from './contexts/AppContext';
import UnsafeAlert from './components/UnsafeAlert';
import TorConnectionBadge from './components/TorConnection';
@ -11,53 +10,31 @@ import { I18nextProvider } from 'react-i18next';
import i18n from './i18n/Web';
import { systemClient } from './services/System';
import { Settings } from './models';
import ErrorBoundary from './components/ErrorBoundary';
const makeTheme = function (settings: Settings) {
const theme: Theme = createTheme({
palette: {
mode: settings.mode,
background: {
default: settings.mode === 'dark' ? '#070707' : '#fff',
},
},
typography: { fontSize: settings.fontSize },
});
return theme;
};
const App = (): JSX.Element => {
const [theme, setTheme] = useState<Theme>(makeTheme(new Settings()));
const [settings, setSettings] = useState<Settings>(new Settings());
useEffect(() => {
setTheme(makeTheme(settings));
}, [settings.fontSize, settings.mode]);
useEffect(() => {
i18n.changeLanguage(settings.language);
}, []);
const store = useAppStore();
return (
<StrictMode>
<ErrorBoundary>
<Suspense fallback='loading language'>
<Suspense fallback='loading'>
<I18nextProvider i18n={i18n}>
<ThemeProvider theme={theme}>
<AppContextProvider settings={settings} setSettings={setSettings}>
<AppContext.Provider value={store}>
<ThemeProvider theme={store.theme}>
<CssBaseline />
{window.NativeRobosats === undefined ? <UnsafeAlert /> : <TorConnectionBadge />}
<Main />
</AppContextProvider>
</ThemeProvider>
</AppContext.Provider>
</I18nextProvider>
</Suspense>
</ErrorBoundary>
</StrictMode>
);
};
const loadApp = () => {
// waits until the environment is ready for the Android WebView app
if (systemClient.loading) {
setTimeout(loadApp, 200);
} else {

View File

@ -10,7 +10,7 @@ import BookTable from '../../components/BookTable';
// Icons
import { BarChart, FormatListBulleted } from '@mui/icons-material';
import { AppContext, AppContextProps } from '../../contexts/AppContext';
import { AppContext, UseAppStoreType } from '../../contexts/AppContext';
const BookPage = (): JSX.Element => {
const {
@ -24,7 +24,7 @@ const BookPage = (): JSX.Element => {
book,
setDelay,
setOrder,
} = useContext<AppContextProps>(AppContext);
} = useContext<UseAppStoreType>(AppContext);
const { t } = useTranslation();
const navigate = useNavigate();
const [view, setView] = useState<'list' | 'depth'>('list');

View File

@ -14,7 +14,7 @@ import RobotAvatar from '../components/RobotAvatar';
import { useTranslation } from 'react-i18next';
import Notifications from '../components/Notifications';
import { AppContextProps, AppContext } from '../contexts/AppContext';
import { UseAppStoreType, AppContext, closeAll } from '../contexts/AppContext';
const Router = window.NativeRobosats === undefined ? BrowserRouter : MemoryRouter;
@ -29,11 +29,10 @@ const Main = (): JSX.Element => {
page,
setPage,
slideDirection,
closeAll,
setOpen,
windowSize,
navbarHeight,
} = useContext<AppContextProps>(AppContext);
} = useContext<UseAppStoreType>(AppContext);
return (
<Router>
@ -41,7 +40,11 @@ const Main = (): JSX.Element => {
style={{ display: 'none' }}
nickname={robot.nickname}
baseUrl={baseUrl}
onLoad={() => setRobot({ ...robot, avatarLoaded: true })}
onLoad={() =>
setRobot((robot) => {
return { ...robot, avatarLoaded: true };
})
}
/>
<Notifications
order={order}

View File

@ -9,7 +9,7 @@ import {
UpdateClientDialog,
} from '../../components/Dialogs';
import { pn } from '../../utils';
import { AppContext, AppContextProps } from '../../contexts/AppContext';
import { AppContext, UseAppStoreType, closeAll } from '../../contexts/AppContext';
export interface OpenDialogs {
more: boolean;
@ -23,18 +23,8 @@ export interface OpenDialogs {
}
const MainDialogs = (): JSX.Element => {
const {
open,
setOpen,
info,
limits,
closeAll,
robot,
setRobot,
setPage,
setCurrentOrder,
baseUrl,
} = useContext<AppContextProps>(AppContext);
const { open, setOpen, info, limits, robot, setRobot, setPage, setCurrentOrder, baseUrl } =
useContext<UseAppStoreType>(AppContext);
const [maxAmount, setMaxAmount] = useState<string>('...loading...');

View File

@ -8,7 +8,7 @@ import { filterOrders } from '../../utils';
import MakerForm from '../../components/MakerForm';
import BookTable from '../../components/BookTable';
import { AppContext, AppContextProps } from '../../contexts/AppContext';
import { AppContext, UseAppStoreType } from '../../contexts/AppContext';
import { NoRobotDialog } from '../../components/Dialogs';
const MakerPage = (): JSX.Element => {
@ -24,7 +24,7 @@ const MakerPage = (): JSX.Element => {
setPage,
setOrder,
setDelay,
} = useContext<AppContextProps>(AppContext);
} = useContext<UseAppStoreType>(AppContext);
const { t } = useTranslation();
const navigate = useNavigate();

View File

@ -1,8 +1,8 @@
import React, { useEffect, useState } from 'react';
import React from 'react';
import { useTranslation } from 'react-i18next';
import { useTheme, styled, Grid, IconButton } from '@mui/material';
import Tooltip, { TooltipProps, tooltipClasses } from '@mui/material/Tooltip';
import { closeAll } from '../../contexts/AppContext';
import { OpenDialogs } from '../MainDialogs';
import { BubbleChart, Info, People, PriceChange, School } from '@mui/icons-material';
@ -22,11 +22,10 @@ const StyledTooltip = styled(({ className, ...props }: TooltipProps) => (
interface MoreTooltipProps {
open: OpenDialogs;
setOpen: (state: OpenDialogs) => void;
closeAll: OpenDialogs;
children: JSX.Element;
}
const MoreTooltip = ({ open, setOpen, closeAll, children }: MoreTooltipProps): JSX.Element => {
const MoreTooltip = ({ open, setOpen, children }: MoreTooltipProps): JSX.Element => {
const { t } = useTranslation();
const theme = useTheme();
return (

View File

@ -15,7 +15,7 @@ import {
MoreHoriz,
} from '@mui/icons-material';
import RobotAvatar from '../../components/RobotAvatar';
import { AppContext, AppContextProps } from '../../contexts/AppContext';
import { AppContext, UseAppStoreType, closeAll } from '../../contexts/AppContext';
interface NavBarProps {
width: number;
@ -31,10 +31,9 @@ const NavBar = ({ width, height }: NavBarProps): JSX.Element => {
setSlideDirection,
open,
setOpen,
closeAll,
currentOrder,
baseUrl,
} = useContext<AppContextProps>(AppContext);
} = useContext<UseAppStoreType>(AppContext);
const theme = useTheme();
const { t } = useTranslation();

View File

@ -7,7 +7,7 @@ import TradeBox from '../../components/TradeBox';
import OrderDetails from '../../components/OrderDetails';
import { apiClient } from '../../services/api';
import { AppContext, AppContextProps } from '../../contexts/AppContext';
import { AppContext, UseAppStoreType } from '../../contexts/AppContext';
const OrderPage = (): JSX.Element => {
const {
@ -23,7 +23,7 @@ const OrderPage = (): JSX.Element => {
setPage,
baseUrl,
navbarHeight,
} = useContext<AppContextProps>(AppContext);
} = useContext<UseAppStoreType>(AppContext);
const { t } = useTranslation();
const navigate = useNavigate();
const params = useParams();

View File

@ -18,7 +18,7 @@ import RobotAvatar from '../../components/RobotAvatar';
import TokenInput from './TokenInput';
import { Page } from '../NavBar';
import { Slot, Robot } from '../../models';
import { AppContext, AppContextProps } from '../../contexts/AppContext';
import { AppContext, UseAppStoreType } from '../../contexts/AppContext';
import { genBase62Token } from '../../utils';
import { LoadingButton } from '@mui/lab';
@ -53,7 +53,7 @@ const RobotProfile = ({
width,
}: RobotProfileProps): JSX.Element => {
const { currentSlot, garage, setCurrentSlot, windowSize } =
useContext<AppContextProps>(AppContext);
useContext<UseAppStoreType>(AppContext);
const { t } = useTranslation();
const theme = useTheme();
const navigate = useNavigate();

View File

@ -8,7 +8,6 @@ import { systemClient } from '../../services/System';
interface TokenInputProps {
robot: Robot;
editable?: boolean;
showDownload?: boolean;
fullWidth?: boolean;
loading?: boolean;
setRobot: (state: Robot) => void;
@ -42,16 +41,6 @@ const TokenInput = ({
setShowCopied(false);
}, [inputToken]);
const createJsonFile = () => {
return {
token: robot.token,
token_shannon_entropy: robot.shannonEntropy,
token_bit_entropy: robot.bitsEntropy,
public_key: robot.pubKey,
encrypted_private_key: robot.encPrivKey,
};
};
if (loading) {
return <LinearProgress sx={{ height: '0.8em' }} />;
} else {
@ -84,7 +73,9 @@ const TokenInput = ({
systemClient.copyToClipboard(inputToken);
setShowCopied(true);
setTimeout(() => setShowCopied(false), 1000);
setRobot({ ...robot, copiedToken: true });
setRobot((robot) => {
return { ...robot, copiedToken: true };
});
}}
>
<ContentCopy sx={{ width: '1em', height: '1em' }} />

View File

@ -13,18 +13,17 @@ import {
import { useParams } from 'react-router-dom';
import { Robot } from '../../models';
import { apiClient } from '../../services/api';
import Onboarding from './Onboarding';
import Welcome from './Welcome';
import RobotProfile from './RobotProfile';
import Recovery from './Recovery';
import { TorIcon } from '../../components/Icons';
import { genKey } from '../../pgp';
import { AppContext, AppContextProps } from '../../contexts/AppContext';
import { AppContext, UseAppStoreType } from '../../contexts/AppContext';
const RobotPage = (): JSX.Element => {
const { robot, setRobot, setPage, setCurrentOrder, fetchRobot, torStatus, windowSize, baseUrl } =
useContext<AppContextProps>(AppContext);
useContext<UseAppStoreType>(AppContext);
const { t } = useTranslation();
const params = useParams();
const refCode = params.refCode;
@ -138,7 +137,7 @@ const RobotPage = (): JSX.Element => {
<Onboarding
setView={setView}
robot={robot}
setRobot={() => null}
setRobot={setRobot}
badRequest={badRequest}
inputToken={inputToken}
setInputToken={setInputToken}
@ -152,7 +151,7 @@ const RobotPage = (): JSX.Element => {
<RobotProfile
setView={setView}
robot={robot}
setRobot={() => null}
setRobot={setRobot}
setCurrentOrder={setCurrentOrder}
badRequest={badRequest}
getGenerateRobot={getGenerateRobot}
@ -170,7 +169,7 @@ const RobotPage = (): JSX.Element => {
<Recovery
setView={setView}
robot={robot}
setRobot={() => null}
setRobot={setRobot}
badRequest={badRequest}
inputToken={inputToken}
setInputToken={setInputToken}

View File

@ -1,13 +1,10 @@
import React, { useContext } from 'react';
import { useTranslation } from 'react-i18next';
import { Grid, Paper, useTheme } from '@mui/material';
import { Grid, Paper } from '@mui/material';
import SettingsForm from '../../components/SettingsForm';
import { AppContextProps, AppContext } from '../../contexts/AppContext';
import { UseAppStoreType, AppContext } from '../../contexts/AppContext';
const SettingsPage = (): JSX.Element => {
const { windowSize, navbarHeight } = useContext<AppContextProps>(AppContext);
const theme = useTheme();
const { t } = useTranslation();
const { windowSize, navbarHeight } = useContext<UseAppStoreType>(AppContext);
const maxHeight = (windowSize.height - navbarHeight) * 0.85 - 3;
return (

View File

@ -32,7 +32,7 @@ import RobotAvatar from '../RobotAvatar';
// Icons
import { Fullscreen, FullscreenExit, Refresh } from '@mui/icons-material';
import { AppContext, AppContextProps } from '../../contexts/AppContext';
import { AppContext, UseAppStoreType } from '../../contexts/AppContext';
interface BookTableProps {
orderList?: PublicOrder[];
@ -63,7 +63,7 @@ const BookTable = ({
showNoResults = true,
onOrderClicked = () => null,
}: BookTableProps): JSX.Element => {
const { book, fetchBook, fav, setFav, baseUrl } = useContext<AppContextProps>(AppContext);
const { book, fetchBook, fav, setFav, baseUrl } = useContext<UseAppStoreType>(AppContext);
const { t } = useTranslation();
const theme = useTheme();

View File

@ -26,7 +26,7 @@ import { amountToString, matchMedian, statusBadgeColor } from '../../../utils';
import currencyDict from '../../../../static/assets/currencies.json';
import { PaymentStringAsIcons } from '../../PaymentMethods';
import getNivoScheme from '../NivoScheme';
import { AppContextProps, AppContext } from '../../../contexts/AppContext';
import { UseAppStoreType, AppContext } from '../../../contexts/AppContext';
interface DepthChartProps {
maxWidth: number;
@ -43,7 +43,7 @@ const DepthChart: React.FC<DepthChartProps> = ({
elevation = 6,
onOrderClicked = () => null,
}) => {
const { book, fav, info, limits, baseUrl } = useContext<AppContextProps>(AppContext);
const { book, fav, info, limits, baseUrl } = useContext<UseAppStoreType>(AppContext);
const { t } = useTranslation();
const theme = useTheme();
const [enrichedOrders, setEnrichedOrders] = useState<Order[]>([]);

View File

@ -9,7 +9,7 @@ import {
Button,
} from '@mui/material';
import { useNavigate } from 'react-router-dom';
import { AppContext, AppContextProps } from '../../contexts/AppContext';
import { AppContext, UseAppStoreType } from '../../contexts/AppContext';
interface Props {
open: boolean;
@ -17,7 +17,7 @@ interface Props {
}
const NoRobotDialog = ({ open, onClose }: Props): JSX.Element => {
const { setPage } = useContext<AppContextProps>(AppContext);
const { setPage } = useContext<UseAppStoreType>(AppContext);
const { t } = useTranslation();
const navigate = useNavigate();

View File

@ -14,7 +14,7 @@ import {
} from '@mui/material';
import { systemClient } from '../../services/System';
import ContentCopy from '@mui/icons-material/ContentCopy';
import { AppContext, AppContextProps } from '../../contexts/AppContext';
import { AppContext, UseAppStoreType } from '../../contexts/AppContext';
interface Props {
open: boolean;
@ -24,7 +24,7 @@ interface Props {
}
const StoreTokenDialog = ({ open, onClose, onClickBack, onClickDone }: Props): JSX.Element => {
const { robot } = useContext<AppContextProps>(AppContext);
const { robot } = useContext<UseAppStoreType>(AppContext);
const { t } = useTranslation();
return (

View File

@ -12,6 +12,8 @@ interface ErrorBoundaryState {
}
export default class ErrorBoundary extends Component<ErrorBoundaryProps, ErrorBoundaryState> {
// In case the app crashes this component will restart it in 10 seconds
// It will also print an obnoxious error message (useful for end users to grab a screenshot and report)
constructor(props: ErrorBoundaryProps) {
super(props);
this.state = {

View File

@ -40,7 +40,7 @@ import { amountToString, computeSats, pn } from '../../utils';
import { SelfImprovement, Lock, HourglassTop, DeleteSweep, Edit } from '@mui/icons-material';
import { LoadingButton } from '@mui/lab';
import { AppContext, AppContextProps } from '../../contexts/AppContext';
import { AppContext, UseAppStoreType } from '../../contexts/AppContext';
interface MakerFormProps {
disableRequest?: boolean;
@ -64,7 +64,7 @@ const MakerForm = ({
hasRobot = true,
}: MakerFormProps): JSX.Element => {
const { fav, setFav, limits, fetchLimits, info, maker, setMaker, setPage, baseUrl } =
useContext<AppContextProps>(AppContext);
useContext<UseAppStoreType>(AppContext);
const { t } = useTranslation();
const theme = useTheme();

View File

@ -22,7 +22,6 @@ import { apiClient } from '../../services/api';
import { Order } from '../../models';
import { ConfirmationDialog } from '../Dialogs';
import { Page } from '../../basic/NavBar';
import { LoadingButton } from '@mui/lab';
interface TakeButtonProps {

View File

@ -1,6 +1,6 @@
import React, { useContext } from 'react';
import { useTranslation } from 'react-i18next';
import { AppContextProps, AppContext } from '../../contexts/AppContext';
import { UseAppStoreType, AppContext } from '../../contexts/AppContext';
import {
Grid,
Paper,
@ -35,7 +35,7 @@ interface SettingsFormProps {
}
const SettingsForm = ({ dense = false, showNetwork = false }: SettingsFormProps): JSX.Element => {
const { fav, setFav, settings, setSettings } = useContext<AppContextProps>(AppContext);
const { fav, setFav, settings, setSettings } = useContext<UseAppStoreType>(AppContext);
const theme = useTheme();
const { t } = useTranslation();
const fontSizes = [

View File

@ -2,7 +2,7 @@ import React, { useContext } from 'react';
import { Box, CircularProgress, Tooltip } from '@mui/material';
import { TorIcon } from './Icons';
import { useTranslation } from 'react-i18next';
import { AppContext, AppContextProps } from '../contexts/AppContext';
import { AppContext, UseAppStoreType } from '../contexts/AppContext';
interface TorIndicatorProps {
color: 'inherit' | 'error' | 'warning' | 'success' | 'primary' | 'secondary' | 'info' | undefined;
@ -55,7 +55,7 @@ const TorIndicator = ({
};
const TorConnectionBadge = (): JSX.Element => {
const { torStatus } = useContext<AppContextProps>(AppContext);
const { torStatus } = useContext<UseAppStoreType>(AppContext);
const { t } = useTranslation();
if (window?.NativeRobosats == null) {

View File

@ -1,11 +1,11 @@
import React, { useState, useEffect, useContext } from 'react';
import { AppContext, AppContextProps } from '../contexts/AppContext';
import { AppContext, UseAppStoreType } from '../contexts/AppContext';
import { useTranslation, Trans } from 'react-i18next';
import { Paper, Alert, AlertTitle, Button, Link } from '@mui/material';
import { getHost } from '../utils';
const UnsafeAlert = (): JSX.Element => {
const { windowSize } = useContext<AppContextProps>(AppContext);
const { windowSize } = useContext<UseAppStoreType>(AppContext);
const { t } = useTranslation();
const [show, setShow] = useState<boolean>(true);

View File

@ -1,4 +1,4 @@
import React, { useEffect, useState } from 'react';
import React, { createContext, useEffect, useState } from 'react';
import { Page } from '../basic/NavBar';
import { OpenDialogs } from '../basic/MainDialogs';
@ -23,7 +23,8 @@ import { checkVer, getHost, tokenStrength } from '../utils';
import { sha256 } from 'js-sha256';
import defaultCoordinators from '../../static/federation.json';
import { useTheme } from '@mui/material';
import { createTheme, Theme } from '@mui/material/styles';
import i18n from '../i18n/Web';
const getWindowSize = function (fontSize: number) {
// returns window size in EM units
@ -72,61 +73,10 @@ export interface fetchRobotProps {
export type TorStatus = 'NOTINIT' | 'STARTING' | '"Done"' | 'DONE';
export interface AppContextProps {
torStatus: TorStatus;
federation: Coordinator[];
setFederation: (state: Coordinator[]) => void;
settings: Settings;
setSettings: (state: Settings) => void;
book: Book;
info: Info;
garage: Garage;
setGarage: (state: Garage) => void;
currentSlot: number;
setCurrentSlot: (state: number) => void;
setBook: (state: Book) => void;
fetchBook: () => void;
limits: { list: LimitList; loading: boolean };
setLimits: (state: { list: LimitList; loading: boolean }) => void;
fetchLimits: () => void;
maker: Maker;
setMaker: (state: Maker) => void;
clearOrder: () => void;
robot: Robot;
setRobot: (state: Robot) => void;
focusedCoordinator: number;
setFocusedCoordinator: (state: number) => void;
baseUrl: string;
setBaseUrl: (state: string) => void;
fav: Favorites;
setFav: (state: Favorites) => void;
order: Order | undefined;
setOrder: (state: Order | undefined) => void;
badOrder: string;
setBadOrder: (state: string | undefined) => void;
setDelay: (state: number) => void;
page: Page;
setPage: (state: Page) => void;
slideDirection: SlideDirection;
setSlideDirection: (state: SlideDirection) => void;
currentOrder: number | undefined;
setCurrentOrder: (state: number) => void;
navbarHeight: number;
closeAll: OpenDialogs;
open: OpenDialogs;
setOpen: (state: OpenDialogs) => void;
windowSize: { width: number; height: number };
clientVersion: {
semver: Version;
short: string;
long: string;
};
}
const entryPage: Page | '' =
window.NativeRobosats === undefined ? window.location.pathname.split('/')[1] : '';
const closeAll = {
export const closeAll = {
more: false,
learn: false,
community: false,
@ -138,66 +88,40 @@ const closeAll = {
profile: false,
};
// export const initialState = {
// federation: defaultFederation,
// setFederation: () => null,
// settings: new Settings(),
// setSettings: () => null,
// book: { orders: [], loading: true },
// setBook: () => null,
// fetchBook: () => null,
// limits: {
// list: [],
// loading: true,
// },
// setLimits:() => null,
// fetchLimits: ()=> null,
// maker: defaultMaker,
// setMaker: () => null,
// clearOrder: () => null,
// robot: new Robot(),
// setRobot: () => null,
// info: defaultExchange,
// setExchange: () => null,
// focusedCoordinator: 0,
// setFocusedCoordinator: () => null,
// baseUrl: '',
// setBaseUrl: () => null,
// fav: { type: null, currency: 0 },
// setFav: () => null,
// order: undefined,
// setOrder: () => null,
// badOrder: '',
// setBadOrder: () => null,
// setDelay: () => null,
// page: entryPage == '' ? 'robot' : entryPage,
// setPage: () => null,
// slideDirection: {
// in: undefined,
// out: undefined,
// },
// setSlideDirection: () => null,
// currentOrder: undefined,
// setCurrentOrder: () => null,
// navbarHeight: 2.5,
// closeAll,
// open: closeAll,
// setOpen: () => null,
// windowSize: getWindowSize(14),
// }
const makeTheme = function (settings: Settings) {
const theme: Theme = createTheme({
palette: {
mode: settings.mode,
background: {
default: settings.mode === 'dark' ? '#070707' : '#fff',
},
},
typography: { fontSize: settings.fontSize },
});
export interface AppContextProviderProps {
children: React.ReactNode;
settings: Settings;
setSettings: (state: Settings) => void;
}
return theme;
};
export const AppContextProvider = ({
children,
settings,
setSettings,
}: AppContextProviderProps): JSX.Element => {
const theme = useTheme();
const initialSettings = new Settings();
const initialTheme = makeTheme(initialSettings);
const initialGarage = new Garage();
const initialSlot = initialGarage.slots.length - 1;
const initialRobot = new Robot(initialGarage.slots[initialSlot].robot);
export const useAppStore = () => {
// State provided right at the top level of the app. A chaotic bucket of everything.
// Contains app-wide state and functions. Triggers re-renders on the full tree often.
const [theme, setTheme] = useState<Theme>(initialTheme);
const [settings, setSettings] = useState<Settings>(initialSettings);
useEffect(() => {
setTheme(makeTheme(settings));
}, [settings.fontSize, settings.mode]);
useEffect(() => {
i18n.changeLanguage(settings.language);
}, []);
// All app data structured
const [torStatus, setTorStatus] = useState<TorStatus>('NOTINIT');
@ -206,13 +130,9 @@ export const AppContextProvider = ({
list: [],
loading: true,
});
const [garage, setGarage] = useState<Garage>(() => {
const initialState = { setGarage };
const newGarage = new Garage(initialState);
return newGarage;
});
const [currentSlot, setCurrentSlot] = useState<number>(garage.slots.length - 1);
const [robot, setRobot] = useState<Robot>(new Robot(garage.slots[currentSlot].robot));
const [garage, setGarage] = useState<Garage>(initialGarage);
const [currentSlot, setCurrentSlot] = useState<number>(initialSlot);
const [robot, setRobot] = useState<Robot>(initialRobot);
const [maker, setMaker] = useState<Maker>(defaultMaker);
const [info, setInfo] = useState<Info>(defaultInfo);
const [coordinators, setCoordinators] = useState<Coordinator[]>(defaultCoordinators);
@ -224,8 +144,6 @@ export const AppContextProvider = ({
const [order, setOrder] = useState<Order | undefined>(undefined);
const [badOrder, setBadOrder] = useState<string | undefined>(undefined);
const entryPage: Page | '' =
window.NativeRobosats === undefined ? window.location.pathname.split('/')[1] : '';
const [page, setPage] = useState<Page>(entryPage == '' ? 'robot' : entryPage);
const [slideDirection, setSlideDirection] = useState<SlideDirection>({
in: undefined,
@ -234,16 +152,6 @@ export const AppContextProvider = ({
const [currentOrder, setCurrentOrder] = useState<number | undefined>(undefined);
const navbarHeight = 2.5;
const closeAll = {
more: false,
learn: false,
community: false,
info: false,
coordinator: false,
stats: false,
update: false,
profile: false,
};
const [open, setOpen] = useState<OpenDialogs>(closeAll);
const [windowSize, setWindowSize] = useState<{ width: number; height: number }>(
@ -252,7 +160,7 @@ export const AppContextProvider = ({
useEffect(() => {
window.addEventListener('torStatus', (event) => {
// UX improv: delay the "Conencted" status by 10 secs to avoid long waits for first requests
// Trick to improve UX on Android webview: delay the "Connected to TOR" status by 5 secs to avoid long waits on the first request.
setTimeout(() => setTorStatus(event?.detail), event?.detail === '"Done"' ? 5000 : 0);
});
}, []);
@ -486,9 +394,8 @@ export const AppContextProvider = ({
}
}, [open.profile, baseUrl]);
return (
<AppContext.Provider
value={{
return {
theme,
torStatus,
settings,
setSettings,
@ -525,15 +432,12 @@ export const AppContextProvider = ({
currentOrder,
setCurrentOrder,
navbarHeight,
closeAll,
open,
setOpen,
windowSize,
}}
>
{children}
</AppContext.Provider>
);
};
};
export const AppContext = React.createContext();
export type UseAppStoreType = ReturnType<typeof useAppStore>;
export const AppContext = createContext<UseAppStoreType | null>(null);

View File

@ -10,22 +10,19 @@ const emptySlot: Slot = { robot: new Robot(), order: null };
class Garage {
constructor(initialState?: Garage) {
const slotsDump: string | undefined = systemClient.getItem('garage');
const slotsDump: string = systemClient.getItem('garage');
if (initialState?.slots === undefined && slotsDump != '') {
this.slots = JSON.parse(slotsDump);
console.log('Robot Garage was loaded from local storage');
} else {
this.slots = [emptySlot];
}
this.setGarage = initialState?.setGarage ?? (() => {});
}
slots: Slot[] = [emptySlot];
setGarage: (state: Garage) => void = () => {};
save = () => {
systemClient.setItem('garage', JSON.stringify(this.slots));
this.setGarage(new Garage(this));
};
delete = () => {

View File

@ -12,7 +12,7 @@ import {
import ToolBar from '../pro/ToolBar';
import LandingDialog from '../pro/LandingDialog';
import { AppContext, AppContextProps } from '../contexts/AppContext';
import { AppContext, UseAppStoreType } from '../contexts/AppContext';
// To Do. Add dotted grid when layout is not frozen
// ${freeze ?
@ -71,7 +71,7 @@ const Main = (): JSX.Element => {
windowSize,
badOrder,
setBadOrder,
} = useContext<AppContextProps>(AppContext);
} = useContext<UseAppStoreType>(AppContext);
const theme = useTheme();
const em: number = theme.typography.fontSize;

View File

@ -1,5 +1,5 @@
import React, { useContext } from 'react';
import { AppContext, AppContextProps } from '../../contexts/AppContext';
import { AppContext, UseAppStoreType } from '../../contexts/AppContext';
import { Book, Favorites } from '../../models';
import { Paper } from '@mui/material';
@ -34,7 +34,7 @@ const BookWidget = React.forwardRef(
}: BookWidgetProps,
ref,
) => {
const { book, windowSize, fav } = useContext<AppContextProps>(AppContext);
const { book, windowSize, fav } = useContext<UseAppStoreType>(AppContext);
return React.useMemo(() => {
return (
<Paper elevation={3} style={{ width: '100%', height: '100%' }}>

View File

@ -1,5 +1,5 @@
import React, { useContext } from 'react';
import { AppContext, AppContextProps } from '../../contexts/AppContext';
import { AppContext, UseAppStoreType } from '../../contexts/AppContext';
import { Paper, useTheme } from '@mui/material';
import DepthChart from '../../components/Charts/DepthChart';
@ -27,7 +27,7 @@ const DepthChartWidget = React.forwardRef(
ref,
) => {
const theme = useTheme();
const { fav, book, limits } = useContext<AppContextProps>(AppContext);
const { fav, book, limits } = useContext<UseAppStoreType>(AppContext);
return React.useMemo(() => {
return (
<Paper elevation={3} style={{ width: '100%', height: '100%' }}>

View File

@ -1,5 +1,5 @@
import React, { useContext } from 'react';
import { AppContext, AppContextProps } from '../../contexts/AppContext';
import { AppContext, UseAppStoreType } from '../../contexts/AppContext';
import MakerForm from '../../components/MakerForm';
import { LimitList, Maker, Favorites } from '../../models';
@ -15,7 +15,7 @@ interface MakerWidgetProps {
const MakerWidget = React.forwardRef(
({ style, className, onMouseDown, onMouseUp, onTouchEnd }: MakerWidgetProps, ref) => {
const { maker, fav, limits } = useContext<AppContextProps>(AppContext);
const { maker, fav, limits } = useContext<UseAppStoreType>(AppContext);
return React.useMemo(() => {
return (
<Paper

View File

@ -1,5 +1,5 @@
import React, { useContext } from 'react';
import { AppContextProps, AppContext } from '../../contexts/AppContext';
import { UseAppStoreType, AppContext } from '../../contexts/AppContext';
import { Settings } from '../../models';
import { Paper } from '@mui/material';
import SettingsForm from '../../components/SettingsForm';
@ -14,7 +14,7 @@ interface SettingsWidgetProps {
const SettingsWidget = React.forwardRef(
({ style, className, onMouseDown, onMouseUp, onTouchEnd }: SettingsWidgetProps, ref) => {
const { settings } = useContext<AppContextProps>(AppContext);
const { settings } = useContext<UseAppStoreType>(AppContext);
return React.useMemo(() => {
return (
<Paper