mirror of
https://github.com/kremalicious/blog.git
synced 2025-02-14 21:10:25 +01:00
token selection interaction fixes
This commit is contained in:
parent
11953cb4d5
commit
ad22b84349
@ -3,7 +3,7 @@ import * as Select from '@radix-ui/react-select'
|
|||||||
import { formatCurrency } from '@coingecko/cryptoformat'
|
import { formatCurrency } from '@coingecko/cryptoformat'
|
||||||
import './Token.css'
|
import './Token.css'
|
||||||
import { Icon as Check } from '@images/components/react/Check'
|
import { Icon as Check } from '@images/components/react/Check'
|
||||||
import type { GetToken } from '@features/Web3/stores/tokens'
|
import type { GetToken } from '@features/Web3/hooks/useFetchTokens'
|
||||||
|
|
||||||
interface SelectItemProps extends HTMLAttributes<HTMLDivElement> {
|
interface SelectItemProps extends HTMLAttributes<HTMLDivElement> {
|
||||||
token: GetToken | undefined
|
token: GetToken | undefined
|
||||||
|
@ -6,19 +6,14 @@ import { Icon as ChevronsDown } from '@images/components/react/ChevronsDown'
|
|||||||
import { Icon as ChevronsUp } from '@images/components/react/ChevronsUp'
|
import { Icon as ChevronsUp } from '@images/components/react/ChevronsUp'
|
||||||
import { useFetchTokens } from '@features/Web3/hooks/useFetchTokens'
|
import { useFetchTokens } from '@features/Web3/hooks/useFetchTokens'
|
||||||
import { useStore } from '@nanostores/react'
|
import { useStore } from '@nanostores/react'
|
||||||
import {
|
import { $selectedToken, $setSelectedToken } from '@features/Web3/stores'
|
||||||
$tokens,
|
|
||||||
$selectedToken,
|
|
||||||
$setSelectedToken
|
|
||||||
} from '@features/Web3/stores'
|
|
||||||
import { Loader } from '@components/Loader'
|
import { Loader } from '@components/Loader'
|
||||||
import { useAccount } from 'wagmi'
|
import { useAccount } from 'wagmi'
|
||||||
import { useEffect } from 'react'
|
import { useEffect } from 'react'
|
||||||
|
|
||||||
export function TokenSelect() {
|
export function TokenSelect() {
|
||||||
const { address } = useAccount()
|
const { address } = useAccount()
|
||||||
const { isLoading } = useFetchTokens()
|
const { data: tokens, isLoading } = useFetchTokens()
|
||||||
const tokens = useStore($tokens)
|
|
||||||
const selectedToken = useStore($selectedToken)
|
const selectedToken = useStore($selectedToken)
|
||||||
|
|
||||||
const items = tokens?.map((token) => (
|
const items = tokens?.map((token) => (
|
||||||
@ -31,24 +26,20 @@ export function TokenSelect() {
|
|||||||
$setSelectedToken(token)
|
$setSelectedToken(token)
|
||||||
}
|
}
|
||||||
|
|
||||||
// reset when no account connected
|
|
||||||
useEffect(() => {
|
|
||||||
if (!address && tokens?.length && selectedToken) {
|
|
||||||
$tokens.set(undefined)
|
|
||||||
$setSelectedToken(undefined)
|
|
||||||
}
|
|
||||||
}, [address])
|
|
||||||
|
|
||||||
// Auto-select native token
|
// Auto-select native token
|
||||||
|
// when no selection was made yet
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (isLoading || !tokens || selectedToken) return
|
if (selectedToken?.address || !tokens || !tokens?.length) return
|
||||||
|
|
||||||
|
console.log(tokens)
|
||||||
handleValueChange('0x0')
|
handleValueChange('0x0')
|
||||||
|
console.log('auto-select 0x0')
|
||||||
}, [tokens, selectedToken])
|
}, [tokens, selectedToken])
|
||||||
|
|
||||||
return tokens ? (
|
return tokens && address ? (
|
||||||
<Select.Root
|
<Select.Root
|
||||||
// defaultValue={selectedToken?.address || tokens[0].address}
|
defaultValue={selectedToken?.address || tokens[0].address}
|
||||||
|
value={selectedToken?.address}
|
||||||
onValueChange={(value: `0x${string}`) => handleValueChange(value)}
|
onValueChange={(value: `0x${string}`) => handleValueChange(value)}
|
||||||
disabled={isLoading}
|
disabled={isLoading}
|
||||||
>
|
>
|
||||||
|
@ -1 +1,2 @@
|
|||||||
export * from './useFetchTokens'
|
export * from './useFetchTokens'
|
||||||
|
export * from './types'
|
||||||
|
@ -1,9 +1,7 @@
|
|||||||
import { useEffect, useState } from 'react'
|
import { useEffect, useState } from 'react'
|
||||||
import useSWR from 'swr'
|
import useSWR from 'swr'
|
||||||
import type { GetToken } from '@features/Web3/stores/tokens'
|
|
||||||
import { useNetwork, useAccount } from 'wagmi'
|
import { useNetwork, useAccount } from 'wagmi'
|
||||||
import { $tokens } from '@features/Web3/stores'
|
import type { GetToken } from './types'
|
||||||
import { useStore } from '@nanostores/react'
|
|
||||||
|
|
||||||
const fetcher = (url: string) => fetch(url).then((res) => res.json())
|
const fetcher = (url: string) => fetch(url).then((res) => res.json())
|
||||||
const apiUrl = import.meta.env.PUBLIC_WEB3_API_URL
|
const apiUrl = import.meta.env.PUBLIC_WEB3_API_URL
|
||||||
@ -14,30 +12,22 @@ const apiUrl = import.meta.env.PUBLIC_WEB3_API_URL
|
|||||||
export function useFetchTokens() {
|
export function useFetchTokens() {
|
||||||
const { chain } = useNetwork()
|
const { chain } = useNetwork()
|
||||||
const { address } = useAccount()
|
const { address } = useAccount()
|
||||||
const tokens = useStore($tokens)
|
|
||||||
|
|
||||||
const [url, setUrl] = useState<string | undefined>()
|
const [url, setUrl] = useState<string | undefined>()
|
||||||
|
|
||||||
const fetchResults = useSWR<GetToken[] | undefined>(url, fetcher)
|
const fetchResults = useSWR<GetToken[] | undefined>(url, fetcher)
|
||||||
const { data } = fetchResults
|
|
||||||
|
|
||||||
// Set url only after we have all data loaded on client,
|
// Set url only after we have all data loaded on client,
|
||||||
// preventing initial fetch.
|
// preventing initial fetch.
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!address || !chain?.id) return
|
if (!address || !chain?.id) {
|
||||||
|
setUrl(undefined)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
const url = `${apiUrl}/balance?address=${address}&chainId=${chain?.id}`
|
const url = `${apiUrl}/balance?address=${address}&chainId=${chain?.id}`
|
||||||
setUrl(url)
|
setUrl(url)
|
||||||
}, [address, chain?.id])
|
}, [address, chain?.id])
|
||||||
|
|
||||||
// Sync with $tokens store
|
|
||||||
useEffect(() => {
|
|
||||||
if (!data) return
|
|
||||||
|
|
||||||
if (data !== tokens) {
|
|
||||||
$tokens.set(data)
|
|
||||||
}
|
|
||||||
}, [data])
|
|
||||||
|
|
||||||
return fetchResults
|
return fetchResults
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,2 @@
|
|||||||
export * from './tokens'
|
|
||||||
export * from './selectedToken'
|
export * from './selectedToken'
|
||||||
export * from './send'
|
export * from './send'
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { action } from 'nanostores'
|
import { action } from 'nanostores'
|
||||||
import { persistentAtom } from '@nanostores/persistent'
|
import { persistentAtom } from '@nanostores/persistent'
|
||||||
import type { GetToken } from './tokens'
|
import type { GetToken } from '../hooks/useFetchTokens'
|
||||||
|
|
||||||
// export const $selectedToken = atom<GetToken | undefined>()
|
// export const $selectedToken = atom<GetToken | undefined>()
|
||||||
|
|
||||||
|
@ -1,2 +0,0 @@
|
|||||||
export * from './tokens'
|
|
||||||
export * from './types'
|
|
@ -1,13 +0,0 @@
|
|||||||
import { atom } from 'nanostores'
|
|
||||||
import type { GetToken } from './types'
|
|
||||||
|
|
||||||
export const $tokens = atom<GetToken[] | undefined>()
|
|
||||||
|
|
||||||
// export const $setTokens = action(
|
|
||||||
// $tokens,
|
|
||||||
// 'setTokens',
|
|
||||||
// (store, tokens: GetToken[] | undefined) => {
|
|
||||||
// store.set(tokens)
|
|
||||||
// return store.get()
|
|
||||||
// }
|
|
||||||
// )
|
|
Loading…
x
Reference in New Issue
Block a user