From 9dbf7c90a07c56d22fb20e57bba746fc4368d305 Mon Sep 17 00:00:00 2001 From: saml33 Date: Mon, 13 Feb 2023 15:03:11 +1100 Subject: [PATCH] mobile perp positions table --- components/trade/OpenOrders.tsx | 26 +-- components/trade/PerpPositions.tsx | 279 +++++++++++++++++++---------- components/trade/TradeHistory.tsx | 2 +- 3 files changed, 187 insertions(+), 120 deletions(-) diff --git a/components/trade/OpenOrders.tsx b/components/trade/OpenOrders.tsx index 24e3a0fd..6c56ce92 100644 --- a/components/trade/OpenOrders.tsx +++ b/components/trade/OpenOrders.tsx @@ -252,21 +252,14 @@ const OpenOrders = () => { let market: PerpMarket | Serum3Market let tickSize: number let minOrderSize: number - let quoteSymbol if (o instanceof PerpOrder) { market = group.getPerpMarketByMarketIndex(o.perpMarketIndex) - quoteSymbol = group.getFirstBankByTokenIndex( - market.settleTokenIndex - ).name tickSize = market.tickSize minOrderSize = market.minOrderSize } else { market = group.getSerum3MarketByExternalMarket( new PublicKey(marketPk) ) - quoteSymbol = group.getFirstBankByTokenIndex( - market!.quoteTokenIndex - ).name const serumMarket = group.getSerum3ExternalMarket( market.serumMarketExternal ) @@ -297,10 +290,7 @@ const OpenOrders = () => { {o.price.toLocaleString(undefined, { minimumFractionDigits: getDecimalCount(tickSize), maximumFractionDigits: getDecimalCount(tickSize), - })}{' '} - - {quoteSymbol} - + })} @@ -329,7 +319,7 @@ const OpenOrders = () => { )} - + { let market: PerpMarket | Serum3Market let tickSize: number let minOrderSize: number - let quoteSymbol: string let baseSymbol: string if (o instanceof PerpOrder) { market = group.getPerpMarketByMarketIndex(o.perpMarketIndex) baseSymbol = market.name.split('-')[0] - quoteSymbol = group.getFirstBankByTokenIndex( - market.settleTokenIndex - ).name tickSize = market.tickSize minOrderSize = market.minOrderSize } else { @@ -418,9 +404,6 @@ const OpenOrders = () => { new PublicKey(marketPk) ) baseSymbol = market.name.split('/')[0] - quoteSymbol = group.getFirstBankByTokenIndex( - market!.quoteTokenIndex - ).name const serumMarket = group.getSerum3ExternalMarket( market.serumMarketExternal ) @@ -445,14 +428,13 @@ const OpenOrders = () => { })} {' '} {baseSymbol} - {' for '} + {' at '} {o.price.toLocaleString(undefined, { minimumFractionDigits: getDecimalCount(tickSize), maximumFractionDigits: getDecimalCount(tickSize), })} - {' '} - {quoteSymbol} +

) : ( diff --git a/components/trade/PerpPositions.tsx b/components/trade/PerpPositions.tsx index 9748c937..6f6dff9a 100644 --- a/components/trade/PerpPositions.tsx +++ b/components/trade/PerpPositions.tsx @@ -10,9 +10,11 @@ import useMangoAccount from 'hooks/useMangoAccount' import useMangoGroup from 'hooks/useMangoGroup' import useSelectedMarket from 'hooks/useSelectedMarket' import useUnownedAccount from 'hooks/useUnownedAccount' +import { useViewport } from 'hooks/useViewport' import { useTranslation } from 'next-i18next' import { useCallback, useState } from 'react' import { floorToDecimal, getDecimalCount } from 'utils/numbers' +import { breakpoints } from 'utils/theme' import { calculateLimitPriceForMarketOrder } from 'utils/tradeForm' import MarketCloseModal from './MarketCloseModal' import PerpSideBadge from './PerpSideBadge' @@ -30,6 +32,8 @@ const PerpPositions = () => { const { connected } = useWallet() const { mangoAccountAddress } = useMangoAccount() const isUnownedAccount = useUnownedAccount() + const { width } = useViewport() + const showTableView = width ? width > breakpoints.md : false const handlePositionClick = (positionSize: number, market: PerpMarket) => { const tradeForm = mangoStore.getState().tradeForm @@ -74,53 +78,152 @@ const PerpPositions = () => { ) return mangoAccountAddress && openPerpPositions.length ? ( - <> -
- - - - - - - - - - - {!isUnownedAccount ? - - {openPerpPositions.map((position) => { - const market = group.getPerpMarketByMarketIndex( - position.marketIndex - ) - const basePosition = position.getBasePositionUi(market) - const floorBasePosition = floorToDecimal( - basePosition, - getDecimalCount(market.minOrderSize) - ).toNumber() - const isSelectedMarket = - selectedMarket instanceof PerpMarket && - selectedMarket.perpMarketIndex === position.marketIndex + showTableView ? ( + <> +
+
{t('market')}{t('trade:side')}{t('trade:size')}{t('trade:notional')}{t('trade:entry-price')}{`${t('trade:unsettled')} ${t( - 'pnl' - )}`}{t('pnl')} : null} - -
+ + + + + + + + + + {!isUnownedAccount ? + + {openPerpPositions.map((position) => { + const market = group.getPerpMarketByMarketIndex( + position.marketIndex + ) + const basePosition = position.getBasePositionUi(market) + const floorBasePosition = floorToDecimal( + basePosition, + getDecimalCount(market.minOrderSize) + ).toNumber() + const isSelectedMarket = + selectedMarket instanceof PerpMarket && + selectedMarket.perpMarketIndex === position.marketIndex - if (!basePosition) return null + if (!basePosition) return null - const unsettledPnl = position.getUnsettledPnlUi(market) - const cummulativePnl = - position.cumulativePnlOverPositionLifetimeUi(market) + const unsettledPnl = position.getUnsettledPnlUi(market) + const cummulativePnl = + position.cumulativePnlOverPositionLifetimeUi(market) - return ( - - - - + + + + + + + {!isUnownedAccount ? ( + + ) : null} + + ) + })} + +
{t('market')}{t('trade:side')}{t('trade:size')}{t('trade:notional')}{t('trade:entry-price')}{`${t('trade:unsettled')} ${t( + 'pnl' + )}`}{t('pnl')} : null} + +
- - - - -

+ return ( + +

+ + + + +

+ {isSelectedMarket ? ( + + handlePositionClick(floorBasePosition, market) + } + > + + + ) : ( + + )} +

+
+ + + + + + 0 ? 'text-th-up' : 'text-th-down' + }`} + > + + + +
+
+ {showMarketCloseModal && positionToClose ? ( + + ) : null} + + ) : ( + <> + {openPerpPositions.map((position) => { + const market = group.getPerpMarketByMarketIndex(position.marketIndex) + const basePosition = position.getBasePositionUi(market) + const floorBasePosition = floorToDecimal( + basePosition, + getDecimalCount(market.minOrderSize) + ).toNumber() + const isSelectedMarket = + selectedMarket instanceof PerpMarket && + selectedMarket.perpMarketIndex === position.marketIndex + + if (!basePosition) return null + const cummulativePnl = + position.cumulativePnlOverPositionLifetimeUi(market) + return ( +
+
+ +
+ +

+ {isSelectedMarket ? ( @@ -138,60 +241,42 @@ const PerpPositions = () => { decimals={getDecimalCount(market.minOrderSize)} /> )} -

- - - - - - - - - - - 0 ? 'text-th-up' : 'text-th-down' - }`} + + {' at '} + + + +

+
+
+
+
0 ? 'text-th-up' : 'text-th-down' + }`} + > + +
+ {!isUnownedAccount ? ( + - - ) : null} - - ) - })} - - -
- {showMarketCloseModal && positionToClose ? ( - - ) : null} - + Close + + ) : null} +
+ + ) + })} + + ) ) : mangoAccountAddress || connected ? (
diff --git a/components/trade/TradeHistory.tsx b/components/trade/TradeHistory.tsx index 31c94fe3..57f661ab 100644 --- a/components/trade/TradeHistory.tsx +++ b/components/trade/TradeHistory.tsx @@ -340,7 +340,7 @@ const TradeHistory = () => { {trade.size} - {' for '} + {' at '}