chore: refactor global store (#1241)

This commit is contained in:
Matthew Russell 2022-09-05 07:25:33 -07:00 committed by GitHub
parent e674efdb14
commit 9cb84df35c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 72 additions and 88 deletions

View File

@ -13,10 +13,11 @@ interface NavbarProps {
} }
export const Navbar = ({ theme, toggleTheme }: NavbarProps) => { export const Navbar = ({ theme, toggleTheme }: NavbarProps) => {
const store = useGlobalStore(); const { marketId, update } = useGlobalStore((store) => ({
const tradingPath = store.marketId marketId: store.marketId,
? `/markets/${store.marketId}` update: store.update,
: '/markets'; }));
const tradingPath = marketId ? `/markets/${marketId}` : '/markets';
return ( return (
<div className="px-4 flex items-stretch border-b border-neutral-300 dark:border-neutral-700 bg-black"> <div className="px-4 flex items-stretch border-b border-neutral-300 dark:border-neutral-700 bg-black">
<div className="flex gap-4 mr-4 items-center h-full"> <div className="flex gap-4 mr-4 items-center h-full">
@ -48,9 +49,7 @@ export const Navbar = ({ theme, toggleTheme }: NavbarProps) => {
fixedBg="dark" fixedBg="dark"
/> />
<VegaWalletConnectButton <VegaWalletConnectButton
setConnectDialog={(open) => { setConnectDialog={(open) => update({ connectDialog: open })}
store.setVegaWalletConnectDialog(open);
}}
/> />
</div> </div>
</div> </div>

View File

@ -7,7 +7,7 @@ beforeEach(() => {
localStorage.clear(); localStorage.clear();
useGlobalStore.setState((state) => ({ useGlobalStore.setState((state) => ({
...state, ...state,
vegaRiskNoticeDialog: false, riskNoticeDialog: false,
})); }));
}); });

View File

@ -8,28 +8,27 @@ import { useGlobalStore } from '../../stores';
export const RISK_ACCEPTED_KEY = 'vega-risk-accepted'; export const RISK_ACCEPTED_KEY = 'vega-risk-accepted';
export const RiskNoticeDialog = () => { export const RiskNoticeDialog = () => {
const store = useGlobalStore(); const { riskNoticeDialog, update } = useGlobalStore((store) => ({
riskNoticeDialog: store.riskNoticeDialog,
update: store.update,
}));
const { VEGA_ENV } = useEnvironment(); const { VEGA_ENV } = useEnvironment();
useEffect(() => { useEffect(() => {
const isRiskAccepted = LocalStorage.getItem(RISK_ACCEPTED_KEY) === 'true'; const isRiskAccepted = LocalStorage.getItem(RISK_ACCEPTED_KEY) === 'true';
if (!isRiskAccepted && VEGA_ENV === Networks.MAINNET) { if (!isRiskAccepted && VEGA_ENV === Networks.MAINNET) {
store.setVegaRiskNoticeDialog(true); update({ riskNoticeDialog: true });
} }
// eslint-disable-next-line react-hooks/exhaustive-deps // eslint-disable-next-line react-hooks/exhaustive-deps
}, [store.setVegaRiskNoticeDialog, VEGA_ENV]); }, [update, VEGA_ENV]);
const handleAcceptRisk = () => { const handleAcceptRisk = () => {
store.setVegaRiskNoticeDialog(false); update({ riskNoticeDialog: false });
LocalStorage.setItem(RISK_ACCEPTED_KEY, 'true'); LocalStorage.setItem(RISK_ACCEPTED_KEY, 'true');
}; };
return ( return (
<Dialog <Dialog open={riskNoticeDialog} title={t('WARNING')} size="medium">
open={store.vegaRiskNoticeDialog}
title={t('WARNING')}
size="medium"
>
<h4 className="text-xl mb-2 mt-4"> <h4 className="text-xl mb-2 mt-4">
{t('Regulation may apply to use of this app')} {t('Regulation may apply to use of this app')}
</h4> </h4>

View File

@ -9,7 +9,7 @@ interface VegaWalletContainerProps {
} }
export const VegaWalletContainer = ({ children }: VegaWalletContainerProps) => { export const VegaWalletContainer = ({ children }: VegaWalletContainerProps) => {
const store = useGlobalStore(); const { update } = useGlobalStore((store) => ({ update: store.update }));
const { keypair } = useVegaWallet(); const { keypair } = useVegaWallet();
if (!keypair) { if (!keypair) {
@ -20,7 +20,7 @@ export const VegaWalletContainer = ({ children }: VegaWalletContainerProps) => {
{t('Connect your Vega wallet')} {t('Connect your Vega wallet')}
</p> </p>
<Button <Button
onClick={() => store.setVegaWalletConnectDialog(true)} onClick={() => update({ connectDialog: true })}
data-testid="vega-wallet-connect" data-testid="vega-wallet-connect"
> >
{t('Connect')} {t('Connect')}

View File

@ -2,11 +2,7 @@ import type { AppProps } from 'next/app';
import Head from 'next/head'; import Head from 'next/head';
import { Navbar } from '../components/navbar'; import { Navbar } from '../components/navbar';
import { t, ThemeContext, useThemeSwitcher } from '@vegaprotocol/react-helpers'; import { t, ThemeContext, useThemeSwitcher } from '@vegaprotocol/react-helpers';
import { import { VegaConnectDialog, VegaWalletProvider } from '@vegaprotocol/wallet';
VegaConnectDialog,
VegaManageDialog,
VegaWalletProvider,
} from '@vegaprotocol/wallet';
import { EnvironmentProvider } from '@vegaprotocol/environment'; import { EnvironmentProvider } from '@vegaprotocol/environment';
import { Connectors } from '../lib/vega-connectors'; import { Connectors } from '../lib/vega-connectors';
import { AppLoader } from '../components/app-loader'; import { AppLoader } from '../components/app-loader';
@ -20,7 +16,10 @@ import {
import { Footer } from '../components/footer'; import { Footer } from '../components/footer';
function AppBody({ Component, pageProps }: AppProps) { function AppBody({ Component, pageProps }: AppProps) {
const store = useGlobalStore(); const { connectDialog, update } = useGlobalStore((store) => ({
connectDialog: store.connectDialog,
update: store.update,
}));
const { const {
isAssetDetailsDialogOpen, isAssetDetailsDialogOpen,
assetDetailsDialogSymbol, assetDetailsDialogSymbol,
@ -43,12 +42,8 @@ function AppBody({ Component, pageProps }: AppProps) {
<Footer /> <Footer />
<VegaConnectDialog <VegaConnectDialog
connectors={Connectors} connectors={Connectors}
dialogOpen={store.vegaWalletConnectDialog} dialogOpen={connectDialog}
setDialogOpen={(open) => store.setVegaWalletConnectDialog(open)} setDialogOpen={(open) => update({ connectDialog: open })}
/>
<VegaManageDialog
dialogOpen={store.vegaWalletManageDialog}
setDialogOpen={(open) => store.setVegaWalletManageDialog(open)}
/> />
<AssetDetailsDialog <AssetDetailsDialog
assetSymbol={assetDetailsDialogSymbol} assetSymbol={assetDetailsDialogSymbol}

View File

@ -9,18 +9,18 @@ export function Index() {
// The default market selected in the platform behind the overlay // The default market selected in the platform behind the overlay
// should be the oldest market that is currently trading in continuous mode(i.e. not in auction). // should be the oldest market that is currently trading in continuous mode(i.e. not in auction).
const { data, error, loading } = useMarketList(); const { data, error, loading } = useMarketList();
const { vegaRiskNoticeDialog, setLandingDialog } = useGlobalStore( const { riskNoticeDialog, update } = useGlobalStore((store) => ({
(store) => store riskNoticeDialog: store.riskNoticeDialog,
); update: store.update,
}));
useEffect(() => { useEffect(() => {
setLandingDialog(true); update({ landingDialog: true });
if (data) { if (data) {
const marketId = data[0]?.id; const marketId = data[0]?.id;
if (marketId) { if (marketId) {
setLandingDialog(true);
replace(`/markets/${marketId}`); replace(`/markets/${marketId}`);
} }
// Fallback to the markets list page // Fallback to the markets list page
@ -28,7 +28,7 @@ export function Index() {
replace('/markets'); replace('/markets');
} }
} }
}, [data, replace, vegaRiskNoticeDialog, setLandingDialog]); }, [data, replace, riskNoticeDialog, update]);
return ( return (
<AsyncRenderer data={data} loading={loading} error={error}> <AsyncRenderer data={data} loading={loading} error={error}>

View File

@ -9,8 +9,8 @@ import React, { useEffect, useState } from 'react';
import { PageQueryContainer } from '../../components/page-query-container'; import { PageQueryContainer } from '../../components/page-query-container';
import { useGlobalStore } from '../../stores'; import { useGlobalStore } from '../../stores';
import { TradeGrid, TradePanels } from './trade-grid'; import { TradeGrid, TradePanels } from './trade-grid';
import type { Market, MarketVariables } from './__generated__/Market'; import type { Market, MarketVariables } from './__generated__/Market';
// Top level page query // Top level page query
const MARKET_QUERY = gql` const MARKET_QUERY = gql`
query Market($marketId: ID!, $interval: Interval!, $since: String!) { query Market($marketId: ID!, $interval: Interval!, $since: String!) {
@ -77,7 +77,13 @@ const MARKET_QUERY = gql`
const MarketPage = ({ id }: { id?: string }) => { const MarketPage = ({ id }: { id?: string }) => {
const { query } = useRouter(); const { query } = useRouter();
const { w } = useWindowSize(); const { w } = useWindowSize();
const store = useGlobalStore(); const { landingDialog, riskNoticeDialog, update } = useGlobalStore(
(store) => ({
landingDialog: store.landingDialog,
riskNoticeDialog: store.riskNoticeDialog,
update: store.update,
})
);
// Default to first marketId query item if found // Default to first marketId query item if found
const marketId = const marketId =
@ -123,13 +129,13 @@ const MarketPage = ({ id }: { id?: string }) => {
<TradePanels market={market} /> <TradePanels market={market} />
)} )}
<SelectMarketDialog <SelectMarketDialog
dialogOpen={store.landingDialog && !store.vegaRiskNoticeDialog} dialogOpen={landingDialog && !riskNoticeDialog}
setDialogOpen={(isOpen: boolean) => setDialogOpen={(isOpen: boolean) =>
store.setLandingDialog(isOpen) update({ landingDialog: isOpen })
} }
onSelect={(marketId: string) => { onSelect={(marketId: string) => {
if (marketId && store.marketId !== marketId) { if (marketId && marketId !== marketId) {
store.setMarketId(marketId); update({ marketId });
} }
}} }}
/> />

View File

@ -3,12 +3,12 @@ import { MarketsContainer } from '@vegaprotocol/market-list';
import { useGlobalStore } from '../../stores'; import { useGlobalStore } from '../../stores';
const Markets = () => { const Markets = () => {
const store = useGlobalStore(); const { update } = useGlobalStore((store) => ({ update: store.update }));
const router = useRouter(); const router = useRouter();
return ( return (
<MarketsContainer <MarketsContainer
onSelect={(marketId) => { onSelect={(marketId) => {
store.setMarketId(marketId); update({ marketId });
router.push(`/markets/${marketId}`); router.push(`/markets/${marketId}`);
}} }}
/> />

View File

@ -117,23 +117,26 @@ export const TradeMarketHeader = ({ market }: TradeMarketHeaderProps) => {
const { VEGA_EXPLORER_URL } = useEnvironment(); const { VEGA_EXPLORER_URL } = useEnvironment();
const { setAssetDetailsDialogOpen, setAssetDetailsDialogSymbol } = const { setAssetDetailsDialogOpen, setAssetDetailsDialogSymbol } =
useAssetDetailsDialogStore(); useAssetDetailsDialogStore();
const candlesClose: string[] = (market?.candles || []) const { update } = useGlobalStore((store) => ({
.map((candle) => candle?.close) update: store.update,
.filter((c): c is CandleClose => c !== null); }));
const symbol =
market.tradableInstrument.instrument.product?.settlementAsset?.symbol;
const itemClass =
'min-w-min w-[120px] whitespace-nowrap pb-3 px-4 border-l border-neutral-300 dark:border-neutral-700';
const itemHeading = 'text-neutral-400';
const store = useGlobalStore();
const onSelect = (marketId: string) => { const onSelect = (marketId: string) => {
if (marketId && store.marketId !== marketId) { if (marketId && marketId !== marketId) {
store.setMarketId(marketId); update({ marketId });
} }
}; };
const candlesClose: string[] = (market?.candles || [])
.map((candle) => candle?.close)
.filter((c): c is CandleClose => c !== null);
const hasExpiry = market.marketTimestamps.close !== null; const hasExpiry = market.marketTimestamps.close !== null;
const symbol =
market.tradableInstrument.instrument.product?.settlementAsset?.symbol;
const itemClass =
'min-w-min w-[120px] whitespace-nowrap pb-3 px-4 border-l border-neutral-300 dark:border-neutral-700';
const itemHeading = 'text-neutral-400';
return ( return (
<header className="w-screen xl:px-4 pt-4 border-b border-neutral-300 dark:border-neutral-700"> <header className="w-screen xl:px-4 pt-4 border-b border-neutral-300 dark:border-neutral-700">

View File

@ -1,43 +1,21 @@
import create from 'zustand'; import create from 'zustand';
interface GlobalStore { interface GlobalStore {
vegaWalletConnectDialog: boolean; connectDialog: boolean;
setVegaWalletConnectDialog: (isOpen: boolean) => void; networkSwitcherDialog: boolean;
vegaWalletManageDialog: boolean;
setVegaWalletManageDialog: (isOpen: boolean) => void;
vegaNetworkSwitcherDialog: boolean;
setVegaNetworkSwitcherDialog: (isOpen: boolean) => void;
landingDialog: boolean; landingDialog: boolean;
setLandingDialog: (isOpen: boolean) => void; riskNoticeDialog: boolean;
vegaRiskNoticeDialog: boolean;
setVegaRiskNoticeDialog: (isOpen: boolean) => void;
marketId: string | null; marketId: string | null;
setMarketId: (marketId: string) => void; update: (store: Partial<Omit<GlobalStore, 'update'>>) => void;
} }
export const useGlobalStore = create<GlobalStore>((set) => ({ export const useGlobalStore = create<GlobalStore>((set) => ({
vegaWalletConnectDialog: false, connectDialog: false,
setVegaWalletConnectDialog: (isOpen: boolean) => { networkSwitcherDialog: false,
set({ vegaWalletConnectDialog: isOpen });
},
vegaWalletManageDialog: false,
setVegaWalletManageDialog: (isOpen: boolean) => {
set({ vegaWalletManageDialog: isOpen });
},
vegaNetworkSwitcherDialog: false,
setVegaNetworkSwitcherDialog: (isOpen: boolean) => {
set({ vegaNetworkSwitcherDialog: isOpen });
},
landingDialog: false, landingDialog: false,
setLandingDialog: (isOpen: boolean) => { riskNoticeDialog: false,
set({ landingDialog: isOpen });
},
vegaRiskNoticeDialog: false,
setVegaRiskNoticeDialog: (isOpen: boolean) => {
set({ vegaRiskNoticeDialog: isOpen });
},
marketId: null, marketId: null,
setMarketId: (id: string) => { update: (state) => {
set({ marketId: id }); set(state);
}, },
})); }));

View File

@ -14,5 +14,9 @@ export default async function build(
const { env, ...nextOptions } = options; const { env, ...nextOptions } = options;
await setup(env, context, 'tools/executors/next/build'); await setup(env, context, 'tools/executors/next/build');
return await nextBuildExecutor(nextOptions, context); try {
return await nextBuildExecutor(nextOptions, context);
} catch (err) {
console.error(err);
}
} }