Merge pull request #234 from blockworks-foundation/favorite-swaps
add favoriting swap pairs
This commit is contained in:
commit
f37f352975
|
@ -0,0 +1,56 @@
|
||||||
|
import { StarIcon } from '@heroicons/react/24/outline'
|
||||||
|
import { StarIcon as FilledStarIcon } from '@heroicons/react/20/solid'
|
||||||
|
import useLocalStorageState from 'hooks/useLocalStorageState'
|
||||||
|
import { FAVORITE_SWAPS_KEY } from 'utils/constants'
|
||||||
|
import { useMemo } from 'react'
|
||||||
|
import Tooltip from '@components/shared/Tooltip'
|
||||||
|
import { useTranslation } from 'react-i18next'
|
||||||
|
|
||||||
|
const FavoriteSwapButton = ({
|
||||||
|
inputToken,
|
||||||
|
outputToken,
|
||||||
|
}: {
|
||||||
|
inputToken: string
|
||||||
|
outputToken: string
|
||||||
|
}) => {
|
||||||
|
const { t } = useTranslation('swap')
|
||||||
|
const [favoriteSwaps, setFavoriteSwaps] = useLocalStorageState<string[]>(
|
||||||
|
FAVORITE_SWAPS_KEY,
|
||||||
|
[],
|
||||||
|
)
|
||||||
|
|
||||||
|
const swapPair = useMemo(() => {
|
||||||
|
return `${inputToken}/${outputToken}`
|
||||||
|
}, [inputToken, outputToken])
|
||||||
|
|
||||||
|
const addToFavorites = (pair: string) => {
|
||||||
|
const newFavorites = [...favoriteSwaps, pair]
|
||||||
|
setFavoriteSwaps(newFavorites)
|
||||||
|
}
|
||||||
|
|
||||||
|
const removeFromFavorites = (marketName: string) => {
|
||||||
|
setFavoriteSwaps(favoriteSwaps.filter((m: string) => m !== marketName))
|
||||||
|
}
|
||||||
|
|
||||||
|
return favoriteSwaps.find((pair: string) => pair === swapPair) ? (
|
||||||
|
<Tooltip content={t('swap:tooltip-favorite-swap-remove')}>
|
||||||
|
<button
|
||||||
|
className="flex items-center justify-center text-th-active focus-visible:text-th-fgd-4 md:hover:text-th-fgd-3"
|
||||||
|
onClick={() => removeFromFavorites(swapPair)}
|
||||||
|
>
|
||||||
|
<FilledStarIcon className="h-5 w-5" />
|
||||||
|
</button>
|
||||||
|
</Tooltip>
|
||||||
|
) : (
|
||||||
|
<Tooltip content={t('swap:tooltip-favorite-swap-add')}>
|
||||||
|
<button
|
||||||
|
className="flex items-center justify-center text-th-fgd-4 focus-visible:text-th-active md:hover:text-th-active"
|
||||||
|
onClick={() => addToFavorites(swapPair)}
|
||||||
|
>
|
||||||
|
<StarIcon className="h-5 w-5" />
|
||||||
|
</button>
|
||||||
|
</Tooltip>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default FavoriteSwapButton
|
|
@ -0,0 +1,58 @@
|
||||||
|
import { Transition } from '@headlessui/react'
|
||||||
|
import { StarIcon } from '@heroicons/react/20/solid'
|
||||||
|
import useLocalStorageState from 'hooks/useLocalStorageState'
|
||||||
|
import useMangoGroup from 'hooks/useMangoGroup'
|
||||||
|
import { FAVORITE_SWAPS_KEY } from 'utils/constants'
|
||||||
|
import { LinkButton } from '@components/shared/Button'
|
||||||
|
import { Bank } from '@blockworks-foundation/mango-v4'
|
||||||
|
import mangoStore from '@store/mangoStore'
|
||||||
|
|
||||||
|
const set = mangoStore.getState().set
|
||||||
|
|
||||||
|
const FavoriteSwapsBar = () => {
|
||||||
|
const [favoriteSwaps] = useLocalStorageState(FAVORITE_SWAPS_KEY, [])
|
||||||
|
const { group } = useMangoGroup()
|
||||||
|
|
||||||
|
const handleFavoriteClick = (
|
||||||
|
inputBank: Bank | undefined,
|
||||||
|
outputBank: Bank | undefined,
|
||||||
|
) => {
|
||||||
|
if (!inputBank || !outputBank) return
|
||||||
|
set((state) => {
|
||||||
|
state.swap.inputBank = inputBank
|
||||||
|
state.swap.outputBank = outputBank
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Transition
|
||||||
|
className="hide-scroll flex items-center space-x-2 overflow-x-auto border-b border-th-bkg-3 bg-th-bkg-2 py-1 px-4 md:space-x-4 md:px-6"
|
||||||
|
show={!!favoriteSwaps.length}
|
||||||
|
enter="transition-all ease-in duration-200"
|
||||||
|
enterFrom="opacity-0 h-0"
|
||||||
|
enterTo="opacity-100 h-8"
|
||||||
|
leave="transition-all ease-out duration-200"
|
||||||
|
leaveFrom="opacity-100 h-8"
|
||||||
|
leaveTo="opacity-0 h-0"
|
||||||
|
>
|
||||||
|
<StarIcon className="h-4 w-4 flex-shrink-0 text-th-fgd-4" />
|
||||||
|
{favoriteSwaps.map((pair: string) => {
|
||||||
|
const inputToken = pair.split('/')[0]
|
||||||
|
const outputToken = pair.split('/')[1]
|
||||||
|
const inputBank = group?.banksMapByName.get(inputToken)?.[0]
|
||||||
|
const outputBank = group?.banksMapByName.get(outputToken)?.[0]
|
||||||
|
return (
|
||||||
|
<LinkButton
|
||||||
|
className={`flex items-center whitespace-nowrap py-1 text-xs hover:text-th-active hover:opacity-100 focus-visible:text-th-fgd-1 focus-visible:opacity-100 focus-visible:outline-none`}
|
||||||
|
key={pair}
|
||||||
|
onClick={() => handleFavoriteClick(inputBank, outputBank)}
|
||||||
|
>
|
||||||
|
<span className="mb-0 mr-1.5 text-xs">{pair}</span>
|
||||||
|
</LinkButton>
|
||||||
|
)
|
||||||
|
})}
|
||||||
|
</Transition>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default FavoriteSwapsBar
|
|
@ -12,6 +12,7 @@ import mangoStore from '@store/mangoStore'
|
||||||
// import useLocalStorageState from 'hooks/useLocalStorageState'
|
// import useLocalStorageState from 'hooks/useLocalStorageState'
|
||||||
// import { IS_ONBOARDED_KEY } from 'utils/constants'
|
// import { IS_ONBOARDED_KEY } from 'utils/constants'
|
||||||
import SwapTokenChart from './SwapTokenChart'
|
import SwapTokenChart from './SwapTokenChart'
|
||||||
|
import FavoriteSwapsBar from './FavoriteSwapsBar'
|
||||||
|
|
||||||
const SwapPage = () => {
|
const SwapPage = () => {
|
||||||
const { mangoAccountAddress } = useMangoAccount()
|
const { mangoAccountAddress } = useMangoAccount()
|
||||||
|
@ -34,6 +35,9 @@ const SwapPage = () => {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className="grid grid-cols-12">
|
<div className="grid grid-cols-12">
|
||||||
|
<div className="col-span-12">
|
||||||
|
<FavoriteSwapsBar />
|
||||||
|
</div>
|
||||||
<div className="col-span-12 border-th-bkg-3 md:col-span-6 md:border-b lg:col-span-7 xl:col-span-8">
|
<div className="col-span-12 border-th-bkg-3 md:col-span-6 md:border-b lg:col-span-7 xl:col-span-8">
|
||||||
<SwapTokenChart />
|
<SwapTokenChart />
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -48,6 +48,7 @@ import { IconButton } from '@components/shared/Button'
|
||||||
import Tooltip from '@components/shared/Tooltip'
|
import Tooltip from '@components/shared/Tooltip'
|
||||||
import { SwapHistoryItem } from 'types'
|
import { SwapHistoryItem } from 'types'
|
||||||
import useThemeWrapper from 'hooks/useThemeWrapper'
|
import useThemeWrapper from 'hooks/useThemeWrapper'
|
||||||
|
import FavoriteSwapButton from './FavoriteSwapButton'
|
||||||
|
|
||||||
dayjs.extend(relativeTime)
|
dayjs.extend(relativeTime)
|
||||||
|
|
||||||
|
@ -549,6 +550,10 @@ const SwapTokenChart = () => {
|
||||||
</div>
|
</div>
|
||||||
<div className="mt-2 h-40 w-auto md:h-72">
|
<div className="mt-2 h-40 w-auto md:h-72">
|
||||||
<div className="absolute top-[2px] right-0 -mb-2 flex items-center justify-end space-x-4">
|
<div className="absolute top-[2px] right-0 -mb-2 flex items-center justify-end space-x-4">
|
||||||
|
<FavoriteSwapButton
|
||||||
|
inputToken={inputBank!.name}
|
||||||
|
outputToken={outputBank!.name}
|
||||||
|
/>
|
||||||
<Tooltip
|
<Tooltip
|
||||||
content={
|
content={
|
||||||
showSwaps
|
showSwaps
|
||||||
|
|
|
@ -39,6 +39,8 @@
|
||||||
"tooltip-borrow-no-balance": "You'll borrow {{borrowAmount}} {{token}} to execute this swap. The current {{token}} variable borrow rate is {{rate}}%",
|
"tooltip-borrow-no-balance": "You'll borrow {{borrowAmount}} {{token}} to execute this swap. The current {{token}} variable borrow rate is {{rate}}%",
|
||||||
"tooltip-margin": "When margin is enabled you can add leverage to your swaps. Borrows are opened automatically if a swap exceeds your balance.",
|
"tooltip-margin": "When margin is enabled you can add leverage to your swaps. Borrows are opened automatically if a swap exceeds your balance.",
|
||||||
"tooltip-max-slippage": "If price slips beyond your maximum slippage your swap will not be executed",
|
"tooltip-max-slippage": "If price slips beyond your maximum slippage your swap will not be executed",
|
||||||
|
"tooltip-favorite-swap-add": "Add pair to favorites",
|
||||||
|
"tooltip-favorite-swap-remove": "Remove pair from favorites",
|
||||||
"use-margin": "Allow Margin",
|
"use-margin": "Allow Margin",
|
||||||
"no-swap-found": "No swap found"
|
"no-swap-found": "No swap found"
|
||||||
}
|
}
|
|
@ -45,6 +45,8 @@ export const TRADE_CHART_UI_KEY = 'tradeChart-0.3'
|
||||||
|
|
||||||
export const FAVORITE_MARKETS_KEY = 'favoriteMarkets-0.2'
|
export const FAVORITE_MARKETS_KEY = 'favoriteMarkets-0.2'
|
||||||
|
|
||||||
|
export const FAVORITE_SWAPS_KEY = 'favoriteSwaps-0.1'
|
||||||
|
|
||||||
export const THEME_KEY = 'theme-0.1'
|
export const THEME_KEY = 'theme-0.1'
|
||||||
|
|
||||||
export const RPC_PROVIDER_KEY = 'rpcProviderKey-0.7'
|
export const RPC_PROVIDER_KEY = 'rpcProviderKey-0.7'
|
||||||
|
|
Loading…
Reference in New Issue