diff --git a/RELEASE b/RELEASE index 5be499ed5c7..855d2fb1902 100644 --- a/RELEASE +++ b/RELEASE @@ -1,6 +1,6 @@ IPFS hash of the deployment: -- CIDv0: `QmUT3C4vpZnekvr6tpufvmko2T9KRR8VfDvMB3ddJhEC8s` -- CIDv1: `bafybeic2zedotxnbrjgoh3kki7g4oatccgiqwag5xsmcuk33tijqgv2zpq` +- CIDv0: `QmPJRmYQHgjfL1W5skf8cUmsFMFGBxVmDS8svqWBT81Lew` +- CIDv1: `bafybeiaojhskjkwp2cbsehkj7fm4cfv6pjsapflwz5eebreopupzbuna6q` The latest release is always mirrored at [app.uniswap.org](https://app.uniswap.org). @@ -10,40 +10,15 @@ You can also access the Uniswap Interface from an IPFS gateway. Your Uniswap settings are never remembered across different URLs. IPFS gateways: -- https://bafybeic2zedotxnbrjgoh3kki7g4oatccgiqwag5xsmcuk33tijqgv2zpq.ipfs.dweb.link/ -- https://bafybeic2zedotxnbrjgoh3kki7g4oatccgiqwag5xsmcuk33tijqgv2zpq.ipfs.cf-ipfs.com/ -- [ipfs://QmUT3C4vpZnekvr6tpufvmko2T9KRR8VfDvMB3ddJhEC8s/](ipfs://QmUT3C4vpZnekvr6tpufvmko2T9KRR8VfDvMB3ddJhEC8s/) +- https://bafybeiaojhskjkwp2cbsehkj7fm4cfv6pjsapflwz5eebreopupzbuna6q.ipfs.dweb.link/ +- https://bafybeiaojhskjkwp2cbsehkj7fm4cfv6pjsapflwz5eebreopupzbuna6q.ipfs.cf-ipfs.com/ +- [ipfs://QmPJRmYQHgjfL1W5skf8cUmsFMFGBxVmDS8svqWBT81Lew/](ipfs://QmPJRmYQHgjfL1W5skf8cUmsFMFGBxVmDS8svqWBT81Lew/) -## 5.46.0 (2024-09-11) - - -### Features - -* **web:** [multi-explore] disable not hide TX tab on all networks (#11527) 54773e6 -* **web:** add info popups to search results (#11588) bc09156 -* **web:** memoize most of explore - staging (#11748) fae44d0 -* **web:** update the columns in the explore pools tab (#11492) 7fc1c8d -* **web:** use Spore radio button for LP fee selector (#11284) 33c77c8 +### 5.46.1 (2024-09-12) ### Bug Fixes -* **web:** 09 09 fix web remove vote pages staging (#11700) 60b48d3 -* **web:** Add unsupported style to Explore Table network options - staging (#11708) 1fd4a47 -* **web:** connected account button toggles modal (#11343) 8834682 -* **web:** fix missing charts on PDP (#11312) 3dae6a8 -* **web:** fix uniswap wallet connect QR code (#11507) cf360ff -* **web:** hide scroll more on midHeight (#11509) d121ce1 -* **web:** landing page should also have multichainUX (#11484) 49e7ad9 -* **web:** Show all tabs when multichain_explore is disabled (#11532) 1e5febc -* **web:** show share menu over chart (#11513) 20035a7 -* **web:** update chart header z index (#11608) c0adb87 -* **web:** use onchain instead of swapping (#11779) e0020fd -* **web): Revert "feat(web:** [multi-explore] disable not hide TX tab on all net… (#11775) 5a40308 - - -### Continuous Integration - -* **web:** update sitemaps 0fdba92 +* **web:** remove frontend global search sorting/filtering logic [prod hotfix] (#11829) a5fcd4e diff --git a/VERSION b/VERSION index 1e8233dc2df..b4077aeb48c 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -web/5.46.0 \ No newline at end of file +web/5.46.1 \ No newline at end of file diff --git a/apps/web/src/components/NavBar/SearchBar/index.tsx b/apps/web/src/components/NavBar/SearchBar/index.tsx index c4a986119dc..be5413afcc5 100644 --- a/apps/web/src/components/NavBar/SearchBar/index.tsx +++ b/apps/web/src/components/NavBar/SearchBar/index.tsx @@ -7,7 +7,6 @@ import Row from 'components/Row' import { useSearchTokens } from 'graphql/data/SearchTokens' import { useCollectionSearch } from 'graphql/data/nft/CollectionSearch' import { useScreenSize } from 'hooks/screenSize' -import { useAccount } from 'hooks/useAccount' import useDebounce from 'hooks/useDebounce' import { useDisableNFTRoutes } from 'hooks/useDisableNFTRoutes' import { useIsNftPage } from 'hooks/useIsNftPage' @@ -203,8 +202,7 @@ export const SearchBar = ({ const { data: collections, loading: collectionsAreLoading } = useCollectionSearch(debouncedSearchValue) - const account = useAccount() - const { data: tokens, loading: tokensAreLoading } = useSearchTokens(debouncedSearchValue, account.chainId ?? 1) + const { data: tokens, loading: tokensAreLoading } = useSearchTokens(debouncedSearchValue) const isNFTPage = useIsNftPage() const [reducedTokens, reducedCollections] = organizeSearchResults(isNFTPage, tokens ?? [], collections ?? []) diff --git a/apps/web/src/graphql/data/SearchTokens.ts b/apps/web/src/graphql/data/SearchTokens.ts index 5ff779402d4..186415e17cd 100644 --- a/apps/web/src/graphql/data/SearchTokens.ts +++ b/apps/web/src/graphql/data/SearchTokens.ts @@ -1,7 +1,5 @@ -import { BACKEND_SUPPORTED_CHAINS, SupportedInterfaceChainId, chainIdToBackendChain } from 'constants/chains' -import { ARB, NATIVE_CHAIN_ID, WRAPPED_NATIVE_CURRENCY } from 'constants/tokens' +import { BACKEND_SUPPORTED_CHAINS } from 'constants/chains' import { useMemo } from 'react' -import invariant from 'tiny-invariant' import { Chain, SearchTokensWebQuery, @@ -9,101 +7,18 @@ import { useSearchTokensWebQuery, } from 'uniswap/src/data/graphql/uniswap-data-api/__generated__/types-and-hooks' -const ARB_ADDRESS = ARB.address.toLowerCase() - -/* Returns the more relevant cross-chain token based on native status and search chain */ -function dedupeCrosschainTokens(current: GqlSearchToken, existing: GqlSearchToken | undefined, searchChain: Chain) { - if (!existing) { - return current - } - invariant(current.project?.id === existing.project?.id, 'Cannot dedupe tokens within different tokenProjects') - - // Special case: always prefer Arbitrum ARB over Mainnet ARB - if (current.address?.toLowerCase() === ARB_ADDRESS) { - return current - } - if (existing.address?.toLowerCase() === ARB_ADDRESS) { - return existing - } - - // Always prioritize natives, and if both tokens are native, prefer native on current chain (i.e. Matic on Polygon over Matic on Mainnet ) - if ( - current.standard === NATIVE_CHAIN_ID && - (existing.standard !== NATIVE_CHAIN_ID || current.chain === searchChain) - ) { - return current - } - - // Prefer tokens on the searched chain, otherwise prefer mainnet tokens - if (current.chain === searchChain || (existing.chain !== searchChain && current.chain === Chain.Ethereum)) { - return current - } - - return existing -} - -/* Places natives first, wrapped native on current chain next, then sorts by volume */ -function searchTokenSortFunction( - searchChain: Chain, - wrappedNativeAddress: string | undefined, - a: GqlSearchToken, - b: GqlSearchToken, -) { - if (a.standard === NATIVE_CHAIN_ID) { - if (b.standard === NATIVE_CHAIN_ID) { - if (a.chain === searchChain) { - return -1 - } else if (b.chain === searchChain) { - return 1 - } else { - return 0 - } - } else { - return -1 - } - } else if (b.standard === NATIVE_CHAIN_ID) { - return 1 - } else if (wrappedNativeAddress && a.address === wrappedNativeAddress) { - return -1 - } else if (wrappedNativeAddress && b.address === wrappedNativeAddress) { - return 1 - } else { - return (b.market?.volume24H?.value ?? 0) - (a.market?.volume24H?.value ?? 0) - } +// Filters out results that are undefined, or where the token's chain is not supported in explore. +function isExploreSupportedToken(token: GqlSearchToken | undefined): token is Token { + return token !== undefined && (BACKEND_SUPPORTED_CHAINS as ReadonlyArray).includes(token.chain) } -export function useSearchTokens(searchQuery: string | undefined, chainId: SupportedInterfaceChainId) { - const { data, loading, error } = useSearchTokensWebQuery({ - variables: { - searchQuery: searchQuery ?? '', - }, - skip: !searchQuery, - }) - - const sortedTokens = useMemo(() => { - const searchChain = chainIdToBackendChain({ chainId, withFallback: true }) - // Stores results, allowing overwriting cross-chain tokens w/ more 'relevant token' - const selectionMap: { [projectId: string]: GqlSearchToken } = {} - const filteredTokens = data?.searchTokens?.filter( - (token): token is Token => - token !== undefined && (BACKEND_SUPPORTED_CHAINS as ReadonlyArray).includes(token.chain), - ) - filteredTokens?.forEach((token) => { - if (token.project?.id) { - const existing = selectionMap[token.project.id] - selectionMap[token.project.id] = dedupeCrosschainTokens(token, existing, searchChain) - } - }) - return Object.values(selectionMap).sort( - searchTokenSortFunction.bind(null, searchChain, WRAPPED_NATIVE_CURRENCY[chainId]?.address), - ) - }, [data, chainId]) +export function useSearchTokens(searchQuery: string = '') { + const { data, loading, error } = useSearchTokensWebQuery({ variables: { searchQuery }, skip: searchQuery === '' }) - return { - data: sortedTokens, - loading, - error, - } + return useMemo(() => { + const sortedTokens = data?.searchTokens?.filter(isExploreSupportedToken) ?? [] + return { data: sortedTokens, loading, error } + }, [data?.searchTokens, loading, error]) } export type GqlSearchToken = NonNullable[number]>