1
0
mirror of https://github.com/oceanprotocol/market.git synced 2024-11-14 17:24:51 +01:00

Owner/publisher search (#187)

* make owner search work

* owner/publisher search from asset details

* copy & cleanup

* style tweaks

* timing

* make search combinations work again

* remove account search highjacking

* switch owner source

* search route fixes

* eth address truncation in text search titles
This commit is contained in:
Matthias Kretschmann 2020-11-03 14:57:40 +01:00 committed by GitHub
parent 3974e4a9a3
commit 3505db21da
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 58 additions and 28 deletions

8
package-lock.json generated
View File

@ -15058,6 +15058,14 @@
} }
} }
}, },
"ethereum-address": {
"version": "0.0.4",
"resolved": "https://registry.npmjs.org/ethereum-address/-/ethereum-address-0.0.4.tgz",
"integrity": "sha1-kXKbK8igBEu+4sBcz20EF5U+X5U=",
"requires": {
"crypto-js": "^3.1.6"
}
},
"ethereum-blockies": { "ethereum-blockies": {
"version": "github:MyEtherWallet/blockies#d36f87e50149aacafb34f099fe0bea1df76e010c", "version": "github:MyEtherWallet/blockies#d36f87e50149aacafb34f099fe0bea1df76e010c",
"from": "github:MyEtherWallet/blockies" "from": "github:MyEtherWallet/blockies"

View File

@ -37,6 +37,7 @@
"decimal.js": "^10.2.1", "decimal.js": "^10.2.1",
"dom-confetti": "^0.2.2", "dom-confetti": "^0.2.2",
"dotenv": "^8.2.0", "dotenv": "^8.2.0",
"ethereum-address": "0.0.4",
"ethereum-blockies": "github:MyEtherWallet/blockies", "ethereum-blockies": "github:MyEtherWallet/blockies",
"filesize": "^6.1.0", "filesize": "^6.1.0",
"formik": "^2.2.1", "formik": "^2.2.1",

View File

@ -3,3 +3,7 @@ declare module 'intersection-observer'
declare module 'ethereum-blockies' { declare module 'ethereum-blockies' {
export function toDataUrl(address: string): string export function toDataUrl(address: string): string
} }
declare module 'ethereum-address' {
export function isAddress(address: string): boolean
}

View File

@ -19,7 +19,7 @@ export default function Seo({
return ( return (
<Helmet <Helmet
defaultTitle={`${siteTitle}${siteTagline}`} defaultTitle={`${siteTitle}${siteTagline}`}
titleTemplate="%s — Ocean Protocol" titleTemplate={`%s — ${siteTitle}`}
title={title} title={title}
> >
<html lang="en" /> <html lang="en" />

View File

@ -26,7 +26,7 @@ export default function SearchBar({
function startSearch(e: FormEvent<HTMLButtonElement>) { function startSearch(e: FormEvent<HTMLButtonElement>) {
e.preventDefault() e.preventDefault()
if (value === '') return if (value === '') return
navigate(`/search?text=${value}`) navigate(`/search/?text=${value}`)
} }
return ( return (

View File

@ -9,7 +9,7 @@ import AssetActions from '../AssetActions'
import { DDO } from '@oceanprotocol/lib' import { DDO } from '@oceanprotocol/lib'
import { useUserPreferences } from '../../../providers/UserPreferences' import { useUserPreferences } from '../../../providers/UserPreferences'
import Pricing from './Pricing' import Pricing from './Pricing'
import { useOcean, usePricing } from '@oceanprotocol/react' import { useMetadata, useOcean, usePricing } from '@oceanprotocol/react'
import EtherscanLink from '../../atoms/EtherscanLink' import EtherscanLink from '../../atoms/EtherscanLink'
import Bookmark from './Bookmark' import Bookmark from './Bookmark'
import { accountTruncate } from '../../../utils/wallet' import { accountTruncate } from '../../../utils/wallet'
@ -26,9 +26,10 @@ export default function AssetContent({
}: AssetContentProps): ReactElement { }: AssetContentProps): ReactElement {
const { debug } = useUserPreferences() const { debug } = useUserPreferences()
const { accountId, networkId } = useOcean() const { accountId, networkId } = useOcean()
const { owner } = useMetadata(ddo)
const { dtSymbol, dtName } = usePricing(ddo) const { dtSymbol, dtName } = usePricing(ddo)
const isOwner = accountId === ddo.publicKey[0].owner const isOwner = accountId === owner
const hasNoPrice = ddo.price.datatoken === 0 && ddo.price.value === 0 const hasNoPrice = ddo.price.datatoken === 0 && ddo.price.value === 0
const showPricing = isOwner && hasNoPrice const showPricing = isOwner && hasNoPrice
@ -49,20 +50,24 @@ export default function AssetContent({
path={`token/${ddo.dataToken}`} path={`token/${ddo.dataToken}`}
> >
{dtName ? ( {dtName ? (
`${dtName} - ${dtSymbol}` `${dtName} ${dtSymbol}`
) : ( ) : (
<code>{ddo.dataToken}</code> <code>{ddo.dataToken}</code>
)} )}
</EtherscanLink> </EtherscanLink>
</p> </p>
<p className={styles.datatoken} title={ddo.publicKey[0].owner}> <p>
Published by{' '} Published by{' '}
<EtherscanLink <Link
networkId={networkId} to={`/search/?owner=${owner}`}
path={`address/${ddo.publicKey[0].owner}`} title="Show all data sets created by this account."
> >
{accountTruncate(ddo.publicKey[0].owner)} {owner && accountTruncate(owner)}
</Link>
{' — '}
<EtherscanLink networkId={networkId} path={`address/${owner}`}>
Etherscan
</EtherscanLink> </EtherscanLink>
</p> </p>

View File

@ -15,7 +15,7 @@ export default function SearchPage({
}): ReactElement { }): ReactElement {
const { config } = useOcean() const { config } = useOcean()
const parsed = queryString.parse(location.search) const parsed = queryString.parse(location.search)
const { text, tags, page } = parsed const { text, owner, tags, page } = parsed
const [queryResult, setQueryResult] = useState<QueryResult>() const [queryResult, setQueryResult] = useState<QueryResult>()
const [loading, setLoading] = useState<boolean>() const [loading, setLoading] = useState<boolean>()
@ -27,12 +27,14 @@ export default function SearchPage({
setLoading(false) setLoading(false)
} }
initSearch() initSearch()
}, [text, tags, page, config.metadataCacheUri]) }, [text, owner, tags, page, config.metadataCacheUri])
return ( return (
<section className={styles.grid}> <section className={styles.grid}>
<div className={styles.search}> <div className={styles.search}>
{text && <SearchBar initialValue={text as string} />} {(text || owner) && (
<SearchBar initialValue={(text || owner) as string} />
)}
</div> </div>
<div className={styles.results}> <div className={styles.results}>

View File

@ -5,19 +5,21 @@ import {
import { MetadataCache, Logger } from '@oceanprotocol/lib' import { MetadataCache, Logger } from '@oceanprotocol/lib'
export function getSearchQuery( export function getSearchQuery(
page?: string | string[], text?: string,
offset?: string | string[], owner?: string,
text?: string | string[], tags?: string,
tags?: string | string[], categories?: string,
categories?: string | string[] page?: string,
offset?: string
): SearchQuery { ): SearchQuery {
return { return {
page: Number(page) || 1, page: Number(page) || 1,
offset: Number(offset) || 21, offset: Number(offset) || 21,
query: { query: {
text, text,
tags: tags ? [tags] : undefined, ...(owner && { 'publicKey.owner': [owner] }),
categories: categories ? [categories] : undefined ...(tags && { tags: [tags] }),
...(categories && { categories: [categories] })
}, },
sort: { sort: {
created: -1 created: -1
@ -33,6 +35,7 @@ export function getSearchQuery(
export async function getResults( export async function getResults(
params: { params: {
text?: string text?: string
owner?: string
tags?: string tags?: string
categories?: string categories?: string
page?: string page?: string
@ -40,11 +43,11 @@ export async function getResults(
}, },
metadataCacheUri: string metadataCacheUri: string
): Promise<QueryResult> { ): Promise<QueryResult> {
const { text, tags, page, offset, categories } = params const { text, owner, tags, page, offset, categories } = params
const metadataCache = new MetadataCache(metadataCacheUri, Logger) const metadataCache = new MetadataCache(metadataCacheUri, Logger)
const queryResult = await metadataCache.queryMetadata( const queryResult = await metadataCache.queryMetadata(
getSearchQuery(page, offset, text, tags, categories) getSearchQuery(text, owner, tags, categories, page, offset)
) )
return queryResult return queryResult

View File

@ -3,17 +3,24 @@ import PageSearch from '../components/templates/Search'
import { PageProps } from 'gatsby' import { PageProps } from 'gatsby'
import Layout from '../components/Layout' import Layout from '../components/Layout'
import queryString from 'query-string' import queryString from 'query-string'
import { accountTruncate } from '../utils/wallet'
import ethereumAddress from 'ethereum-address'
export default function PageGatsbySearch(props: PageProps): ReactElement { export default function PageGatsbySearch(props: PageProps): ReactElement {
const parsed = queryString.parse(props.location.search) const parsed = queryString.parse(props.location.search)
const { text, tags, categories } = parsed const { text, owner, tags, categories } = parsed
const searchValue = text || tags || categories
const isETHAddress = ethereumAddress.isAddress(text as string)
const searchValue =
(isETHAddress ? accountTruncate(text as string) : text) ||
tags ||
categories
const title = owner
? `Published by ${accountTruncate(owner as string)}`
: `Search for ${searchValue || 'all data sets'}`
return ( return (
<Layout <Layout title={title} uri={props.uri}>
title={`Search for ${searchValue || 'all data sets'}`}
uri={props.uri}
>
<PageSearch location={props.location} /> <PageSearch location={props.location} />
</Layout> </Layout>
) )