Skip to content

Commit

Permalink
Implement cross-network search
Browse files Browse the repository at this point in the history
  • Loading branch information
csillag committed May 23, 2023
1 parent 923f03f commit d0482aa
Show file tree
Hide file tree
Showing 14 changed files with 493 additions and 169 deletions.
9 changes: 9 additions & 0 deletions src/app/components/NetworkThemeBubble/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import React, { FC } from 'react'
import { Network } from '../../../types/network'
import { ThemeProvider } from '@mui/material/styles'
import { getThemesForNetworks } from '../../../styles/theme'

export const NetworkThemeBubble: FC<{ network: Network; children: React.ReactNode }> = ({
network,
children,
}) => <ThemeProvider theme={getThemesForNetworks()[network]}>{children}</ThemeProvider>
10 changes: 2 additions & 8 deletions src/app/pages/HomePage/Graph/NetworkSelector/index.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { FC, useState } from 'react'
import { useTranslation } from 'react-i18next'
import { TFunction } from 'i18next'
import { useTheme } from '@mui/material/styles'
import useMediaQuery from '@mui/material/useMediaQuery'
import AddIcon from '@mui/icons-material/Add'
Expand All @@ -11,7 +10,7 @@ import RemoveIcon from '@mui/icons-material/Remove'
import Typography from '@mui/material/Typography'
import { styled } from '@mui/material/styles'
import { COLORS } from '../../../../../styles/theme/colors'
import { Network } from '../../../../../types/network'
import { getNetworkNames, Network } from '../../../../../types/network'
import Collapse from '@mui/material/Collapse'
import { RouteUtils } from '../../../../utils/route-utils'

Expand Down Expand Up @@ -60,18 +59,13 @@ type NetworkSelectorProps = {
setNetwork: (network: Network) => void
}

const getLabels = (t: TFunction): { [key in Network]: string } => ({
mainnet: t('common.mainnet'),
testnet: t('common.testnet'),
})

