Skip to content

Commit

Permalink
limit order imporovement (#2306)
Browse files Browse the repository at this point in the history
  • Loading branch information
nguyenhoaidanh authored Oct 23, 2023
1 parent b0d15d0 commit 3d921e9
Show file tree
Hide file tree
Showing 20 changed files with 337 additions and 65 deletions.
Binary file added src/assets/images/limit_order_pnl.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
41 changes: 41 additions & 0 deletions src/components/SwapForm/GasPriceNote.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { ChainId } from '@kyberswap/ks-sdk-core'
import { Trans, t } from '@lingui/macro'
import { FC } from 'react'
import { Text } from 'rebass'

import WarningNote from 'components/WarningNote'
import { useActiveWeb3React } from 'hooks'
import useTheme from 'hooks/useTheme'
import { useSwitchPairToLimitOrder } from 'state/swap/hooks'

type Props = {
gasUsd?: string
}

const GAS_USD_THRESHOLD = 20
const GasPriceNote: FC<Props> = ({ gasUsd = 0 }) => {
const theme = useTheme()

const { chainId } = useActiveWeb3React()
const switchToLimitOrder = useSwitchPairToLimitOrder()
if (+gasUsd < GAS_USD_THRESHOLD || chainId !== ChainId.MAINNET) return null

return (
<WarningNote
shortText={t`Gas fee is higher than $${GAS_USD_THRESHOLD}.`}
longText={
<Text>
<Trans>
Do you want to make a{' '}
<Text as="b" sx={{ cursor: 'pointer' }} color={theme.primary} onClick={switchToLimitOrder}>
Limit Order
</Text>{' '}
instead?
</Trans>
</Text>
}
/>
)
}

export default GasPriceNote
49 changes: 35 additions & 14 deletions src/components/SwapForm/PriceImpactNote.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,11 @@ import { FC } from 'react'
import { Text } from 'rebass'
import styled from 'styled-components'

import Column from 'components/Column'
import Row from 'components/Row'
import WarningNote from 'components/WarningNote'
import useTheme from 'hooks/useTheme'
import { useSwitchPairToLimitOrder } from 'state/swap/hooks'
import { checkPriceImpact } from 'utils/prices'

const TextUnderlineColor = styled(Text)`
Expand All @@ -28,10 +31,13 @@ const PRICE_IMPACT_EXPLANATION_URL =
type Props = {
isDegenMode?: boolean
priceImpact: number | undefined
showLimitOrderLink?: boolean
}

const PriceImpactNote: FC<Props> = ({ isDegenMode, priceImpact }) => {
const PriceImpactNote: FC<Props> = ({ isDegenMode, priceImpact, showLimitOrderLink = false }) => {
const priceImpactResult = checkPriceImpact(priceImpact)
const theme = useTheme()
const switchToLimitOrder = useSwitchPairToLimitOrder()

if (typeof priceImpact !== 'number') {
return null
Expand Down Expand Up @@ -71,6 +77,18 @@ const PriceImpactNote: FC<Props> = ({ isDegenMode, priceImpact }) => {
)
}

const limitOrderNote = showLimitOrderLink ? (
<Text>
<Trans>
Do you want to make a{' '}
<Text as="b" sx={{ cursor: 'pointer' }} color={theme.primary} onClick={switchToLimitOrder}>
Limit Order
</Text>{' '}
instead?
</Trans>
</Text>
) : undefined

// VERY high
if (priceImpactResult.isVeryHigh) {
return (
Expand All @@ -89,18 +107,21 @@ const PriceImpactNote: FC<Props> = ({ isDegenMode, priceImpact }) => {
</Row>
}
longText={
<Text>
{isDegenMode ? (
<Trans>
You have turned on Degen Mode from settings. Trades with very high price impact can be executed
</Trans>
) : (
<Trans>
You can turn on Degen Mode from Settings to execute trades with very high price impact. This can result
in bad rates and loss of funds
</Trans>
)}
</Text>
<Column gap="4px">
<Text>
{isDegenMode ? (
<Trans>
You have turned on Degen Mode from settings. Trades with very high price impact can be executed
</Trans>
) : (
<Trans>
You can turn on Degen Mode from Settings to execute trades with very high price impact. This can
result in bad rates and loss of funds
</Trans>
)}
</Text>
{limitOrderNote}
</Column>
}
/>
)
Expand All @@ -120,7 +141,7 @@ const PriceImpactNote: FC<Props> = ({ isDegenMode, priceImpact }) => {
)

if (priceImpactResult.isHigh) {
return <WarningNote shortText={shortText} />
return <WarningNote shortText={shortText} longText={limitOrderNote} />
}

return null
Expand Down
5 changes: 4 additions & 1 deletion src/components/SwapForm/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import AddressInputPanel from 'components/AddressInputPanel'
import { Clock } from 'components/Icons'
import { AutoRow } from 'components/Row'
import SlippageWarningNote from 'components/SlippageWarningNote'
import GasPriceNote from 'components/SwapForm/GasPriceNote'
import InputCurrencyPanel from 'components/SwapForm/InputCurrencyPanel'
import OutputCurrencyPanel from 'components/SwapForm/OutputCurrencyPanel'
import SlippageSettingGroup from 'components/SwapForm/SlippageSettingGroup'
Expand Down Expand Up @@ -259,7 +260,9 @@ const SwapForm: React.FC<SwapFormProps> = props => {

{!isWrapOrUnwrap && <SlippageWarningNote rawSlippage={slippage} isStablePairSwap={isStablePairSwap} />}

<PriceImpactNote priceImpact={routeSummary?.priceImpact} isDegenMode={isDegenMode} />
<PriceImpactNote priceImpact={routeSummary?.priceImpact} isDegenMode={isDegenMode} showLimitOrderLink />

<GasPriceNote gasUsd={routeSummary?.gasUsd} />

<SwapActionButton
isGettingRoute={isGettingRoute}
Expand Down
3 changes: 2 additions & 1 deletion src/components/Tutorial/TutorialSwap/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -399,8 +399,9 @@ const getListSteps = (isLogin: boolean, isSolana: boolean) => {
])
}

const TutorialKeys = {
export const TutorialKeys = {
SHOWED_SWAP_GUIDE: 'showedTutorialSwapGuide',
SHOWED_LO_GUIDE: 'showedTutorialLO',
}

export default memo(function TutorialSwap() {
Expand Down
18 changes: 14 additions & 4 deletions src/components/swapv2/LimitOrder/LimitOrderForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -138,8 +138,15 @@ const LimitOrderForm = forwardRef<LimitOrderFormHandle, Props>(function LimitOrd
const notify = useNotify()
const { mixpanelHandler } = useMixpanel()

const { setCurrencyIn, setCurrencyOut, switchCurrency, removeOrderNeedCreated, resetState, setOrderEditing } =
useLimitActionHandlers()
const {
setCurrencyIn,
setCurrencyOut,
switchCurrency,
removeOrderNeedCreated,
resetState,
setOrderEditing,
setInputValue: setInputValueGlobal,
} = useLimitActionHandlers()
const { ordersNeedCreated, inputAmount: inputAmountGlobal } = useLimitState()

const [inputAmount, setInputAmount] = useState(defaultInputAmount)
Expand Down Expand Up @@ -526,8 +533,11 @@ const LimitOrderForm = forwardRef<LimitOrderFormHandle, Props>(function LimitOrd
}, [account, chainId, ordersNeedCreated, removeOrderNeedCreated, refreshActiveMakingAmount, isEdit])

useEffect(() => {
if (inputAmountGlobal) onSetInput(inputAmountGlobal)
}, [inputAmountGlobal, onSetInput]) // when redux state change, ex: type and swap
if (inputAmountGlobal) {
onSetInput(inputAmountGlobal)
setInputValueGlobal('')
}
}, [inputAmountGlobal, onSetInput, setInputValueGlobal]) // when redux state change, ex: type and swap

useEffect(() => {
return () => {
Expand Down
19 changes: 16 additions & 3 deletions src/components/swapv2/LimitOrder/ListOrder/ActionButtons.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,14 @@ const ActionButtons = ({

const iconExpand =
((isActiveTab && numberTxs >= 1) || (!isActiveTab && numberTxs > 1)) && !isChildren ? (
<IconWrap color={theme.subText} onClick={onExpand} style={itemStyle}>
<IconWrap
color={theme.subText}
onClick={e => {
e.stopPropagation()
onExpand?.()
}}
style={itemStyle}
>
<DropdownArrowIcon rotate={!!expand} color={theme.subText} />
</IconWrap>
) : null
Expand All @@ -131,7 +138,10 @@ const ActionButtons = ({
<IconWrap
color={theme.primary}
style={itemStyle}
onClick={() => onEditOrder?.(order)}
onClick={e => {
e.stopPropagation()
onEditOrder?.(order)
}}
isDisabled={disabledCancel}
>
<Edit3 color={disabledCancel ? theme.border : theme.primary} size={15} />
Expand All @@ -143,7 +153,10 @@ const ActionButtons = ({
color={theme.red}
style={itemStyle}
isDisabled={disabledCancel}
onClick={() => onCancelOrder?.(order)}
onClick={e => {
e.stopPropagation()
onCancelOrder?.(order)
}}
>
<Trash color={disabledCancel ? theme.border : theme.red} size={15} />
</IconWrap>
Expand Down
35 changes: 29 additions & 6 deletions src/components/swapv2/LimitOrder/ListOrder/OrderItem.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
import { Token } from '@kyberswap/ks-sdk-core'
import { Trans, t } from '@lingui/macro'
import dayjs from 'dayjs'
import { rgba } from 'polished'
import { stringify } from 'querystring'
import { useMemo, useState } from 'react'
import { Repeat } from 'react-feather'
import { useNavigate } from 'react-router-dom'
import { useMedia } from 'react-use'
import { Flex, Text } from 'rebass'
import styled, { CSSProperties, DefaultTheme } from 'styled-components'
Expand All @@ -27,6 +30,10 @@ export const ItemWrapper = styled.div<{ hasBorder?: boolean; active?: boolean }>
display: grid;
gap: 10px;
align-items: center;
cursor: pointer;
:hover {
background-color: ${({ theme }) => rgba(theme.primary, 0.2)};
}
${({ theme, active }) => theme.mediaWidth.upToLarge`
grid-template-columns: 1.5fr 1.5fr 1.5fr ${active ? '110px' : '80px'};
.rate {
Expand Down Expand Up @@ -61,7 +68,7 @@ const Colum = styled.div`
const TimeText = ({ time, style = {} }: { time: number; style?: CSSProperties }) => {
const theme = useTheme()
return (
<Flex fontWeight={'500'} color={theme.subText} style={style}>
<Flex fontWeight={'500'} color={theme.text} style={style}>
<Text>{dayjs(time * 1000).format('DD/MM/YYYY')}</Text>
&nbsp; <Text>{dayjs(time * 1000).format('HH:mm')}</Text>
</Flex>
Expand Down Expand Up @@ -124,7 +131,7 @@ const AmountInfo = ({ order }: { order: LimitOrder }) => {
<SingleAmountInfo
decimals={makerAssetDecimals}
plus={false}
color={theme.border}
color={theme.subText}
logoUrl={makerAssetLogoURL}
amount={makingAmount}
symbol={makerAssetSymbol}
Expand All @@ -141,8 +148,8 @@ const TradeRateOrder = ({ order, style = {} }: { order: LimitOrder; style?: CSSP
return (
<Colum style={style}>
<Flex style={{ gap: 6, cursor: 'pointer', alignItems: 'center' }} onClick={() => setInvert(!invert)}>
<Text color={theme.subText}>{!invert ? `${symbolOut}/${symbolIn}` : `${symbolIn}/${symbolOut}`}</Text>
<Repeat color={theme.subText} size={12} />
<Text color={theme.text}>{!invert ? `${symbolOut}/${symbolIn}` : `${symbolIn}/${symbolOut}`}</Text>
<Repeat color={theme.text} size={12} />
</Flex>
<Text color={theme.text}>{formatRateLimitOrder(order, invert)}</Text>
</Colum>
Expand Down Expand Up @@ -239,6 +246,8 @@ export default function OrderItem({
transactions = [],
takerAssetSymbol,
takerAssetDecimals,
takerAsset,
makerAsset,
} = order
const status = isCancelling ? LimitOrderStatus.CANCELLING : order.status
const isOrderActive = isActiveStatus(order.status)
Expand All @@ -261,6 +270,16 @@ export default function OrderItem({
const selectedPrice = Number(formatRateLimitOrder(order, false))
const percent = ((marketPrice - selectedPrice) / marketPrice) * 100

const navigate = useNavigate()
const onClickOrder = () => {
navigate({
search: stringify({
inputCurrency: makerAsset,
outputCurrency: takerAsset,
}),
})
}

const renderProgressComponent = () => {
const getTooltipText = () => {
const texts = [<Trans key={0}>Insufficient {order.makerAssetSymbol} balance for order execution.</Trans>]
Expand Down Expand Up @@ -312,7 +331,7 @@ export default function OrderItem({

if (upToSmall) {
return (
<ItemWrapperMobile>
<ItemWrapperMobile onClick={onClickOrder}>
<Flex justifyContent={'space-between'}>
<AmountInfo order={order} />
<ActionButtons
Expand Down Expand Up @@ -370,7 +389,11 @@ export default function OrderItem({
}
return (
<>
<ItemWrapper hasBorder={isLast ? false : !transactions.length || !expand} active={hasOrderCancelling}>
<ItemWrapper
hasBorder={isLast ? false : !transactions.length || !expand}
active={hasOrderCancelling}
onClick={onClickOrder}
>
<Flex alignItems={'center'} style={{ gap: 10 }}>
<IndexText>{index + 1}</IndexText>
<AmountInfo order={order} />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ export default function CancelStatusCountDown({
</Timer>
<Text fontSize={'10px'} fontWeight={'400'} color={theme.subText}>
<Trans>*There is a possibility that the order might be filled before cancellation.</Trans>{' '}
<ExternalLink href={DOCS_LINKS.USER_GUIDE}>
<ExternalLink href={DOCS_LINKS.CANCEL_GUIDE}>
<Trans>Learn more ↗︎</Trans>
</ExternalLink>
</Text>
Expand Down Expand Up @@ -139,7 +139,7 @@ export default function CancelStatusCountDown({
<Flex sx={{ gap: '4px' }}>
<Trans>Your request has timed out.</Trans>{' '}
<Text fontSize={'10px'} fontWeight={'400'} alignSelf={'flex-end'}>
<ExternalLink href={DOCS_LINKS.USER_GUIDE}>
<ExternalLink href={DOCS_LINKS.CANCEL_GUIDE}>
<Trans>Learn more ↗︎</Trans>
</ExternalLink>
</Text>
Expand Down
Loading

0 comments on commit 3d921e9

Please sign in to comment.