Merge pull request #258 from blockworks-foundation/toggle-orderbook-size-units
toggle orderbook size between base and quote
This commit is contained in:
commit
160b5fd9c1
|
@ -17,7 +17,11 @@ import Decimal from 'decimal.js'
|
|||
import Tooltip from '@components/shared/Tooltip'
|
||||
import GroupSize from './GroupSize'
|
||||
// import { useViewport } from 'hooks/useViewport'
|
||||
import { BookSide, Serum3Market } from '@blockworks-foundation/mango-v4'
|
||||
import {
|
||||
BookSide,
|
||||
PerpMarket,
|
||||
Serum3Market,
|
||||
} from '@blockworks-foundation/mango-v4'
|
||||
import useSelectedMarket from 'hooks/useSelectedMarket'
|
||||
import { INITIAL_ANIMATION_SETTINGS } from '@components/settings/AnimationSettings'
|
||||
import { OrderbookFeed } from '@blockworks-foundation/mango-feeds'
|
||||
|
@ -33,6 +37,7 @@ import {
|
|||
import { OrderbookData, OrderbookL2 } from 'types'
|
||||
import isEqual from 'lodash/isEqual'
|
||||
import { useViewport } from 'hooks/useViewport'
|
||||
import TokenLogo from '@components/shared/TokenLogo'
|
||||
|
||||
const sizeCompacter = Intl.NumberFormat('en', {
|
||||
maximumFractionDigits: 6,
|
||||
|
@ -51,6 +56,7 @@ const Orderbook = () => {
|
|||
const [useOrderbookFeed, setUseOrderbookFeed] = useState(false)
|
||||
const orderbookElRef = useRef<HTMLDivElement>(null)
|
||||
const [isScrolled, setIsScrolled] = useState(false)
|
||||
const [sizeInBase, setSizeInBase] = useState(true)
|
||||
// const [useOrderbookFeed, setUseOrderbookFeed] = useState(
|
||||
// localStorage.getItem(USE_ORDERBOOK_FEED_KEY) !== null
|
||||
// ? localStorage.getItem(USE_ORDERBOOK_FEED_KEY) === 'true'
|
||||
|
@ -60,6 +66,23 @@ const Orderbook = () => {
|
|||
const [orderbookData, setOrderbookData] = useState<OrderbookData | null>(null)
|
||||
const currentOrderbookData = useRef<OrderbookL2>()
|
||||
|
||||
const [baseBank, quoteBank] = useMemo(() => {
|
||||
const { group } = mangoStore.getState()
|
||||
if (!market || !group) return [undefined, undefined]
|
||||
if (market instanceof PerpMarket) {
|
||||
const baseTokenName = market.name.split('-')[0]
|
||||
const base = group.banksMapByName.get(baseTokenName)?.[0]
|
||||
const quote = group.getFirstBankByTokenIndex(market.settleTokenIndex)
|
||||
return [base, quote]
|
||||
} else {
|
||||
const base = group.getFirstBankByMint(market.baseMintAddress)
|
||||
const quote = group.getFirstBankByMint(market.quoteMintAddress)
|
||||
return [base, quote]
|
||||
}
|
||||
}, [market])
|
||||
|
||||
console.log(baseBank, quoteBank)
|
||||
|
||||
const depth = useMemo(() => {
|
||||
return isDesktop ? 30 : 12
|
||||
}, [isDesktop])
|
||||
|
@ -454,7 +477,7 @@ const Orderbook = () => {
|
|||
|
||||
return (
|
||||
<div className="flex h-full flex-col">
|
||||
<div className="flex h-10 items-center justify-between border-b border-th-bkg-3 px-4">
|
||||
<div className="flex h-8 items-center justify-between border-b border-th-bkg-3 px-4">
|
||||
{market ? (
|
||||
<>
|
||||
<p className="text-xs">{t('trade:grouping')}:</p>
|
||||
|
@ -475,9 +498,43 @@ const Orderbook = () => {
|
|||
</>
|
||||
) : null}
|
||||
</div>
|
||||
<div className="grid grid-cols-2 px-2 py-0.5 text-xxs text-th-fgd-4">
|
||||
<div className="grid grid-cols-2 px-2 pb-1 pt-1.5 text-xxs text-th-fgd-4">
|
||||
<div className="col-span-1">{t('price')}</div>
|
||||
<div className="col-span-1 text-right">{t('trade:size')}</div>
|
||||
<div className="col-span-1 flex items-center justify-end space-x-2">
|
||||
<span className="text-right">{t('trade:size')}</span>
|
||||
{baseBank && quoteBank ? (
|
||||
<div className="flex h-[18px] space-x-1">
|
||||
<Tooltip
|
||||
content={t('trade:tooltip-size-base-quote', {
|
||||
token: baseBank.name,
|
||||
})}
|
||||
>
|
||||
<button
|
||||
className={`rounded border p-0.5 ${
|
||||
sizeInBase ? 'border-th-fgd-2' : 'border-th-bkg-4'
|
||||
} focus:outline-none focus-visible:border-th-active md:hover:border-th-fgd-2`}
|
||||
onClick={() => setSizeInBase(true)}
|
||||
>
|
||||
<TokenLogo bank={baseBank} size={12} />
|
||||
</button>
|
||||
</Tooltip>
|
||||
<Tooltip
|
||||
content={t('trade:tooltip-size-base-quote', {
|
||||
token: quoteBank.name,
|
||||
})}
|
||||
>
|
||||
<button
|
||||
className={`rounded border p-0.5 ${
|
||||
!sizeInBase ? 'border-th-fgd-2' : 'border-th-bkg-4'
|
||||
} focus:outline-none focus-visible:border-th-active md:hover:border-th-fgd-2`}
|
||||
onClick={() => setSizeInBase(false)}
|
||||
>
|
||||
<TokenLogo bank={quoteBank} size={12} />
|
||||
</button>
|
||||
</Tooltip>
|
||||
</div>
|
||||
) : null}
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className="hide-scroll relative h-full overflow-y-scroll"
|
||||
|
@ -511,6 +568,7 @@ const Orderbook = () => {
|
|||
orderbookData?.asks[index].cumulativeSizePercent
|
||||
}
|
||||
grouping={grouping}
|
||||
sizeInBase={sizeInBase}
|
||||
/>
|
||||
) : null}
|
||||
</div>
|
||||
|
@ -559,6 +617,7 @@ const Orderbook = () => {
|
|||
orderbookData?.bids[index].cumulativeSizePercent
|
||||
}
|
||||
grouping={grouping}
|
||||
sizeInBase={sizeInBase}
|
||||
/>
|
||||
) : null}
|
||||
</div>
|
||||
|
@ -582,6 +641,7 @@ const OrderbookRow = ({
|
|||
cumulativeSizePercent,
|
||||
tickSize,
|
||||
grouping,
|
||||
sizeInBase,
|
||||
}: {
|
||||
side: 'buy' | 'sell'
|
||||
price: number
|
||||
|
@ -596,6 +656,7 @@ const OrderbookRow = ({
|
|||
grouping: number
|
||||
minOrderSize: number
|
||||
tickSize: number
|
||||
sizeInBase: boolean
|
||||
}) => {
|
||||
const element = useRef<HTMLDivElement>(null)
|
||||
const [animationSettings] = useLocalStorageState(
|
||||
|
@ -618,10 +679,21 @@ const OrderbookRow = ({
|
|||
}, [price, size])
|
||||
|
||||
const formattedSize = useMemo(() => {
|
||||
return minOrderSize && !isNaN(size)
|
||||
? floorToDecimal(size, getDecimalCount(minOrderSize))
|
||||
: new Decimal(size ?? -1)
|
||||
}, [size, minOrderSize])
|
||||
if (!minOrderSize || isNaN(size)) return new Decimal(size ?? -1)
|
||||
const sizeToShow = sizeInBase
|
||||
? size
|
||||
: new Decimal(size).mul(new Decimal(price)).toNumber()
|
||||
const decimals = sizeInBase
|
||||
? getDecimalCount(minOrderSize)
|
||||
: getDecimalCount(tickSize)
|
||||
return floorToDecimal(sizeToShow, decimals)
|
||||
}, [minOrderSize, price, size, sizeInBase, tickSize])
|
||||
|
||||
// const formattedSize = useMemo(() => {
|
||||
// return minOrderSize && !isNaN(size)
|
||||
// ? floorToDecimal(size, getDecimalCount(minOrderSize))
|
||||
// : new Decimal(size ?? -1)
|
||||
// }, [size, minOrderSize, sizeInBase, tickSize])
|
||||
|
||||
const formattedPrice = useMemo(() => {
|
||||
return tickSize && !isNaN(price)
|
||||
|
@ -647,16 +719,28 @@ const OrderbookRow = ({
|
|||
const handleSizeClick = useCallback(() => {
|
||||
const set = mangoStore.getState().set
|
||||
set((state) => {
|
||||
state.tradeForm.baseSize = formattedSize.toString()
|
||||
if (sizeInBase) {
|
||||
state.tradeForm.baseSize = formattedSize.toString()
|
||||
} else {
|
||||
state.tradeForm.quoteSize = formattedSize.toString()
|
||||
}
|
||||
if (formattedSize && state.tradeForm.price) {
|
||||
const quoteSize = floorToDecimal(
|
||||
formattedSize.mul(new Decimal(state.tradeForm.price)),
|
||||
getDecimalCount(tickSize),
|
||||
)
|
||||
state.tradeForm.quoteSize = quoteSize.toString()
|
||||
if (sizeInBase) {
|
||||
const quoteSize = floorToDecimal(
|
||||
formattedSize.mul(new Decimal(state.tradeForm.price)),
|
||||
getDecimalCount(tickSize),
|
||||
)
|
||||
state.tradeForm.quoteSize = quoteSize.toString()
|
||||
} else {
|
||||
const baseSize = floorToDecimal(
|
||||
formattedSize.div(new Decimal(state.tradeForm.price)),
|
||||
getDecimalCount(minOrderSize),
|
||||
)
|
||||
state.tradeForm.baseSize = baseSize.toString()
|
||||
}
|
||||
}
|
||||
})
|
||||
}, [formattedSize, tickSize])
|
||||
}, [formattedSize, minOrderSize, size, sizeInBase, tickSize])
|
||||
|
||||
const groupingDecimalCount = useMemo(
|
||||
() => getDecimalCount(grouping),
|
||||
|
|
|
@ -106,6 +106,7 @@
|
|||
"tooltip-ioc": "Immediate-Or-Cancel (IOC) orders are guaranteed to be the taker and must be executed immediately. Any portion of the order that can't be filled immediately will be cancelled",
|
||||
"tooltip-insured": "Whether or not {{tokenOrMarket}} losses can be recovered from the insurance fund in the event of bankruptcies.",
|
||||
"tooltip-post": "Post orders are guaranteed to be the maker or they will be canceled",
|
||||
"tooltip-size-base-quote": "Show size in {{token}}",
|
||||
"tooltip-private-counterparty": "Counterparty has Private Account enabled",
|
||||
"tooltip-slippage": "An estimate of the difference between the current price and the price your trade will be executed at",
|
||||
"tooltip-stable-price": "Stable price is used in a safety mechanism that limits a user's ability to enter risky positions when the oracle price is changing rapidly",
|
||||
|
|
|
@ -106,6 +106,7 @@
|
|||
"tooltip-ioc": "Immediate-Or-Cancel (IOC) orders are guaranteed to be the taker and must be executed immediately. Any portion of the order that can't be filled immediately will be cancelled",
|
||||
"tooltip-insured": "Whether or not {{tokenOrMarket}} losses can be recovered from the insurance fund in the event of bankruptcies.",
|
||||
"tooltip-post": "Post orders are guaranteed to be the maker or they will be canceled",
|
||||
"tooltip-size-base-quote": "Show size in {{token}}",
|
||||
"tooltip-private-counterparty": "Counterparty has Private Account enabled",
|
||||
"tooltip-slippage": "An estimate of the difference between the current price and the price your trade will be executed at",
|
||||
"tooltip-stable-price": "Stable price is used in a safety mechanism that limits a user's ability to enter risky positions when the oracle price is changing rapidly",
|
||||
|
|
|
@ -106,6 +106,7 @@
|
|||
"tooltip-ioc": "Immediate-Or-Cancel (IOC) orders are guaranteed to be the taker and must be executed immediately. Any portion of the order that can't be filled immediately will be cancelled",
|
||||
"tooltip-insured": "Whether or not {{tokenOrMarket}} losses can be recovered from the insurance fund in the event of bankruptcies.",
|
||||
"tooltip-post": "Post orders are guaranteed to be the maker or they will be canceled",
|
||||
"tooltip-size-base-quote": "Show size in {{token}}",
|
||||
"tooltip-private-counterparty": "Counterparty has Private Account enabled",
|
||||
"tooltip-slippage": "An estimate of the difference between the current price and the price your trade will be executed at",
|
||||
"tooltip-stable-price": "Stable price is used in a safety mechanism that limits a user's ability to enter risky positions when the oracle price is changing rapidly",
|
||||
|
|
|
@ -111,6 +111,7 @@
|
|||
"tooltip-insured": "如果发生破产,{{tokenOrMarket}}损失是否可以从保险基金中归还",
|
||||
"tooltip-ioc": "IOC交易若不吃单就会被取消。任何无法立刻成交的部分将被取消",
|
||||
"tooltip-post": "Post交易若不挂单就会被取消。",
|
||||
"tooltip-size-base-quote": "Show size in {{token}}",
|
||||
"tooltip-private-counterparty": "Counterparty has Private Account enabled",
|
||||
"tooltip-slippage": "当前价格与您的交易将执行的价格之间的差值的估计",
|
||||
"tooltip-stable-price": "稳定价格用于一个安全机制。此机制可以限制用户在预言机价格快速波动时下风险高的订单",
|
||||
|
|
|
@ -106,6 +106,7 @@
|
|||
"tooltip-insured": "如果發生破產,{{tokenOrMarket}}損失是否可以從保險基金中歸還",
|
||||
"tooltip-ioc": "IOC交易若不吃單就會被取消。任何無法立刻成交的部分將被取消",
|
||||
"tooltip-post": "Post交易若不掛單就會被取消。",
|
||||
"tooltip-size-base-quote": "Show size in {{token}}",
|
||||
"tooltip-private-counterparty": "Counterparty has Private Account enabled",
|
||||
"tooltip-slippage": "當前價格與您的交易將執行的價格之間的差值的估計",
|
||||
"tooltip-stable-price": "穩定價格用於一個安全機制。此機制可以限制用戶在預言機價格快速波動時下風險高的訂單",
|
||||
|
|
Loading…
Reference in New Issue