This commit is contained in:
mulan xia
2024-02-08 01:19:37 -05:00
parent 5959a1cf02
commit 02b9421bf7
5 changed files with 41 additions and 88 deletions
+7 -28
View File
@@ -1,5 +1,5 @@
import { useEffect, useRef, useState } from 'react';
import { shallowEqual, useDispatch, useSelector } from 'react-redux';
import { useEffect } from 'react';
import { shallowEqual, useSelector } from 'react-redux';
import isEmpty from 'lodash/isEmpty';
import { LanguageCode, ResolutionString, widget } from 'public/tradingview/charting_library';
@@ -15,12 +15,7 @@ import { store } from '@/state/_store';
import { getSelectedNetwork } from '@/state/appSelectors';
import { getAppTheme, getAppColorMode } from '@/state/configsSelectors';
import { getSelectedLocale } from '@/state/localizationSelectors';
import { setShowOrderLines } from '@/state/perpetuals';
import {
getCurrentMarketId,
getShouldShowOrderLines,
getMarketIds,
} from '@/state/perpetualsSelectors';
import { getCurrentMarketId, getMarketIds } from '@/state/perpetualsSelectors';
import { getDydxDatafeed } from '@/lib/tradingView/dydxfeed';
import { getSavedResolution, getWidgetOptions, getWidgetOverrides } from '@/lib/tradingView/utils';
@@ -30,20 +25,18 @@ import { getSavedResolution, getWidgetOptions, getWidgetOverrides } from '@/lib/
*/
export const useTradingView = ({
tvWidgetRef,
displayButtonRef,
setIsChartReady,
}: {
tvWidgetRef: React.MutableRefObject<any>;
displayButtonRef: React.MutableRefObject<any>;
setIsChartReady: React.Dispatch<React.SetStateAction<boolean>>;
}) => {
const stringGetter = useStringGetter();
const dispatch = useDispatch();
const appTheme = useSelector(getAppTheme);
const appColorMode = useSelector(getAppColorMode);
const [displayOrdersButton, setDisplayOrdersButton] = useState(null);
const showOrderLines = useSelector(getShouldShowOrderLines);
const marketId = useSelector(getCurrentMarketId);
const marketIds = useSelector(getMarketIds, shallowEqual);
const selectedLocale = useSelector(getSelectedLocale);
@@ -58,20 +51,6 @@ export const useTradingView = ({
const savedResolution = getSavedResolution({ savedConfig: savedTvChartConfig });
const hasMarkets = marketIds.length > 0;
useEffect(() => {
if (displayOrdersButton) {
displayOrdersButton.onclick = () => {
const newShowOrderLinesState = !showOrderLines;
if (newShowOrderLinesState) {
displayOrdersButton?.classList?.add('order-lines-active');
} else {
displayOrdersButton?.classList?.remove('order-lines-active');
}
dispatch(setShowOrderLines({ showOrderLines: newShowOrderLinesState }));
};
}
}, [displayOrdersButton, showOrderLines]);
useEffect(() => {
if (hasMarkets && isClientConnected && marketId) {
const widgetOptions = getWidgetOptions();
@@ -98,8 +77,8 @@ export const useTradingView = ({
key: STRING_KEYS.ORDER_LINES,
})}</span> <div class="displayOrdersButton-toggle"></div>`;
button.setAttribute('title', stringGetter({ key: STRING_KEYS.ORDER_LINES_TOOLTIP }));
setDisplayOrdersButton(button);
}
displayButtonRef.current = button;
\ }
});
tvWidgetRef?.current?.subscribe('onAutoSaveNeeded', () =>
+7 -4
View File
@@ -1,11 +1,14 @@
import { useEffect } from 'react';
import { useSelector } from 'react-redux';
import type { IChartingLibraryWidget, ThemeName } from 'public/tradingview/charting_library';
import type {
IChartingLibraryWidget,
IOrderLineAdapter,
ThemeName,
} from 'public/tradingview/charting_library';
import { AppColorMode, AppTheme } from '@/state/configs';
import { getAppTheme, getAppColorMode } from '@/state/configsSelectors';
import { getOrderLines } from '@/state/perpetualsSelectors';
import { getWidgetOverrides, getOrderLineColors } from '@/lib/tradingView/utils';
@@ -23,17 +26,17 @@ const isIFrame = (element: HTMLElement | null): element is HTMLIFrameElement =>
* In order to support our Classic along with Dark/Light, we are directly accessing the <html> within the iFrame.
*/
export const useTradingViewTheme = ({
orderLines,
tvWidget,
isWidgetReady,
}: {
orderLines: Record<string, IOrderLineAdapter>;
tvWidget: (IChartingLibraryWidget & { _id?: string; _ready?: boolean }) | null;
isWidgetReady?: boolean;
}) => {
const appTheme: AppTheme = useSelector(getAppTheme);
const appColorMode: AppColorMode = useSelector(getAppColorMode);
const orderLines = useSelector(getOrderLines);
useEffect(() => {
if (tvWidget && isWidgetReady) {
tvWidget
-22
View File
@@ -1,8 +1,6 @@
import merge from 'lodash/merge';
import { createSlice, type PayloadAction } from '@reduxjs/toolkit';
import type { IOrderLineAdapter } from 'public/tradingview/charting_library';
import type {
MarketOrderbook,
MarketTrade,
@@ -37,8 +35,6 @@ export interface PerpetualsState {
}
>;
historicalFundings: Record<string, MarketHistoricalFunding[]>;
showOrderLines?: boolean;
orderLines: Record<string, IOrderLineAdapter>;
}
const initialState: PerpetualsState = {
@@ -49,8 +45,6 @@ const initialState: PerpetualsState = {
orderbooks: undefined,
orderbooksMap: undefined,
historicalFundings: {},
showOrderLines: false,
orderLines: {},
};
const MAX_NUM_LIVE_TRADES = 100;
@@ -152,20 +146,6 @@ export const perpetualsSlice = createSlice({
) => {
state.historicalFundings[action.payload.marketId] = action.payload.historicalFundings;
},
setShowOrderLines: (
state: PerpetualsState,
action: PayloadAction<{ showOrderLines: boolean }>
) => ({
...state,
showOrderLines: action.payload.showOrderLines,
}),
setOrderLines: (
state: PerpetualsState,
action: PayloadAction<{ orderLines: Record<string, IOrderLineAdapter> }>
) => ({
...state,
orderLines: action.payload.orderLines,
}),
resetPerpetualsState: () =>
({
...initialState,
@@ -183,7 +163,5 @@ export const {
setOrderbook,
setTvChartResolution,
setHistoricalFundings,
setShowOrderLines,
setOrderLines,
resetPerpetualsState,
} = perpetualsSlice.actions;
-12
View File
@@ -153,15 +153,3 @@ export const getCurrentMarketNextFundingRate = createSelector(
[getCurrentMarketData],
(marketData) => marketData?.perpetual?.nextFundingRate
);
/**
*
* @returns boolean on whether we should show order lines
*/
export const getShouldShowOrderLines = (state: RootState) => state.perpetuals.showOrderLines;
/**
*
* @returns all order lines being shown on chart
*/
export const getOrderLines = (state: RootState) => state.perpetuals.orderLines;
+27 -22
View File
@@ -27,23 +27,23 @@ import { LoadingSpace } from '@/components/Loading/LoadingSpinner';
import { getCurrentMarketOrders } from '@/state/accountSelectors';
import { getAppTheme, getAppColorMode } from '@/state/configsSelectors';
import { setOrderLines, setTvChartResolution } from '@/state/perpetuals';
import {
getCurrentMarketId,
getOrderLines,
getShouldShowOrderLines,
getSelectedResolutionForMarket,
} from '@/state/perpetualsSelectors';
import { setTvChartResolution } from '@/state/perpetuals';
import { getCurrentMarketId, getSelectedResolutionForMarket } from '@/state/perpetualsSelectors';
import { layoutMixins } from '@/styles/layoutMixins';
type TvWidget = IChartingLibraryWidget & { _id?: string; _ready?: boolean };
let orderLines: Record<string, IOrderLineAdapter> = {};
export const TvChart = () => {
const dispatch = useDispatch();
const stringGetter = useStringGetter();
const [isChartReady, setIsChartReady] = useState(false);
const [showOrderLines, setShowOrderLines] = useState(false);
const displayButtonRef = useRef<HTMLElement | null>(null);
const appTheme = useSelector(getAppTheme);
const appColorMode = useSelector(getAppColorMode);
@@ -51,9 +51,6 @@ export const TvChart = () => {
const currentMarketId: string = useSelector(getCurrentMarketId) || DEFAULT_MARKETID;
const currentMarketOrders = useSelector(getCurrentMarketOrders, shallowEqual);
const showOrderLines = useSelector(getShouldShowOrderLines);
const orderLines = useSelector(getOrderLines);
const selectedResolution: string =
useSelector(getSelectedResolutionForMarket(currentMarketId)) || DEFAULT_RESOLUTION;
@@ -63,8 +60,8 @@ export const TvChart = () => {
const chart = isWidgetReady ? tvWidget?.chart() : undefined;
const chartResolution = chart?.resolution?.();
const { savedResolution } = useTradingView({ tvWidgetRef, setIsChartReady });
useTradingViewTheme({ tvWidget, isWidgetReady });
const { savedResolution } = useTradingView({ tvWidgetRef, displayButtonRef, setIsChartReady });
useTradingViewTheme({ tvWidget, isWidgetReady, orderLines });
const setVisibleRangeForResolution = ({ resolution }: { resolution: ResolutionString }) => {
// Different resolutions have different timeframes to display data efficiently.
@@ -79,6 +76,20 @@ export const TvChart = () => {
tvWidget?.activeChart().setVisibleRange(newRange, { percentRightMargin: 10 });
};
useEffect(() => {
if (displayButtonRef && displayButtonRef.current) {
displayButtonRef.current.onclick = () => {
const newShowOrderLinesState = !showOrderLines;
if (newShowOrderLinesState) {
displayButtonRef.current?.classList?.add('order-lines-active');
} else {
displayButtonRef.current?.classList?.remove('order-lines-active');
}
setShowOrderLines(newShowOrderLinesState);
};
}
}, [isChartReady, showOrderLines]);
/**
* @description Hooks to handle state of show orders button
*/
@@ -100,7 +111,6 @@ export const TvChart = () => {
}, [showOrderLines, currentMarketOrders, isChartReady]);
const drawOrderLines = () => {
const updatedOrderLines: Record<string, IOrderLineAdapter> = {};
currentMarketOrders.forEach(
({ id, type, status, side, cancelReason, remainingSize, size, triggerPrice, price }) => {
const key = `${side.rawValue}-${id}`;
@@ -119,12 +129,12 @@ export const TvChart = () => {
if (maybeOrderLine) {
if (!shouldShow) {
maybeOrderLine.remove();
delete orderLines[key];
return;
} else if (maybeOrderLine.getQuantity() !== quantity) {
maybeOrderLine.setQuantity(quantity);
return;
}
updatedOrderLines[key] = maybeOrderLine;
return;
} else if (!shouldShow) {
return;
} else {
@@ -146,23 +156,18 @@ export const TvChart = () => {
.setQuantityTextColor(textButtonColor);
if (orderLine) {
updatedOrderLines[key] = orderLine;
orderLines[key] = orderLine;
}
}
}
);
dispatch(
setOrderLines({
orderLines: updatedOrderLines,
})
);
};
const deleteOrderLines = () => {
Object.values(orderLines).forEach((line) => {
line.remove();
});
dispatch(setOrderLines({ orderLines: {} }));
orderLines = {};
};
useEffect(() => {