Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[7] fix(tokens): fix tokens list loading state #3201

Merged
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
59 commits
Select commit Hold shift + click to select a range
840af3f
fix: fix tokens list loading state
shoom3301 Oct 10, 2023
d1f8851
fix: fix token store updating inconsistency
shoom3301 Oct 10, 2023
70b87f9
chore: move DEFAULT_FAVOURITE_TOKENS to separate file
shoom3301 Oct 10, 2023
58b890f
refactor: refactor useSearchToken() hook
shoom3301 Oct 10, 2023
614feea
chore: fix tokens lib exports
shoom3301 Oct 10, 2023
b5c1508
chore: refactor TokensListsUpdater
shoom3301 Oct 10, 2023
c3cc4a8
fix: remove duplicates from token search results
shoom3301 Oct 10, 2023
e1626e7
fix(tokens): fix lists toggling
shoom3301 Oct 10, 2023
16ef0a0
fix(tokens): fix list importing
shoom3301 Oct 10, 2023
2a8d3d7
refactor(tokens): refactor tokens state
shoom3301 Oct 11, 2023
d8e4330
Merge branch 'refactor/tokens-remove-legacy' of https://github.com/co…
shoom3301 Oct 11, 2023
7287a63
feat(tokens): lists analytics events
shoom3301 Oct 11, 2023
e7573de
refactor: group and rename entities
shoom3301 Oct 11, 2023
e6be7d3
chore: fix imports
shoom3301 Oct 11, 2023
c684d98
chore: fix cosmos fixtures
shoom3301 Oct 11, 2023
822d170
chore: remove unused code
shoom3301 Oct 11, 2023
9701d07
Merge branch 'refactor/tokens-remove-legacy' of https://github.com/co…
shoom3301 Oct 11, 2023
2592593
chore: fix import
shoom3301 Oct 11, 2023
db8105f
chore: fix typo
shoom3301 Oct 11, 2023
4a28d8c
chore: trim input value
shoom3301 Oct 11, 2023
caeeeb7
chore: fix list removing
shoom3301 Oct 11, 2023
c1ac055
chore: diagrams
shoom3301 Oct 11, 2023
6837b14
refactor: simplify unsupported token hooks
shoom3301 Oct 12, 2023
cc53a88
refactor: simplify useSearchToken
shoom3301 Oct 12, 2023
3127c0e
refactor: rename isTokenAlreadyFoundByAddress
shoom3301 Oct 12, 2023
7370a0b
refactor: use lastUpdateTimeAtom instead of localStorage
shoom3301 Oct 12, 2023
4ab7dbd
chore: remove TOKENS_LISTS_UPDATER_INTERVAL duplicate
shoom3301 Oct 12, 2023
7400345
refactor: use TokenWithLogo.fromToken
shoom3301 Oct 12, 2023
9fc64a1
fix: fix FavouriteTokensList mobile view
shoom3301 Oct 16, 2023
437ca57
fix: fix mobile appearance
shoom3301 Oct 16, 2023
e02d368
fix: select token after import
shoom3301 Oct 16, 2023
45feae5
fix: search token by symbol for autoimporting
shoom3301 Oct 16, 2023
5552b69
feat: add trust as a fallback to logo urls
shoom3301 Oct 16, 2023
734c5f4
refactor: simplify TokenSearchResponse
shoom3301 Oct 16, 2023
20af0e7
chore: docs for complex entities
shoom3301 Oct 16, 2023
c11ac54
chore: cache inputLowerCase
shoom3301 Oct 16, 2023
e1bae58
chore: rename tokenMapToListWithLogo
shoom3301 Oct 16, 2023
cbeaa9b
chore: remove unused files
shoom3301 Oct 17, 2023
010dcb2
feat: reset unsupported tokens periodically
shoom3301 Oct 17, 2023
f07e036
chore: remove excessive files
shoom3301 Oct 17, 2023
34e06de
fix: use token with logo in orders state
shoom3301 Oct 17, 2023
bf7490c
Merge branch 'refactor/tokens-remove-legacy' of https://github.com/co…
shoom3301 Oct 17, 2023
b12a429
refactor: simplify token lists state
shoom3301 Oct 17, 2023
2243394
fix: remove local logos for tokens
shoom3301 Oct 17, 2023
3a8ffc4
chore: fix test
shoom3301 Oct 17, 2023
19e7d6d
chore: change refreshInterval for native balance
shoom3301 Oct 17, 2023
b3cc7ca
refactor: fix press enter handler
shoom3301 Oct 17, 2023
c4cc71e
chore: fix build
shoom3301 Oct 17, 2023
55d2528
chore: fix test
shoom3301 Oct 17, 2023
b2dd6b3
chore: fix text
shoom3301 Oct 17, 2023
099c3bc
chore: fix OrderLogPopupMixData
shoom3301 Oct 17, 2023
2903c28
chore: merge develop
shoom3301 Oct 23, 2023
40c0d9d
chore: fix build
shoom3301 Oct 23, 2023
78dc458
chore: fix build
shoom3301 Oct 23, 2023
b3192bd
chore: fix getTokenLogoFallbacks
shoom3301 Oct 23, 2023
3d28e21
chore: fix lists overriding and search input
shoom3301 Oct 23, 2023
6a7a227
feat: loader for list search
shoom3301 Oct 23, 2023
8602757
chore: fix token logo rounding
shoom3301 Oct 24, 2023
f4af72b
chore: fix tokens sorting
shoom3301 Oct 24, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
refactor(tokens): refactor tokens state
  • Loading branch information
