Skip to content

Commit

Permalink
Highlight matching part in token names in search results
Browse files Browse the repository at this point in the history
  • Loading branch information
csillag committed Jul 11, 2023
1 parent 2982cc7 commit c2445fe
Show file tree
Hide file tree
Showing 10 changed files with 58 additions and 20 deletions.
1 change: 1 addition & 0 deletions .changelog/646.feature.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Highlight matching part in token names in search results
1 change: 1 addition & 0 deletions src/app/components/Search/search-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,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
Expand Down
15 changes: 12 additions & 3 deletions src/app/components/Tokens/TokenDetails.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,15 @@ import { DelayedContractVerificationIcon } from '../ContractVerificationIcon'
import Box from '@mui/material/Box'
import { COLORS } from '../../../styles/theme/colors'
import { TokenTypeTag } from './TokenList'
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()

Expand All @@ -37,8 +39,15 @@ export const TokenDetails: FC<{
)}
<dt>{t('common.name')}</dt>
<dd>
<TokenLink scope={token} address={token.eth_contract_addr ?? token.contract_addr} name={token.name} />
<Box sx={{ ml: 3, fontWeight: 700, color: COLORS.grayMedium }}>({token.symbol})</Box>
<TokenLink
scope={token}
address={token.eth_contract_addr ?? token.contract_addr}
name={token.name}
highlightedPart={highlightedPartOfName}
/>
<Box sx={{ ml: 3, fontWeight: 700, color: COLORS.grayMedium }}>
<HighlightedText text={token.symbol} pattern={highlightedPartOfName} />
</Box>
</dd>

<dt>{t('common.type')}</dt>
Expand Down
14 changes: 8 additions & 6 deletions src/app/components/Tokens/TokenLink.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,17 @@ 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 (
<Link component={RouterLink} to={RouteUtils.getTokenRoute(scope, address)}>
{name || address}
{<HighlightedText text={name} pattern={highlightedPart} /> ?? address}
</Link>
)
}
11 changes: 7 additions & 4 deletions src/app/pages/SearchResultsPage/GlobalSearchResultsView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -41,6 +42,7 @@ export const GlobalSearchResultsView: FC<{ searchResults: SearchResults; tokenPr
<SearchResultsList
key={Network.mainnet}
title={networkNames[Network.mainnet]}
searchTerm={searchTerm}
searchResults={mainnetResults}
networkForTheme={Network.mainnet}
tokenPrices={tokenPrices}
Expand All @@ -54,6 +56,7 @@ export const GlobalSearchResultsView: FC<{ searchResults: SearchResults; tokenPr
<SearchResultsList
key={net}
title={networkNames[net]}
searchTerm={searchTerm}
searchResults={otherResults.filter(getFilterForNetwork(net))}
networkForTheme={net}
tokenPrices={tokenPrices}
Expand Down
5 changes: 4 additions & 1 deletion src/app/pages/SearchResultsPage/ScopedSearchResultsView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,10 @@ import { useRedirectIfSingleResult } from './useRedirectIfSingleResult'

export const ScopedSearchResultsView: FC<{
wantedScope: SearchScope
searchTerm: string
searchResults: SearchResults
tokenPrices: AllTokenPrices
}> = ({ wantedScope, searchResults, tokenPrices }) => {
}> = ({ wantedScope, searchTerm, searchResults, tokenPrices }) => {
const { t } = useTranslation()
const [othersOpen, setOthersOpen] = useState(false)
const networkNames = getNetworkNames(t)
Expand All @@ -38,6 +39,7 @@ export const ScopedSearchResultsView: FC<{
{wantedResults.length ? (
<SearchResultsList
title={getNameForScope(t, wantedScope)}
searchTerm={searchTerm}
searchResults={wantedResults}
networkForTheme={wantedScope.network}
tokenPrices={tokenPrices}
Expand All @@ -55,6 +57,7 @@ export const ScopedSearchResultsView: FC<{
key={net}
networkForTheme={net}
title={networkNames[net]}
searchTerm={searchTerm}
searchResults={otherResults.filter(getFilterForNetwork(net))}
tokenPrices={tokenPrices}
/>
Expand Down
5 changes: 3 additions & 2 deletions src/app/pages/SearchResultsPage/SearchResultsList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -87,7 +88,7 @@ export const SearchResultsList: FC<{
<ResultsGroupByType
title={t('search.results.tokens.title')}
results={searchResults.filter((item): item is TokenResult => item.resultType === 'token')}
resultComponent={item => <TokenDetails token={item} showLayer />}
resultComponent={item => <TokenDetails token={item} highlightedPartOfName={searchTerm} showLayer />}
link={token => RouteUtils.getTokenRoute(token, token.eth_contract_addr ?? token.contract_addr)}
linkLabel={t('search.results.tokens.viewLink')}
/>
Expand Down
10 changes: 8 additions & 2 deletions src/app/pages/SearchResultsPage/SearchResultsView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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 (
<PageLayout>
Expand All @@ -28,11 +29,16 @@ export const SearchResultsView: FC<{
) : wantedScope ? (
<ScopedSearchResultsView
wantedScope={wantedScope}
searchTerm={searchTerm}
searchResults={searchResults.filter(getFilterForLayer(wantedScope.layer))}
tokenPrices={tokenPrices}
/>
) : (
<GlobalSearchResultsView searchResults={searchResults} tokenPrices={tokenPrices} />
<GlobalSearchResultsView
searchTerm={searchTerm}
searchResults={searchResults}
tokenPrices={tokenPrices}
/>
)}
</PageLayout>
)
Expand Down
1 change: 1 addition & 0 deletions src/app/pages/SearchResultsPage/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ export const SearchResultsPage: FC = () => {
return (
<SearchResultsView
wantedScope={scope}
searchTerm={searchParams.searchTerm}
searchResults={results}
isLoading={isLoading}
tokenPrices={tokenPrices}
Expand Down
15 changes: 13 additions & 2 deletions src/app/pages/TokensOverviewPage/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -94,12 +94,23 @@ export const TokensPage: FC = () => {
<TokenDetailsBox>
{tokensQuery.isLoading &&
[...Array(PAGE_SIZE).keys()].map(key => (
<TokenDetails key={key} isLoading={true} token={undefined} standalone />
<TokenDetails
key={key}
isLoading={true}
token={undefined}
highlightedPartOfName={undefined}
standalone
/>
))}

{!tokensQuery.isLoading &&
tokensQuery.data?.data.evm_tokens.map(token => (
<TokenDetails key={token.contract_addr} token={token} standalone />
<TokenDetails
key={token.contract_addr}
token={token}
standalone
highlightedPartOfName={undefined}
/>
))}
</TokenDetailsBox>
)}
Expand Down

0 comments on commit c2445fe

Please sign in to comment.