useCurrentMarketId hook for navigation
This commit is contained in:
+1
-4
@@ -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' && (
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,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';
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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}>
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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
@@ -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,
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user