shoom3301 committed Oct 11, 2023
commit 2a8d3d724eb6b44cf7beb602ec0746ba75968f43
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import { useMemo } from 'react'

import {
FetchedTokenList,
ListSearchResponse,
TokenListInfo,
useActiveTokenListsIds,
ListState,
useListsEnabledState,
useRemoveTokenList,
useToggleListCallback,
} from '@cowprotocol/tokens'
Expand All @@ -15,15 +14,21 @@ import { useAddListImport } from '../../hooks/useAddListImport'
import { ImportTokenListItem } from '../../pure/ImportTokenListItem'
import { ListItem } from '../../pure/ListItem'

interface ListSearchState {
source: 'existing' | 'external'
loading: boolean
listToImport: ListState | null
}

export interface ManageListsProps {
lists: TokenListInfo[]
lists: ListState[]
listSearchResponse: ListSearchResponse
}

export function ManageLists(props: ManageListsProps) {
const { lists, listSearchResponse } = props

const activeTokenListsIds = useActiveTokenListsIds()
const activeTokenListsIds = useListsEnabledState()
const addListImport = useAddListImport()
const removeCustomTokenLists = useRemoveTokenList()
const toggleList = useToggleListCallback()
Expand Down Expand Up @@ -59,32 +64,28 @@ export function ManageLists(props: ManageListsProps) {
)
}

