From b29b733f8f1200a1f6e2c8c69e03172920568066 Mon Sep 17 00:00:00 2001 From: midas-myth Date: Fri, 21 Feb 2025 16:30:02 +0100 Subject: [PATCH 1/3] TV control init --- sdk/src/utils/objects.ts | 6 + .../OrderEditorContainer.tsx | 4 +- .../Synthetics/OrderEditor/OrderEditor.tsx | 135 ++++++++++-------- src/components/Synthetics/TVChart/TVChart.tsx | 110 +------------- .../TVChartContainer/DynamicLineComponent.tsx | 133 +++++++++++++++++ .../TVChartContainer/OrderLinesContainer.tsx | 103 +++++++++++++ .../TVChartContainer/TVChartContainer.tsx | 22 ++- src/components/TVChartContainer/constants.ts | 17 ++- src/components/TVChartContainer/types.tsx | 28 ++++ .../PendingTxnsContext/PendingTxnsContext.tsx | 2 +- .../SyntheticsEventsProvider.tsx | 25 +++- src/context/SyntheticsEvents/types.ts | 9 +- .../hooks/orderEditorHooks.ts | 8 ++ .../index.ts} | 6 +- .../selectChartDynamicLines.tsx | 69 +++++++++ .../chartSelectors/selectChartLines.tsx | 71 +++++++++ .../selectors/orderEditorSelectors.ts | 2 + .../synthetics/orders/updateOrderTxn.ts | 41 ++++-- .../synthetics/orders/useOrderEditorState.ts | 4 + src/domain/synthetics/orders/utils.tsx | 3 +- .../synthetics/subaccount/initSubaccount.ts | 3 +- src/lib/contracts/callContract.tsx | 12 +- src/locales/de/messages.po | 48 +++++-- src/locales/en/messages.po | 48 +++++-- src/locales/es/messages.po | 48 +++++-- src/locales/fr/messages.po | 48 +++++-- src/locales/ja/messages.po | 48 +++++-- src/locales/ko/messages.po | 48 +++++-- src/locales/pseudo/messages.po | 48 +++++-- src/locales/ru/messages.po | 48 +++++-- src/locales/zh/messages.po | 48 +++++-- 31 files changed, 964 insertions(+), 281 deletions(-) create mode 100644 src/components/TVChartContainer/DynamicLineComponent.tsx create mode 100644 src/components/TVChartContainer/OrderLinesContainer.tsx create mode 100644 src/components/TVChartContainer/types.tsx rename src/context/SyntheticsStateContext/selectors/{chartSelectors.ts => chartSelectors/index.ts} (96%) create mode 100644 src/context/SyntheticsStateContext/selectors/chartSelectors/selectChartDynamicLines.tsx create mode 100644 src/context/SyntheticsStateContext/selectors/chartSelectors/selectChartLines.tsx diff --git a/sdk/src/utils/objects.ts b/sdk/src/utils/objects.ts index 4d762fd492..c513f73354 100644 --- a/sdk/src/utils/objects.ts +++ b/sdk/src/utils/objects.ts @@ -13,3 +13,9 @@ export function getByKey(obj?: { [key: string]: T }, key?: string): T | undef return obj[key]; } + +export function deleteByKey(obj: { [key: string]: T }, key: string) { + const newObj = { ...obj }; + delete newObj[key]; + return newObj; +} diff --git a/src/components/OrderEditorContainer/OrderEditorContainer.tsx b/src/components/OrderEditorContainer/OrderEditorContainer.tsx index 2ec1778b0e..4091ddcac7 100644 --- a/src/components/OrderEditorContainer/OrderEditorContainer.tsx +++ b/src/components/OrderEditorContainer/OrderEditorContainer.tsx @@ -3,14 +3,12 @@ import { useMemo } from "react"; import { useEditingOrderKeyState } from "context/SyntheticsStateContext/hooks/orderEditorHooks"; import { selectEditingOrder } from "context/SyntheticsStateContext/selectors/orderEditorSelectors"; import { useSelector } from "context/SyntheticsStateContext/utils"; -import { usePendingTxns } from "context/PendingTxnsContext/PendingTxnsContext"; import { OrderEditor } from "components/Synthetics/OrderEditor/OrderEditor"; export function OrderEditorContainer() { const editingOrder = useSelector(selectEditingOrder); const [, setEditingOrderKey] = useEditingOrderKeyState(); - const { setPendingTxns } = usePendingTxns(); const handleClose = useMemo(() => () => setEditingOrderKey(undefined), [setEditingOrderKey]); @@ -18,5 +16,5 @@ export function OrderEditorContainer() { return null; } - return ; + return ; } diff --git a/src/components/Synthetics/OrderEditor/OrderEditor.tsx b/src/components/Synthetics/OrderEditor/OrderEditor.tsx index 0dc4a592e8..729f49b952 100644 --- a/src/components/Synthetics/OrderEditor/OrderEditor.tsx +++ b/src/components/Synthetics/OrderEditor/OrderEditor.tsx @@ -1,59 +1,20 @@ import { Trans, t } from "@lingui/macro"; import { ReactNode, useEffect, useMemo, useState } from "react"; +import { useKey } from "react-use"; -import { USD_DECIMALS } from "config/factors"; -import useUiFeeFactorRequest from "domain/synthetics/fees/utils/useUiFeeFactor"; -import { - OrderInfo, - OrderType, - PositionOrderInfo, - SwapOrderInfo, - isLimitOrderType, - isSwapOrderType, - isTriggerDecreaseOrderType, -} from "domain/synthetics/orders"; -import { updateOrderTxn } from "domain/synthetics/orders/updateOrderTxn"; -import { - formatAcceptablePrice, - formatLeverage, - formatLiquidationPrice, - getTriggerNameByOrderType, - substractMaxLeverageSlippage, -} from "domain/synthetics/positions"; -import { convertToTokenAmount, convertToUsd, getTokenData } from "domain/synthetics/tokens"; -import { useChainId } from "lib/chains"; -import { - calculateDisplayDecimals, - formatAmount, - formatAmountFree, - formatBalanceAmount, - formatDeltaUsd, - formatTokenAmountWithUsd, - formatUsdPrice, -} from "lib/numbers"; - -import Button from "components/Button/Button"; -import StatsTooltipRow from "components/StatsTooltip/StatsTooltipRow"; -import TooltipWithPortal from "components/Tooltip/TooltipWithPortal"; -import { ValueTransition } from "components/ValueTransition/ValueTransition"; -import { BASIS_POINTS_DIVISOR } from "config/factors"; +import { BASIS_POINTS_DIVISOR, USD_DECIMALS } from "config/factors"; +import { usePendingTxns } from "context/PendingTxnsContext/PendingTxnsContext"; import { useSettings } from "context/SettingsContext/SettingsContextProvider"; import { useSubaccount } from "context/SubaccountContext/SubaccountContext"; +import { useSyntheticsEvents } from "context/SyntheticsEvents"; import { usePositionsConstants, useTokensData, useUserReferralInfo, } from "context/SyntheticsStateContext/hooks/globalsHooks"; -import { getIncreasePositionAmounts, getNextPositionValuesForIncreaseTrade } from "domain/synthetics/trade"; -import useWallet from "lib/wallets/useWallet"; - -import BuyInputSection from "components/BuyInputSection/BuyInputSection"; -import Modal from "components/Modal/Modal"; -import { AcceptablePriceImpactInputRow } from "components/Synthetics/AcceptablePriceImpactInputRow/AcceptablePriceImpactInputRow"; - -import ExternalLink from "components/ExternalLink/ExternalLink"; import { useMarketInfo } from "context/SyntheticsStateContext/hooks/marketHooks"; import { + useOrderEditorIsSubmittingState, useOrderEditorSizeInputValueState, useOrderEditorTriggerPriceInputValueState, useOrderEditorTriggerRatioInputValueState, @@ -81,28 +42,69 @@ import { selectOrderEditorTriggerRatio, } from "context/SyntheticsStateContext/selectors/orderEditorSelectors"; import { useSelector } from "context/SyntheticsStateContext/utils"; +import useUiFeeFactorRequest from "domain/synthetics/fees/utils/useUiFeeFactor"; +import { + OrderInfo, + OrderType, + PositionOrderInfo, + SwapOrderInfo, + isLimitOrderType, + isSwapOrderType, + isTriggerDecreaseOrderType, +} from "domain/synthetics/orders"; +import { updateOrderTxn } from "domain/synthetics/orders/updateOrderTxn"; +import { + formatAcceptablePrice, + formatLeverage, + formatLiquidationPrice, + getTriggerNameByOrderType, + substractMaxLeverageSlippage, +} from "domain/synthetics/positions"; +import { convertToTokenAmount, convertToUsd, getTokenData } from "domain/synthetics/tokens"; +import { getIncreasePositionAmounts, getNextPositionValuesForIncreaseTrade } from "domain/synthetics/trade"; import { getIsMaxLeverageExceeded } from "domain/synthetics/trade/utils/validation"; + import { numericBinarySearch } from "lib/binarySearch"; +import { useChainId } from "lib/chains"; import { helperToast } from "lib/helperToast"; -import { useKey } from "react-use"; +import { + calculateDisplayDecimals, + formatAmount, + formatAmountFree, + formatBalanceAmount, + formatDeltaUsd, + formatTokenAmountWithUsd, + formatUsdPrice, +} from "lib/numbers"; +import useWallet from "lib/wallets/useWallet"; import { bigMath } from "sdk/utils/bigmath"; +import Button from "components/Button/Button"; +import BuyInputSection from "components/BuyInputSection/BuyInputSection"; +import ExternalLink from "components/ExternalLink/ExternalLink"; +import Modal from "components/Modal/Modal"; +import StatsTooltipRow from "components/StatsTooltip/StatsTooltipRow"; +import { AcceptablePriceImpactInputRow } from "components/Synthetics/AcceptablePriceImpactInputRow/AcceptablePriceImpactInputRow"; +import TooltipWithPortal from "components/Tooltip/TooltipWithPortal"; +import { ValueTransition } from "components/ValueTransition/ValueTransition"; import { SyntheticsInfoRow } from "../SyntheticsInfoRow"; + import "./OrderEditor.scss"; type Props = { order: OrderInfo; onClose: () => void; - setPendingTxns: (txns: any) => void; }; export function OrderEditor(p: Props) { const { chainId } = useChainId(); const { signer } = useWallet(); const tokensData = useTokensData(); + const { setPendingTxns } = usePendingTxns(); + const { setPendingOrderUpdate } = useSyntheticsEvents(); const [isInited, setIsInited] = useState(false); - const [isSubmitting, setIsSubmitting] = useState(false); + const [isSubmitting, setIsSubmitting] = useOrderEditorIsSubmittingState(); const [sizeInputValue, setSizeInputValue] = useOrderEditorSizeInputValueState(); const [triggerPriceInputValue, setTriggerPriceInputValue] = useOrderEditorTriggerPriceInputValueState(); @@ -426,17 +428,25 @@ export function OrderEditor(p: Props) { setIsSubmitting(true); - const txnPromise = updateOrderTxn(chainId, signer, subaccount, { - orderKey: p.order.key, - sizeDeltaUsd: sizeDeltaUsd ?? positionOrder.sizeDeltaUsd, - triggerPrice: triggerPrice ?? positionOrder.triggerPrice, - acceptablePrice: acceptablePrice ?? positionOrder.acceptablePrice, - minOutputAmount: minOutputAmount ?? positionOrder.minOutputAmount, - executionFee: additionalExecutionFee?.feeTokenAmount, - indexToken: indexToken, - autoCancel: positionOrder.autoCancel, - setPendingTxns: p.setPendingTxns, - }); + const txnPromise = updateOrderTxn( + chainId, + signer, + subaccount, + { + orderKey: p.order.key, + sizeDeltaUsd: sizeDeltaUsd ?? positionOrder.sizeDeltaUsd, + triggerPrice: triggerPrice ?? positionOrder.triggerPrice, + acceptablePrice: acceptablePrice ?? positionOrder.acceptablePrice, + minOutputAmount: minOutputAmount ?? positionOrder.minOutputAmount, + executionFee: additionalExecutionFee?.feeTokenAmount, + indexToken: indexToken, + autoCancel: positionOrder.autoCancel, + }, + { + setPendingTxns, + setPendingOrderUpdate, + } + ); if (subaccount) { p.onClose(); @@ -481,9 +491,11 @@ export function OrderEditor(p: Props) { const price = positionOrder.triggerPrice ?? 0n; const decimals = calculateDisplayDecimals(price, USD_DECIMALS, indexToken?.visualMultiplier); - setTriggerPriceInputValue( - formatAmount(price, USD_DECIMALS, decimals, undefined, undefined, indexToken?.visualMultiplier) - ); + if (triggerPriceInputValue === "") { + setTriggerPriceInputValue( + formatAmount(price, USD_DECIMALS, decimals, undefined, undefined, indexToken?.visualMultiplier) + ); + } } setIsInited(true); @@ -495,6 +507,7 @@ export function OrderEditor(p: Props) { setSizeInputValue, setTriggerPriceInputValue, setTriggerRatioInputValue, + triggerPriceInputValue, ] ); diff --git a/src/components/Synthetics/TVChart/TVChart.tsx b/src/components/Synthetics/TVChart/TVChart.tsx index 31758c34d8..32fde4cd40 100644 --- a/src/components/Synthetics/TVChart/TVChart.tsx +++ b/src/components/Synthetics/TVChart/TVChart.tsx @@ -1,136 +1,34 @@ -import { t } from "@lingui/macro"; import { useEffect, useMemo } from "react"; -import { USD_DECIMALS } from "config/factors"; import { SUPPORTED_RESOLUTIONS_V2 } from "config/tradingview"; -import { - useOrdersInfoData, - usePositionsInfoData, - useTokensData, -} from "context/SyntheticsStateContext/hooks/globalsHooks"; import { selectChartToken } from "context/SyntheticsStateContext/selectors/chartSelectors"; +import { selectChartLines } from "context/SyntheticsStateContext/selectors/chartSelectors/selectChartLines"; import { selectSetIsCandlesLoaded } from "context/SyntheticsStateContext/selectors/globalSelectors"; import { selectSelectedMarketVisualMultiplier } from "context/SyntheticsStateContext/selectors/statsSelectors"; import { useSelector } from "context/SyntheticsStateContext/utils"; -import { convertTokenAddress, getPriceDecimals, getTokenVisualMultiplier } from "sdk/configs/tokens"; -import { PositionOrderInfo, isIncreaseOrderType, isSwapOrderType } from "domain/synthetics/orders"; -import { getTokenData } from "domain/synthetics/tokens"; import { useChainId } from "lib/chains"; import { CHART_PERIODS } from "lib/legacy"; import { useLocalStorageSerializeKey } from "lib/localStorage"; -import { formatAmount } from "lib/numbers"; -import TVChartContainer, { ChartLine } from "components/TVChartContainer/TVChartContainer"; +import TVChartContainer from "components/TVChartContainer/TVChartContainer"; import "./TVChart.scss"; const DEFAULT_PERIOD = "5m"; export function TVChart() { + const { chainId } = useChainId(); const { chartToken, symbol: chartTokenSymbol } = useSelector(selectChartToken); const visualMultiplier = useSelector(selectSelectedMarketVisualMultiplier); const setIsCandlesLoaded = useSelector(selectSetIsCandlesLoaded); - const ordersInfo = useOrdersInfoData(); - const tokensData = useTokensData(); - const positionsInfo = usePositionsInfoData(); - - const { chainId } = useChainId(); - const chartTokenAddress = chartToken?.address; - let [period, setPeriod] = useLocalStorageSerializeKey([chainId, "Chart-period-v2"], DEFAULT_PERIOD); if (!period || !(period in CHART_PERIODS)) { period = DEFAULT_PERIOD; } - const chartLines = useMemo(() => { - if (!chartTokenAddress) { - return []; - } - - const orderLines: ChartLine[] = Object.values(ordersInfo || {}) - .filter((order) => { - if (isSwapOrderType(order.orderType)) { - return false; - } - - const positionOrder = order as PositionOrderInfo; - - return ( - positionOrder.marketInfo && - positionOrder.triggerPrice !== undefined && - convertTokenAddress(chainId, positionOrder.marketInfo.indexTokenAddress, "wrapped") === - convertTokenAddress(chainId, chartTokenAddress, "wrapped") - ); - }) - .map((order) => { - const positionOrder = order as PositionOrderInfo; - const priceDecimal = getPriceDecimals(chainId, positionOrder.indexToken.symbol); - - const longOrShortText = order.isLong ? t`Long` : t`Short`; - const orderTypeText = isIncreaseOrderType(order.orderType) ? t`Inc.` : t`Dec.`; - const token = getTokenData(tokensData, positionOrder.marketInfo.indexTokenAddress, "native"); - const tokenSymbol = token?.symbol; - const prefix = token ? getTokenVisualMultiplier(token) : ""; - const tokenVisualMultiplier = token?.visualMultiplier; - - return { - title: `${longOrShortText} ${orderTypeText} ${prefix}${tokenSymbol}`, - price: parseFloat( - formatAmount( - positionOrder.triggerPrice, - USD_DECIMALS, - priceDecimal, - undefined, - undefined, - tokenVisualMultiplier - ) - ), - }; - }); - - const positionLines = Object.values(positionsInfo || {}).reduce((acc, position) => { - const priceDecimal = getPriceDecimals(chainId, position.indexToken.symbol); - if ( - position.marketInfo && - convertTokenAddress(chainId, position.marketInfo.indexTokenAddress, "wrapped") === - convertTokenAddress(chainId, chartTokenAddress, "wrapped") - ) { - const longOrShortText = position.isLong ? t`Long` : t`Short`; - const token = getTokenData(tokensData, position.marketInfo?.indexTokenAddress, "native"); - const tokenSymbol = token?.symbol; - const prefix = token ? getTokenVisualMultiplier(token) : ""; - const tokenVisualMultiplier = token?.visualMultiplier; - - const liquidationPrice = formatAmount( - position?.liquidationPrice, - USD_DECIMALS, - priceDecimal, - undefined, - undefined, - tokenVisualMultiplier - ); - - acc.push({ - title: t`Open ${longOrShortText} ${prefix}${tokenSymbol}`, - price: parseFloat( - formatAmount(position.entryPrice, USD_DECIMALS, priceDecimal, undefined, undefined, tokenVisualMultiplier) - ), - }); - if (liquidationPrice && liquidationPrice !== "NA") { - acc.push({ - title: t`Liq. ${longOrShortText} ${prefix}${tokenSymbol}`, - price: parseFloat(liquidationPrice), - }); - } - } - - return acc; - }, [] as ChartLine[]); - - return orderLines.concat(positionLines); - }, [chainId, chartTokenAddress, ordersInfo, positionsInfo, tokensData]); + const chartLines = useSelector(selectChartLines); useEffect( function updatePeriod() { diff --git a/src/components/TVChartContainer/DynamicLineComponent.tsx b/src/components/TVChartContainer/DynamicLineComponent.tsx new file mode 100644 index 0000000000..79289ff4f7 --- /dev/null +++ b/src/components/TVChartContainer/DynamicLineComponent.tsx @@ -0,0 +1,133 @@ +import { t } from "@lingui/macro"; +import { useLingui } from "@lingui/react"; +import { useEffect, useRef } from "react"; +import { useLatest, usePrevious } from "react-use"; + +import { FREQUENT_UPDATE_INTERVAL } from "lib/timeConstants"; +import type { IChartingLibraryWidget, IOrderLineAdapter } from "../../charting_library"; +import { dynamicKeys } from "./constants"; +import { DynamicChartLine, LineStyle } from "./types"; + +export function DynamicLineComponent({ + orderType, + isLong, + price, + id, + onEdit, + onCancel, + tvWidgetRef, + isEdited, + isPending, +}: { + isEdited: boolean; + isPending: boolean; + tvWidgetRef: React.RefObject; + onEdit: (id: string, price?: number) => void; + onCancel: (id: string) => void; +} & DynamicChartLine) { + const { _ } = useLingui(); + const lineApi = useRef(undefined); + const latestOnEdit = useLatest(onEdit); + const latestOnCancel = useLatest(onCancel); + const latestPrice = useLatest(price); + const prevIsPending = usePrevious(isPending); + const prevIsEdited = usePrevious(isEdited); + + useEffect(() => { + if (!tvWidgetRef.current?.activeChart?.().dataReady()) { + return; + } + + const chart = tvWidgetRef.current.activeChart(); + + const orderLine = chart.createOrderLine({ disableUndo: true }); + const predefinedKey = dynamicKeys[`${orderType}-${isLong ? "long" : "short"}`]; + const title = predefinedKey ? _(predefinedKey) : t`Unknown Order`; + + const orderLineApi = orderLine + .setText(title) + .setPrice(price) + .setQuantity("\u270E") + .setModifyTooltip(t`Edit Order`) + .onModify(() => { + latestOnEdit.current(id); + }) + .setCancelTooltip(t`Cancel Order`) + .onCancel(() => { + latestOnCancel.current(id); + }) + .onMove(() => { + latestOnEdit.current(id, orderLineApi.getPrice()); + }) + .setEditable(true) + .setLineStyle(LineStyle.Dashed) + .setLineLength(-200, "pixel") + .setLineColor("#3a3e5e") + + .setBodyFont(`normal 12pt "Relative", sans-serif`) + .setBodyTextColor("#fff") + .setBodyBackgroundColor("#3a3e5e") + .setBodyBorderColor("#252a47") + + .setQuantityBackgroundColor("#16182e") + .setQuantityFont(`normal 16pt "Relative", sans-serif`) + .setQuantityBorderColor("#252a47") + + .setCancelButtonBackgroundColor("#16182e") + .setCancelButtonBorderColor("#252a47") + .setCancelButtonIconColor("#fff"); + + lineApi.current = orderLineApi; + + return () => { + orderLineApi.remove(); + }; + }, [_, id, isLong, latestOnCancel, latestOnEdit, orderType, price, tvWidgetRef]); + + useEffect(() => { + if (!lineApi.current || lineApi.current.getPrice() === price) { + return; + } + + lineApi.current.setPrice(price); + }, [price]); + + useEffect( + function handleDropEdit() { + if (!lineApi.current) { + return; + } + + if (prevIsEdited && !isEdited && !(isPending || prevIsPending)) { + lineApi.current.setPrice(price); + } + }, + [isEdited, isPending, prevIsEdited, prevIsPending, price] + ); + + useEffect( + function handleDropPending() { + if (!lineApi.current) { + return; + } + + if (prevIsPending && !isPending) { + let counter = 0; + const interval = setInterval(() => { + const text = ".".repeat((counter % 3) + 1); + lineApi.current?.setQuantity(text); + counter++; + }, 1000); + + setTimeout(() => { + clearInterval(interval); + lineApi.current?.setQuantity("\u270E"); + lineApi.current?.setPrice(latestPrice.current); + }, FREQUENT_UPDATE_INTERVAL); + } + }, + [isPending, latestPrice, prevIsPending] + ); + + return null; +} diff --git a/src/components/TVChartContainer/OrderLinesContainer.tsx b/src/components/TVChartContainer/OrderLinesContainer.tsx new file mode 100644 index 0000000000..e0b9a01a63 --- /dev/null +++ b/src/components/TVChartContainer/OrderLinesContainer.tsx @@ -0,0 +1,103 @@ +import { useCallback } from "react"; +import type { IChartingLibraryWidget } from "../../charting_library"; + +import { USD_DECIMALS } from "config/factors"; +import { usePendingTxns } from "context/PendingTxnsContext/PendingTxnsContext"; +import { useSubaccount, useSubaccountCancelOrdersDetailsMessage } from "context/SubaccountContext/SubaccountContext"; +import { useSyntheticsEvents } from "context/SyntheticsEvents/SyntheticsEventsProvider"; +import { + useCancellingOrdersKeysState, + useEditingOrderKeyState, + useOrderEditorIsSubmittingState, +} from "context/SyntheticsStateContext/hooks/orderEditorHooks"; +import { selectChartDynamicLines } from "context/SyntheticsStateContext/selectors/chartSelectors/selectChartDynamicLines"; +import { selectChainId, selectOrdersInfoData } from "context/SyntheticsStateContext/selectors/globalSelectors"; +import { selectOrderEditorSetTriggerPriceInputValue } from "context/SyntheticsStateContext/selectors/orderEditorSelectors"; +import { useSelector } from "context/SyntheticsStateContext/utils"; +import { useMarkets } from "domain/synthetics/markets"; +import { cancelOrdersTxn } from "domain/synthetics/orders/cancelOrdersTxn"; +import { calculateDisplayDecimals, formatAmount } from "lib/numbers"; +import { getByKey } from "lib/objects"; +import useWallet from "lib/wallets/useWallet"; +import { getToken } from "sdk/configs/tokens"; +import { PositionOrderInfo } from "sdk/types/orders"; + +import { DynamicLineComponent } from "./DynamicLineComponent"; + +export function OrderLinesContainer({ + tvWidgetRef, + chartReady, +}: { + tvWidgetRef: React.RefObject; + chartReady: boolean; +}) { + const dynamicChartLines = useSelector(selectChartDynamicLines); + const { signer } = useWallet(); + const chainId = useSelector(selectChainId); + const subaccount = useSubaccount(null); + const [, setCancellingOrdersKeys] = useCancellingOrdersKeysState(); + const cancelOrdersDetailsMessage = useSubaccountCancelOrdersDetailsMessage(undefined, 1); + const [isSubmitting] = useOrderEditorIsSubmittingState(); + const [editingOrderKey, setEditingOrderKey] = useEditingOrderKeyState(); + const setTriggerPriceInputValue = useSelector(selectOrderEditorSetTriggerPriceInputValue); + const ordersInfoData = useSelector(selectOrdersInfoData); + const { marketsData } = useMarkets(chainId); + const { setPendingTxns } = usePendingTxns(); + const { pendingOrdersUpdates } = useSyntheticsEvents(); + + const onCancelOrder = useCallback( + (key: string) => { + if (!signer) return; + setCancellingOrdersKeys((prev) => [...prev, key]); + + cancelOrdersTxn(chainId, signer, subaccount, { + orderKeys: [key], + setPendingTxns: setPendingTxns, + detailsMsg: cancelOrdersDetailsMessage, + }).finally(() => { + setCancellingOrdersKeys((prev) => prev.filter((k) => k !== key)); + }); + }, + [cancelOrdersDetailsMessage, chainId, setCancellingOrdersKeys, setPendingTxns, signer, subaccount] + ); + + const onEditOrder = useCallback( + (id: string, price?: number) => { + setEditingOrderKey(id); + const order = getByKey(ordersInfoData, id) as PositionOrderInfo; + if (!order) return; + + const indexTokenAddress = getByKey(marketsData, order.marketAddress)?.indexTokenAddress; + if (!indexTokenAddress) return; + + const indexToken = getToken(chainId, indexTokenAddress); + if (!indexToken) return; + + const decimals = calculateDisplayDecimals(order.triggerPrice, USD_DECIMALS, indexToken?.visualMultiplier); + const formattedInitialPrice = formatAmount( + order.triggerPrice, + USD_DECIMALS, + decimals, + undefined, + undefined, + indexToken?.visualMultiplier + ); + setTriggerPriceInputValue(price !== undefined ? String(price) : formattedInitialPrice); + }, + [chainId, marketsData, ordersInfoData, setEditingOrderKey, setTriggerPriceInputValue] + ); + + if (!chartReady) return null; + + return dynamicChartLines.map((line) => ( + + )); +} diff --git a/src/components/TVChartContainer/TVChartContainer.tsx b/src/components/TVChartContainer/TVChartContainer.tsx index 43af505aa1..a408baae11 100644 --- a/src/components/TVChartContainer/TVChartContainer.tsx +++ b/src/components/TVChartContainer/TVChartContainer.tsx @@ -1,15 +1,15 @@ import Loader from "components/Common/Loader"; import { TV_SAVE_LOAD_CHARTS_KEY } from "config/localStorage"; -import { isChartAvailableForToken } from "sdk/configs/tokens"; import { SUPPORTED_RESOLUTIONS_V1, SUPPORTED_RESOLUTIONS_V2 } from "config/tradingview"; import { useSettings } from "context/SettingsContext/SettingsContextProvider"; -import { useOracleKeeperFetcher } from "lib/oracleKeeperFetcher"; import { TokenPrices } from "domain/tokens"; import { DataFeed } from "domain/tradingview/DataFeed"; import { getObjectKeyFromValue, getSymbolName } from "domain/tradingview/utils"; +import { useOracleKeeperFetcher } from "lib/oracleKeeperFetcher"; import { useTradePageVersion } from "lib/useTradePageVersion"; import { CSSProperties, useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState } from "react"; import { useLatest, useLocalStorage, useMedia } from "react-use"; +import { isChartAvailableForToken } from "sdk/configs/tokens"; import type { ChartData, ChartingLibraryWidgetOptions, @@ -19,15 +19,12 @@ import type { } from "../../charting_library"; import { SaveLoadAdapter } from "./SaveLoadAdapter"; import { defaultChartProps, disabledFeaturesOnMobile } from "./constants"; - -export type ChartLine = { - price: number; - title: string; -}; +import { OrderLinesContainer } from "./OrderLinesContainer"; +import { StaticChartLine } from "./types"; type Props = { chainId: number; - chartLines: ChartLine[]; + chartLines: StaticChartLine[]; period: string; setPeriod: (period: string) => void; chartToken: @@ -85,7 +82,7 @@ export default function TVChartContainer({ const symbolRef = useRef(chartToken.symbol); const drawLineOnChart = useCallback( - (title: string, price: number) => { + ({ title, price }: StaticChartLine) => { if (chartReady && tvWidgetRef.current?.activeChart?.().dataReady()) { const chart = tvWidgetRef.current.activeChart(); const positionLine = chart.createPositionLine({ disableUndo: true }); @@ -110,12 +107,12 @@ export default function TVChartContainer({ function updateLines() { const lines: (IPositionLineAdapter | undefined)[] = []; if (shouldShowPositionLines) { - chartLines.forEach((order) => { - lines.push(drawLineOnChart(order.title, order.price)); + chartLines.forEach((line) => { + lines.push(drawLineOnChart(line)); }); } return () => { - lines.forEach((line) => line?.remove()); + lines.forEach((lineApi) => lineApi?.remove()); }; }, [chartLines, shouldShowPositionLines, drawLineOnChart] @@ -244,6 +241,7 @@ export default function TVChartContainer({
{chartDataLoading && }
+
); } diff --git a/src/components/TVChartContainer/constants.ts b/src/components/TVChartContainer/constants.ts index ee7994ae3a..32c12a817e 100644 --- a/src/components/TVChartContainer/constants.ts +++ b/src/components/TVChartContainer/constants.ts @@ -1,7 +1,11 @@ +import type { MessageDescriptor } from "@lingui/core"; +import { msg } from "@lingui/macro"; import { ChartingLibraryFeatureset, ChartingLibraryWidgetOptions, WidgetOverrides } from "charting_library"; +import { lightFormat, parse } from "date-fns"; + import { ARBITRUM, AVALANCHE } from "config/chains"; import { USD_DECIMALS } from "config/factors"; -import { lightFormat, parse } from "date-fns"; +import { OrderType } from "domain/synthetics/orders"; import { formatTVDate, formatTVTime } from "lib/dates"; import { calculateDisplayDecimals, numberToBigint } from "lib/numbers"; @@ -130,3 +134,14 @@ export const defaultChartProps = { } satisfies Partial; export const availableNetworksForChart = [ARBITRUM, AVALANCHE]; + +export const dynamicKeys: Partial> = { + [`${OrderType.LimitIncrease}-short`]: msg`Limit - Short Inc.`, + [`${OrderType.LimitIncrease}-long`]: msg`Limit - Long Inc.`, + + [`${OrderType.LimitDecrease}-short`]: msg`TP - Short Dec.`, + [`${OrderType.LimitDecrease}-long`]: msg`TP - Long Dec.`, + + [`${OrderType.StopLossDecrease}-long`]: msg`SL - Long Dec.`, + [`${OrderType.StopLossDecrease}-short`]: msg`SL - Short Dec.`, +}; diff --git a/src/components/TVChartContainer/types.tsx b/src/components/TVChartContainer/types.tsx new file mode 100644 index 0000000000..bdd031f731 --- /dev/null +++ b/src/components/TVChartContainer/types.tsx @@ -0,0 +1,28 @@ +import type { OrderType } from "sdk/types/orders"; + +export enum LineStyle { + /** + * Solid line style. + */ + Solid = 0, + /** + * Dotted line style. + */ + Dotted = 1, + /** + * Dashed line style. + */ + Dashed = 2, +} + +export type StaticChartLine = { + price: number; + title: string; +}; + +export type DynamicChartLine = { + id: string; + price: number; + orderType: OrderType; + isLong: boolean; +}; diff --git a/src/context/PendingTxnsContext/PendingTxnsContext.tsx b/src/context/PendingTxnsContext/PendingTxnsContext.tsx index 2ccc56eb00..c2cae57b28 100644 --- a/src/context/PendingTxnsContext/PendingTxnsContext.tsx +++ b/src/context/PendingTxnsContext/PendingTxnsContext.tsx @@ -26,7 +26,7 @@ export type PendingTransactionData = { export type PendingTransaction = { hash: string; message: string; - messageDetails?: string; + messageDetails?: ReactNode; metricId?: OrderMetricId; data?: PendingTransactionData; }; diff --git a/src/context/SyntheticsEvents/SyntheticsEventsProvider.tsx b/src/context/SyntheticsEvents/SyntheticsEventsProvider.tsx index 42dd83a1d2..b899459f7e 100644 --- a/src/context/SyntheticsEvents/SyntheticsEventsProvider.tsx +++ b/src/context/SyntheticsEvents/SyntheticsEventsProvider.tsx @@ -19,6 +19,8 @@ import { isLiquidationOrderType, isMarketOrderType, isSwapOrderType, + OrderTxnType, + UpdateOrderParams, } from "domain/synthetics/orders"; import { getPositionKey } from "domain/synthetics/positions"; import { useTokensDataRequest } from "domain/synthetics/tokens"; @@ -37,7 +39,7 @@ import { sendOrderExecutedMetric, } from "lib/metrics/utils"; import { formatTokenAmount, formatUsd } from "lib/numbers"; -import { getByKey, setByKey, updateByKey } from "lib/objects"; +import { deleteByKey, getByKey, setByKey, updateByKey } from "lib/objects"; import { getProvider } from "lib/rpc"; import { useHasLostFocus } from "lib/useHasPageLostFocus"; import { usePendingTxns } from "context/PendingTxnsContext/PendingTxnsContext"; @@ -55,6 +57,7 @@ import { PendingDepositData, PendingFundingFeeSettlementData, PendingOrderData, + PendingOrdersUpdates, PendingPositionsUpdates, PendingPositionUpdate, PendingShiftData, @@ -115,6 +118,7 @@ export function SyntheticsEventsProvider({ children }: { children: ReactNode }) const { tokensBalancesUpdates, setTokensBalancesUpdates } = useTokensBalancesUpdates(); const [approvalStatuses, setApprovalStatuses] = useState({}); + const [pendingOrdersUpdates, setPendingOrdersUpdates] = useState({}); const [pendingPositionsUpdates, setPendingPositionsUpdates] = useState({}); const [positionIncreaseEvents, setPositionIncreaseEvents] = useState([]); const [positionDecreaseEvents, setPositionDecreaseEvents] = useState([]); @@ -183,6 +187,8 @@ export function SyntheticsEventsProvider({ children }: { children: ReactNode }) createdAt: Date.now(), }) ); + + setPendingOrdersUpdates((old) => deleteByKey(old, data.key)); }, OrderUpdated: (eventData: EventLogData, txnParams: EventTxnParams) => { @@ -207,6 +213,8 @@ export function SyntheticsEventsProvider({ children }: { children: ReactNode }) }); } }); + + setPendingOrdersUpdates((old) => deleteByKey(old, key)); }, OrderExecuted: (eventData: EventLogData, txnParams: EventTxnParams) => { @@ -876,6 +884,7 @@ export function SyntheticsEventsProvider({ children }: { children: ReactNode }) shiftStatuses, tokensBalancesUpdates, approvalStatuses, + pendingOrdersUpdates, pendingPositionsUpdates, positionIncreaseEvents, positionDecreaseEvents, @@ -896,6 +905,19 @@ export function SyntheticsEventsProvider({ children }: { children: ReactNode }) className: "OrdersStatusNotificiation", } ); + + const arrayData = Array.isArray(data) ? data : [data]; + const objData: Record = arrayData.reduce( + (acc, order) => (!order.orderKey ? acc : setByKey(acc, order.orderKey, order.txnType)), + {} + ); + + setPendingOrdersUpdates((old) => ({ ...old, ...objData })); + }, + setPendingOrderUpdate: (data: UpdateOrderParams, remove?: "remove") => { + setPendingOrdersUpdates((old) => + remove ? deleteByKey(old, data.orderKey) : setByKey(old, data.orderKey, "update") + ); }, setPendingFundingFeeSettlement: (data: PendingFundingFeeSettlementData) => { const toastId = Date.now(); @@ -987,6 +1009,7 @@ export function SyntheticsEventsProvider({ children }: { children: ReactNode }) shiftStatuses, tokensBalancesUpdates, approvalStatuses, + pendingOrdersUpdates, pendingPositionsUpdates, positionIncreaseEvents, positionDecreaseEvents, diff --git a/src/context/SyntheticsEvents/types.ts b/src/context/SyntheticsEvents/types.ts index 5caf85f671..086d685f85 100644 --- a/src/context/SyntheticsEvents/types.ts +++ b/src/context/SyntheticsEvents/types.ts @@ -1,4 +1,4 @@ -import { OrderTxnType, OrderType } from "domain/synthetics/orders"; +import { OrderTxnType, OrderType, UpdateOrderParams } from "domain/synthetics/orders"; export type MultiTransactionStatus = { key: string; @@ -69,6 +69,10 @@ export type PendingPositionsUpdates = { [key: string]: PendingPositionUpdate | undefined; }; +export type PendingOrdersUpdates = { + [key: string]: OrderTxnType; +}; + export type EventLogItems = { [key: string]: T; }; @@ -103,10 +107,12 @@ export type SyntheticsEventsContextType = { withdrawalStatuses: WithdrawalStatuses; shiftStatuses: ShiftStatuses; approvalStatuses: ApprovalStatuses; + pendingOrdersUpdates: PendingOrdersUpdates; pendingPositionsUpdates: PendingPositionsUpdates; positionIncreaseEvents: PositionIncreaseEvent[] | undefined; positionDecreaseEvents: PositionDecreaseEvent[] | undefined; setPendingOrder: SetPendingOrder; + setPendingOrderUpdate: SetPendingOrderUpdate; setPendingFundingFeeSettlement: SetPendingFundingFeeSettlement; setPendingPosition: SetPendingPosition; setPendingDeposit: SetPendingDeposit; @@ -119,6 +125,7 @@ export type SyntheticsEventsContextType = { }; export type SetPendingOrder = (data: PendingOrderData | PendingOrderData[]) => void; +export type SetPendingOrderUpdate = (data: UpdateOrderParams, remove?: "remove") => void; export type SetPendingPosition = (update: PendingPositionUpdate) => void; export type SetPendingDeposit = (data: PendingDepositData) => void; export type SetPendingWithdrawal = (data: PendingWithdrawalData) => void; diff --git a/src/context/SyntheticsStateContext/hooks/orderEditorHooks.ts b/src/context/SyntheticsStateContext/hooks/orderEditorHooks.ts index 4954235f92..76024f88da 100644 --- a/src/context/SyntheticsStateContext/hooks/orderEditorHooks.ts +++ b/src/context/SyntheticsStateContext/hooks/orderEditorHooks.ts @@ -9,6 +9,8 @@ import { selectOrderEditorSizeInputValue, selectOrderEditorTriggerPriceInputValue, selectOrderEditorTriggerRatioInputValue, + selectOrderEditorIsSubmitting, + selectOrderEditorSetIsSubmitting, } from "../selectors/orderEditorSelectors"; import { useSelector } from "../utils"; @@ -24,6 +26,12 @@ export const useEditingOrderKeyState = () => { return [editingOrderKey, setEditingOrderKey] as const; }; +export const useOrderEditorIsSubmittingState = () => { + const isSubmitting = useSelector(selectOrderEditorIsSubmitting); + const setIsSubmitting = useSelector(selectOrderEditorSetIsSubmitting); + return [isSubmitting, setIsSubmitting] as const; +}; + export const useOrderEditorSizeInputValueState = () => { const sizeInputValue = useSelector(selectOrderEditorSizeInputValue); const setSizeInputValue = useSelector(selectOrderEditorSetSizeInputValue); diff --git a/src/context/SyntheticsStateContext/selectors/chartSelectors.ts b/src/context/SyntheticsStateContext/selectors/chartSelectors/index.ts similarity index 96% rename from src/context/SyntheticsStateContext/selectors/chartSelectors.ts rename to src/context/SyntheticsStateContext/selectors/chartSelectors/index.ts index 839a41e79b..c210f8a2db 100644 --- a/src/context/SyntheticsStateContext/selectors/chartSelectors.ts +++ b/src/context/SyntheticsStateContext/selectors/chartSelectors/index.ts @@ -4,15 +4,15 @@ import { getAvailableUsdLiquidityForPosition } from "domain/synthetics/markets"; import { getTokenData } from "domain/synthetics/tokens"; import { bigMath } from "sdk/utils/bigmath"; import { CHART_PERIODS } from "lib/legacy"; -import { createSelector } from "../utils"; -import { selectChainId, selectTokensData } from "./globalSelectors"; +import { createSelector } from "../../utils"; +import { selectChainId, selectTokensData } from "../globalSelectors"; import { selectTradeboxAvailableTokensOptions, selectTradeboxFromTokenAddress, selectTradeboxMarketInfo, selectTradeboxToTokenAddress, selectTradeboxTradeFlags, -} from "./tradeboxSelectors"; +} from "../tradeboxSelectors"; export const selectChartToken = createSelector(function selectChartToken(q) { const fromTokenAddress = q(selectTradeboxFromTokenAddress); diff --git a/src/context/SyntheticsStateContext/selectors/chartSelectors/selectChartDynamicLines.tsx b/src/context/SyntheticsStateContext/selectors/chartSelectors/selectChartDynamicLines.tsx new file mode 100644 index 0000000000..0dc6df0193 --- /dev/null +++ b/src/context/SyntheticsStateContext/selectors/chartSelectors/selectChartDynamicLines.tsx @@ -0,0 +1,69 @@ +import { DynamicChartLine } from "components/TVChartContainer/types"; +import { USD_DECIMALS } from "config/factors"; +import { selectChartToken } from "context/SyntheticsStateContext/selectors/chartSelectors"; +import { + selectChainId, + selectOrdersInfoData, + selectTokensData, +} from "context/SyntheticsStateContext/selectors/globalSelectors"; +import { createSelector } from "context/SyntheticsStateContext/utils"; +import { PositionOrderInfo, isSwapOrderType } from "domain/synthetics/orders"; +import { getTokenData } from "domain/synthetics/tokens"; +import { formatAmount } from "lib/numbers"; +import { EMPTY_ARRAY } from "lib/objects"; +import { convertTokenAddress, getPriceDecimals } from "sdk/configs/tokens"; + +export const selectChartDynamicLines = createSelector((q) => { + const chainId = q(selectChainId); + const { chartToken } = q(selectChartToken); + const ordersInfo = q(selectOrdersInfoData); + + const chartTokenAddress = chartToken?.address; + + if (!chartTokenAddress) { + return EMPTY_ARRAY; + } + + const orderLines: DynamicChartLine[] = Object.values(ordersInfo || {}) + .filter((order) => { + if (isSwapOrderType(order.orderType)) { + return false; + } + + const positionOrder = order as PositionOrderInfo; + + return ( + positionOrder.marketInfo && + positionOrder.triggerPrice !== undefined && + convertTokenAddress(chainId, positionOrder.marketInfo.indexTokenAddress, "wrapped") === + convertTokenAddress(chainId, chartTokenAddress, "wrapped") + ); + }) + .map((order) => { + const positionOrder = order as PositionOrderInfo; + const priceDecimal = getPriceDecimals(chainId, positionOrder.indexToken.symbol); + + const token = q((state) => + getTokenData(selectTokensData(state), positionOrder.marketInfo.indexTokenAddress, "native") + ); + const tokenVisualMultiplier = token?.visualMultiplier; + + return { + id: positionOrder.key, + orderType: positionOrder.orderType, + isLong: order.isLong, + price: parseFloat( + formatAmount( + positionOrder.triggerPrice, + USD_DECIMALS, + priceDecimal, + undefined, + undefined, + tokenVisualMultiplier + ) + ), + }; + }); + + return orderLines; +}); diff --git a/src/context/SyntheticsStateContext/selectors/chartSelectors/selectChartLines.tsx b/src/context/SyntheticsStateContext/selectors/chartSelectors/selectChartLines.tsx new file mode 100644 index 0000000000..0ad8f9439e --- /dev/null +++ b/src/context/SyntheticsStateContext/selectors/chartSelectors/selectChartLines.tsx @@ -0,0 +1,71 @@ +import { t } from "@lingui/macro"; + +import { USD_DECIMALS } from "config/factors"; +import { selectChartToken } from "context/SyntheticsStateContext/selectors/chartSelectors"; +import { + selectChainId, + selectPositionsInfoData, + selectTokensData, +} from "context/SyntheticsStateContext/selectors/globalSelectors"; +import { createSelector } from "context/SyntheticsStateContext/utils"; +import { getTokenData } from "domain/synthetics/tokens"; +import { formatAmount } from "lib/numbers"; +import { convertTokenAddress, getPriceDecimals, getTokenVisualMultiplier } from "sdk/configs/tokens"; +import { StaticChartLine } from "components/TVChartContainer/types"; +import { EMPTY_ARRAY } from "lib/objects"; + +export const selectChartLines = createSelector((q) => { + const chainId = q(selectChainId); + const { chartToken } = q(selectChartToken); + const positionsInfo = q(selectPositionsInfoData); + + const chartTokenAddress = chartToken?.address; + + if (!chartTokenAddress) { + return EMPTY_ARRAY; + } + + const positionLines = Object.values(positionsInfo || {}).reduce((acc, position) => { + const priceDecimal = getPriceDecimals(chainId, position.indexToken.symbol); + if ( + position.marketInfo && + convertTokenAddress(chainId, position.marketInfo.indexTokenAddress, "wrapped") === + convertTokenAddress(chainId, chartTokenAddress, "wrapped") + ) { + const longOrShortText = position.isLong ? t`Long` : t`Short`; + const token = q((state) => + getTokenData(selectTokensData(state), position.marketInfo?.indexTokenAddress, "native") + ); + const tokenSymbol = token?.symbol; + const prefix = token ? getTokenVisualMultiplier(token) : ""; + const tokenVisualMultiplier = token?.visualMultiplier; + + const liquidationPrice = formatAmount( + position?.liquidationPrice, + USD_DECIMALS, + priceDecimal, + undefined, + undefined, + tokenVisualMultiplier + ); + + acc.push({ + title: t`Open ${longOrShortText} ${prefix}${tokenSymbol}`, + + price: parseFloat( + formatAmount(position.entryPrice, USD_DECIMALS, priceDecimal, undefined, undefined, tokenVisualMultiplier) + ), + }); + if (liquidationPrice && liquidationPrice !== "NA") { + acc.push({ + title: t`Liq. ${longOrShortText} ${prefix}${tokenSymbol}`, + price: parseFloat(liquidationPrice), + }); + } + } + + return acc; + }, [] as StaticChartLine[]); + + return positionLines; +}); diff --git a/src/context/SyntheticsStateContext/selectors/orderEditorSelectors.ts b/src/context/SyntheticsStateContext/selectors/orderEditorSelectors.ts index 3591ce3164..599c48271d 100644 --- a/src/context/SyntheticsStateContext/selectors/orderEditorSelectors.ts +++ b/src/context/SyntheticsStateContext/selectors/orderEditorSelectors.ts @@ -64,6 +64,8 @@ export const selectSetCancellingOrdersKeys = (s: SyntheticsState) => s.orderEdit export const selectEditingOrderKey = (s: SyntheticsState) => s.orderEditor.editingOrderKey; export const selectSetEditingOrderKey = (s: SyntheticsState) => s.orderEditor.setEditingOrderKey; +export const selectOrderEditorIsSubmitting = (s: SyntheticsState) => s.orderEditor.isSubmitting; +export const selectOrderEditorSetIsSubmitting = (s: SyntheticsState) => s.orderEditor.setIsSubmitting; export const selectOrderEditorSizeInputValue = (s: SyntheticsState) => s.orderEditor.sizeInputValue; export const selectOrderEditorSetSizeInputValue = (s: SyntheticsState) => s.orderEditor.setSizeInputValue; export const selectOrderEditorTriggerPriceInputValue = (s: SyntheticsState) => s.orderEditor.triggerPriceInputValue; diff --git a/src/domain/synthetics/orders/updateOrderTxn.ts b/src/domain/synthetics/orders/updateOrderTxn.ts index f56008bb72..8d0713ee71 100644 --- a/src/domain/synthetics/orders/updateOrderTxn.ts +++ b/src/domain/synthetics/orders/updateOrderTxn.ts @@ -1,13 +1,15 @@ import { t } from "@lingui/macro"; import { Signer, ethers } from "ethers"; -import ExchangeRouter from "sdk/abis/ExchangeRouter.json"; import { getContract } from "config/contracts"; +import type { SetPendingTransactions } from "context/PendingTxnsContext/PendingTxnsContext"; import { Subaccount } from "context/SubaccountContext/SubaccountContext"; +import type { SetPendingOrderUpdate } from "context/SyntheticsEvents"; import { getSubaccountRouterContract } from "domain/synthetics/subaccount/getSubaccountContract"; import { convertToContractPrice } from "domain/synthetics/tokens"; import { Token } from "domain/tokens"; import { callContract } from "lib/contracts"; +import ExchangeRouter from "sdk/abis/ExchangeRouter.json"; export type UpdateOrderParams = { orderKey: string; @@ -19,14 +21,19 @@ export type UpdateOrderParams = { autoCancel: boolean; // used to top-up execution fee for frozen orders executionFee?: bigint; - setPendingTxns: (txns: any) => void; }; -export function updateOrderTxn( +export type UpdateOrderCallbacks = { + setPendingTxns: SetPendingTransactions; + setPendingOrderUpdate: SetPendingOrderUpdate; +}; + +export async function updateOrderTxn( chainId: number, signer: Signer, subaccount: Subaccount, - p: UpdateOrderParams + p: UpdateOrderParams, + callbacks: UpdateOrderCallbacks ): Promise { const { orderKey, @@ -35,7 +42,6 @@ export function updateOrderTxn( acceptablePrice, minOutputAmount, executionFee, - setPendingTxns, indexToken, autoCancel, } = p; @@ -57,15 +63,22 @@ export function updateOrderTxn( autoCancel, }); - return callContract(chainId, router, "multicall", [encodedPayload], { - value: executionFee != undefined && executionFee > 0 ? executionFee : undefined, - sentMsg: t`Updating order`, - successMsg: t`Update order executed`, - failMsg: t`Failed to update order`, - customSigners: subaccount?.customSigners, - setPendingTxns, - showPreliminaryMsg: Boolean(subaccount), - }); + callbacks.setPendingOrderUpdate(p); + + try { + return await callContract(chainId, router, "multicall", [encodedPayload], { + value: executionFee != undefined && executionFee > 0 ? executionFee : undefined, + sentMsg: t`Updating order`, + successMsg: t`Update order executed`, + failMsg: t`Failed to update order`, + customSigners: subaccount?.customSigners, + setPendingTxns: callbacks.setPendingTxns, + showPreliminaryMsg: Boolean(subaccount), + }); + } catch (e) { + callbacks.setPendingOrderUpdate(p, "remove"); + throw e; + } } export function createUpdateEncodedPayload({ diff --git a/src/domain/synthetics/orders/useOrderEditorState.ts b/src/domain/synthetics/orders/useOrderEditorState.ts index 6a72847b20..03f1bf2a45 100644 --- a/src/domain/synthetics/orders/useOrderEditorState.ts +++ b/src/domain/synthetics/orders/useOrderEditorState.ts @@ -12,6 +12,7 @@ export type OrderEditorState = ReturnType; export function useOrderEditorState(ordersInfoData: OrdersInfoData | undefined) { const [cancellingOrdersKeys, setCancellingOrdersKeys] = useState([]); const [editingOrderKey, setEditingOrderKey] = useState(); + const [isSubmitting, setIsSubmitting] = useState(false); const [sizeInputValue, setSizeInputValue] = useState(""); const [triggerPriceInputValue, setTriggerPriceInputValue] = useState(""); const [triggerRatioInputValue, setTriggerRatioInputValue] = useState(""); @@ -62,6 +63,8 @@ export function useOrderEditorState(ordersInfoData: OrdersInfoData | undefined) setCancellingOrdersKeys, editingOrderKey, setEditingOrderKey, + isSubmitting, + setIsSubmitting, sizeInputValue, setSizeInputValue, triggerPriceInputValue, @@ -80,6 +83,7 @@ export function useOrderEditorState(ordersInfoData: OrdersInfoData | undefined) cancellingOrdersKeys, editingOrderKey, initialAcceptablePriceImpactBps, + isSubmitting, setAcceptablePriceImpactBps, sizeInputValue, triggerPriceInputValue, diff --git a/src/domain/synthetics/orders/utils.tsx b/src/domain/synthetics/orders/utils.tsx index ac83713606..96bb259ab6 100644 --- a/src/domain/synthetics/orders/utils.tsx +++ b/src/domain/synthetics/orders/utils.tsx @@ -1,5 +1,6 @@ import { Trans, t } from "@lingui/macro"; import ExternalLink from "components/ExternalLink/ExternalLink"; +import { PendingOrderData } from "context/SyntheticsEvents"; import { Token } from "domain/tokens"; import { formatPercentage, formatTokenAmount, formatUsd } from "lib/numbers"; import { NATIVE_TOKEN_ADDRESS, convertTokenAddress, getTokenVisualMultiplier } from "sdk/configs/tokens"; @@ -417,7 +418,7 @@ export function getPendingOrderFromParams( chainId: number, txnType: OrderTxnType, p: DecreaseOrderParams | SecondaryUpdateOrderParams | SecondaryCancelOrderParams -) { +): PendingOrderData { const isNativeReceive = p.receiveTokenAddress === NATIVE_TOKEN_ADDRESS; const shouldApplySlippage = isMarketOrderType(p.orderType); diff --git a/src/domain/synthetics/subaccount/initSubaccount.ts b/src/domain/synthetics/subaccount/initSubaccount.ts index abbe4529b2..e931aa3546 100644 --- a/src/domain/synthetics/subaccount/initSubaccount.ts +++ b/src/domain/synthetics/subaccount/initSubaccount.ts @@ -4,6 +4,7 @@ import { SUBACCOUNT_ORDER_ACTION } from "./constants"; import { getSubaccountRouterContract } from "./getSubaccountContract"; import { SubaccountParams } from "./types"; import { BN_ZERO } from "lib/numbers"; +import { SetPendingTransactions } from "context/PendingTxnsContext/PendingTxnsContext"; export async function initSubaccount( chainId: number, @@ -12,7 +13,7 @@ export async function initSubaccount( mainAccountAddress: string, isAccountActive: boolean, currentActionsCount: bigint | null, - setPendingTxns: (txns: any[]) => void, + setPendingTxns: SetPendingTransactions, { topUp, maxAllowedActions, maxAutoTopUpAmount, wntForAutoTopUps }: SubaccountParams ) { const subaccountRouter = getSubaccountRouterContract(chainId, signer); diff --git a/src/lib/contracts/callContract.tsx b/src/lib/contracts/callContract.tsx index 65cb8a301d..76153e4387 100644 --- a/src/lib/contracts/callContract.tsx +++ b/src/lib/contracts/callContract.tsx @@ -1,7 +1,11 @@ import { Trans, t } from "@lingui/macro"; import ExternalLink from "components/ExternalLink/ExternalLink"; import { getExplorerUrl } from "config/chains"; -import { PendingTransactionData } from "context/PendingTxnsContext/PendingTxnsContext"; +import { + PendingTransaction, + PendingTransactionData, + SetPendingTransactions, +} from "context/PendingTxnsContext/PendingTxnsContext"; import { Contract, Overrides, Wallet } from "ethers"; import { OrderMetricId } from "lib/metrics/types"; import { sendOrderTxnSubmittedMetric } from "lib/metrics/utils"; @@ -32,7 +36,7 @@ export async function callContract( customSignersGasLimits?: (bigint | number)[]; customSignersGasPrices?: GasPriceData[]; bestNonce?: number; - setPendingTxns?: (txns: any) => void; + setPendingTxns?: SetPendingTransactions; pendingTransactionData?: PendingTransactionData; metricId?: OrderMetricId; } @@ -149,8 +153,8 @@ export async function callContract( } if (opts.setPendingTxns) { - const message = opts.hideSuccessMsg ? undefined : opts.successMsg || t`Transaction completed!`; - const pendingTxn = { + const message = opts.hideSuccessMsg ? "" : opts.successMsg || t`Transaction completed!`; + const pendingTxn: PendingTransaction = { hash: res.hash, message, messageDetails: opts.successDetailsMsg ?? opts.detailsMsg, diff --git a/src/locales/de/messages.po b/src/locales/de/messages.po index fb04080da4..cb5c21df3f 100644 --- a/src/locales/de/messages.po +++ b/src/locales/de/messages.po @@ -729,6 +729,10 @@ msgstr "" msgid "Paraswap" msgstr "" +#: src/components/TVChartContainer/constants.ts +msgid "TP - Long Dec." +msgstr "" + #: src/components/Referrals/AffiliatesStats.tsx msgid "Claimable Rebates" msgstr "" @@ -827,6 +831,10 @@ msgstr "" msgid "Code already taken" msgstr "Code bereits vergeben" +#: src/components/TVChartContainer/constants.ts +msgid "SL - Short Dec." +msgstr "" + #: src/components/SettingsModal/SettingsModal.tsx msgid "Slippage should be less than -5%" msgstr "" @@ -1428,6 +1436,10 @@ msgstr "Swap Order Erstellung fehlgeschlagen." msgid "Chart positions" msgstr "Chart-Positionen" +#: src/components/TVChartContainer/DynamicLineComponent.tsx +msgid "Unknown Order" +msgstr "" + #: src/components/Exchange/ConfirmationBox.jsx msgid "The order will only execute if the price conditions are met and there is sufficient liquidity" msgstr "Der Auftrag wird nur ausgeführt, wenn die Preisbedingungen erfüllt sind und genügend Liquidität vorhanden ist." @@ -1817,7 +1829,7 @@ msgstr "" msgid "{0, plural, one {Pending {symbolsText} approval} other {Pending {symbolsText} approvals}}" msgstr "" -#: src/components/Synthetics/TVChart/TVChart.tsx +#: src/context/SyntheticsStateContext/selectors/chartSelectors/selectChartLines.tsx msgid "Open {longOrShortText} {prefix}{tokenSymbol}" msgstr "" @@ -2943,7 +2955,7 @@ msgstr "" msgid "Decreased {tokenSymbol} {longOrShortText}, -{0} USD." msgstr "Verringert {tokenSymbol} {longOrShortText}, -{0} USD." -#: src/components/Synthetics/TVChart/TVChart.tsx +#: src/context/SyntheticsStateContext/selectors/chartSelectors/selectChartLines.tsx msgid "Liq. {longOrShortText} {prefix}{tokenSymbol}" msgstr "" @@ -3241,6 +3253,10 @@ msgstr "" msgid "Start Unrealized PnL" msgstr "" +#: src/components/TVChartContainer/constants.ts +msgid "Limit - Short Inc." +msgstr "" + #: src/components/Synthetics/MarketStats/components/CompositionTable.tsx msgid "AMOUNT" msgstr "" @@ -3510,6 +3526,10 @@ msgstr "" msgid "Select a GLV Vault" msgstr "" +#: src/components/TVChartContainer/DynamicLineComponent.tsx +msgid "Cancel Order" +msgstr "" + #: src/components/Exchange/PositionEditor.jsx #: src/components/Exchange/PositionEditor.jsx #: src/components/Exchange/PositionEditor.jsx @@ -3701,6 +3721,10 @@ msgstr "" msgid "Impact+Fees" msgstr "" +#: src/components/TVChartContainer/constants.ts +msgid "TP - Short Dec." +msgstr "" + #: src/pages/Ecosystem/ecosystemConstants.tsx msgid "Compass Labs GM Token Dashboard" msgstr "" @@ -3884,10 +3908,9 @@ msgstr "Trigger-Preis für den Auftrag." #: src/components/Synthetics/TradeBox/tradeboxConstants.tsx #: src/components/Synthetics/TradeHistory/TradeHistoryRow/utils/position.ts #: src/components/Synthetics/TVChart/components/AvailableLiquidityTooltip.tsx -#: src/components/Synthetics/TVChart/TVChart.tsx -#: src/components/Synthetics/TVChart/TVChart.tsx #: src/context/SyntheticsEvents/SyntheticsEventsProvider.tsx #: src/context/SyntheticsEvents/SyntheticsEventsProvider.tsx +#: src/context/SyntheticsStateContext/selectors/chartSelectors/selectChartLines.tsx #: src/domain/synthetics/orders/utils.tsx #: src/pages/Exchange/Exchange.tsx #: src/pages/Exchange/Exchange.tsx @@ -4327,6 +4350,10 @@ msgstr "" msgid "There is not enough {0} in your account on {networkName} to send this transaction.<0/><1/><2>Buy or Transfer {1} to {networkName}" msgstr "" +#: src/components/TVChartContainer/constants.ts +msgid "SL - Long Dec." +msgstr "" + #: src/components/Synthetics/UserIncentiveDistributionList/UserIncentiveDistributionList.tsx msgid "Airdrop" msgstr "" @@ -4526,7 +4553,6 @@ msgid "Max slippage precision is -0.01%" msgstr "" #: src/components/Exchange/ExchangeTVChart.jsx -#: src/components/Synthetics/TVChart/TVChart.tsx msgid "Dec." msgstr "Dezentr." @@ -5242,6 +5268,10 @@ msgstr "" msgid "There is no liquidation price, as the position's collateral value will increase to cover any negative PnL." msgstr "" +#: src/components/TVChartContainer/DynamicLineComponent.tsx +msgid "Edit Order" +msgstr "" + #: src/components/MarketSelector/GmPoolsSelectorForGlvMarket.tsx #: src/components/MarketSelector/PoolSelector.tsx msgid "Search Pool" @@ -6215,7 +6245,6 @@ msgid "" msgstr "" #: src/components/Exchange/ExchangeTVChart.jsx -#: src/components/Synthetics/TVChart/TVChart.tsx msgid "Inc." msgstr "Inc." @@ -7013,10 +7042,9 @@ msgstr "" #: src/components/Synthetics/TradeBox/tradeboxConstants.tsx #: src/components/Synthetics/TradeHistory/TradeHistoryRow/utils/position.ts #: src/components/Synthetics/TVChart/components/AvailableLiquidityTooltip.tsx -#: src/components/Synthetics/TVChart/TVChart.tsx -#: src/components/Synthetics/TVChart/TVChart.tsx #: src/context/SyntheticsEvents/SyntheticsEventsProvider.tsx #: src/context/SyntheticsEvents/SyntheticsEventsProvider.tsx +#: src/context/SyntheticsStateContext/selectors/chartSelectors/selectChartLines.tsx #: src/domain/synthetics/orders/utils.tsx #: src/pages/Exchange/Exchange.tsx #: src/pages/Exchange/Exchange.tsx @@ -7759,6 +7787,10 @@ msgstr "" msgid "Orders ({ordersCount})" msgstr "" +#: src/components/TVChartContainer/constants.ts +msgid "Limit - Long Inc." +msgstr "" + #: src/pages/Earn/ClaimModal.tsx msgid "<0>Delegate your undelegated {0} GMX DAOvoting power before claiming." msgstr "" diff --git a/src/locales/en/messages.po b/src/locales/en/messages.po index b7c1e8f4bd..c0596bf1f9 100644 --- a/src/locales/en/messages.po +++ b/src/locales/en/messages.po @@ -729,6 +729,10 @@ msgstr "What did you like the most about our service?" msgid "Paraswap" msgstr "Paraswap" +#: src/components/TVChartContainer/constants.ts +msgid "TP - Long Dec." +msgstr "TP - Long Dec." + #: src/components/Referrals/AffiliatesStats.tsx msgid "Claimable Rebates" msgstr "Claimable Rebates" @@ -827,6 +831,10 @@ msgstr "Closing..." msgid "Code already taken" msgstr "Code already taken" +#: src/components/TVChartContainer/constants.ts +msgid "SL - Short Dec." +msgstr "SL - Short Dec." + #: src/components/SettingsModal/SettingsModal.tsx msgid "Slippage should be less than -5%" msgstr "Slippage should be less than -5%" @@ -1428,6 +1436,10 @@ msgstr "Swap Order creation failed." msgid "Chart positions" msgstr "Chart positions" +#: src/components/TVChartContainer/DynamicLineComponent.tsx +msgid "Unknown Order" +msgstr "Unknown Order" + #: src/components/Exchange/ConfirmationBox.jsx msgid "The order will only execute if the price conditions are met and there is sufficient liquidity" msgstr "The order will only execute if the price conditions are met and there is sufficient liquidity" @@ -1817,7 +1829,7 @@ msgstr "GMX Alerts" msgid "{0, plural, one {Pending {symbolsText} approval} other {Pending {symbolsText} approvals}}" msgstr "{0, plural, one {Pending {symbolsText} approval} other {Pending {symbolsText} approvals}}" -#: src/components/Synthetics/TVChart/TVChart.tsx +#: src/context/SyntheticsStateContext/selectors/chartSelectors/selectChartLines.tsx msgid "Open {longOrShortText} {prefix}{tokenSymbol}" msgstr "Open {longOrShortText} {prefix}{tokenSymbol}" @@ -2943,7 +2955,7 @@ msgstr "{col2}" msgid "Decreased {tokenSymbol} {longOrShortText}, -{0} USD." msgstr "Decreased {tokenSymbol} {longOrShortText}, -{0} USD." -#: src/components/Synthetics/TVChart/TVChart.tsx +#: src/context/SyntheticsStateContext/selectors/chartSelectors/selectChartLines.tsx msgid "Liq. {longOrShortText} {prefix}{tokenSymbol}" msgstr "Liq. {longOrShortText} {prefix}{tokenSymbol}" @@ -3241,6 +3253,10 @@ msgstr "The Max Network Fee is set to a higher value to handle potential increas msgid "Start Unrealized PnL" msgstr "Start Unrealized PnL" +#: src/components/TVChartContainer/constants.ts +msgid "Limit - Short Inc." +msgstr "Limit - Short Inc." + #: src/components/Synthetics/MarketStats/components/CompositionTable.tsx msgid "AMOUNT" msgstr "AMOUNT" @@ -3510,6 +3526,10 @@ msgstr "No claims yet" msgid "Select a GLV Vault" msgstr "Select a GLV Vault" +#: src/components/TVChartContainer/DynamicLineComponent.tsx +msgid "Cancel Order" +msgstr "Cancel Order" + #: src/components/Exchange/PositionEditor.jsx #: src/components/Exchange/PositionEditor.jsx #: src/components/Exchange/PositionEditor.jsx @@ -3701,6 +3721,10 @@ msgstr "Buy GLV" msgid "Impact+Fees" msgstr "Impact+Fees" +#: src/components/TVChartContainer/constants.ts +msgid "TP - Short Dec." +msgstr "TP - Short Dec." + #: src/pages/Ecosystem/ecosystemConstants.tsx msgid "Compass Labs GM Token Dashboard" msgstr "Compass Labs GM Token Dashboard" @@ -3887,10 +3911,9 @@ msgstr "Trigger price for the order." #: src/components/Synthetics/TradeBox/tradeboxConstants.tsx #: src/components/Synthetics/TradeHistory/TradeHistoryRow/utils/position.ts #: src/components/Synthetics/TVChart/components/AvailableLiquidityTooltip.tsx -#: src/components/Synthetics/TVChart/TVChart.tsx -#: src/components/Synthetics/TVChart/TVChart.tsx #: src/context/SyntheticsEvents/SyntheticsEventsProvider.tsx #: src/context/SyntheticsEvents/SyntheticsEventsProvider.tsx +#: src/context/SyntheticsStateContext/selectors/chartSelectors/selectChartLines.tsx #: src/domain/synthetics/orders/utils.tsx #: src/pages/Exchange/Exchange.tsx #: src/pages/Exchange/Exchange.tsx @@ -4330,6 +4353,10 @@ msgstr "Take Profit / Stop Loss" msgid "There is not enough {0} in your account on {networkName} to send this transaction.<0/><1/><2>Buy or Transfer {1} to {networkName}" msgstr "There is not enough {0} in your account on {networkName} to send this transaction.<0/><1/><2>Buy or Transfer {1} to {networkName}" +#: src/components/TVChartContainer/constants.ts +msgid "SL - Long Dec." +msgstr "SL - Long Dec." + #: src/components/Synthetics/UserIncentiveDistributionList/UserIncentiveDistributionList.tsx msgid "Airdrop" msgstr "Airdrop" @@ -4529,7 +4556,6 @@ msgid "Max slippage precision is -0.01%" msgstr "Max slippage precision is -0.01%" #: src/components/Exchange/ExchangeTVChart.jsx -#: src/components/Synthetics/TVChart/TVChart.tsx msgid "Dec." msgstr "Dec." @@ -5245,6 +5271,10 @@ msgstr "Last 90d" msgid "There is no liquidation price, as the position's collateral value will increase to cover any negative PnL." msgstr "There is no liquidation price, as the position's collateral value will increase to cover any negative PnL." +#: src/components/TVChartContainer/DynamicLineComponent.tsx +msgid "Edit Order" +msgstr "Edit Order" + #: src/components/MarketSelector/GmPoolsSelectorForGlvMarket.tsx #: src/components/MarketSelector/PoolSelector.tsx msgid "Search Pool" @@ -6221,7 +6251,6 @@ msgstr "" "{2} Price: {3} USD" #: src/components/Exchange/ExchangeTVChart.jsx -#: src/components/Synthetics/TVChart/TVChart.tsx msgid "Inc." msgstr "Inc." @@ -7019,10 +7048,9 @@ msgstr "Shift error." #: src/components/Synthetics/TradeBox/tradeboxConstants.tsx #: src/components/Synthetics/TradeHistory/TradeHistoryRow/utils/position.ts #: src/components/Synthetics/TVChart/components/AvailableLiquidityTooltip.tsx -#: src/components/Synthetics/TVChart/TVChart.tsx -#: src/components/Synthetics/TVChart/TVChart.tsx #: src/context/SyntheticsEvents/SyntheticsEventsProvider.tsx #: src/context/SyntheticsEvents/SyntheticsEventsProvider.tsx +#: src/context/SyntheticsStateContext/selectors/chartSelectors/selectChartLines.tsx #: src/domain/synthetics/orders/utils.tsx #: src/pages/Exchange/Exchange.tsx #: src/pages/Exchange/Exchange.tsx @@ -7765,6 +7793,10 @@ msgstr "Not enough {0} on your Main Account. Use the \"<0>Convert {1} to {2} msgid "Orders ({ordersCount})" msgstr "Orders ({ordersCount})" +#: src/components/TVChartContainer/constants.ts +msgid "Limit - Long Inc." +msgstr "Limit - Long Inc." + #: src/pages/Earn/ClaimModal.tsx msgid "<0>Delegate your undelegated {0} GMX DAOvoting power before claiming." msgstr "<0>Delegate your undelegated {0} GMX DAOvoting power before claiming." diff --git a/src/locales/es/messages.po b/src/locales/es/messages.po index 271887e6f8..28d5d15a1a 100644 --- a/src/locales/es/messages.po +++ b/src/locales/es/messages.po @@ -729,6 +729,10 @@ msgstr "" msgid "Paraswap" msgstr "" +#: src/components/TVChartContainer/constants.ts +msgid "TP - Long Dec." +msgstr "" + #: src/components/Referrals/AffiliatesStats.tsx msgid "Claimable Rebates" msgstr "" @@ -827,6 +831,10 @@ msgstr "" msgid "Code already taken" msgstr "Código ya cogido" +#: src/components/TVChartContainer/constants.ts +msgid "SL - Short Dec." +msgstr "" + #: src/components/SettingsModal/SettingsModal.tsx msgid "Slippage should be less than -5%" msgstr "" @@ -1428,6 +1436,10 @@ msgstr "Falló la creación de la Orden de Intercambio." msgid "Chart positions" msgstr "Posiciones en gráfca" +#: src/components/TVChartContainer/DynamicLineComponent.tsx +msgid "Unknown Order" +msgstr "" + #: src/components/Exchange/ConfirmationBox.jsx msgid "The order will only execute if the price conditions are met and there is sufficient liquidity" msgstr "La orden sólo se ejecutará si las condiciones de precio se alcanzan y hay suficiente liquidez" @@ -1817,7 +1829,7 @@ msgstr "" msgid "{0, plural, one {Pending {symbolsText} approval} other {Pending {symbolsText} approvals}}" msgstr "" -#: src/components/Synthetics/TVChart/TVChart.tsx +#: src/context/SyntheticsStateContext/selectors/chartSelectors/selectChartLines.tsx msgid "Open {longOrShortText} {prefix}{tokenSymbol}" msgstr "" @@ -2943,7 +2955,7 @@ msgstr "" msgid "Decreased {tokenSymbol} {longOrShortText}, -{0} USD." msgstr "Reducido {tokenSymbol} {longOrShortText}, -{0} USD." -#: src/components/Synthetics/TVChart/TVChart.tsx +#: src/context/SyntheticsStateContext/selectors/chartSelectors/selectChartLines.tsx msgid "Liq. {longOrShortText} {prefix}{tokenSymbol}" msgstr "" @@ -3241,6 +3253,10 @@ msgstr "" msgid "Start Unrealized PnL" msgstr "" +#: src/components/TVChartContainer/constants.ts +msgid "Limit - Short Inc." +msgstr "" + #: src/components/Synthetics/MarketStats/components/CompositionTable.tsx msgid "AMOUNT" msgstr "" @@ -3510,6 +3526,10 @@ msgstr "" msgid "Select a GLV Vault" msgstr "" +#: src/components/TVChartContainer/DynamicLineComponent.tsx +msgid "Cancel Order" +msgstr "" + #: src/components/Exchange/PositionEditor.jsx #: src/components/Exchange/PositionEditor.jsx #: src/components/Exchange/PositionEditor.jsx @@ -3701,6 +3721,10 @@ msgstr "" msgid "Impact+Fees" msgstr "" +#: src/components/TVChartContainer/constants.ts +msgid "TP - Short Dec." +msgstr "" + #: src/pages/Ecosystem/ecosystemConstants.tsx msgid "Compass Labs GM Token Dashboard" msgstr "" @@ -3884,10 +3908,9 @@ msgstr "Precio de activación para la orden." #: src/components/Synthetics/TradeBox/tradeboxConstants.tsx #: src/components/Synthetics/TradeHistory/TradeHistoryRow/utils/position.ts #: src/components/Synthetics/TVChart/components/AvailableLiquidityTooltip.tsx -#: src/components/Synthetics/TVChart/TVChart.tsx -#: src/components/Synthetics/TVChart/TVChart.tsx #: src/context/SyntheticsEvents/SyntheticsEventsProvider.tsx #: src/context/SyntheticsEvents/SyntheticsEventsProvider.tsx +#: src/context/SyntheticsStateContext/selectors/chartSelectors/selectChartLines.tsx #: src/domain/synthetics/orders/utils.tsx #: src/pages/Exchange/Exchange.tsx #: src/pages/Exchange/Exchange.tsx @@ -4327,6 +4350,10 @@ msgstr "" msgid "There is not enough {0} in your account on {networkName} to send this transaction.<0/><1/><2>Buy or Transfer {1} to {networkName}" msgstr "" +#: src/components/TVChartContainer/constants.ts +msgid "SL - Long Dec." +msgstr "" + #: src/components/Synthetics/UserIncentiveDistributionList/UserIncentiveDistributionList.tsx msgid "Airdrop" msgstr "" @@ -4526,7 +4553,6 @@ msgid "Max slippage precision is -0.01%" msgstr "" #: src/components/Exchange/ExchangeTVChart.jsx -#: src/components/Synthetics/TVChart/TVChart.tsx msgid "Dec." msgstr "Dic." @@ -5242,6 +5268,10 @@ msgstr "" msgid "There is no liquidation price, as the position's collateral value will increase to cover any negative PnL." msgstr "" +#: src/components/TVChartContainer/DynamicLineComponent.tsx +msgid "Edit Order" +msgstr "" + #: src/components/MarketSelector/GmPoolsSelectorForGlvMarket.tsx #: src/components/MarketSelector/PoolSelector.tsx msgid "Search Pool" @@ -6215,7 +6245,6 @@ msgid "" msgstr "" #: src/components/Exchange/ExchangeTVChart.jsx -#: src/components/Synthetics/TVChart/TVChart.tsx msgid "Inc." msgstr "Inc." @@ -7013,10 +7042,9 @@ msgstr "" #: src/components/Synthetics/TradeBox/tradeboxConstants.tsx #: src/components/Synthetics/TradeHistory/TradeHistoryRow/utils/position.ts #: src/components/Synthetics/TVChart/components/AvailableLiquidityTooltip.tsx -#: src/components/Synthetics/TVChart/TVChart.tsx -#: src/components/Synthetics/TVChart/TVChart.tsx #: src/context/SyntheticsEvents/SyntheticsEventsProvider.tsx #: src/context/SyntheticsEvents/SyntheticsEventsProvider.tsx +#: src/context/SyntheticsStateContext/selectors/chartSelectors/selectChartLines.tsx #: src/domain/synthetics/orders/utils.tsx #: src/pages/Exchange/Exchange.tsx #: src/pages/Exchange/Exchange.tsx @@ -7759,6 +7787,10 @@ msgstr "" msgid "Orders ({ordersCount})" msgstr "" +#: src/components/TVChartContainer/constants.ts +msgid "Limit - Long Inc." +msgstr "" + #: src/pages/Earn/ClaimModal.tsx msgid "<0>Delegate your undelegated {0} GMX DAOvoting power before claiming." msgstr "" diff --git a/src/locales/fr/messages.po b/src/locales/fr/messages.po index b652155d9b..888a3480e9 100644 --- a/src/locales/fr/messages.po +++ b/src/locales/fr/messages.po @@ -729,6 +729,10 @@ msgstr "" msgid "Paraswap" msgstr "" +#: src/components/TVChartContainer/constants.ts +msgid "TP - Long Dec." +msgstr "" + #: src/components/Referrals/AffiliatesStats.tsx msgid "Claimable Rebates" msgstr "" @@ -827,6 +831,10 @@ msgstr "" msgid "Code already taken" msgstr "Code déjà pris" +#: src/components/TVChartContainer/constants.ts +msgid "SL - Short Dec." +msgstr "" + #: src/components/SettingsModal/SettingsModal.tsx msgid "Slippage should be less than -5%" msgstr "" @@ -1428,6 +1436,10 @@ msgstr "Ordre d'échange échoué." msgid "Chart positions" msgstr "Positions sur les graphiques" +#: src/components/TVChartContainer/DynamicLineComponent.tsx +msgid "Unknown Order" +msgstr "" + #: src/components/Exchange/ConfirmationBox.jsx msgid "The order will only execute if the price conditions are met and there is sufficient liquidity" msgstr "L'ordre ne sera exécuté que si les conditions de prix sont remplies et si la liquidité est suffisante." @@ -1817,7 +1829,7 @@ msgstr "" msgid "{0, plural, one {Pending {symbolsText} approval} other {Pending {symbolsText} approvals}}" msgstr "" -#: src/components/Synthetics/TVChart/TVChart.tsx +#: src/context/SyntheticsStateContext/selectors/chartSelectors/selectChartLines.tsx msgid "Open {longOrShortText} {prefix}{tokenSymbol}" msgstr "" @@ -2943,7 +2955,7 @@ msgstr "" msgid "Decreased {tokenSymbol} {longOrShortText}, -{0} USD." msgstr "{tokenSymbol} {longOrShortText} diminué, -{0} USD." -#: src/components/Synthetics/TVChart/TVChart.tsx +#: src/context/SyntheticsStateContext/selectors/chartSelectors/selectChartLines.tsx msgid "Liq. {longOrShortText} {prefix}{tokenSymbol}" msgstr "" @@ -3241,6 +3253,10 @@ msgstr "" msgid "Start Unrealized PnL" msgstr "" +#: src/components/TVChartContainer/constants.ts +msgid "Limit - Short Inc." +msgstr "" + #: src/components/Synthetics/MarketStats/components/CompositionTable.tsx msgid "AMOUNT" msgstr "" @@ -3510,6 +3526,10 @@ msgstr "" msgid "Select a GLV Vault" msgstr "" +#: src/components/TVChartContainer/DynamicLineComponent.tsx +msgid "Cancel Order" +msgstr "" + #: src/components/Exchange/PositionEditor.jsx #: src/components/Exchange/PositionEditor.jsx #: src/components/Exchange/PositionEditor.jsx @@ -3701,6 +3721,10 @@ msgstr "" msgid "Impact+Fees" msgstr "" +#: src/components/TVChartContainer/constants.ts +msgid "TP - Short Dec." +msgstr "" + #: src/pages/Ecosystem/ecosystemConstants.tsx msgid "Compass Labs GM Token Dashboard" msgstr "" @@ -3884,10 +3908,9 @@ msgstr "Prix de déclenchement pour l'ordre." #: src/components/Synthetics/TradeBox/tradeboxConstants.tsx #: src/components/Synthetics/TradeHistory/TradeHistoryRow/utils/position.ts #: src/components/Synthetics/TVChart/components/AvailableLiquidityTooltip.tsx -#: src/components/Synthetics/TVChart/TVChart.tsx -#: src/components/Synthetics/TVChart/TVChart.tsx #: src/context/SyntheticsEvents/SyntheticsEventsProvider.tsx #: src/context/SyntheticsEvents/SyntheticsEventsProvider.tsx +#: src/context/SyntheticsStateContext/selectors/chartSelectors/selectChartLines.tsx #: src/domain/synthetics/orders/utils.tsx #: src/pages/Exchange/Exchange.tsx #: src/pages/Exchange/Exchange.tsx @@ -4327,6 +4350,10 @@ msgstr "" msgid "There is not enough {0} in your account on {networkName} to send this transaction.<0/><1/><2>Buy or Transfer {1} to {networkName}" msgstr "" +#: src/components/TVChartContainer/constants.ts +msgid "SL - Long Dec." +msgstr "" + #: src/components/Synthetics/UserIncentiveDistributionList/UserIncentiveDistributionList.tsx msgid "Airdrop" msgstr "" @@ -4526,7 +4553,6 @@ msgid "Max slippage precision is -0.01%" msgstr "" #: src/components/Exchange/ExchangeTVChart.jsx -#: src/components/Synthetics/TVChart/TVChart.tsx msgid "Dec." msgstr "Dec." @@ -5242,6 +5268,10 @@ msgstr "" msgid "There is no liquidation price, as the position's collateral value will increase to cover any negative PnL." msgstr "" +#: src/components/TVChartContainer/DynamicLineComponent.tsx +msgid "Edit Order" +msgstr "" + #: src/components/MarketSelector/GmPoolsSelectorForGlvMarket.tsx #: src/components/MarketSelector/PoolSelector.tsx msgid "Search Pool" @@ -6215,7 +6245,6 @@ msgid "" msgstr "" #: src/components/Exchange/ExchangeTVChart.jsx -#: src/components/Synthetics/TVChart/TVChart.tsx msgid "Inc." msgstr "Inc." @@ -7013,10 +7042,9 @@ msgstr "" #: src/components/Synthetics/TradeBox/tradeboxConstants.tsx #: src/components/Synthetics/TradeHistory/TradeHistoryRow/utils/position.ts #: src/components/Synthetics/TVChart/components/AvailableLiquidityTooltip.tsx -#: src/components/Synthetics/TVChart/TVChart.tsx -#: src/components/Synthetics/TVChart/TVChart.tsx #: src/context/SyntheticsEvents/SyntheticsEventsProvider.tsx #: src/context/SyntheticsEvents/SyntheticsEventsProvider.tsx +#: src/context/SyntheticsStateContext/selectors/chartSelectors/selectChartLines.tsx #: src/domain/synthetics/orders/utils.tsx #: src/pages/Exchange/Exchange.tsx #: src/pages/Exchange/Exchange.tsx @@ -7759,6 +7787,10 @@ msgstr "" msgid "Orders ({ordersCount})" msgstr "" +#: src/components/TVChartContainer/constants.ts +msgid "Limit - Long Inc." +msgstr "" + #: src/pages/Earn/ClaimModal.tsx msgid "<0>Delegate your undelegated {0} GMX DAOvoting power before claiming." msgstr "" diff --git a/src/locales/ja/messages.po b/src/locales/ja/messages.po index d94545032b..9e235747e8 100644 --- a/src/locales/ja/messages.po +++ b/src/locales/ja/messages.po @@ -729,6 +729,10 @@ msgstr "" msgid "Paraswap" msgstr "" +#: src/components/TVChartContainer/constants.ts +msgid "TP - Long Dec." +msgstr "" + #: src/components/Referrals/AffiliatesStats.tsx msgid "Claimable Rebates" msgstr "" @@ -827,6 +831,10 @@ msgstr "" msgid "Code already taken" msgstr "そのコードは既に使用されています" +#: src/components/TVChartContainer/constants.ts +msgid "SL - Short Dec." +msgstr "" + #: src/components/SettingsModal/SettingsModal.tsx msgid "Slippage should be less than -5%" msgstr "" @@ -1428,6 +1436,10 @@ msgstr "スワップ注文が作成できませんでした。" msgid "Chart positions" msgstr "ポジションをチャートに" +#: src/components/TVChartContainer/DynamicLineComponent.tsx +msgid "Unknown Order" +msgstr "" + #: src/components/Exchange/ConfirmationBox.jsx msgid "The order will only execute if the price conditions are met and there is sufficient liquidity" msgstr "価格の条件が満たされ、さらに十分な流動性が存在している場合にのみ注文は執行されます。" @@ -1817,7 +1829,7 @@ msgstr "" msgid "{0, plural, one {Pending {symbolsText} approval} other {Pending {symbolsText} approvals}}" msgstr "" -#: src/components/Synthetics/TVChart/TVChart.tsx +#: src/context/SyntheticsStateContext/selectors/chartSelectors/selectChartLines.tsx msgid "Open {longOrShortText} {prefix}{tokenSymbol}" msgstr "" @@ -2943,7 +2955,7 @@ msgstr "" msgid "Decreased {tokenSymbol} {longOrShortText}, -{0} USD." msgstr "{tokenSymbol} {longOrShortText}の減額 -{0} USD" -#: src/components/Synthetics/TVChart/TVChart.tsx +#: src/context/SyntheticsStateContext/selectors/chartSelectors/selectChartLines.tsx msgid "Liq. {longOrShortText} {prefix}{tokenSymbol}" msgstr "" @@ -3241,6 +3253,10 @@ msgstr "" msgid "Start Unrealized PnL" msgstr "" +#: src/components/TVChartContainer/constants.ts +msgid "Limit - Short Inc." +msgstr "" + #: src/components/Synthetics/MarketStats/components/CompositionTable.tsx msgid "AMOUNT" msgstr "" @@ -3510,6 +3526,10 @@ msgstr "" msgid "Select a GLV Vault" msgstr "" +#: src/components/TVChartContainer/DynamicLineComponent.tsx +msgid "Cancel Order" +msgstr "" + #: src/components/Exchange/PositionEditor.jsx #: src/components/Exchange/PositionEditor.jsx #: src/components/Exchange/PositionEditor.jsx @@ -3701,6 +3721,10 @@ msgstr "" msgid "Impact+Fees" msgstr "" +#: src/components/TVChartContainer/constants.ts +msgid "TP - Short Dec." +msgstr "" + #: src/pages/Ecosystem/ecosystemConstants.tsx msgid "Compass Labs GM Token Dashboard" msgstr "" @@ -3884,10 +3908,9 @@ msgstr "注文のトリガー価格" #: src/components/Synthetics/TradeBox/tradeboxConstants.tsx #: src/components/Synthetics/TradeHistory/TradeHistoryRow/utils/position.ts #: src/components/Synthetics/TVChart/components/AvailableLiquidityTooltip.tsx -#: src/components/Synthetics/TVChart/TVChart.tsx -#: src/components/Synthetics/TVChart/TVChart.tsx #: src/context/SyntheticsEvents/SyntheticsEventsProvider.tsx #: src/context/SyntheticsEvents/SyntheticsEventsProvider.tsx +#: src/context/SyntheticsStateContext/selectors/chartSelectors/selectChartLines.tsx #: src/domain/synthetics/orders/utils.tsx #: src/pages/Exchange/Exchange.tsx #: src/pages/Exchange/Exchange.tsx @@ -4327,6 +4350,10 @@ msgstr "" msgid "There is not enough {0} in your account on {networkName} to send this transaction.<0/><1/><2>Buy or Transfer {1} to {networkName}" msgstr "" +#: src/components/TVChartContainer/constants.ts +msgid "SL - Long Dec." +msgstr "" + #: src/components/Synthetics/UserIncentiveDistributionList/UserIncentiveDistributionList.tsx msgid "Airdrop" msgstr "" @@ -4526,7 +4553,6 @@ msgid "Max slippage precision is -0.01%" msgstr "" #: src/components/Exchange/ExchangeTVChart.jsx -#: src/components/Synthetics/TVChart/TVChart.tsx msgid "Dec." msgstr "12月" @@ -5242,6 +5268,10 @@ msgstr "" msgid "There is no liquidation price, as the position's collateral value will increase to cover any negative PnL." msgstr "" +#: src/components/TVChartContainer/DynamicLineComponent.tsx +msgid "Edit Order" +msgstr "" + #: src/components/MarketSelector/GmPoolsSelectorForGlvMarket.tsx #: src/components/MarketSelector/PoolSelector.tsx msgid "Search Pool" @@ -6215,7 +6245,6 @@ msgid "" msgstr "" #: src/components/Exchange/ExchangeTVChart.jsx -#: src/components/Synthetics/TVChart/TVChart.tsx msgid "Inc." msgstr "含む" @@ -7013,10 +7042,9 @@ msgstr "" #: src/components/Synthetics/TradeBox/tradeboxConstants.tsx #: src/components/Synthetics/TradeHistory/TradeHistoryRow/utils/position.ts #: src/components/Synthetics/TVChart/components/AvailableLiquidityTooltip.tsx -#: src/components/Synthetics/TVChart/TVChart.tsx -#: src/components/Synthetics/TVChart/TVChart.tsx #: src/context/SyntheticsEvents/SyntheticsEventsProvider.tsx #: src/context/SyntheticsEvents/SyntheticsEventsProvider.tsx +#: src/context/SyntheticsStateContext/selectors/chartSelectors/selectChartLines.tsx #: src/domain/synthetics/orders/utils.tsx #: src/pages/Exchange/Exchange.tsx #: src/pages/Exchange/Exchange.tsx @@ -7759,6 +7787,10 @@ msgstr "" msgid "Orders ({ordersCount})" msgstr "" +#: src/components/TVChartContainer/constants.ts +msgid "Limit - Long Inc." +msgstr "" + #: src/pages/Earn/ClaimModal.tsx msgid "<0>Delegate your undelegated {0} GMX DAOvoting power before claiming." msgstr "" diff --git a/src/locales/ko/messages.po b/src/locales/ko/messages.po index 1889e772ca..109a7c2589 100644 --- a/src/locales/ko/messages.po +++ b/src/locales/ko/messages.po @@ -729,6 +729,10 @@ msgstr "" msgid "Paraswap" msgstr "" +#: src/components/TVChartContainer/constants.ts +msgid "TP - Long Dec." +msgstr "" + #: src/components/Referrals/AffiliatesStats.tsx msgid "Claimable Rebates" msgstr "" @@ -827,6 +831,10 @@ msgstr "" msgid "Code already taken" msgstr "이미 사용된 코드입니다" +#: src/components/TVChartContainer/constants.ts +msgid "SL - Short Dec." +msgstr "" + #: src/components/SettingsModal/SettingsModal.tsx msgid "Slippage should be less than -5%" msgstr "" @@ -1428,6 +1436,10 @@ msgstr "스왑 주문 생성 실패." msgid "Chart positions" msgstr "차트 포지션" +#: src/components/TVChartContainer/DynamicLineComponent.tsx +msgid "Unknown Order" +msgstr "" + #: src/components/Exchange/ConfirmationBox.jsx msgid "The order will only execute if the price conditions are met and there is sufficient liquidity" msgstr "주문은 가격 조건 및 유동성 충분 요건이 만족하는 경우에만 실행됩니다" @@ -1817,7 +1829,7 @@ msgstr "" msgid "{0, plural, one {Pending {symbolsText} approval} other {Pending {symbolsText} approvals}}" msgstr "" -#: src/components/Synthetics/TVChart/TVChart.tsx +#: src/context/SyntheticsStateContext/selectors/chartSelectors/selectChartLines.tsx msgid "Open {longOrShortText} {prefix}{tokenSymbol}" msgstr "" @@ -2943,7 +2955,7 @@ msgstr "" msgid "Decreased {tokenSymbol} {longOrShortText}, -{0} USD." msgstr "{tokenSymbol} {longOrShortText} 감소, -{0} USD." -#: src/components/Synthetics/TVChart/TVChart.tsx +#: src/context/SyntheticsStateContext/selectors/chartSelectors/selectChartLines.tsx msgid "Liq. {longOrShortText} {prefix}{tokenSymbol}" msgstr "" @@ -3241,6 +3253,10 @@ msgstr "" msgid "Start Unrealized PnL" msgstr "" +#: src/components/TVChartContainer/constants.ts +msgid "Limit - Short Inc." +msgstr "" + #: src/components/Synthetics/MarketStats/components/CompositionTable.tsx msgid "AMOUNT" msgstr "" @@ -3510,6 +3526,10 @@ msgstr "" msgid "Select a GLV Vault" msgstr "" +#: src/components/TVChartContainer/DynamicLineComponent.tsx +msgid "Cancel Order" +msgstr "" + #: src/components/Exchange/PositionEditor.jsx #: src/components/Exchange/PositionEditor.jsx #: src/components/Exchange/PositionEditor.jsx @@ -3701,6 +3721,10 @@ msgstr "" msgid "Impact+Fees" msgstr "" +#: src/components/TVChartContainer/constants.ts +msgid "TP - Short Dec." +msgstr "" + #: src/pages/Ecosystem/ecosystemConstants.tsx msgid "Compass Labs GM Token Dashboard" msgstr "" @@ -3884,10 +3908,9 @@ msgstr "주문의 트리거 가격입니다." #: src/components/Synthetics/TradeBox/tradeboxConstants.tsx #: src/components/Synthetics/TradeHistory/TradeHistoryRow/utils/position.ts #: src/components/Synthetics/TVChart/components/AvailableLiquidityTooltip.tsx -#: src/components/Synthetics/TVChart/TVChart.tsx -#: src/components/Synthetics/TVChart/TVChart.tsx #: src/context/SyntheticsEvents/SyntheticsEventsProvider.tsx #: src/context/SyntheticsEvents/SyntheticsEventsProvider.tsx +#: src/context/SyntheticsStateContext/selectors/chartSelectors/selectChartLines.tsx #: src/domain/synthetics/orders/utils.tsx #: src/pages/Exchange/Exchange.tsx #: src/pages/Exchange/Exchange.tsx @@ -4327,6 +4350,10 @@ msgstr "" msgid "There is not enough {0} in your account on {networkName} to send this transaction.<0/><1/><2>Buy or Transfer {1} to {networkName}" msgstr "" +#: src/components/TVChartContainer/constants.ts +msgid "SL - Long Dec." +msgstr "" + #: src/components/Synthetics/UserIncentiveDistributionList/UserIncentiveDistributionList.tsx msgid "Airdrop" msgstr "" @@ -4526,7 +4553,6 @@ msgid "Max slippage precision is -0.01%" msgstr "" #: src/components/Exchange/ExchangeTVChart.jsx -#: src/components/Synthetics/TVChart/TVChart.tsx msgid "Dec." msgstr "12월" @@ -5242,6 +5268,10 @@ msgstr "" msgid "There is no liquidation price, as the position's collateral value will increase to cover any negative PnL." msgstr "" +#: src/components/TVChartContainer/DynamicLineComponent.tsx +msgid "Edit Order" +msgstr "" + #: src/components/MarketSelector/GmPoolsSelectorForGlvMarket.tsx #: src/components/MarketSelector/PoolSelector.tsx msgid "Search Pool" @@ -6215,7 +6245,6 @@ msgid "" msgstr "" #: src/components/Exchange/ExchangeTVChart.jsx -#: src/components/Synthetics/TVChart/TVChart.tsx msgid "Inc." msgstr "Inc." @@ -7013,10 +7042,9 @@ msgstr "" #: src/components/Synthetics/TradeBox/tradeboxConstants.tsx #: src/components/Synthetics/TradeHistory/TradeHistoryRow/utils/position.ts #: src/components/Synthetics/TVChart/components/AvailableLiquidityTooltip.tsx -#: src/components/Synthetics/TVChart/TVChart.tsx -#: src/components/Synthetics/TVChart/TVChart.tsx #: src/context/SyntheticsEvents/SyntheticsEventsProvider.tsx #: src/context/SyntheticsEvents/SyntheticsEventsProvider.tsx +#: src/context/SyntheticsStateContext/selectors/chartSelectors/selectChartLines.tsx #: src/domain/synthetics/orders/utils.tsx #: src/pages/Exchange/Exchange.tsx #: src/pages/Exchange/Exchange.tsx @@ -7759,6 +7787,10 @@ msgstr "" msgid "Orders ({ordersCount})" msgstr "" +#: src/components/TVChartContainer/constants.ts +msgid "Limit - Long Inc." +msgstr "" + #: src/pages/Earn/ClaimModal.tsx msgid "<0>Delegate your undelegated {0} GMX DAOvoting power before claiming." msgstr "" diff --git a/src/locales/pseudo/messages.po b/src/locales/pseudo/messages.po index a0cdd54e5e..ab6091499e 100644 --- a/src/locales/pseudo/messages.po +++ b/src/locales/pseudo/messages.po @@ -729,6 +729,10 @@ msgstr "" msgid "Paraswap" msgstr "" +#: src/components/TVChartContainer/constants.ts +msgid "TP - Long Dec." +msgstr "" + #: src/components/Referrals/AffiliatesStats.tsx msgid "Claimable Rebates" msgstr "" @@ -827,6 +831,10 @@ msgstr "" msgid "Code already taken" msgstr "" +#: src/components/TVChartContainer/constants.ts +msgid "SL - Short Dec." +msgstr "" + #: src/components/SettingsModal/SettingsModal.tsx msgid "Slippage should be less than -5%" msgstr "" @@ -1428,6 +1436,10 @@ msgstr "" msgid "Chart positions" msgstr "" +#: src/components/TVChartContainer/DynamicLineComponent.tsx +msgid "Unknown Order" +msgstr "" + #: src/components/Exchange/ConfirmationBox.jsx msgid "The order will only execute if the price conditions are met and there is sufficient liquidity" msgstr "" @@ -1817,7 +1829,7 @@ msgstr "" msgid "{0, plural, one {Pending {symbolsText} approval} other {Pending {symbolsText} approvals}}" msgstr "" -#: src/components/Synthetics/TVChart/TVChart.tsx +#: src/context/SyntheticsStateContext/selectors/chartSelectors/selectChartLines.tsx msgid "Open {longOrShortText} {prefix}{tokenSymbol}" msgstr "" @@ -2943,7 +2955,7 @@ msgstr "" msgid "Decreased {tokenSymbol} {longOrShortText}, -{0} USD." msgstr "" -#: src/components/Synthetics/TVChart/TVChart.tsx +#: src/context/SyntheticsStateContext/selectors/chartSelectors/selectChartLines.tsx msgid "Liq. {longOrShortText} {prefix}{tokenSymbol}" msgstr "" @@ -3241,6 +3253,10 @@ msgstr "" msgid "Start Unrealized PnL" msgstr "" +#: src/components/TVChartContainer/constants.ts +msgid "Limit - Short Inc." +msgstr "" + #: src/components/Synthetics/MarketStats/components/CompositionTable.tsx msgid "AMOUNT" msgstr "" @@ -3510,6 +3526,10 @@ msgstr "" msgid "Select a GLV Vault" msgstr "" +#: src/components/TVChartContainer/DynamicLineComponent.tsx +msgid "Cancel Order" +msgstr "" + #: src/components/Exchange/PositionEditor.jsx #: src/components/Exchange/PositionEditor.jsx #: src/components/Exchange/PositionEditor.jsx @@ -3701,6 +3721,10 @@ msgstr "" msgid "Impact+Fees" msgstr "" +#: src/components/TVChartContainer/constants.ts +msgid "TP - Short Dec." +msgstr "" + #: src/pages/Ecosystem/ecosystemConstants.tsx msgid "Compass Labs GM Token Dashboard" msgstr "" @@ -3884,10 +3908,9 @@ msgstr "" #: src/components/Synthetics/TradeBox/tradeboxConstants.tsx #: src/components/Synthetics/TradeHistory/TradeHistoryRow/utils/position.ts #: src/components/Synthetics/TVChart/components/AvailableLiquidityTooltip.tsx -#: src/components/Synthetics/TVChart/TVChart.tsx -#: src/components/Synthetics/TVChart/TVChart.tsx #: src/context/SyntheticsEvents/SyntheticsEventsProvider.tsx #: src/context/SyntheticsEvents/SyntheticsEventsProvider.tsx +#: src/context/SyntheticsStateContext/selectors/chartSelectors/selectChartLines.tsx #: src/domain/synthetics/orders/utils.tsx #: src/pages/Exchange/Exchange.tsx #: src/pages/Exchange/Exchange.tsx @@ -4327,6 +4350,10 @@ msgstr "" msgid "There is not enough {0} in your account on {networkName} to send this transaction.<0/><1/><2>Buy or Transfer {1} to {networkName}" msgstr "" +#: src/components/TVChartContainer/constants.ts +msgid "SL - Long Dec." +msgstr "" + #: src/components/Synthetics/UserIncentiveDistributionList/UserIncentiveDistributionList.tsx msgid "Airdrop" msgstr "" @@ -4526,7 +4553,6 @@ msgid "Max slippage precision is -0.01%" msgstr "" #: src/components/Exchange/ExchangeTVChart.jsx -#: src/components/Synthetics/TVChart/TVChart.tsx msgid "Dec." msgstr "" @@ -5242,6 +5268,10 @@ msgstr "" msgid "There is no liquidation price, as the position's collateral value will increase to cover any negative PnL." msgstr "" +#: src/components/TVChartContainer/DynamicLineComponent.tsx +msgid "Edit Order" +msgstr "" + #: src/components/MarketSelector/GmPoolsSelectorForGlvMarket.tsx #: src/components/MarketSelector/PoolSelector.tsx msgid "Search Pool" @@ -6215,7 +6245,6 @@ msgid "" msgstr "" #: src/components/Exchange/ExchangeTVChart.jsx -#: src/components/Synthetics/TVChart/TVChart.tsx msgid "Inc." msgstr "" @@ -7013,10 +7042,9 @@ msgstr "" #: src/components/Synthetics/TradeBox/tradeboxConstants.tsx #: src/components/Synthetics/TradeHistory/TradeHistoryRow/utils/position.ts #: src/components/Synthetics/TVChart/components/AvailableLiquidityTooltip.tsx -#: src/components/Synthetics/TVChart/TVChart.tsx -#: src/components/Synthetics/TVChart/TVChart.tsx #: src/context/SyntheticsEvents/SyntheticsEventsProvider.tsx #: src/context/SyntheticsEvents/SyntheticsEventsProvider.tsx +#: src/context/SyntheticsStateContext/selectors/chartSelectors/selectChartLines.tsx #: src/domain/synthetics/orders/utils.tsx #: src/pages/Exchange/Exchange.tsx #: src/pages/Exchange/Exchange.tsx @@ -7759,6 +7787,10 @@ msgstr "" msgid "Orders ({ordersCount})" msgstr "" +#: src/components/TVChartContainer/constants.ts +msgid "Limit - Long Inc." +msgstr "" + #: src/pages/Earn/ClaimModal.tsx msgid "<0>Delegate your undelegated {0} GMX DAOvoting power before claiming." msgstr "" diff --git a/src/locales/ru/messages.po b/src/locales/ru/messages.po index 77dc96fb12..36502234e4 100644 --- a/src/locales/ru/messages.po +++ b/src/locales/ru/messages.po @@ -729,6 +729,10 @@ msgstr "" msgid "Paraswap" msgstr "" +#: src/components/TVChartContainer/constants.ts +msgid "TP - Long Dec." +msgstr "" + #: src/components/Referrals/AffiliatesStats.tsx msgid "Claimable Rebates" msgstr "" @@ -827,6 +831,10 @@ msgstr "" msgid "Code already taken" msgstr "Код уже занят" +#: src/components/TVChartContainer/constants.ts +msgid "SL - Short Dec." +msgstr "" + #: src/components/SettingsModal/SettingsModal.tsx msgid "Slippage should be less than -5%" msgstr "" @@ -1428,6 +1436,10 @@ msgstr "Обменный Ордер не создан" msgid "Chart positions" msgstr "Позиции на графике" +#: src/components/TVChartContainer/DynamicLineComponent.tsx +msgid "Unknown Order" +msgstr "" + #: src/components/Exchange/ConfirmationBox.jsx msgid "The order will only execute if the price conditions are met and there is sufficient liquidity" msgstr "" @@ -1817,7 +1829,7 @@ msgstr "" msgid "{0, plural, one {Pending {symbolsText} approval} other {Pending {symbolsText} approvals}}" msgstr "" -#: src/components/Synthetics/TVChart/TVChart.tsx +#: src/context/SyntheticsStateContext/selectors/chartSelectors/selectChartLines.tsx msgid "Open {longOrShortText} {prefix}{tokenSymbol}" msgstr "" @@ -2943,7 +2955,7 @@ msgstr "" msgid "Decreased {tokenSymbol} {longOrShortText}, -{0} USD." msgstr "Уменьшено {tokenSymbol} {longOrShortText}, -{0} USD." -#: src/components/Synthetics/TVChart/TVChart.tsx +#: src/context/SyntheticsStateContext/selectors/chartSelectors/selectChartLines.tsx msgid "Liq. {longOrShortText} {prefix}{tokenSymbol}" msgstr "" @@ -3241,6 +3253,10 @@ msgstr "" msgid "Start Unrealized PnL" msgstr "" +#: src/components/TVChartContainer/constants.ts +msgid "Limit - Short Inc." +msgstr "" + #: src/components/Synthetics/MarketStats/components/CompositionTable.tsx msgid "AMOUNT" msgstr "" @@ -3510,6 +3526,10 @@ msgstr "" msgid "Select a GLV Vault" msgstr "" +#: src/components/TVChartContainer/DynamicLineComponent.tsx +msgid "Cancel Order" +msgstr "" + #: src/components/Exchange/PositionEditor.jsx #: src/components/Exchange/PositionEditor.jsx #: src/components/Exchange/PositionEditor.jsx @@ -3701,6 +3721,10 @@ msgstr "" msgid "Impact+Fees" msgstr "" +#: src/components/TVChartContainer/constants.ts +msgid "TP - Short Dec." +msgstr "" + #: src/pages/Ecosystem/ecosystemConstants.tsx msgid "Compass Labs GM Token Dashboard" msgstr "" @@ -3884,10 +3908,9 @@ msgstr "Цена триггера для ордера." #: src/components/Synthetics/TradeBox/tradeboxConstants.tsx #: src/components/Synthetics/TradeHistory/TradeHistoryRow/utils/position.ts #: src/components/Synthetics/TVChart/components/AvailableLiquidityTooltip.tsx -#: src/components/Synthetics/TVChart/TVChart.tsx -#: src/components/Synthetics/TVChart/TVChart.tsx #: src/context/SyntheticsEvents/SyntheticsEventsProvider.tsx #: src/context/SyntheticsEvents/SyntheticsEventsProvider.tsx +#: src/context/SyntheticsStateContext/selectors/chartSelectors/selectChartLines.tsx #: src/domain/synthetics/orders/utils.tsx #: src/pages/Exchange/Exchange.tsx #: src/pages/Exchange/Exchange.tsx @@ -4327,6 +4350,10 @@ msgstr "" msgid "There is not enough {0} in your account on {networkName} to send this transaction.<0/><1/><2>Buy or Transfer {1} to {networkName}" msgstr "" +#: src/components/TVChartContainer/constants.ts +msgid "SL - Long Dec." +msgstr "" + #: src/components/Synthetics/UserIncentiveDistributionList/UserIncentiveDistributionList.tsx msgid "Airdrop" msgstr "" @@ -4526,7 +4553,6 @@ msgid "Max slippage precision is -0.01%" msgstr "" #: src/components/Exchange/ExchangeTVChart.jsx -#: src/components/Synthetics/TVChart/TVChart.tsx msgid "Dec." msgstr "Дец." @@ -5242,6 +5268,10 @@ msgstr "" msgid "There is no liquidation price, as the position's collateral value will increase to cover any negative PnL." msgstr "" +#: src/components/TVChartContainer/DynamicLineComponent.tsx +msgid "Edit Order" +msgstr "" + #: src/components/MarketSelector/GmPoolsSelectorForGlvMarket.tsx #: src/components/MarketSelector/PoolSelector.tsx msgid "Search Pool" @@ -6215,7 +6245,6 @@ msgid "" msgstr "" #: src/components/Exchange/ExchangeTVChart.jsx -#: src/components/Synthetics/TVChart/TVChart.tsx msgid "Inc." msgstr "Инк." @@ -7013,10 +7042,9 @@ msgstr "" #: src/components/Synthetics/TradeBox/tradeboxConstants.tsx #: src/components/Synthetics/TradeHistory/TradeHistoryRow/utils/position.ts #: src/components/Synthetics/TVChart/components/AvailableLiquidityTooltip.tsx -#: src/components/Synthetics/TVChart/TVChart.tsx -#: src/components/Synthetics/TVChart/TVChart.tsx #: src/context/SyntheticsEvents/SyntheticsEventsProvider.tsx #: src/context/SyntheticsEvents/SyntheticsEventsProvider.tsx +#: src/context/SyntheticsStateContext/selectors/chartSelectors/selectChartLines.tsx #: src/domain/synthetics/orders/utils.tsx #: src/pages/Exchange/Exchange.tsx #: src/pages/Exchange/Exchange.tsx @@ -7759,6 +7787,10 @@ msgstr "" msgid "Orders ({ordersCount})" msgstr "" +#: src/components/TVChartContainer/constants.ts +msgid "Limit - Long Inc." +msgstr "" + #: src/pages/Earn/ClaimModal.tsx msgid "<0>Delegate your undelegated {0} GMX DAOvoting power before claiming." msgstr "" diff --git a/src/locales/zh/messages.po b/src/locales/zh/messages.po index 97c189274f..f5a71e7d4f 100644 --- a/src/locales/zh/messages.po +++ b/src/locales/zh/messages.po @@ -729,6 +729,10 @@ msgstr "" msgid "Paraswap" msgstr "" +#: src/components/TVChartContainer/constants.ts +msgid "TP - Long Dec." +msgstr "" + #: src/components/Referrals/AffiliatesStats.tsx msgid "Claimable Rebates" msgstr "" @@ -827,6 +831,10 @@ msgstr "" msgid "Code already taken" msgstr "已采取的代码" +#: src/components/TVChartContainer/constants.ts +msgid "SL - Short Dec." +msgstr "" + #: src/components/SettingsModal/SettingsModal.tsx msgid "Slippage should be less than -5%" msgstr "" @@ -1428,6 +1436,10 @@ msgstr "创建交易订单失败" msgid "Chart positions" msgstr "图表位置" +#: src/components/TVChartContainer/DynamicLineComponent.tsx +msgid "Unknown Order" +msgstr "" + #: src/components/Exchange/ConfirmationBox.jsx msgid "The order will only execute if the price conditions are met and there is sufficient liquidity" msgstr "该订单只在满足价格条件并有足够的流动性时才会执行" @@ -1817,7 +1829,7 @@ msgstr "" msgid "{0, plural, one {Pending {symbolsText} approval} other {Pending {symbolsText} approvals}}" msgstr "" -#: src/components/Synthetics/TVChart/TVChart.tsx +#: src/context/SyntheticsStateContext/selectors/chartSelectors/selectChartLines.tsx msgid "Open {longOrShortText} {prefix}{tokenSymbol}" msgstr "" @@ -2943,7 +2955,7 @@ msgstr "" msgid "Decreased {tokenSymbol} {longOrShortText}, -{0} USD." msgstr "已减少{tokenSymbol} {longOrShortText}, -{0} USD" -#: src/components/Synthetics/TVChart/TVChart.tsx +#: src/context/SyntheticsStateContext/selectors/chartSelectors/selectChartLines.tsx msgid "Liq. {longOrShortText} {prefix}{tokenSymbol}" msgstr "" @@ -3241,6 +3253,10 @@ msgstr "" msgid "Start Unrealized PnL" msgstr "" +#: src/components/TVChartContainer/constants.ts +msgid "Limit - Short Inc." +msgstr "" + #: src/components/Synthetics/MarketStats/components/CompositionTable.tsx msgid "AMOUNT" msgstr "" @@ -3510,6 +3526,10 @@ msgstr "" msgid "Select a GLV Vault" msgstr "" +#: src/components/TVChartContainer/DynamicLineComponent.tsx +msgid "Cancel Order" +msgstr "" + #: src/components/Exchange/PositionEditor.jsx #: src/components/Exchange/PositionEditor.jsx #: src/components/Exchange/PositionEditor.jsx @@ -3701,6 +3721,10 @@ msgstr "" msgid "Impact+Fees" msgstr "" +#: src/components/TVChartContainer/constants.ts +msgid "TP - Short Dec." +msgstr "" + #: src/pages/Ecosystem/ecosystemConstants.tsx msgid "Compass Labs GM Token Dashboard" msgstr "" @@ -3884,10 +3908,9 @@ msgstr "订单的触发价格" #: src/components/Synthetics/TradeBox/tradeboxConstants.tsx #: src/components/Synthetics/TradeHistory/TradeHistoryRow/utils/position.ts #: src/components/Synthetics/TVChart/components/AvailableLiquidityTooltip.tsx -#: src/components/Synthetics/TVChart/TVChart.tsx -#: src/components/Synthetics/TVChart/TVChart.tsx #: src/context/SyntheticsEvents/SyntheticsEventsProvider.tsx #: src/context/SyntheticsEvents/SyntheticsEventsProvider.tsx +#: src/context/SyntheticsStateContext/selectors/chartSelectors/selectChartLines.tsx #: src/domain/synthetics/orders/utils.tsx #: src/pages/Exchange/Exchange.tsx #: src/pages/Exchange/Exchange.tsx @@ -4327,6 +4350,10 @@ msgstr "" msgid "There is not enough {0} in your account on {networkName} to send this transaction.<0/><1/><2>Buy or Transfer {1} to {networkName}" msgstr "" +#: src/components/TVChartContainer/constants.ts +msgid "SL - Long Dec." +msgstr "" + #: src/components/Synthetics/UserIncentiveDistributionList/UserIncentiveDistributionList.tsx msgid "Airdrop" msgstr "" @@ -4526,7 +4553,6 @@ msgid "Max slippage precision is -0.01%" msgstr "" #: src/components/Exchange/ExchangeTVChart.jsx -#: src/components/Synthetics/TVChart/TVChart.tsx msgid "Dec." msgstr "Dec" @@ -5242,6 +5268,10 @@ msgstr "" msgid "There is no liquidation price, as the position's collateral value will increase to cover any negative PnL." msgstr "" +#: src/components/TVChartContainer/DynamicLineComponent.tsx +msgid "Edit Order" +msgstr "" + #: src/components/MarketSelector/GmPoolsSelectorForGlvMarket.tsx #: src/components/MarketSelector/PoolSelector.tsx msgid "Search Pool" @@ -6215,7 +6245,6 @@ msgid "" msgstr "" #: src/components/Exchange/ExchangeTVChart.jsx -#: src/components/Synthetics/TVChart/TVChart.tsx msgid "Inc." msgstr "公司" @@ -7013,10 +7042,9 @@ msgstr "" #: src/components/Synthetics/TradeBox/tradeboxConstants.tsx #: src/components/Synthetics/TradeHistory/TradeHistoryRow/utils/position.ts #: src/components/Synthetics/TVChart/components/AvailableLiquidityTooltip.tsx -#: src/components/Synthetics/TVChart/TVChart.tsx -#: src/components/Synthetics/TVChart/TVChart.tsx #: src/context/SyntheticsEvents/SyntheticsEventsProvider.tsx #: src/context/SyntheticsEvents/SyntheticsEventsProvider.tsx +#: src/context/SyntheticsStateContext/selectors/chartSelectors/selectChartLines.tsx #: src/domain/synthetics/orders/utils.tsx #: src/pages/Exchange/Exchange.tsx #: src/pages/Exchange/Exchange.tsx @@ -7759,6 +7787,10 @@ msgstr "" msgid "Orders ({ordersCount})" msgstr "" +#: src/components/TVChartContainer/constants.ts +msgid "Limit - Long Inc." +msgstr "" + #: src/pages/Earn/ClaimModal.tsx msgid "<0>Delegate your undelegated {0} GMX DAOvoting power before claiming." msgstr "" From fee01101c829d2a97e2ae11c7edab275f21a3750 Mon Sep 17 00:00:00 2001 From: midas-myth Date: Fri, 21 Feb 2025 16:37:36 +0100 Subject: [PATCH 2/3] Force rebuild From d61bb32ead4ff6651cfa35630b89b6bc8acf42f7 Mon Sep 17 00:00:00 2001 From: midas-myth Date: Fri, 21 Feb 2025 17:33:41 +0100 Subject: [PATCH 3/3] TV control fix market switch --- .../TVChartContainer/DynamicLineComponent.tsx | 90 ++++++++++--------- 1 file changed, 49 insertions(+), 41 deletions(-) diff --git a/src/components/TVChartContainer/DynamicLineComponent.tsx b/src/components/TVChartContainer/DynamicLineComponent.tsx index 79289ff4f7..087aacf085 100644 --- a/src/components/TVChartContainer/DynamicLineComponent.tsx +++ b/src/components/TVChartContainer/DynamicLineComponent.tsx @@ -34,53 +34,61 @@ export function DynamicLineComponent({ const prevIsEdited = usePrevious(isEdited); useEffect(() => { - if (!tvWidgetRef.current?.activeChart?.().dataReady()) { + if (!tvWidgetRef.current?.activeChart().dataReady()) { return; } - const chart = tvWidgetRef.current.activeChart(); - const orderLine = chart.createOrderLine({ disableUndo: true }); - const predefinedKey = dynamicKeys[`${orderType}-${isLong ? "long" : "short"}`]; - const title = predefinedKey ? _(predefinedKey) : t`Unknown Order`; - - const orderLineApi = orderLine - .setText(title) - .setPrice(price) - .setQuantity("\u270E") - .setModifyTooltip(t`Edit Order`) - .onModify(() => { - latestOnEdit.current(id); - }) - .setCancelTooltip(t`Cancel Order`) - .onCancel(() => { - latestOnCancel.current(id); - }) - .onMove(() => { - latestOnEdit.current(id, orderLineApi.getPrice()); - }) - .setEditable(true) - .setLineStyle(LineStyle.Dashed) - .setLineLength(-200, "pixel") - .setLineColor("#3a3e5e") - - .setBodyFont(`normal 12pt "Relative", sans-serif`) - .setBodyTextColor("#fff") - .setBodyBackgroundColor("#3a3e5e") - .setBodyBorderColor("#252a47") - - .setQuantityBackgroundColor("#16182e") - .setQuantityFont(`normal 16pt "Relative", sans-serif`) - .setQuantityBorderColor("#252a47") - - .setCancelButtonBackgroundColor("#16182e") - .setCancelButtonBorderColor("#252a47") - .setCancelButtonIconColor("#fff"); - - lineApi.current = orderLineApi; + const range = chart.getVisibleRange(); + + if (range.from === 0 && range.to === 0) { + chart.onVisibleRangeChanged().subscribe(null, init, true); + } else { + init(); + } + + function init() { + const predefinedKey = dynamicKeys[`${orderType}-${isLong ? "long" : "short"}`]; + const title = predefinedKey ? _(predefinedKey) : t`Unknown Order`; + + lineApi.current = chart + .createOrderLine({ disableUndo: true }) + .setText(title) + .setPrice(price) + .setQuantity("\u270E") + .setModifyTooltip(t`Edit Order`) + .onModify(() => { + latestOnEdit.current(id); + }) + .setCancelTooltip(t`Cancel Order`) + .onCancel(() => { + latestOnCancel.current(id); + }) + .onMove(() => { + latestOnEdit.current(id, lineApi.current!.getPrice()); + }) + .setEditable(true) + .setLineStyle(LineStyle.Dashed) + .setLineLength(-200, "pixel") + .setLineColor("#3a3e5e") + + .setBodyFont(`normal 12pt "Relative", sans-serif`) + .setBodyTextColor("#fff") + .setBodyBackgroundColor("#3a3e5e") + .setBodyBorderColor("#252a47") + + .setQuantityBackgroundColor("#16182e") + .setQuantityFont(`normal 16pt "Relative", sans-serif`) + .setQuantityBorderColor("#252a47") + + .setCancelButtonBackgroundColor("#16182e") + .setCancelButtonBorderColor("#252a47") + .setCancelButtonIconColor("#fff"); + } return () => { - orderLineApi.remove(); + lineApi.current?.remove(); + lineApi.current = undefined; }; }, [_, id, isLong, latestOnCancel, latestOnEdit, orderType, price, tvWidgetRef]);