mars-v2-frontend/src/components/perps/Module/PerpsModule.tsx
Linkie Link 6ac7708ca5
feat: debounce input sliders (#784)
* feat: debounce input sliders

* fix: fixed the debounce function
2024-02-09 08:29:26 +01:00

145 lines
4.6 KiB
TypeScript

import debounce from 'lodash.debounce'
import { useCallback, useEffect, useMemo, useState } from 'react'
import Card from 'components/common/Card'
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 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'
import { AvailableOrderType } from 'components/trade/TradeModule/SwapForm/OrderTypeSelector/types'
import { BN_ZERO } from 'constants/math'
import useCurrentAccount from 'hooks/accounts/useCurrentAccount'
import usePerpsAsset from 'hooks/perps/usePerpsAsset'
import { useUpdatedAccount } from 'hooks/useUpdatedAccount'
import getPerpsPosition from 'utils/getPerpsPosition'
import { BN } from 'utils/helpers'
export function PerpsModule() {
const [selectedOrderType, setSelectedOrderType] = useState<AvailableOrderType>('Market')
const [tradeDirection, setTradeDirection] = useState<TradeDirection>('long')
const { perpsAsset } = usePerpsAsset()
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(
() =>
debounce((perpsPosition: PerpsPosition) => {
if (
addedPerps &&
perpsPosition.amount === addedPerps.amount &&
perpsPosition.tradeDirection === addedPerps.tradeDirection
)
return
simulatePerps(perpsPosition)
}, 100),
[simulatePerps, addedPerps],
)
useEffect(() => {
const perpsPosition = getPerpsPosition(
perpsAsset,
amount ?? previousAmount,
tradeDirection ?? previousTradeDirection,
)
debouncedUpdateAccount(perpsPosition)
}, [
debouncedUpdateAccount,
amount,
perpsAsset,
tradeDirection,
previousAmount,
previousTradeDirection,
])
const onDebounce = useCallback(() => {
// TODO: Implement debounced simulation
}, [])
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} hasActivePosition={hasActivePosition} />}
className='h-full mb-4'
>
<OrderTypeSelector selected={selectedOrderType} onChange={setSelectedOrderType} />
<TradeDirectionSelector
direction={tradeDirection}
onChangeDirection={onChangeTradeDirection}
/>
<AssetAmountInput
label='Amount'
max={BN(1000000)} // TODO: Implement max calculation
amount={amount.abs()}
setAmount={onChangeAmount}
asset={perpsAsset}
maxButtonLabel='Max:'
disabled={false}
/>
{!hasActivePosition && (
<>
<Or />
<Text size='sm'>Position Leverage</Text>
<LeverageSlider
min={1}
max={10}
value={leverage}
onChange={setLeverage}
onDebounce={onDebounce}
type={tradeDirection}
/>
<LeverageButtons />
</>
)}
<Spacer />
<PerpsSummary
amount={amount ?? previousAmount}
tradeDirection={tradeDirection ?? previousTradeDirection}
asset={perpsAsset}
leverage={leverage}
previousAmount={previousAmount}
previousTradeDirection={previousTradeDirection}
previousLeverage={previousLeverage}
hasActivePosition={hasActivePosition}
onTxExecuted={() => setAmount(BN_ZERO)}
/>
</Card>
)
}