function useListSearchResponse(listSearchResponse: ListSearchResponse): {
source: 'existing' | 'external'
loading: boolean
listToImport: FetchedTokenList | null
} {
function useListSearchResponse(listSearchResponse: ListSearchResponse): ListSearchState {
return useMemo(() => {
const source = listSearchResponse.source
const { source, response } = listSearchResponse

if (listSearchResponse.source === 'existing') {
if (source === 'existing') {
return {
source,
loading: false,
listToImport: { info: listSearchResponse.response, tokens: [] },
}
} else {
if (!listSearchResponse.response) {
return { source, loading: false, listToImport: null }
listToImport: response,
}
}

const { isLoading, data } = listSearchResponse.response
if (!response) {
return { source, loading: false, listToImport: null }
}

return {
source,
loading: isLoading,
listToImport: data || null,
}
const { isLoading, data } = response

return {
source,
loading: isLoading,
listToImport: data || null,
}
}, [listSearchResponse])
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { useMemo, useState } from 'react'

import { TokenWithLogo } from '@cowprotocol/common-const'
import { isAddress, parseENSAddress, uriToHttp } from '@cowprotocol/common-utils'
import { TokenListInfo, useSearchList, useSearchToken } from '@cowprotocol/tokens'
import { ListState, useSearchList, useSearchToken } from '@cowprotocol/tokens'

import * as styledEl from './styled'

Expand All @@ -11,7 +11,7 @@ import { ManageLists } from '../ManageLists'
import { ManageTokens } from '../ManageTokens'

export interface ManageListsAndTokensProps {
lists: TokenListInfo[]
lists: ListState[]
customTokens: TokenWithLogo[]
onBack(): void
onDismiss(): void
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { useMemo } from 'react'

import { TokenWithLogo } from '@cowprotocol/common-const'
import { ExplorerDataType, getExplorerLink, isTruthy } from '@cowprotocol/common-utils'
import { ExplorerDataType, getExplorerLink } from '@cowprotocol/common-utils'
import { TokenLogo, TokenSearchResponse, useRemoveTokenCallback, useResetUserTokensCallback } from '@cowprotocol/tokens'
import { TokenSymbol } from '@cowprotocol/ui'

Expand All @@ -10,6 +12,15 @@ import * as styledEl from './styled'
import { useAddTokenImportCallback } from '../../hooks/useAddTokenImportCallback'
import { ImportTokenItem } from '../../pure/ImportTokenItem'

const tokensListToMap = (tokens: TokenWithLogo[] | null) => {
if (!tokens) return {}

return tokens.reduce<Record<string, TokenWithLogo>>((acc, token) => {
acc[token.address.toLowerCase()] = token
return acc
}, {})
}

export interface ManageTokensProps {
tokens: TokenWithLogo[]
tokenSearchResponse: TokenSearchResponse
Expand All @@ -24,7 +35,15 @@ export function ManageTokens(props: ManageTokensProps) {

const { inactiveListsResult, blockchainResult, activeListsResult, externalApiResult } = tokenSearchResponse

const tokensToImport = [blockchainResult, inactiveListsResult, externalApiResult].filter(isTruthy).flat()
const tokensToImport = useMemo(() => {
const tokensMap = {
...tokensListToMap(blockchainResult),
...tokensListToMap(externalApiResult),
...tokensListToMap(inactiveListsResult),
}

return Object.values(tokensMap)
}, [blockchainResult, externalApiResult, inactiveListsResult])

return (
<styledEl.Wrapper>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ import { useCallback, useState } from 'react'

import { TokenWithLogo } from '@cowprotocol/common-const'
import {
FetchedTokenList,
ListState,
useAddCustomTokenLists,
useAllTokenListsInfo,
useAllListsList,
useAllTokens,
useFavouriteTokens,
useImportTokenCallback,
Expand Down Expand Up @@ -45,7 +45,7 @@ export function SelectTokenWidget() {
const allTokens = useAllTokens()
const favouriteTokens = useFavouriteTokens()
const userAddedTokens = useUserAddedTokens()
const allTokenLists = useAllTokenListsInfo()
const allTokenLists = useAllListsList()

const closeTokenSelectWidget = useCallback(() => {
updateSelectTokenWidget({
Expand Down Expand Up @@ -73,7 +73,7 @@ export function SelectTokenWidget() {
onDismiss()
}

const importListAndBack = (list: FetchedTokenList) => {
const importListAndBack = (list: ListState) => {
addCustomTokenLists(list)
updateSelectTokenWidget({ listToImport: undefined })
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import { useSetAtom } from 'jotai/index'
import { useCallback } from 'react'

import { FetchedTokenList } from '@cowprotocol/tokens'
import { ListState } from '@cowprotocol/tokens'

import { updateSelectTokenWidgetAtom } from '../state/selectTokenWidgetAtom'

export function useAddListImport() {
const updateSelectTokenWidget = useSetAtom(updateSelectTokenWidgetAtom)

return useCallback(
(listToImport: FetchedTokenList) => {
(listToImport: ListState) => {
updateSelectTokenWidget({
listToImport,
})
Expand Down
42 changes: 24 additions & 18 deletions apps/cowswap-frontend/src/modules/tokensList/mocks.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { TokenWithLogo } from '@cowprotocol/common-const'
import { TokenListInfo } from '@cowprotocol/tokens'
import { ListState } from '@cowprotocol/tokens'

export const allTokensMock: TokenWithLogo[] = [
{
Expand Down Expand Up @@ -97,39 +97,45 @@ export const customTokensMock: TokenWithLogo[] = [
},
].map((item) => new TokenWithLogo(item.logoURI, item.chainId, item.address, item.decimals, item.symbol, item.name))

export const listsMock: TokenListInfo[] = [
export const listsMock: ListState[] = [
{
id: '1',
name: 'CowSwap Goerli',
source: {
url: 'https://tokenlists.org/token-list?url=https://raw.githubusercontent.com/cowprotocol/token-lists/main/src/public/CowSwapGoerli.json',
},
logoUrl: 'https://gnosis.mypinata.cloud/ipfs/Qme9B6jRpGtZsRFcPjHvA5T4ugFuL4c3SzWfxyMPa59AMo',
tokensCount: 7,
version: 'v0.0.0',
timestamp: '',
list: {
name: 'CowSwap Goerli',
logoURI: 'https://gnosis.mypinata.cloud/ipfs/Qme9B6jRpGtZsRFcPjHvA5T4ugFuL4c3SzWfxyMPa59AMo',
tokens: [1, 2, 3, 4, 5, 6, 7] as any[],
version: { major: 0, minor: 0, patch: 1 },
timestamp: '',
},
},
{
id: '2',
name: 'Compound',
source: {
url: 'https://tokenlists.org/token-list?url=https://raw.githubusercontent.com/compound-finance/token-list/master/compound.tokenlist.json',
},
logoUrl: 'https://raw.githubusercontent.com/compound-finance/token-list/master/assets/compound-interface.svg',
tokensCount: 16,
version: 'v0.2.1',
timestamp: '',
list: {
name: 'Compound',
logoURI: 'https://raw.githubusercontent.com/compound-finance/token-list/master/assets/compound-interface.svg',
tokens: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16] as any[],
version: { major: 0, minor: 2, patch: 1 },
timestamp: '',
},
},
]

export const importListsMock: TokenListInfo = {
export const importListsMock: ListState = {
id: '4',
name: 'CoW Swap',
source: {
url: 'https://files.cow.fi/tokens/CowSwap.json',
},
logoUrl: 'https://raw.githubusercontent.com/cowprotocol/token-lists/main/src/public/images/list-logo.png',
tokensCount: 113,
version: 'v0.0.0',
timestamp: '',
list: {
name: 'CoW Swap',
logoURI: 'https://raw.githubusercontent.com/cowprotocol/token-lists/main/src/public/images/list-logo.png',
tokens: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13] as any[],
version: { major: 1, minor: 0, patch: 5 },
timestamp: '',
},
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { useState } from 'react'

import { TokenLogo, getTokenListViewLink, FetchedTokenList } from '@cowprotocol/tokens'
import { TokenLogo, getTokenListViewLink, ListState } from '@cowprotocol/tokens'
import { ButtonPrimary } from '@cowprotocol/ui'

import { AlertTriangle } from 'react-feather'
Expand All @@ -10,8 +10,8 @@ import * as styledEl from './styled'
import { ModalHeader } from '../ModalHeader'

export interface ImportListModalProps {
list: FetchedTokenList
onImport(list: FetchedTokenList): void
list: ListState
onImport(list: ListState): void
onBack(): void
onDismiss(): void
}
Expand All @@ -21,20 +21,19 @@ export function ImportListModal(props: ImportListModalProps) {

const [isAccepted, setIsAccepted] = useState(false)

const { info } = list
const source = 'ensName' in info.source ? info.source.ensName : info.source.url
const viewLink = getTokenListViewLink(info.source)
const source = 'ensName' in list.source ? list.source.ensName : list.source.url
const viewLink = getTokenListViewLink(list.source)

return (
<styledEl.Wrapper>
<ModalHeader onBack={onBack} onClose={onDismiss}>
Import List
</ModalHeader>
<styledEl.ListInfo>
<TokenLogo logoURI={info.logoUrl} size={36} />
<TokenLogo logoURI={list.list.logoURI} size={36} />
<div>
<styledEl.ListTitle>
{info.name} · {info.tokensCount} tokens
{list.list.name} · {list.list.tokens.length} tokens
</styledEl.ListTitle>
<styledEl.ListLink target="_blank" href={viewLink} rel="noreferrer">
{source}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { FetchedTokenList } from '@cowprotocol/tokens'
import { ListState } from '@cowprotocol/tokens'

import { CheckCircle } from 'react-feather'

Expand All @@ -8,17 +8,17 @@ import { ImportButton } from '../commonElements'
import { TokenListDetails } from '../TokenListDetails'

export interface ImportTokenListItemProps {
list: FetchedTokenList
list: ListState
source: 'existing' | 'external'
importList(list: FetchedTokenList): void
importList(list: ListState): void
}

export function ImportTokenListItem(props: ImportTokenListItemProps) {
const { list, source, importList } = props

return (
<styledEl.Wrapper>
<TokenListDetails list={list.info}></TokenListDetails>
<TokenListDetails list={list.list}></TokenListDetails>
{source === 'existing' ? (
<styledEl.LoadedInfo>
<CheckCircle size={16} strokeWidth={2} />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ export function ImportTokenModal(props: ImportTokenModalProps) {
This token doesn't appear on the active token list(s). Make sure this is the token that you want to trade.
</p>
{tokens.map((token) => (
<styledEl.TokenInfo>
<styledEl.TokenInfo key={token.address.toLowerCase()}>
<TokenLogo token={token} size={24} />
<styledEl.StyledTokenSymbol token={token} />
<styledEl.TokenName>{token.name}</styledEl.TokenName>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { useState } from 'react'

import { getTokenListViewLink, TokenListInfo } from '@cowprotocol/tokens'
import { getTokenListViewLink, ListState } from '@cowprotocol/tokens'

import { Menu, MenuItem } from '@reach/menu-button'
import { Settings } from 'react-feather'
Expand All @@ -12,7 +12,7 @@ import * as styledEl from './styled'
import { TokenListDetails } from '../TokenListDetails'

export interface TokenListItemProps {
list: TokenListInfo
list: ListState
enabled: boolean
toggleList(id: string): void
removeList(id: string): void
Expand All @@ -28,16 +28,20 @@ export function ListItem(props: TokenListItemProps) {
setIsActive((state) => !state)
}

const { major, minor, patch } = list.list.version

return (
<styledEl.Wrapper $enabled={isActive}>
<TokenListDetails list={list}>
<TokenListDetails list={list.list}>
<Menu>
<styledEl.SettingsButton>
<Settings size={12} />
</styledEl.SettingsButton>
<styledEl.SettingsContainer>
<MenuItem onSelect={() => void 0}>
<styledEl.ListVersion>{list.version}</styledEl.ListVersion>
<styledEl.ListVersion>
v{major}.{minor}.{patch}
</styledEl.ListVersion>
</MenuItem>
<MenuItem onSelect={() => void 0}>
<styledEl.SettingsAction>
Expand Down
Loading