implement new connect wallet button

This commit is contained in:
Maximilian Schneider 2021-07-16 12:18:21 +02:00
parent 5eaf63bfe6
commit 1c868995a1
7 changed files with 85 additions and 165 deletions

View File

@ -3,7 +3,7 @@ import styled from '@emotion/styled'
import tw from 'twin.macro'
export const idleGradient =
'bg-gradient-to-r from-secondary-2-light to-primary-light'
'bg-gradient-to-r from-secondary-2-light to-primary-dark'
export const activeGradient =
'bg-gradient-to-bl from-secondary-1-light via-primary-dark to-secondary-2-light'
@ -55,7 +55,7 @@ const Button: FunctionComponent<ButtonProps> = ({
}) => {
return (
<StyledButton
className={`${className} relative z-10 px-8 py-2 rounded-full text-fgd-1 ${
className={`${className} relative z-10 py-2 rounded-full text-fgd-1 ${
gray ? 'bg-bkg-4' : idleGradient
}`}
gray={gray}

View File

@ -1,63 +1,89 @@
import styled from '@emotion/styled'
import useWalletStore from '../stores/useWalletStore'
import { WALLET_PROVIDERS, DEFAULT_PROVIDER } from '../hooks/useWallet'
import useLocalStorageState from '../hooks/useLocalStorageState'
import WalletSelect from './WalletSelect'
import WalletIcon from './WalletIcon'
import { Menu } from '@headlessui/react'
import { LinkIcon } from '@heroicons/react/solid'
import useWallet, { WALLET_PROVIDERS } from '../hooks/useWallet'
import Button from './Button'
const StyledWalletTypeLabel = styled.div`
font-size: 0.6rem;
`
const ChevronDownIcon = (props) => (
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
{...props}
>
<path
strokeLinecap="round"
strokeLinejoin="round"
d="M19 9l-7 7-7-7"
></path>
</svg>
)
const ConnectWalletButton = () => {
const wallet = useWalletStore((s) => s.current)
const [savedProviderUrl] = useLocalStorageState(
'walletProvider',
DEFAULT_PROVIDER.url
)
const CheckIcon = (props) => (
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
{...props}
>
<path
strokeLinecap="round"
strokeLinejoin="round"
d="M5 13l4 4L19 7"
></path>
</svg>
)
const ConnectWalletButton = (props) => {
const { connected, provider, setSavedProviderUrl } = useWallet()
return (
<div className="flex justify-between border border-primary-light hover:border-fgd-1 rounded-md h-11 w-48">
<button
onClick={() => wallet.connect()}
disabled={!wallet}
className="focus:outline-none disabled:text-fgd-4 disabled:cursor-wait"
<div className="flex">
<Button
className={`h-9 z-30 px-8 flex items-center`}
gray={connected}
{...props}
>
<div className="flex flex-row items-center px-2 justify-center h-full rounded-l default-transition text-primary-light text-sm hover:bg-primary hover:text-fgd-1">
<WalletIcon className="w-5 h-5 mr-3 fill-current" />
<div>
<span className="whitespace-nowrap">Connect Wallet</span>
<StyledWalletTypeLabel className="font-normal text-fgd-1 text-left leading-3">
{WALLET_PROVIDERS.filter((p) => p.url === savedProviderUrl).map(
({ name }) => name
)}
</StyledWalletTypeLabel>
</div>
</div>
</button>
<div className="relative h-full">
<WalletSelect isPrimary />
<LinkIcon className="h-4 w-4 mr-2" />
{connected ? 'Disconnect' : 'Connect Wallet'}
</Button>
<div className="relative pl-2">
<Menu>
{({ open }) => (
<>
<Menu.Button className="cursor-pointer rounded-full h-9 w-9 py-2 px-2 bg-bkg-4 hover:bg-bkg-3 focus:outline-none">
{open ? (
<ChevronDownIcon className="w-4 h-4 m-auto stroke-3" />
) : (
<img src={provider?.icon} className="w-4 h-4 m-auto" />
)}
</Menu.Button>
<Menu.Items className="z-20 p-1 absolute right-0 top-12 bg-bkg-1 shadow-lg border-2 border-bkg-3 outline-none rounded-2xl">
{WALLET_PROVIDERS.map(({ name, url, icon }) => (
<Menu.Item key={name}>
<button
className="flex p-2 h-9 hover:bg-bkg-2 hover:cursor-pointer hover:rounded-2xl font-normal focus:outline-none"
onClick={() => setSavedProviderUrl(url)}
style={{ width: '14rem' }}
>
<img src={icon} className="h-4 w-4 mr-2" />
<span className="text-sm">{name}</span>
{provider?.url === url ? (
<CheckIcon className="h-4 w-4 text-green-400 stroke-3" />
) : null}
</button>
</Menu.Item>
))}
</Menu.Items>
</>
)}
</Menu>
</div>
</div>
)
}
export default ConnectWalletButton
export const ConnectWalletButtonSmall = ({ connected, ...props }) => (
<div className="relative">
<Button
className="rounded-full h-9 w-44 z-30 relative"
gray={connected}
{...props}
>
<LinkIcon className="h-4 w-4 relative top-1 mr-2" />
{connected ? 'Disconnect' : 'Connect Wallet'}
</Button>
{!connected && (
<div className="absolute animate-connect-wallet-ping bg-secondary-2-light top-0 rounded-full h-10 w-48" />
)}
</div>
)

View File

@ -7,7 +7,7 @@ import {
import useWalletStore from '../stores/useWalletStore'
import Input from './Input'
import Button from './Button'
import { ConnectWalletButtonSmall } from './ConnectWalletButton'
import ConnectWalletButton from './ConnectWalletButton'
import PoolCountdown from './PoolCountdown'
import Slider from './Slider'
import Loading from './Loading'
@ -273,12 +273,8 @@ const ContributionModal = () => {
</Button>
</div>
</div>
<div className="flex justify-center">
<ConnectWalletButtonSmall
className="flex pl-6"
connected={connected}
onClick={handleConnectDisconnect}
/>
<div className="flex items-center justify-center">
<ConnectWalletButton onClick={handleConnectDisconnect} />
</div>
</>
)}

View File

@ -2,7 +2,7 @@ import { useEffect, useState } from 'react'
import useWalletStore from '../stores/useWalletStore'
import Button from './Button'
import Input from './Input'
import { ConnectWalletButtonSmall } from './ConnectWalletButton'
import ConnectWalletButton from './ConnectWalletButton'
import Loading from './Loading'
import useLargestAccounts from '../hooks/useLargestAccounts'
import useVaults from '../hooks/useVaults'
@ -155,11 +155,7 @@ const RedeemModal = () => {
</div>
</div>
<div className="flex justify-center">
<ConnectWalletButtonSmall
className="flex pl-6"
connected={connected}
onClick={handleConnectDisconnect}
/>
<ConnectWalletButton onClick={handleConnectDisconnect} />
</div>
</>
)}

View File

@ -1,55 +1,4 @@
import { useEffect, useState } from 'react'
import { Menu } from '@headlessui/react'
import styled from '@emotion/styled'
import {
ChevronUpIcon,
ChevronDownIcon,
DuplicateIcon,
LogoutIcon,
} from '@heroicons/react/outline'
import ConnectWalletButton from './ConnectWalletButton'
import WalletIcon from './WalletIcon'
import useWalletStore from '../stores/useWalletStore'
const Code = styled.code`
border: 1px solid hsla(0, 0%, 39.2%, 0.2);
border-radius: 3px;
background: hsla(0, 0%, 58.8%, 0.1);
font-size: 13px;
`
const WALLET_OPTIONS = [
{ name: 'Copy address', icon: <DuplicateIcon /> },
{ name: 'Disconnect', icon: <LogoutIcon /> },
]
const TopBar = () => {
const { connected, current: wallet } = useWalletStore((s) => s)
const [isCopied, setIsCopied] = useState(false)
useEffect(() => {
if (isCopied) {
const timer = setTimeout(() => {
setIsCopied(false)
}, 2000)
return () => clearTimeout(timer)
}
}, [isCopied])
const handleWalletMenu = (option) => {
if (option === 'Copy address') {
const el = document.createElement('textarea')
el.value = wallet.publicKey.toString()
document.body.appendChild(el)
el.select()
document.execCommand('copy')
document.body.removeChild(el)
setIsCopied(true)
} else {
wallet.disconnect()
}
}
return (
<nav className={`bg-bkg-1`}>
<div className={`px-4 sm:px-6 lg:px-8`}>
@ -59,54 +8,6 @@ const TopBar = () => {
<img className={`h-8 w-auto`} src="/logo.svg" alt="logo" />
</div>
</div>
<div className="flex">
<div className="flex items-center">
<div className="hidden sm:ml-4 sm:block">
{connected && wallet?.publicKey ? (
<Menu>
{({ open }) => (
<div className="relative">
<Menu.Button className="w-48 h-11 pl-2 pr-2.5 border border-green hover:border-fgd-1 focus:outline-none rounded-md text-fgd-4 hover:text-fgd-1">
<div className="flex flex-row items-center justify-between">
<div className="flex items-center">
<WalletIcon className="w-5 h-5 mr-2 fill-current text-green" />
<Code className="p-1 text-fgd-3 font-light">
{isCopied
? 'Copied!'
: wallet.publicKey.toString().substr(0, 5) +
'...' +
wallet.publicKey.toString().substr(-5)}
</Code>
</div>
{open ? (
<ChevronUpIcon className="h-5 w-5" />
) : (
<ChevronDownIcon className="h-5 w-5" />
)}
</div>
</Menu.Button>
<Menu.Items className="z-20 p-1 absolute right-0 top-11 bg-bkg-1 divide-y divide-bkg-3 shadow-lg outline-none rounded-md w-48">
{WALLET_OPTIONS.map(({ name, icon }) => (
<Menu.Item key={name}>
<button
className="flex flex-row items-center w-full p-2 hover:bg-bkg-2 hover:cursor-pointer font-normal"
onClick={() => handleWalletMenu(name)}
>
<div className="w-5 h-5 mr-2">{icon}</div>
{name}
</button>
</Menu.Item>
))}
</Menu.Items>
</div>
)}
</Menu>
) : (
<ConnectWalletButton />
)}
</div>
</div>
</div>
</div>
</div>
</nav>

View File

@ -139,5 +139,5 @@ export default function useWallet() {
actions.fetchUsdcVault()
}, 20 * SECONDS)
return { connected, wallet }
return { connected, wallet, provider, setSavedProviderUrl }
}

View File

@ -110,6 +110,7 @@ const useWalletStore = create<WalletStore>((set, get) => ({
const connection = get().connection.current
const wallet = get().current
const programId = get().connection.programId
const set = get().set
console.log('fetchPool', connection, poolIdl)
if (connection) {