useCurrentMarketId hook for navigation

This commit is contained in:
jaredvu
2023-08-25 10:59:35 -07:00
parent 71c29524b1
commit e15f4b919c
11 changed files with 83 additions and 34 deletions
+1 -4
View File
@@ -61,10 +61,7 @@ const Content = () => {
<Routes>
<Route path={AppRoute.Trade}>
<Route path=":market" element={<TradePage />} />
<Route
path={AppRoute.Trade}
element={<Navigate to={DEFAULT_TRADE_ROUTE} replace />}
/>
<Route path={AppRoute.Trade} element={<TradePage />} />
</Route>
<Route path={AppRoute.Markets} element={<MarketsPage />} />
{import.meta.env.MODE !== 'production' && (
+2
View File
@@ -1,6 +1,7 @@
import { useApiState } from './useApiState';
import { useBreakpoints } from './useBreakpoints';
import { useCommandMenu } from './useCommandMenu';
import { useCurrentMarketId } from './useCurrentMarketId';
import { useInterval } from './useInterval';
import { useDocumentTitle } from './useDocumentTitle';
import { useDydxClient } from './useDydxClient';
@@ -23,6 +24,7 @@ export {
useApiState,
useBreakpoints,
useCommandMenu,
useCurrentMarketId,
useDocumentTitle,
useDydxClient,
useAccountBalance,
+47
View File
@@ -0,0 +1,47 @@
import { useEffect } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { useMatch, useNavigate } from 'react-router-dom';
import { LocalStorageKey } from '@/constants/localStorage';
import { DEFAULT_MARKETID } from '@/constants/markets';
import { AppRoute, DEFAULT_TRADE_ROUTE } from '@/constants/routes';
import { getSelectedNetwork } from '@/state/appSelectors';
import { closeDialogInTradeBox } from '@/state/dialogs';
import { setCurrentMarketId } from '@/state/perpetuals';
import abacusStateManager from '@/lib/abacus';
import { useLocalStorage } from './useLocalStorage';
export const useCurrentMarketId = () => {
const navigate = useNavigate();
const match = useMatch(`/${AppRoute.Trade}/:marketId`);
const { marketId } = match?.params ?? {};
const dispatch = useDispatch();
const selectedNetwork = useSelector(getSelectedNetwork);
const [lastViewedMarket, setLastViewedMarket] = useLocalStorage({
key: LocalStorageKey.LastViewedMarket,
defaultValue: DEFAULT_MARKETID,
});
useEffect(() => {
setLastViewedMarket(marketId ?? DEFAULT_MARKETID);
dispatch(setCurrentMarketId(marketId ?? DEFAULT_MARKETID));
dispatch(closeDialogInTradeBox());
if (!marketId) {
navigate(lastViewedMarket ? `${AppRoute.Trade}/${lastViewedMarket}` : DEFAULT_TRADE_ROUTE, {
replace: true,
});
} else {
navigate(`${AppRoute.Trade}/${marketId}`, {
replace: true,
});
}
}, [marketId]);
useEffect(() => {
abacusStateManager.setMarket(marketId ?? DEFAULT_MARKETID);
}, [selectedNetwork, marketId]);
};
+1 -1
View File
@@ -1,5 +1,5 @@
import { useEffect } from 'react';
import { shallowEqual, useSelector } from 'react-redux';
import { useSelector } from 'react-redux';
import { DEFAULT_DOCUMENT_TITLE } from '@/constants/routes';
+2 -2
View File
@@ -1,6 +1,7 @@
import styled, { type AnyStyledComponent } from 'styled-components';
import { useDispatch, useSelector } from 'react-redux';
import { ButtonAction, ButtonSize } from '@/constants/buttons';
import { DialogTypes } from '@/constants/dialogs';
import { STRING_KEYS } from '@/constants/localization';
import { DEFAULT_MARKETID } from '@/constants/markets';
@@ -15,9 +16,8 @@ import { BellIcon, MarketsIcon, PlayIcon, PortfolioIcon, ProfileIcon, TradeIcon
import { IconButton } from '@/components/IconButton';
import { calculateCanAccountTrade } from '@/state/accountCalculators';
import { getCurrentMarketId } from '@/state/perpetualsSelectors';
import { openDialog } from '@/state/dialogs';
import { ButtonAction, ButtonSize } from '@/constants/buttons';
import { getCurrentMarketId } from '@/state/perpetualsSelectors';
export const FooterMobile = () => {
const dispatch = useDispatch();
+4 -6
View File
@@ -1,21 +1,19 @@
import styled, { type AnyStyledComponent } from 'styled-components';
import { shallowEqual, useSelector } from 'react-redux';
import { DEFAULT_MARKETID } from '@/constants/markets';
import { layoutMixins } from '@/styles/layoutMixins';
import { VerticalSeparator } from '@/components/Separator';
import { getCurrentMarketAssetData } from '@/state/assetsSelectors';
import { getCurrentMarketId } from '@/state/perpetualsSelectors';
import { MarketsDropdown } from '@/views/MarketsDropdown';
import { MarketStatsDetails } from '@/views/MarketStatsDetails';
import { getCurrentMarketAssetData } from '@/state/assetsSelectors';
import { getCurrentMarketId } from '@/state/perpetualsSelectors';
export const MarketSelectorAndStats = ({ className }: { className?: string }) => {
const { symbol = '' } = useSelector(getCurrentMarketAssetData, shallowEqual) ?? {};
const currentMarketId = useSelector(getCurrentMarketId) ?? DEFAULT_MARKETID;
const currentMarketId = useSelector(getCurrentMarketId);
return (
<Styled.Container className={className}>
+5 -14
View File
@@ -1,16 +1,13 @@
import { useEffect, useRef, useState } from 'react';
import { useRef, useState } from 'react';
import styled, { AnyStyledComponent, css } from 'styled-components';
import { useLocation } from 'react-router-dom';
import { useDispatch, useSelector } from 'react-redux';
import { useSelector } from 'react-redux';
import { breakpoints } from '@/styles';
import { layoutMixins } from '@/styles/layoutMixins';
import { TradeLayouts } from '@/constants/layout';
import { useBreakpoints, usePageTitlePriceUpdates } from '@/hooks';
import { setTradeLocation } from '@/state/navigation';
import { useBreakpoints, useCurrentMarketId, usePageTitlePriceUpdates } from '@/hooks';
import { calculateCanAccountTrade } from '@/state/accountCalculators';
import { getSelectedTradeLayout } from '@/state/layoutSelectors';
@@ -32,18 +29,12 @@ import { TradeBox } from '@/views/TradeBox';
const TradePage = () => {
const tradePageRef = useRef<HTMLDivElement>(null);
const location = useLocation();
const dispatch = useDispatch();
useCurrentMarketId();
const { isTablet } = useBreakpoints();
const tradeLayout = useSelector(getSelectedTradeLayout);
const [isHorizontalPanelOpen, setIsHorizontalPanelOpen] = useState(true);
const canAccountTrade = useSelector(calculateCanAccountTrade);
useEffect(() => {
dispatch(setTradeLocation(location));
}, [location.pathname]);
const [isHorizontalPanelOpen, setIsHorizontalPanelOpen] = useState(true);
usePageTitlePriceUpdates();
+2 -2
View File
@@ -7,13 +7,13 @@ import { STRING_KEYS } from '@/constants/localization';
import { useStringGetter } from '@/hooks';
import { getCurrentMarketId } from '@/state/perpetualsSelectors';
import { Tabs } from '@/components/Tabs';
import { Orderbook, orderbookMixins, OrderbookScrollBehavior } from '@/views/tables/Orderbook';
import { LiveTrades } from '@/views/tables/LiveTrades';
import { getCurrentMarketId } from '@/state/perpetualsSelectors';
enum Tab {
Orderbook = 'Orderbook',
Trades = 'Trades',
+16 -1
View File
@@ -10,6 +10,10 @@ import type {
} from '@/constants/abacus';
import { Candle, RESOLUTION_MAP } from '@/constants/candles';
import { LocalStorageKey } from '@/constants/localStorage';
import { DEFAULT_MARKETID } from '@/constants/markets';
import { getLocalStorage } from '@/lib/localStorage';
interface CandleDataByMarket {
data: Record<string, Candle[]>;
@@ -17,6 +21,7 @@ interface CandleDataByMarket {
}
export interface PerpetualsState {
currentMarketId?: string;
candles: Record<string, CandleDataByMarket>;
liveTrades?: Record<string, MarketTrade[]>;
markets?: Record<string, PerpetualMarket>;
@@ -25,6 +30,7 @@ export interface PerpetualsState {
}
const initialState: PerpetualsState = {
currentMarketId: undefined,
candles: {},
liveTrades: {},
markets: undefined,
@@ -38,6 +44,9 @@ export const perpetualsSlice = createSlice({
name: 'Perpetuals',
initialState,
reducers: {
setCurrentMarketId: (state: PerpetualsState, action: PayloadAction<string>) => {
state.currentMarketId = action.payload;
},
setCandles: (
state: PerpetualsState,
action: PayloadAction<{ candles: Candle[]; marketId: string; resolution: string }>
@@ -116,11 +125,17 @@ export const perpetualsSlice = createSlice({
) => {
state.historicalFundings[action.payload.marketId] = action.payload.historicalFundings;
},
resetPerpetualsState: () => initialState,
resetPerpetualsState: () =>
({
...initialState,
currentMarketId:
getLocalStorage({ key: LocalStorageKey.LastViewedMarket }) ?? DEFAULT_MARKETID,
} as PerpetualsState),
},
});
export const {
setCurrentMarketId,
setCandles,
setLiveTrades,
setMarkets,
+1 -2
View File
@@ -11,8 +11,7 @@ import { mapCandle } from '@/lib/tradingView/utils';
* @param state
* @returns marketId of the market the user is currently viewing
*/
export const getCurrentMarketId = (state: RootState) =>
matchPath(TRADE_ROUTE, state.navigation.tradeLocation.pathname)?.params.market;
export const getCurrentMarketId = (state: RootState) => state.perpetuals.currentMarketId;
/**
* @returns assetId of the currentMarket
+2 -2
View File
@@ -15,7 +15,7 @@ import { AssetIcon } from '@/components/AssetIcon';
import { Icon, IconName } from '@/components/Icon';
import { Output, OutputType } from '@/components/Output';
import { Popover, TriggerType } from '@/components/Popover';
import { Tag, TagSize } from '@/components/Tag';
import { Tag } from '@/components/Tag';
import { Toolbar } from '@/components/Toolbar';
import { ColumnDef, Table } from '@/components/Table';
@@ -152,7 +152,7 @@ const MarketsDropdownContent = ({ onRowAction }: { onRowAction?: (market: string
);
};
export const MarketsDropdown: React.FC<{ currentMarketId: string; symbol: string | null }> = memo(
export const MarketsDropdown: React.FC<{ currentMarketId?: string; symbol: string | null }> = memo(
({ currentMarketId, symbol = '' }) => {
const [isOpen, setIsOpen] = useState(false);
const stringGetter = useStringGetter();