1
0
mirror of https://github.com/oceanprotocol/commons.git synced 2023-03-15 18:03:00 +01:00

channel view, latest assets from aquarius

This commit is contained in:
Jernej Pregelj 2019-05-22 16:53:21 +02:00 committed by Matthias Kretschmann
parent 9540236ef0
commit 988e03bcca
Signed by: m
GPG Key ID: 606EEEF3C479A91F
6 changed files with 274 additions and 42 deletions

View File

@ -15624,14 +15624,6 @@
"integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=",
"dev": true
},
"typedarray-to-buffer": {
"version": "3.1.5",
"resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz",
"integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==",
"requires": {
"is-typedarray": "^1.0.0"
}
},
"typescript": {
"version": "3.4.5",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-3.4.5.tgz",
@ -16425,7 +16417,33 @@
"integrity": "sha512-8p6ZLv+1JYa5Vs8oBn33Nn3VGFBbF+wVfO+b78RJS1Qf1uIOzjFVDk3XwYDD7rlz9G5BKpxhaQw+6EGQ7L02aw==",
"requires": {
"underscore": "1.8.3",
"web3-core-helpers": "1.0.0-beta.37",
"web3-core-helpers": "1.0.0-beta.37"
},
"dependencies": {
"bn.js": {
"version": "4.11.6",
"resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz",
"integrity": "sha1-UzRK2xRhehP26N0s4okF0cC6MhU="
},
"web3-core-helpers": {
"version": "1.0.0-beta.37",
"resolved": "https://registry.npmjs.org/web3-core-helpers/-/web3-core-helpers-1.0.0-beta.37.tgz",
"integrity": "sha512-efaLOzN28RMnbugnyelgLwPWWaSwElQzcAJ/x3PZu+uPloM/lE5x0YuBKvIh7/PoSMlHqtRWj1B8CpuQOUQ5Ew==",
"requires": {
"underscore": "1.8.3",
"web3-eth-iban": "1.0.0-beta.37",
"web3-utils": "1.0.0-beta.37"
}
},
"web3-eth-iban": {
"version": "1.0.0-beta.37",
"resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-1.0.0-beta.37.tgz",
"integrity": "sha512-WQRniGJFxH/XCbd7miO6+jnUG+6bvuzfeufPIiOtCbeIC1ypp1kSqER8YVBDrTyinU1xnf1U5v0KBZ2yiWBJxQ==",
"requires": {
"bn.js": "4.11.6",
"web3-utils": "1.0.0-beta.37"
}
},
"websocket": "git://github.com/frozeman/WebSocket-Node.git#6c72925e3f8aaaea8dc8450f97627e85263999f2"
}
},
@ -17202,11 +17220,6 @@
"integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=",
"dev": true
},
"yaeti": {
"version": "0.0.6",
"resolved": "https://registry.npmjs.org/yaeti/-/yaeti-0.0.6.tgz",
"integrity": "sha1-8m9ITXJoTPQr7ft2lwqhYI+/lXc="
},
"yallist": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz",

View File

