feat: separate v1 implementation
This commit is contained in:
parent
89e9942b7e
commit
071cceacec
@ -1,6 +1,6 @@
|
||||
import classNames from 'classnames'
|
||||
import { useCallback, useMemo } from 'react'
|
||||
import { useLocation, useNavigate, useSearchParams } from 'react-router-dom'
|
||||
import { useNavigate, useSearchParams } from 'react-router-dom'
|
||||
import { useSWRConfig } from 'swr'
|
||||
|
||||
import Button from 'components/common/Button'
|
||||
@ -15,11 +15,16 @@ import useToggle from 'hooks/useToggle'
|
||||
import useStore from 'store'
|
||||
import { NETWORK } from 'types/enums/network'
|
||||
import { ChainInfoID } from 'types/enums/wallet'
|
||||
import { getPage, getRoute } from 'utils/route'
|
||||
import { getRoute } from 'utils/route'
|
||||
|
||||
const v1Outposts = [
|
||||
{ chainId: ChainInfoID.Neutron1, name: 'Neutron', url: 'https://neutron.marsprotocol.io' },
|
||||
{ chainId: ChainInfoID.Osmosis1, name: 'Osmosis', url: 'https://v1.marsprotocol.io' },
|
||||
{
|
||||
chainId: ChainInfoID.Neutron1,
|
||||
name: 'Neutron',
|
||||
url: 'https://neutron.marsprotocol.io',
|
||||
target: '_blank',
|
||||
},
|
||||
{ chainId: ChainInfoID.Osmosis1, name: 'Osmosis', url: '/v1', target: '_self' },
|
||||
]
|
||||
|
||||
export default function ChainSelect() {
|
||||
@ -27,8 +32,8 @@ export default function ChainSelect() {
|
||||
const chainConfig = useChainConfig()
|
||||
const { mutate } = useSWRConfig()
|
||||
const navigate = useNavigate()
|
||||
const { pathname } = useLocation()
|
||||
const [searchParams] = useSearchParams()
|
||||
const isV1 = useStore((s) => s.isV1)
|
||||
|
||||
const [_, setCurrentChainId] = useCurrentChainId()
|
||||
|
||||
@ -39,14 +44,15 @@ export default function ChainSelect() {
|
||||
mutate(() => true)
|
||||
useStore.setState({
|
||||
chainConfig,
|
||||
isV1: false,
|
||||
client: undefined,
|
||||
address: undefined,
|
||||
userDomain: undefined,
|
||||
balances: [],
|
||||
})
|
||||
navigate(getRoute(getPage(pathname), searchParams))
|
||||
navigate(getRoute('trade', searchParams))
|
||||
},
|
||||
[setCurrentChainId, setShowMenu, mutate, navigate, pathname, searchParams],
|
||||
[setCurrentChainId, setShowMenu, mutate, navigate, searchParams],
|
||||
)
|
||||
|
||||
const currentChains = useMemo(() => {
|
||||
@ -80,7 +86,7 @@ export default function ChainSelect() {
|
||||
<li
|
||||
className={classNames(
|
||||
'w-full py-2 flex gap-3 group/chain text-white items-center',
|
||||
chainConfig.name === chain.name
|
||||
chainConfig.name === chain.name && !isV1
|
||||
? 'pointer-events-none'
|
||||
: 'opacity-60 hover:opacity-100',
|
||||
)}
|
||||
@ -108,14 +114,22 @@ export default function ChainSelect() {
|
||||
<ul className='w-full px-4 py-3 list-none'>
|
||||
{v1Outposts.map((outpost) => (
|
||||
<li
|
||||
className='flex items-center w-full gap-3 py-2 text-white group/chain opacity-60 hover:opacity-100'
|
||||
className={classNames(
|
||||
'w-full py-2 flex gap-3 group/chain text-white items-center',
|
||||
chainConfig.name === outpost.name && isV1
|
||||
? 'pointer-events-none'
|
||||
: 'opacity-60 hover:opacity-100',
|
||||
)}
|
||||
role='button'
|
||||
onClick={() => window.open(outpost.url, '_blank')}
|
||||
onClick={() => window.open(outpost.url, outpost.target)}
|
||||
key={outpost.name}
|
||||
>
|
||||
<ChainLogo chainID={outpost.chainId} className='w-6' />
|
||||
<Text size='sm'>
|
||||
{outpost.name} <ExternalLink className='w-4 ml-1 mb-0.5 inline' />
|
||||
{outpost.name}{' '}
|
||||
{outpost.target !== '_self' && (
|
||||
<ExternalLink className='w-4 ml-1 mb-0.5 inline' />
|
||||
)}
|
||||
</Text>
|
||||
</li>
|
||||
))}
|
||||
|
@ -16,7 +16,7 @@ import useStore from 'store'
|
||||
import { WalletID } from 'types/enums/wallet'
|
||||
import { getGovernanceUrl } from 'utils/helpers'
|
||||
|
||||
export const menuTree = (walletId: WalletID, chainConfig: ChainConfig): MenuTreeEntry[] => [
|
||||
const menuTree = (walletId: WalletID, chainConfig: ChainConfig): MenuTreeEntry[] => [
|
||||
{
|
||||
pages: ['trade', 'trade-advanced'],
|
||||
label: 'Trade',
|
||||
@ -40,7 +40,6 @@ export const menuTree = (walletId: WalletID, chainConfig: ChainConfig): MenuTree
|
||||
{ pages: ['borrow'], label: 'Borrow' },
|
||||
...(chainConfig.hls ? [{ pages: ['hls-staking'] as Page[], label: 'High Leverage' }] : []),
|
||||
{ pages: ['portfolio'], label: 'Portfolio' },
|
||||
{ pages: ['v1'], label: 'V1' },
|
||||
{ pages: ['governance'], label: 'Governance', externalUrl: getGovernanceUrl(walletId) },
|
||||
]
|
||||
|
||||
@ -49,9 +48,8 @@ export default function DesktopHeader() {
|
||||
const focusComponent = useStore((s) => s.focusComponent)
|
||||
const isOracleStale = useStore((s) => s.isOracleStale)
|
||||
const isHLS = useStore((s) => s.isHLS)
|
||||
const isV1 = useStore((s) => s.isV1)
|
||||
const accountId = useAccountId()
|
||||
const showAccountMenu = address && !isHLS && !isV1
|
||||
const showAccountMenu = address && !isHLS
|
||||
|
||||
function handleCloseFocusMode() {
|
||||
if (focusComponent && focusComponent.onClose) focusComponent.onClose()
|
||||
@ -75,7 +73,7 @@ export default function DesktopHeader() {
|
||||
focusComponent ? 'relative isolate' : 'border-b border-white/20',
|
||||
)}
|
||||
>
|
||||
<DesktopNavigation />
|
||||
<DesktopNavigation menuTree={menuTree} />
|
||||
|
||||
{focusComponent ? (
|
||||
<div className='flex justify-between w-full'>
|
||||
|
81
src/components/header/V1DesktopHeader.tsx
Normal file
81
src/components/header/V1DesktopHeader.tsx
Normal file
@ -0,0 +1,81 @@
|
||||
import classNames from 'classnames'
|
||||
import { useMemo } from 'react'
|
||||
import { isDesktop } from 'react-device-detect'
|
||||
|
||||
import Wallet from 'components/Wallet'
|
||||
import EscButton from 'components/common/Button/EscButton'
|
||||
import Settings from 'components/common/Settings'
|
||||
import ChainSelect from 'components/header/ChainSelect'
|
||||
import OracleResyncButton from 'components/header/OracleResyncButton'
|
||||
import RewardsCenter from 'components/header/RewardsCenter'
|
||||
import DesktopNavigation from 'components/header/navigation/DesktopNavigation'
|
||||
import useAccountId from 'hooks/useAccountId'
|
||||
import useStore from 'store'
|
||||
import { WalletID } from 'types/enums/wallet'
|
||||
import { getGovernanceUrl } from 'utils/helpers'
|
||||
|
||||
const menuTree = (walletId: WalletID, chainConfig: ChainConfig): MenuTreeEntry[] => [
|
||||
{
|
||||
pages: ['v1'],
|
||||
label: 'Red Bank',
|
||||
},
|
||||
{ pages: ['governance'], label: 'Governance', externalUrl: getGovernanceUrl(walletId) },
|
||||
]
|
||||
|
||||
export default function DesktopHeader() {
|
||||
const address = useStore((s) => s.address)
|
||||
const focusComponent = useStore((s) => s.focusComponent)
|
||||
const isOracleStale = useStore((s) => s.isOracleStale)
|
||||
const accountId = useAccountId()
|
||||
|
||||
function handleCloseFocusMode() {
|
||||
if (focusComponent && focusComponent.onClose) focusComponent.onClose()
|
||||
useStore.setState({ focusComponent: null })
|
||||
}
|
||||
|
||||
const showStaleOracle = useMemo(() => isOracleStale && address, [isOracleStale, address])
|
||||
|
||||
if (!isDesktop) return null
|
||||
|
||||
return (
|
||||
<header
|
||||
className={classNames(
|
||||
'fixed left-0 top-0 z-50 w-full',
|
||||
'before:content-[" "] before:absolute before:inset-0 before:-z-1 before:h-full before:w-full before:rounded-sm before:backdrop-blur-sticky',
|
||||
)}
|
||||
>
|
||||
<div
|
||||
className={classNames(
|
||||
'flex items-center justify-between px-4 py-4',
|
||||
focusComponent ? 'relative isolate' : 'border-b border-white/20',
|
||||
)}
|
||||
>
|
||||
<DesktopNavigation menuTree={menuTree} />
|
||||
|
||||
{focusComponent ? (
|
||||
<div className='flex justify-between w-full'>
|
||||
<div className='flex h-5 w-13' />
|
||||
{address && (
|
||||
<div className='flex gap-4'>
|
||||
<Wallet />
|
||||
<ChainSelect />
|
||||
</div>
|
||||
)}
|
||||
<div className='flex gap-4'>
|
||||
{!address && <ChainSelect />}
|
||||
<EscButton onClick={handleCloseFocusMode} />
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
<div className='flex gap-4'>
|
||||
{showStaleOracle && <OracleResyncButton />}
|
||||
{accountId && <RewardsCenter />}
|
||||
<Wallet />
|
||||
<ChainSelect />
|
||||
<Settings />
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</header>
|
||||
)
|
||||
}
|
@ -4,7 +4,6 @@ import { useMemo } from 'react'
|
||||
|
||||
import Button from 'components/common/Button'
|
||||
import { ChevronDown, Logo } from 'components/common/Icons'
|
||||
import { menuTree } from 'components/header/DesktopHeader'
|
||||
import { NavLink } from 'components/header/navigation/NavLink'
|
||||
import { NavMenu } from 'components/header/navigation/NavMenu'
|
||||
import useChainConfig from 'hooks/useChainConfig'
|
||||
@ -12,19 +11,24 @@ import useToggle from 'hooks/useToggle'
|
||||
import useStore from 'store'
|
||||
import { WalletID } from 'types/enums/wallet'
|
||||
|
||||
interface Props {
|
||||
menuTree: (walletId: WalletID, chainConfig: ChainConfig) => MenuTreeEntry[]
|
||||
}
|
||||
|
||||
export function getIsActive(pages: string[]) {
|
||||
const segments = location.pathname.split('/')
|
||||
return pages.some((page) => segments.includes(page))
|
||||
}
|
||||
|
||||
export default function DesktopNavigation() {
|
||||
export default function DesktopNavigation(props: Props) {
|
||||
const { menuTree } = props
|
||||
const [showMenu, setShowMenu] = useToggle()
|
||||
const { recentWallet } = useShuttle()
|
||||
const chainConfig = useChainConfig()
|
||||
const walletId = (recentWallet?.providerId as WalletID) ?? WalletID.Keplr
|
||||
const focusComponent = useStore((s) => s.focusComponent)
|
||||
|
||||
const menu = useMemo(() => menuTree(walletId, chainConfig), [walletId, chainConfig])
|
||||
const menu = useMemo(() => menuTree(walletId, chainConfig), [walletId, chainConfig, menuTree])
|
||||
|
||||
return (
|
||||
<div
|
||||
|
@ -4,13 +4,14 @@ import { isMobile } from 'react-device-detect'
|
||||
import { useLocation } from 'react-router-dom'
|
||||
import { SWRConfig } from 'swr'
|
||||
|
||||
import ModalsContainer from 'components/Modals/ModalsContainer'
|
||||
import AccountDetails from 'components/account/AccountDetails'
|
||||
import Background from 'components/common/Background'
|
||||
import Footer from 'components/common/Footer'
|
||||
import PageMetadata from 'components/common/PageMetadata'
|
||||
import Toaster from 'components/common/Toaster'
|
||||
import DesktopHeader from 'components/header/DesktopHeader'
|
||||
import ModalsContainer from 'components/Modals/ModalsContainer'
|
||||
import V1DesktopHeader from 'components/header/V1DesktopHeader'
|
||||
import { DEFAULT_SETTINGS } from 'constants/defaultSettings'
|
||||
import { LocalStorageKeys } from 'constants/localStorageKeys'
|
||||
import useLocalStorage from 'hooks/localStorage/useLocalStorage'
|
||||
@ -50,6 +51,7 @@ export default function Layout({ children }: { children: React.ReactNode }) {
|
||||
const location = useLocation()
|
||||
const focusComponent = useStore((s) => s.focusComponent)
|
||||
const address = useStore((s) => s.address)
|
||||
const isV1 = useStore((s) => s.isV1)
|
||||
|
||||
const [reduceMotion] = useLocalStorage<boolean>(
|
||||
LocalStorageKeys.REDUCE_MOTION,
|
||||
@ -67,7 +69,7 @@ export default function Layout({ children }: { children: React.ReactNode }) {
|
||||
<SWRConfig value={{ use: [debugSWR] }}>
|
||||
<PageMetadata />
|
||||
<Background />
|
||||
<DesktopHeader />
|
||||
{isV1 ? <V1DesktopHeader /> : <DesktopHeader />}
|
||||
<main
|
||||
className={classNames(
|
||||
'lg:min-h-[calc(100dvh-81px)]',
|
||||
|
Loading…
Reference in New Issue
Block a user