perps: remove modify module and adjust main module (#761)
* perps: remove modify module and adjust main module * fix build
This commit is contained in:
parent
98ab2c635a
commit
19d4d1691d
@ -29,7 +29,6 @@ export default function Manage(props: Props) {
|
||||
setSearchParams({
|
||||
...params,
|
||||
[SearchParams.PERPS_MARKET]: props.perpPosition.asset.denom,
|
||||
[SearchParams.PERPS_MANAGE]: 'true',
|
||||
})
|
||||
},
|
||||
},
|
||||
|
@ -1,109 +0,0 @@
|
||||
import classNames from 'classnames'
|
||||
import debounce from 'lodash.debounce'
|
||||
import { useEffect, useMemo, useState } from 'react'
|
||||
|
||||
import { Cross } from 'components/common/Icons'
|
||||
import LeverageSlider from 'components/common/LeverageSlider'
|
||||
import { Spacer } from 'components/common/Spacer'
|
||||
import Text from 'components/common/Text'
|
||||
import { TradeDirectionSelector } from 'components/common/TradeDirectionSelector'
|
||||
import { LeverageButtons } from 'components/perps/Module/LeverageButtons'
|
||||
import { Or } from 'components/perps/Module/Or'
|
||||
import usePerpsManageModule from 'components/perps/Module/PerpsManageModule/usePerpsManageModule'
|
||||
import PerpsSummary from 'components/perps/Module/Summary'
|
||||
import AssetAmountInput from 'components/trade/TradeModule/SwapForm/AssetAmountInput'
|
||||
import useCurrentAccount from 'hooks/accounts/useCurrentAccount'
|
||||
import { useUpdatedAccount } from 'hooks/useUpdatedAccount'
|
||||
import getPerpsPosition from 'utils/getPerpsPosition'
|
||||
import { BN } from 'utils/helpers'
|
||||
|
||||
export function PerpsManageModule() {
|
||||
const [tradeDirection, setTradeDirection] = useState<TradeDirection | null>(null)
|
||||
const [amount, setAmount] = useState<BigNumber | null>(null)
|
||||
const account = useCurrentAccount()
|
||||
const { simulatePerps, addedPerps } = useUpdatedAccount(account)
|
||||
const {
|
||||
closeManagePerpModule,
|
||||
previousAmount,
|
||||
previousTradeDirection,
|
||||
previousLeverage,
|
||||
leverage,
|
||||
asset,
|
||||
} = usePerpsManageModule(amount)
|
||||
|
||||
const debouncedUpdateAccount = useMemo(
|
||||
() =>
|
||||
debounce((perpsPosition: PerpsPosition) => {
|
||||
if (
|
||||
addedPerps &&
|
||||
perpsPosition.amount === addedPerps.amount &&
|
||||
perpsPosition.tradeDirection === addedPerps.tradeDirection
|
||||
)
|
||||
return
|
||||
simulatePerps(perpsPosition)
|
||||
}, 100),
|
||||
[simulatePerps, addedPerps],
|
||||
)
|
||||
|
||||
useEffect(() => {
|
||||
const perpsPosition = getPerpsPosition(
|
||||
asset,
|
||||
amount ?? previousAmount,
|
||||
tradeDirection ?? previousTradeDirection,
|
||||
)
|
||||
debouncedUpdateAccount(perpsPosition)
|
||||
}, [
|
||||
debouncedUpdateAccount,
|
||||
asset,
|
||||
amount,
|
||||
previousAmount,
|
||||
tradeDirection,
|
||||
previousTradeDirection,
|
||||
])
|
||||
|
||||
if (!asset) return null
|
||||
|
||||
return (
|
||||
<div
|
||||
className={classNames(
|
||||
'px-4 gap-5 flex flex-col h-full pt-6 pb-4 w-full bg-white/5 absolute rounded-base isolate',
|
||||
'before:content-[" "] before:absolute before:inset-0 before:-z-1 before:rounded-base before:p-[1px] before:border-glas',
|
||||
)}
|
||||
>
|
||||
<div className='flex justify-between mb-3'>
|
||||
<Text>Manage Position</Text>
|
||||
<button onClick={closeManagePerpModule} className='mr-1.5'>
|
||||
<Cross width={16} />
|
||||
</button>
|
||||
</div>
|
||||
<TradeDirectionSelector
|
||||
direction={tradeDirection ?? previousTradeDirection}
|
||||
onChangeDirection={setTradeDirection}
|
||||
/>
|
||||
<AssetAmountInput
|
||||
label='Amount'
|
||||
max={BN(1000000)} // TODO: Implement max calculation
|
||||
amount={amount ?? previousAmount}
|
||||
setAmount={setAmount}
|
||||
asset={asset}
|
||||
maxButtonLabel='Max:'
|
||||
disabled={false}
|
||||
/>
|
||||
<Or />
|
||||
<Text size='sm'>Position Leverage</Text>
|
||||
<LeverageSlider max={0} value={0} onChange={() => {}} type={tradeDirection || 'long'} />
|
||||
<LeverageButtons />
|
||||
<Spacer />
|
||||
<PerpsSummary
|
||||
changeTradeDirection
|
||||
amount={amount ?? previousAmount}
|
||||
tradeDirection={tradeDirection ?? previousTradeDirection}
|
||||
asset={asset}
|
||||
leverage={leverage}
|
||||
previousAmount={previousAmount}
|
||||
previousTradeDirection={previousTradeDirection}
|
||||
previousLeverage={previousLeverage}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
import debounce from 'lodash.debounce'
|
||||
import { useEffect, useMemo, useState } from 'react'
|
||||
import { useCallback, useEffect, useMemo, useState } from 'react'
|
||||
|
||||
import Card from 'components/common/Card'
|
||||
import LeverageSlider from 'components/common/LeverageSlider'
|
||||
@ -9,6 +9,7 @@ import { TradeDirectionSelector } from 'components/common/TradeDirectionSelector
|
||||
import { LeverageButtons } from 'components/perps/Module/LeverageButtons'
|
||||
import { Or } from 'components/perps/Module/Or'
|
||||
import PerpsSummary from 'components/perps/Module/Summary'
|
||||
import usePerpsModule from 'components/perps/Module/usePerpsModule'
|
||||
import AssetSelectorPerps from 'components/trade/TradeModule/AssetSelector/AssetSelectorPerps'
|
||||
import AssetAmountInput from 'components/trade/TradeModule/SwapForm/AssetAmountInput'
|
||||
import OrderTypeSelector from 'components/trade/TradeModule/SwapForm/OrderTypeSelector'
|
||||
@ -24,10 +25,11 @@ export function PerpsModule() {
|
||||
const [selectedOrderType, setSelectedOrderType] = useState<AvailableOrderType>('Market')
|
||||
const [tradeDirection, setTradeDirection] = useState<TradeDirection>('long')
|
||||
const { perpsAsset } = usePerpsAsset()
|
||||
const [leverage, setLeverage] = useState<number>(1)
|
||||
const account = useCurrentAccount()
|
||||
const { simulatePerps, addedPerps } = useUpdatedAccount(account)
|
||||
const [amount, setAmount] = useState<BigNumber>(BN_ZERO)
|
||||
const { previousAmount, previousTradeDirection, previousLeverage, leverage, hasActivePosition } =
|
||||
usePerpsModule(amount)
|
||||
|
||||
const debouncedUpdateAccount = useMemo(
|
||||
() =>
|
||||
@ -44,30 +46,69 @@ export function PerpsModule() {
|
||||
)
|
||||
|
||||
useEffect(() => {
|
||||
const perpsPosition = getPerpsPosition(perpsAsset, amount, tradeDirection)
|
||||
const perpsPosition = getPerpsPosition(
|
||||
perpsAsset,
|
||||
amount ?? previousAmount,
|
||||
tradeDirection ?? previousTradeDirection,
|
||||
)
|
||||
debouncedUpdateAccount(perpsPosition)
|
||||
}, [debouncedUpdateAccount, amount, perpsAsset, tradeDirection])
|
||||
}, [
|
||||
debouncedUpdateAccount,
|
||||
amount,
|
||||
perpsAsset,
|
||||
tradeDirection,
|
||||
previousAmount,
|
||||
previousTradeDirection,
|
||||
])
|
||||
|
||||
const setLeverage = useCallback((leverage: number) => {
|
||||
// TODO: Implement leverage setting
|
||||
}, [])
|
||||
|
||||
const onChangeTradeDirection = useCallback(
|
||||
(tradeDirection: TradeDirection) => {
|
||||
setAmount(amount.times(-1))
|
||||
setTradeDirection(tradeDirection)
|
||||
},
|
||||
[amount],
|
||||
)
|
||||
|
||||
const onChangeAmount = useCallback(
|
||||
(amount: BigNumber) => {
|
||||
if (tradeDirection === 'short') {
|
||||
setAmount(amount.times(-1))
|
||||
return
|
||||
}
|
||||
|
||||
setAmount(amount)
|
||||
},
|
||||
[tradeDirection],
|
||||
)
|
||||
|
||||
if (!perpsAsset) return null
|
||||
|
||||
return (
|
||||
<Card
|
||||
contentClassName='px-4 gap-5 flex flex-col h-full pb-4'
|
||||
title={<AssetSelectorPerps asset={perpsAsset} />}
|
||||
title={<AssetSelectorPerps asset={perpsAsset} hasActivePosition={hasActivePosition} />}
|
||||
className='h-full mb-4'
|
||||
>
|
||||
<OrderTypeSelector selected={selectedOrderType} onChange={setSelectedOrderType} />
|
||||
|
||||
<TradeDirectionSelector direction={tradeDirection} onChangeDirection={setTradeDirection} />
|
||||
<TradeDirectionSelector
|
||||
direction={tradeDirection}
|
||||
onChangeDirection={onChangeTradeDirection}
|
||||
/>
|
||||
<AssetAmountInput
|
||||
label='Amount'
|
||||
max={BN(1000000)} // TODO: Implement max calculation
|
||||
amount={amount}
|
||||
setAmount={setAmount}
|
||||
amount={amount.abs()}
|
||||
setAmount={onChangeAmount}
|
||||
asset={perpsAsset}
|
||||
maxButtonLabel='Max:'
|
||||
disabled={false}
|
||||
/>
|
||||
{!hasActivePosition && (
|
||||
<>
|
||||
<Or />
|
||||
<Text size='sm'>Position Leverage</Text>
|
||||
<LeverageSlider
|
||||
@ -78,12 +119,19 @@ export function PerpsModule() {
|
||||
type={tradeDirection}
|
||||
/>
|
||||
<LeverageButtons />
|
||||
</>
|
||||
)}
|
||||
|
||||
<Spacer />
|
||||
<PerpsSummary
|
||||
amount={amount}
|
||||
tradeDirection={tradeDirection}
|
||||
amount={amount ?? previousAmount}
|
||||
tradeDirection={tradeDirection ?? previousTradeDirection}
|
||||
asset={perpsAsset}
|
||||
leverage={leverage}
|
||||
previousAmount={previousAmount}
|
||||
previousTradeDirection={previousTradeDirection}
|
||||
previousLeverage={previousLeverage}
|
||||
hasActivePosition={hasActivePosition}
|
||||
/>
|
||||
</Card>
|
||||
)
|
||||
|
@ -18,10 +18,10 @@ type Props = {
|
||||
amount: BigNumber
|
||||
tradeDirection: TradeDirection
|
||||
asset: Asset
|
||||
changeTradeDirection?: boolean
|
||||
previousAmount?: BigNumber
|
||||
previousTradeDirection?: 'long' | 'short'
|
||||
previousLeverage?: number
|
||||
hasActivePosition: boolean
|
||||
}
|
||||
|
||||
export default function PerpsSummary(props: Props) {
|
||||
@ -70,14 +70,13 @@ export default function PerpsSummary(props: Props) {
|
||||
function ManageSummary(props: Props) {
|
||||
const showTradeDirection =
|
||||
props.previousTradeDirection && props.previousTradeDirection !== props.tradeDirection
|
||||
const showAmount =
|
||||
props.previousAmount && props.amount && !props.previousAmount.isEqualTo(props.amount)
|
||||
const showAmount = !props.amount.isZero() && props.previousAmount
|
||||
const showLeverage =
|
||||
props.previousLeverage &&
|
||||
props.leverage &&
|
||||
props.previousLeverage.toFixed(2) !== props.leverage.toFixed(2)
|
||||
|
||||
if (!showTradeDirection && !showLeverage && !showAmount) return null
|
||||
if ((!showTradeDirection && !showLeverage && !showAmount) || !props.hasActivePosition) return null
|
||||
|
||||
return (
|
||||
<div className='pt-4 px-3 flex flex-col gap-1'>
|
||||
@ -95,14 +94,17 @@ function ManageSummary(props: Props) {
|
||||
|
||||
{showAmount && props.previousAmount && (
|
||||
<SummaryLine label='Size' contentClassName='flex gap-1'>
|
||||
<AssetAmount asset={props.asset} amount={props.previousAmount.toNumber()} />
|
||||
<AssetAmount asset={props.asset} amount={props.previousAmount.abs().toNumber()} />
|
||||
<ArrowRight
|
||||
width={16}
|
||||
className={classNames(
|
||||
props.previousAmount.isGreaterThan(props.amount) ? 'text-error' : 'text-success',
|
||||
)}
|
||||
/>
|
||||
<AssetAmount asset={props.asset} amount={props.amount.toNumber()} />
|
||||
<AssetAmount
|
||||
asset={props.asset}
|
||||
amount={props.previousAmount.plus(props.amount).abs().toNumber()}
|
||||
/>
|
||||
</SummaryLine>
|
||||
)}
|
||||
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { useCallback, useMemo } from 'react'
|
||||
import { useSearchParams } from 'react-router-dom'
|
||||
import { useMemo } from 'react'
|
||||
|
||||
import { BN_ZERO } from 'constants/math'
|
||||
import useCurrentAccount from 'hooks/accounts/useCurrentAccount'
|
||||
@ -8,34 +7,33 @@ import usePerpPosition from 'hooks/perps/usePerpPosition'
|
||||
import usePerpsAsset from 'hooks/perps/usePerpsAsset'
|
||||
import usePrice from 'hooks/usePrice'
|
||||
import usePrices from 'hooks/usePrices'
|
||||
import { SearchParams } from 'types/enums/searchParams'
|
||||
import { getAccountNetValue } from 'utils/accounts'
|
||||
import { byDenom } from 'utils/array'
|
||||
import { demagnify } from 'utils/formatters'
|
||||
import { getSearchParamsObject } from 'utils/route'
|
||||
|
||||
export default function usePerpsManageModule(amount: BigNumber | null) {
|
||||
export default function usePerpsModule(amount: BigNumber | null) {
|
||||
const { perpsAsset } = usePerpsAsset()
|
||||
const [searchParams, setSearchParams] = useSearchParams()
|
||||
const perpPosition = usePerpPosition(perpsAsset.denom)
|
||||
const { data: prices } = usePrices()
|
||||
const assets = useAllAssets()
|
||||
const account = useCurrentAccount()
|
||||
const price = usePrice(perpsAsset.denom)
|
||||
|
||||
const hasActivePosition = useMemo(
|
||||
() => !!account?.perps.find(byDenom(perpsAsset.denom)),
|
||||
[account?.perps, perpsAsset.denom],
|
||||
)
|
||||
|
||||
const accountNetValue = useMemo(() => {
|
||||
if (!account || !prices || !assets) return BN_ZERO
|
||||
return getAccountNetValue(account, prices, assets)
|
||||
}, [account, assets, prices])
|
||||
|
||||
const closeManagePerpModule = useCallback(() => {
|
||||
const params = getSearchParamsObject(searchParams)
|
||||
delete params[SearchParams.PERPS_MANAGE]
|
||||
setSearchParams({
|
||||
...params,
|
||||
})
|
||||
}, [searchParams, setSearchParams])
|
||||
|
||||
const previousAmount = useMemo(() => perpPosition?.amount ?? BN_ZERO, [perpPosition?.amount])
|
||||
const previousAmount = useMemo(
|
||||
() =>
|
||||
(perpPosition?.amount ?? BN_ZERO).times(perpPosition?.tradeDirection === 'short' ? -1 : 1),
|
||||
[perpPosition?.amount, perpPosition?.tradeDirection],
|
||||
)
|
||||
const previousTradeDirection = useMemo(
|
||||
() => perpPosition?.tradeDirection || 'long',
|
||||
[perpPosition?.tradeDirection],
|
||||
@ -43,26 +41,29 @@ export default function usePerpsManageModule(amount: BigNumber | null) {
|
||||
|
||||
const previousLeverage = useMemo(
|
||||
() =>
|
||||
price.times(demagnify(previousAmount, perpsAsset)).div(accountNetValue).plus(1).toNumber(),
|
||||
price
|
||||
.times(demagnify(previousAmount.abs(), perpsAsset))
|
||||
.div(accountNetValue)
|
||||
.plus(1)
|
||||
.toNumber(),
|
||||
[accountNetValue, perpsAsset, previousAmount, price],
|
||||
)
|
||||
|
||||
const leverage = useMemo(
|
||||
() =>
|
||||
price
|
||||
.times(demagnify(amount ?? BN_ZERO, perpsAsset))
|
||||
.times(demagnify(previousAmount.plus(amount ?? BN_ZERO).abs(), perpsAsset))
|
||||
.div(accountNetValue)
|
||||
.plus(1)
|
||||
.toNumber(),
|
||||
[accountNetValue, amount, perpsAsset, price],
|
||||
[accountNetValue, amount, perpsAsset, previousAmount, price],
|
||||
)
|
||||
|
||||
return {
|
||||
closeManagePerpModule,
|
||||
previousAmount,
|
||||
previousTradeDirection,
|
||||
previousLeverage,
|
||||
leverage,
|
||||
asset: perpsAsset,
|
||||
hasActivePosition,
|
||||
}
|
||||
}
|
@ -4,25 +4,32 @@ import Button from 'components/common/Button'
|
||||
import { ChevronDown } from 'components/common/Icons'
|
||||
import Text from 'components/common/Text'
|
||||
import AssetOverlay from 'components/trade/TradeModule/AssetSelector/AssetOverlay'
|
||||
import useCurrentAccount from 'hooks/accounts/useCurrentAccount'
|
||||
import usePerpsEnabledAssets from 'hooks/assets/usePerpsEnabledAssets'
|
||||
import usePerpsAsset from 'hooks/perps/usePerpsAsset'
|
||||
import useStore from 'store'
|
||||
|
||||
interface Props {
|
||||
asset: Asset
|
||||
hasActivePosition: boolean
|
||||
}
|
||||
|
||||
export default function AssetSelectorPerps(props: Props) {
|
||||
const assetOverlayState = useStore((s) => s.assetOverlayState)
|
||||
const { perpsAsset, updatePerpsAsset } = usePerpsAsset()
|
||||
const currentAccount = useCurrentAccount()
|
||||
|
||||
const perpAssets = usePerpsEnabledAssets()
|
||||
|
||||
const onChangePerpsAsset = useCallback(
|
||||
(asset: Asset) => {
|
||||
updatePerpsAsset(asset.denom)
|
||||
let hasPosition = false
|
||||
if (currentAccount && currentAccount.perps.find((perp) => perp.denom === asset.denom)) {
|
||||
hasPosition = true
|
||||
}
|
||||
updatePerpsAsset(asset.denom, hasPosition)
|
||||
},
|
||||
[updatePerpsAsset],
|
||||
[currentAccount, updatePerpsAsset],
|
||||
)
|
||||
|
||||
const handleChangeState = useCallback(() => {
|
||||
@ -37,9 +44,15 @@ export default function AssetSelectorPerps(props: Props) {
|
||||
onClick={() => useStore.setState({ assetOverlayState: 'pair' })}
|
||||
className='flex items-center justify-between w-full py-5 bg-white/5'
|
||||
>
|
||||
<div className='flex gap-2 items-center'>
|
||||
<Text size='sm' className='text-white/60'>
|
||||
<span className='text-white'>{perpsAsset.symbol}</span>/USD
|
||||
</Text>
|
||||
|
||||
{props.hasActivePosition && (
|
||||
<div className='px-1.5 py-0.5 bg-white/20 rounded-sm text-white text-xs'>Active</div>
|
||||
)}
|
||||
</div>
|
||||
<div className='flex items-center gap-2'>
|
||||
<Text>All markets</Text>
|
||||
<ChevronDown className='w-3 h-3' />
|
||||
|
@ -6,6 +6,7 @@ import { LocalStorageKeys } from 'constants/localStorageKeys'
|
||||
import usePerpsEnabledAssets from 'hooks/assets/usePerpsEnabledAssets'
|
||||
import useLocalStorage from 'hooks/localStorage/useLocalStorage'
|
||||
import useChainConfig from 'hooks/useChainConfig'
|
||||
import { SearchParams } from 'types/enums/searchParams'
|
||||
import { getSearchParamsObject } from 'utils/route'
|
||||
|
||||
export default function usePerpsAsset() {
|
||||
@ -18,10 +19,12 @@ export default function usePerpsAsset() {
|
||||
>(chainConfig.id + '/' + LocalStorageKeys.PERPS_ASSET, DEFAULT_SETTINGS.perpsAsset)
|
||||
|
||||
const updatePerpsAsset = useCallback(
|
||||
(denom: string) => {
|
||||
(denom: string, manage?: boolean) => {
|
||||
const params = getSearchParamsObject(searchParams)
|
||||
params.perpsMarket = denom
|
||||
setSearchParams(params)
|
||||
setSearchParams({
|
||||
...params,
|
||||
[SearchParams.PERPS_MARKET]: denom,
|
||||
})
|
||||
setPerpsAssetInLocalStorage(denom)
|
||||
},
|
||||
[searchParams, setPerpsAssetInLocalStorage, setSearchParams],
|
||||
|
@ -15,8 +15,8 @@ export default function usePerpsMarket() {
|
||||
clients && perpsAsset && `chains/${chainConfig.id}/perps/${perpsAsset.denom}`,
|
||||
() => getPerpsMarket(clients!, perpsAsset!),
|
||||
{
|
||||
refreshInterval: 1000,
|
||||
dedupingInterval: 1000,
|
||||
refreshInterval: 5000,
|
||||
dedupingInterval: 5000,
|
||||
},
|
||||
)
|
||||
}
|
||||
|
@ -1,22 +1,14 @@
|
||||
import { useSearchParams } from 'react-router-dom'
|
||||
|
||||
import { PerpsManageModule } from 'components/perps/Module/PerpsManageModule'
|
||||
import { PerpsModule } from 'components/perps/Module/PerpsModule'
|
||||
import { PerpsChart } from 'components/perps/PerpsChart'
|
||||
import { PerpsInfo } from 'components/perps/PerpsInfo'
|
||||
import { PerpsPositions } from 'components/perps/PerpsPositions'
|
||||
import { SearchParams } from 'types/enums/searchParams'
|
||||
|
||||
export default function PerpsPage() {
|
||||
const [searchParams] = useSearchParams()
|
||||
|
||||
const isManagingPosition = searchParams.get(SearchParams.PERPS_MANAGE) === 'true'
|
||||
|
||||
return (
|
||||
<div className='grid grid-cols-[auto_376px] grid-rows-[min-content_auto_auto] w-full gap-4'>
|
||||
<PerpsInfo />
|
||||
<div className='h-full w-[376px] row-span-3 relative'>
|
||||
{isManagingPosition ? <PerpsManageModule /> : <PerpsModule />}
|
||||
<PerpsModule />
|
||||
</div>
|
||||
<PerpsChart />
|
||||
<PerpsPositions />
|
||||
|
@ -1,5 +1,4 @@
|
||||
export enum SearchParams {
|
||||
ACCOUNT_ID = 'accountId',
|
||||
PERPS_MARKET = 'perpsMarket',
|
||||
PERPS_MANAGE = 'perpsManage',
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user