@ -10,6 +10,7 @@ import Publish from './routes/Publish/'
import Search from './routes/Search'
import Faucet from './routes/Faucet'
import History from './routes/History'
import Channel from './routes/Channel'
import Styleguide from './routes/Styleguide'
const Routes = () => (
@ -22,6 +23,7 @@ const Routes = () => (
<Route component={withTracker(Details)} path="/asset/:did" />
<Route component={withTracker(Faucet)} path="/faucet" />
<Route component={withTracker(History)} path="/history" />
<Route component={withTracker(Channel)} path="/channel/:channel" />
<Route component={withTracker(NotFound)} />
</Switch>
)

View File

View File

@ -0,0 +1,51 @@
import React from 'react'
import { render } from 'react-testing-library'
import Channel from './Channel'
import { User } from '../context'
import { createMemoryHistory } from 'history'
describe('Channel', () => {
it('renders without crashing', () => {
const history = createMemoryHistory()
const { container } = render(
<User.Provider
value={{
isLogged: false,
isLoading: false,
isWeb3: false,
isOceanNetwork: false,
account: '',
web3: {},
ocean: {
aquarius: {
queryMetadata: () => {
return {
results: [],
totalResults: 1,
totalPages: 1
}
}
}
},
balance: { eth: 0, ocn: 0 },
network: '',
requestFromFaucet: () => {},
unlockAccounts: () => {},
message: ''
}}
>
<Channel
location={{
search: '',
pathname: '/channel/AI for Good',
state: '',
hash: ''
}}
history={history}
/>
</User.Provider>
)
expect(container.firstChild).toBeInTheDocument()
})
})

View File

@ -0,0 +1,169 @@
import React, { PureComponent } from 'react'
import queryString from 'query-string'
import { History, Location } from 'history'
import { Logger } from '@oceanprotocol/squid'
import Spinner from '../components/atoms/Spinner'
import Route from '../components/templates/Route'
import { User } from '../context'
import Asset from '../components/molecules/Asset'
import Pagination from '../components/molecules/Pagination'
import styles from './Channel.module.scss'
import Content from '../components/atoms/Content'
interface ChannelProps {
location: Location
history: History
match: {
params: any
}
}
interface ChannelState {
results: any[]
totalResults: number
offset: number
totalPages: number
currentPage: number
isLoading: boolean
searchTerm: string
searchCategories: string
channel: {
title: string
description: string
}
}
export default class Channel extends PureComponent<ChannelProps, ChannelState> {
public state = {
results: [],
totalResults: 0,
offset: 25,
totalPages: 1,
currentPage: 1,
isLoading: true,
searchTerm: '',
searchCategories: '',
channel: {
title: 'AI for Good',
description: 'AI 4 Good is an initiative to promote the use of artificial intelligence for good causes, such as fighting poverty, climate change, improving healthcare, safer transportation, and so on. The AI for Good Global Summit is THE leading United Nations platform for global and inclusive dialogue on AI. The Summit is hosted each year in Geneva by the ITU in partnership wutg UN Suster agencies, XPRIZE Foundtation and ACM.'
}
}
public async componentDidMount() {
const { match } = this.props;
// TODO: use next line to use channel name
// const category = match.params.channel
const category = 'Engineering'
const { page } = queryString.parse(this.props.location.search)
if (category) {
await this.setState({
searchCategories: encodeURIComponent(`${category}`)
})
}
// switch to respective page if query string is present
if (page) {
const currentPage = Number(page)
await this.setState({ currentPage })
}
this.getChannelAssets()
}
private getChannelAssets = async () => {
const { ocean } = this.context
const { offset, currentPage, searchTerm, searchCategories } = this.state
const queryValues =
searchCategories !== '' && searchTerm !== ''
? { text: [searchTerm], categories: [searchCategories] }
: searchCategories !== '' && searchTerm === ''
? { categories: [searchCategories] }
: { text: [searchTerm] }
const searchQuery = {
offset,
page: currentPage,
query: {
...queryValues,
price: [-1, 1]
},
sort: {
datePublished: 1
}
}
try {
const search = await ocean.aquarius.queryMetadata(searchQuery)
this.setState({
results: search.results,
totalResults: search.totalResults,
totalPages: search.totalPages,
isLoading: false
})
} catch (error) {
Logger.error(error.message)
this.setState({ isLoading: false })
}
}
private handlePageClick = async (data: { selected: number }) => {
// react-pagination starts counting at 0, we start at 1
let toPage = data.selected + 1
this.props.history.push({
pathname: this.props.location.pathname,
search: `?text=${this.state.searchTerm}&page=${toPage}`
})
await this.setState({ currentPage: toPage, isLoading: true })
await this.getChannelAssets()
}
public renderResults = () =>
this.state.isLoading ? (
<Spinner message="Searching..." />
) : this.state.results && this.state.results.length ? (
<div className={styles.results}>
{this.state.results.map((asset: any) => (
<Asset key={asset.id} asset={asset} />
))}
</div>
) : (
<div>No data sets found.</div>
)
public render() {
const { totalResults, totalPages, currentPage, channel } = this.state
const { match } = this.props;
return (
<Route title={channel.title} wide>
<Content wide>
<div>{channel.description}</div>
{totalResults > 0 && (
<h2
className={styles.resultsTitle}
dangerouslySetInnerHTML={{
__html: `${totalResults} results for <span>${decodeURIComponent(
'' // this.state.channelName
)}</span>`
}}
/>
)}
{this.renderResults()}
<Pagination
totalPages={totalPages}
currentPage={currentPage}
handlePageClick={this.handlePageClick}
/>
</Content>
</Route>
)
}
}
Channel.contextType = User

View File

@ -77,35 +77,28 @@ class Home extends Component<HomeProps, HomeState> {
private getLastAssets = async () => {
const { ocean } = this.context
ocean.keeper.didRegistry.contract.getPastEvents(
'DIDAttributeRegistered',
{
filter: {},
fromBlock: 0,
toBlock: 'latest'
const searchQuery = {
offset: 3,
page: 1,
query: {
price: [-1, 1]
},
async (error: any, events: any) => {
if (error) {
Logger.log('error retrieving', error)
this.setState({ isLoadingLast: false })
} else {
Logger.log('events retrieving', events)
const lastAssets = []
// this will tranverse all published assets from latest to first
for (const event of events.reverse()) {
const ddo = await ocean.assets.resolve(
`did:op:${event.returnValues._did.substring(2)}`
)
// ddo not resolved jump to next ddo
if (ddo === null) continue
lastAssets.push(ddo)
// stop tranversing all events when reaching certain number
if (lastAssets.length >= 1) break
}
this.setState({ lastAssets, isLoadingLast: false })
}
sort: {
created: -1
}
)
}
try {
const search = await ocean.aquarius.queryMetadata(searchQuery)
this.setState({
lastAssets: search.results,
isLoadingLast: false
})
} catch (error) {
Logger.error(error.message)
this.setState({ isLoadingLast: false })
}
}
public render() {
@ -135,7 +128,7 @@ class Home extends Component<HomeProps, HomeState> {
</Content>
<Content wide>
<h4>AI for Good</h4>
<h4 onClick={() => this.openChannel('AI for Good')}>AI for Good</h4>
<div>
{isLoadingCategory ? (
<Spinner message="Loading..." />
@ -190,6 +183,10 @@ class Home extends Component<HomeProps, HomeState> {
event.preventDefault()
this.props.history.push(`/search?text=${this.state.search}`)
}
private openChannel = (channel: string) => {
this.props.history.push(`/channel/${channel}`)
}
}
Home.contextType = User