From 543f81f026c0ad99d7630071c1fdb3587f66edde Mon Sep 17 00:00:00 2001 From: Csillag Kristof Date: Sun, 2 Jul 2023 21:30:46 +0200 Subject: [PATCH] Highlight matching part in token names in search results --- src/app/components/Search/search-utils.ts | 1 + src/app/components/Tokens/TokenDetails.tsx | 23 ++++++++++++++++--- src/app/components/Tokens/TokenLink.tsx | 18 ++++++++++----- .../GlobalSearchResultsView.tsx | 11 +++++---- .../ScopedSearchResultsView.tsx | 5 +++- .../SearchResultsPage/SearchResultsList.tsx | 5 ++-- .../SearchResultsPage/SearchResultsView.tsx | 10 ++++++-- .../__tests__/SearchResultsList.test.tsx | 2 ++ src/app/pages/SearchResultsPage/index.tsx | 1 + src/app/pages/TokensOverviewPage/index.tsx | 15 ++++++++++-- 10 files changed, 71 insertions(+), 20 deletions(-) diff --git a/src/app/components/Search/search-utils.ts b/src/app/components/Search/search-utils.ts index 5747295484..1f253604a6 100644 --- a/src/app/components/Search/search-utils.ts +++ b/src/app/components/Search/search-utils.ts @@ -106,6 +106,7 @@ export const searchParamLoader = async ({ request, params }: LoaderFunctionArgs) Object.entries(validateAndNormalize).map(([key, fn]) => [key, fn(searchTerm)]), ) as { [Key in keyof typeof validateAndNormalize]: string | undefined } return { + searchTerm, ...normalized, // TODO: remove conversion when API supports querying by EVM address // TODO: without async conversion, this won't need to even be a loader diff --git a/src/app/components/Tokens/TokenDetails.tsx b/src/app/components/Tokens/TokenDetails.tsx index 994c1046a2..86f19a358b 100644 --- a/src/app/components/Tokens/TokenDetails.tsx +++ b/src/app/components/Tokens/TokenDetails.tsx @@ -11,13 +11,15 @@ import { DashboardLink } from '../../pages/ParatimeDashboardPage/DashboardLink' import { DelayedContractVerificationInfo } from '../Account/ContractVerificationInfo' import Box from '@mui/material/Box' import { COLORS } from '../../../styles/theme/colors' +import { HighlightedText } from '../HighlightedText' export const TokenDetails: FC<{ isLoading?: boolean token: EvmToken | undefined showLayer?: boolean standalone?: boolean -}> = ({ isLoading, token, showLayer, standalone = false }) => { + highlightedPartOfName: string | undefined +}> = ({ isLoading, token, showLayer, standalone = false, highlightedPartOfName }) => { const { t } = useTranslation() const { isMobile } = useScreenSize() @@ -36,8 +38,23 @@ export const TokenDetails: FC<{ )}
{t('common.name')}
- - ({token.symbol}) + + {token.symbol && ( + + ( + {highlightedPartOfName ? ( + + ) : ( + token.symbol + )} + ) + + )}
{t(isMobile ? 'common.smartContract_short' : 'common.smartContract')}
diff --git a/src/app/components/Tokens/TokenLink.tsx b/src/app/components/Tokens/TokenLink.tsx index 3156c1dbcb..387b08e1df 100644 --- a/src/app/components/Tokens/TokenLink.tsx +++ b/src/app/components/Tokens/TokenLink.tsx @@ -4,15 +4,21 @@ import Link from '@mui/material/Link' import { RouteUtils } from '../../utils/route-utils' import { SearchScope } from '../../../types/searchScope' +import { HighlightedText } from '../HighlightedText' -export const TokenLink: FC<{ scope: SearchScope; address: string; name: string | undefined }> = ({ - scope, - address, - name, -}) => { +export const TokenLink: FC<{ + scope: SearchScope + address: string + name: string | undefined + highlightedPart?: string | undefined +}> = ({ scope, address, name, highlightedPart }) => { return ( - {name || address} + {!!name && !!highlightedPart ? ( + + ) : ( + name ?? address + )} ) } diff --git a/src/app/pages/SearchResultsPage/GlobalSearchResultsView.tsx b/src/app/pages/SearchResultsPage/GlobalSearchResultsView.tsx index b16cfd6ade..de5d11b1cc 100644 --- a/src/app/pages/SearchResultsPage/GlobalSearchResultsView.tsx +++ b/src/app/pages/SearchResultsPage/GlobalSearchResultsView.tsx @@ -19,10 +19,11 @@ import { getThemesForNetworks } from '../../../styles/theme' import { orderByLayer } from '../../../types/layers' import { useRedirectIfSingleResult } from './useRedirectIfSingleResult' -export const GlobalSearchResultsView: FC<{ searchResults: SearchResults; tokenPrices: AllTokenPrices }> = ({ - searchResults, - tokenPrices, -}) => { +export const GlobalSearchResultsView: FC<{ + searchTerm: string + searchResults: SearchResults + tokenPrices: AllTokenPrices +}> = ({ searchTerm, searchResults, tokenPrices }) => { const { t } = useTranslation() const [othersOpen, setOthersOpen] = useState(false) useRedirectIfSingleResult(undefined, searchResults) @@ -41,6 +42,7 @@ export const GlobalSearchResultsView: FC<{ searchResults: SearchResults; tokenPr = ({ wantedScope, searchResults, tokenPrices }) => { +}> = ({ wantedScope, searchTerm, searchResults, tokenPrices }) => { const { t } = useTranslation() const [othersOpen, setOthersOpen] = useState(false) const networkNames = getNetworkNames(t) @@ -38,6 +39,7 @@ export const ScopedSearchResultsView: FC<{ {wantedResults.length ? ( diff --git a/src/app/pages/SearchResultsPage/SearchResultsList.tsx b/src/app/pages/SearchResultsPage/SearchResultsList.tsx index 4bef49c210..42d518900e 100644 --- a/src/app/pages/SearchResultsPage/SearchResultsList.tsx +++ b/src/app/pages/SearchResultsPage/SearchResultsList.tsx @@ -24,7 +24,8 @@ export const SearchResultsList: FC<{ networkForTheme: Network searchResults: SearchResults tokenPrices: AllTokenPrices -}> = ({ title, networkForTheme, searchResults, tokenPrices }) => { + searchTerm: string +}> = ({ title, networkForTheme, searchResults, tokenPrices, searchTerm }) => { const { t } = useTranslation() const numberOfResults = searchResults.length @@ -87,7 +88,7 @@ export const SearchResultsList: FC<{ item.resultType === 'token')} - resultComponent={item => } + resultComponent={item => } link={token => RouteUtils.getTokenRoute(token, token.eth_contract_addr ?? token.contract_addr)} linkLabel={t('search.results.tokens.viewLink')} /> diff --git a/src/app/pages/SearchResultsPage/SearchResultsView.tsx b/src/app/pages/SearchResultsPage/SearchResultsView.tsx index 85aedef40f..e97916a7f3 100644 --- a/src/app/pages/SearchResultsPage/SearchResultsView.tsx +++ b/src/app/pages/SearchResultsPage/SearchResultsView.tsx @@ -13,10 +13,11 @@ import { useScreenSize } from '../../hooks/useScreensize' export const SearchResultsView: FC<{ wantedScope?: SearchScope + searchTerm: string searchResults: SearchResults isLoading: boolean tokenPrices: AllTokenPrices -}> = ({ wantedScope, searchResults, isLoading, tokenPrices }) => { +}> = ({ wantedScope, searchTerm, searchResults, isLoading, tokenPrices }) => { const { isMobile } = useScreenSize() return ( @@ -28,11 +29,16 @@ export const SearchResultsView: FC<{ ) : wantedScope ? ( ) : ( - + )} ) diff --git a/src/app/pages/SearchResultsPage/__tests__/SearchResultsList.test.tsx b/src/app/pages/SearchResultsPage/__tests__/SearchResultsList.test.tsx index 3ad8e96bb7..a1af2380df 100644 --- a/src/app/pages/SearchResultsPage/__tests__/SearchResultsList.test.tsx +++ b/src/app/pages/SearchResultsPage/__tests__/SearchResultsList.test.tsx @@ -22,6 +22,7 @@ describe('SearchResultsView', () => { it('block should correctly link to transactions', () => { renderWithProviders( { it('account should correctly link to erc-20 tokens', () => { renderWithProviders( { return ( { {tokensQuery.isLoading && [...Array(PAGE_SIZE).keys()].map(key => ( - + ))} {!tokensQuery.isLoading && tokensQuery.data?.data.evm_tokens.map(token => ( - + ))} )}