export const NetworkSelector: FC<NetworkSelectorProps> = ({ network, setNetwork }) => {
const { t } = useTranslation()
const theme = useTheme()
const isMobile = useMediaQuery(theme.breakpoints.down('sm'))
const [open, setOpen] = useState(false)
const options: Network[] = RouteUtils.getEnabledNetworks()
const labels = getLabels(t)
const labels = getNetworkNames(t)

return (
<StyledNetworkSelector>
Expand Down
9 changes: 7 additions & 2 deletions src/app/pages/SearchResultsPage/NoResults.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,19 @@ import Link from '@mui/material/Link'
import { SearchSuggestionsLinks } from '../../components/Search/SearchSuggestionsLinks'
import { OptionalBreak } from '../../components/OptionalBreak'
import { useTheme } from '@mui/material/styles'
import { NetworkOrGlobal } from '../../../types/network'
import { getNetworkNames, GlobalNetwork, NetworkOrGlobal } from '../../../types/network'

export const NoResults: FC<{ network: NetworkOrGlobal }> = ({ network }) => {
const { t } = useTranslation()
const theme = useTheme()
const title =
network === GlobalNetwork
? t('search.noResults.header')
: t('search.noResults.networkHeader', { network: getNetworkNames(t)[network] })

return (
<EmptyState
title={t('search.noResults.header')}
title={title}
description={
<Box
sx={{ textAlign: 'center', a: { color: theme.palette.layout.main, textDecoration: 'underline' } }}
Expand Down
5 changes: 3 additions & 2 deletions src/app/pages/SearchResultsPage/ResultsGroup.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import { useTranslation } from 'react-i18next'
import React from 'react'
import { Link as RouterLink } from 'react-router-dom'
import { SubPageCard } from '../../components/SubPageCard'
import { useTranslation } from 'react-i18next'
import Button from '@mui/material/Button'
import Box from '@mui/material/Box'
import Divider from '@mui/material/Divider'
import { styled } from '@mui/material/styles'
import { SubPageCard } from '../../components/SubPageCard'

interface Props<T> {
title: string
Expand Down
104 changes: 104 additions & 0 deletions src/app/pages/SearchResultsPage/ResultsOnForeignNetwork.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
import { FC, useState } from 'react'
import { getNetworkNames, Network } from '../../../types/network'
import { Trans, useTranslation } from 'react-i18next'
import { styled, useTheme } from '@mui/material/styles'
import { getThemesForNetworks } from '../../../styles/theme'
import useMediaQuery from '@mui/material/useMediaQuery'
import { NetworkThemeBubble } from '../../components/NetworkThemeBubble'
import Box from '@mui/material/Box'
import { SearchResultsList } from './SearchResultsList'
import { SearchQueries } from './hooks'
import { COLORS } from '../../../styles/theme/colors'
import ZoomIn from '@mui/icons-material/ZoomIn'
import Warning from '@mui/icons-material/Warning'

const NotificationBox = styled(Box)(({ theme }) => ({
// TODO: this is probably not fully correct.
marginTop: 10,
marginBottom: 20,
fontSize: 14,

boxSizing: 'border-box',
display: 'flex',
flexDirection: 'row',
justifyContent: 'center',
alignItems: 'center',
padding: '5px 10px',
gap: 10,

height: 50,

background: theme.palette.background.default,
border: `2px solid ${theme.palette.layout.border}`,
color: theme.palette.layout.main,

borderRadius: 50,
}))

export const ResultsOnForeignNetwork: FC<{
network: Network
hasLocalMatches: boolean
openByDefault?: boolean
searchQueries: SearchQueries
matches: number
roseFiatValue: number | undefined
}> = ({ network, searchQueries, matches, roseFiatValue, openByDefault = false, hasLocalMatches }) => {
const [open, setOpen] = useState(openByDefault)
const { t } = useTranslation()
const theme = useTheme()
const isMobile = useMediaQuery(theme.breakpoints.down('sm'))
const networkName = getNetworkNames(t)[network]
if (!matches) {
return null
}
const otherTheme = getThemesForNetworks()[network]

if (!open) {
return (
<NetworkThemeBubble network={network}>
<NotificationBox className={'foreignNote'} onClick={() => setOpen(true)}>
<ZoomIn />
{/*{countLabel}*/}
<Trans
t={t}
i18nKey={
hasLocalMatches ? 'search.otherResults.clickToShowMore' : 'search.otherResults.clickToShowThem'
}
values={{
countLabel: t(hasLocalMatches ? 'search.results.moreCount' : 'search.results.count', {
count: matches,
}),
networkName,
}}
/>
</NotificationBox>
</NetworkThemeBubble>
)
}
return (
<NetworkThemeBubble network={network}>
<Box
sx={{
marginTop: 50,
pt: 4,
px: isMobile ? 0 : '4%',
border: isMobile ? 'none' : `solid 15px ${otherTheme.palette.layout.border}`,
background: otherTheme.palette.background.default,
}}
>
<NotificationBox
sx={{
background: COLORS.white, // TODO should come from theme
color: COLORS.grayDark, // TODO should come from theme
border: `2px solid ${otherTheme.palette.layout.border}`,
}}
onClick={() => setOpen(false)}
>
<Warning />
{t('search.otherResults.clickToHide', { networkName })}
</NotificationBox>
<SearchResultsList network={network} searchQueries={searchQueries} roseFiatValue={roseFiatValue} />
</Box>
</NetworkThemeBubble>
)
}
52 changes: 52 additions & 0 deletions src/app/pages/SearchResultsPage/ResultsOnNetwork.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import { FC } from 'react'
import { getNetworkNames, Network } from '../../../types/network'
import { useTranslation } from 'react-i18next'
import { useTheme } from '@mui/material/styles'
import { getThemesForNetworks } from '../../../styles/theme'
import useMediaQuery from '@mui/material/useMediaQuery'
import { NetworkThemeBubble } from '../../components/NetworkThemeBubble'
import Box from '@mui/material/Box'
import { SearchResultsList } from './SearchResultsList'
import { SearchQueries } from './hooks'
import Typography from '@mui/material/Typography'

export const ResultsOnNetwork: FC<{
network: Network
searchQueries: SearchQueries
roseFiatValue: number | undefined
}> = ({ network, searchQueries, roseFiatValue }) => {
const { t } = useTranslation()
const theme = useTheme()
const isMobile = useMediaQuery(theme.breakpoints.down('sm'))
const networkName = getNetworkNames(t)[network]
const otherTheme = getThemesForNetworks()[network]

const content = (
<SearchResultsList network={network} searchQueries={searchQueries} roseFiatValue={roseFiatValue} />
)

return (
<>
<Typography variant="h1" color={theme.palette.layout.main}>
{t('search.sectionHeader', { network: networkName })}
</Typography>
{network === Network.mainnet ? (
content
) : (
<NetworkThemeBubble network={network}>
<Box
sx={{
marginTop: 50,
pt: 4,
px: isMobile ? 0 : '4%',
border: isMobile ? 'none' : `solid 15px ${otherTheme.palette.layout.border}`,
background: otherTheme.palette.background.default,
}}
>
{content}
</Box>
</NetworkThemeBubble>
)}
</>
)
}
56 changes: 56 additions & 0 deletions src/app/pages/SearchResultsPage/SearchResultsList.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import { FC } from 'react'
import { Network } from '../../../types/network'
import { useTranslation } from 'react-i18next'
import { ResultsGroup } from './ResultsGroup'
import { BlockDetailView } from '../BlockDetailPage'
import { RouteUtils } from '../../utils/route-utils'
import { TransactionDetailView } from '../TransactionDetailPage'
import { AccountDetailsView } from '../AccountDetailsPage'
import { SearchQueries } from './hooks'

export const SearchResultsList: FC<{
network: Network
searchQueries: SearchQueries
roseFiatValue: number | undefined
}> = ({ network, searchQueries, roseFiatValue }) => {
const { t } = useTranslation()
return (
<>
<ResultsGroup
title={t('search.results.blocks.title')}
results={searchQueries.blockHeight.results.filter(result => result.network === network)}
resultComponent={item => <BlockDetailView isLoading={false} block={item} showLayer={true} />}
link={item => RouteUtils.getBlockRoute(item.network, item.round, item.layer)}
linkLabel={t('search.results.blocks.viewLink')}
/>

<ResultsGroup
title={t('search.results.transactions.title')}
results={searchQueries.txHash.results.filter(result => result.network === network)}
resultComponent={item => (
<TransactionDetailView isLoading={false} transaction={item} showLayer={true} />
)}
link={item => RouteUtils.getTransactionRoute(item.network, item.eth_hash || item.hash, item.layer)}
linkLabel={t('search.results.transactions.viewLink')}
/>

<ResultsGroup
title={t('search.results.accounts.title')}
results={[
...(searchQueries.oasisAccount.results ?? []).filter(result => result.network === network),
...(searchQueries.evmBech32Account.results ?? []).filter(result => result.network === network),
]}
resultComponent={item => (
<AccountDetailsView
isLoading={false}
account={item}
roseFiatValue={roseFiatValue}
showLayer={true}
/>
)}
link={item => RouteUtils.getAccountRoute(item.network, item.address_eth ?? item.address, item.layer)}
linkLabel={t('search.results.accounts.viewLink')}
/>
</>
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ describe('SearchResultsView', () => {
it('block should correctly link to transactions', () => {
renderWithProviders(
<SearchResultsView
network={Network.mainnet}
wantedNetwork={Network.mainnet}
searchQueries={{
blockHeight: {
isLoading: false,
Expand Down Expand Up @@ -52,7 +52,7 @@ describe('SearchResultsView', () => {
it('account should correctly link to erc-20 tokens', () => {
renderWithProviders(
<SearchResultsView
network={Network.mainnet}
wantedNetwork={Network.mainnet}
searchQueries={{
blockHeight: { isLoading: false, results: [] },
txHash: { isLoading: false, results: [] },
Expand Down

0 comments on commit d0482aa

Please sign in to comment.