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

Merge branch 'master' into feature/docker

This commit is contained in:
Matthias Kretschmann 2019-04-04 17:23:22 +02:00 committed by GitHub
commit 5395767d12
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 286 additions and 148 deletions

View File

@ -11,7 +11,7 @@
}, },
"dependencies": { "dependencies": {
"@oceanprotocol/art": "^2.2.0", "@oceanprotocol/art": "^2.2.0",
"@oceanprotocol/squid": "^0.5.0", "@oceanprotocol/squid": "^0.5.1",
"@oceanprotocol/typographies": "^0.1.0", "@oceanprotocol/typographies": "^0.1.0",
"classnames": "^2.2.6", "classnames": "^2.2.6",
"filesize": "^4.1.2", "filesize": "^4.1.2",

View File

@ -40,6 +40,7 @@ interface AppState {
web3: Web3 web3: Web3
ocean: {} ocean: {}
startLogin: () => void startLogin: () => void
message: string
} }
class App extends Component<{}, AppState> { class App extends Component<{}, AppState> {
@ -94,7 +95,8 @@ class App extends Component<{}, AppState> {
account: '', account: '',
ocean: {}, ocean: {},
startLogin: this.startLogin, startLogin: this.startLogin,
requestFromFaucet: this.requestFromFaucet requestFromFaucet: this.requestFromFaucet,
message: 'Connecting to Ocean...'
} }
public async componentDidMount() { public async componentDidMount() {
@ -185,7 +187,7 @@ class App extends Component<{}, AppState> {
<main className={styles.main}> <main className={styles.main}>
{this.state.isLoading ? ( {this.state.isLoading ? (
<div className={styles.loader}> <div className={styles.loader}>
<Spinner message="Connecting to Ocean..." /> <Spinner message={this.state.message} />
</div> </div>
) : ( ) : (
<Routes /> <Routes />

View File

@ -66,6 +66,7 @@
padding: 0; padding: 0;
color: $brand-pink; color: $brand-pink;
font-size: $font-size-base; font-size: $font-size-base;
font-weight: $font-weight-base;
font-family: inherit; font-family: inherit;
box-shadow: none; box-shadow: none;
cursor: pointer; cursor: pointer;

View File

@ -1,4 +1,5 @@
import React, { PureComponent } from 'react' import React, { PureComponent } from 'react'
import { Link } from 'react-router-dom'
import cx from 'classnames' import cx from 'classnames'
import styles from './Button.module.scss' import styles from './Button.module.scss'
@ -10,6 +11,7 @@ interface ButtonProps {
href?: string href?: string
onClick?: any onClick?: any
disabled?: boolean disabled?: boolean
to?: string
} }
export default class Button extends PureComponent<ButtonProps, any> { export default class Button extends PureComponent<ButtonProps, any> {
@ -21,6 +23,7 @@ export default class Button extends PureComponent<ButtonProps, any> {
href, href,
children, children,
className, className,
to,
...props ...props
} = this.props } = this.props
@ -32,11 +35,23 @@ export default class Button extends PureComponent<ButtonProps, any> {
classes = styles.button classes = styles.button
} }
return href ? ( if (to) {
<a href={href} className={cx(classes, className)} {...props}> return (
{children} <Link to={to} className={cx(classes, className)} {...props}>
</a> {children}
) : ( </Link>
)
}
if (href) {
return (
<a href={href} className={cx(classes, className)} {...props}>
{children}
</a>
)
}
return (
<button className={cx(classes, className)} {...props}> <button className={cx(classes, className)} {...props}>
{children} {children}
</button> </button>

View File

@ -12,8 +12,11 @@ const AssetLink = ({ asset, list }: { asset: any; list?: boolean }) => {
<article className={styles.assetList}> <article className={styles.assetList}>
<Link to={`/asset/${asset.id}`}> <Link to={`/asset/${asset.id}`}>
<h1>{base.name}</h1> <h1>{base.name}</h1>
<div className={styles.date} title={base.dateCreated}> <div
{moment(base.dateCreated, 'YYYYMMDD').fromNow()} className={styles.date}
title={`Published on ${base.datePublished}`}
>
{moment(base.datePublished, 'YYYYMMDD').fromNow()}
</div> </div>
</Link> </Link>
</article> </article>

View File

@ -52,7 +52,7 @@ export default class AssetsUser extends PureComponent<
<div className={styles.assetsUser}> <div className={styles.assetsUser}>
{this.props.recent && ( {this.props.recent && (
<h2 className={styles.subTitle}> <h2 className={styles.subTitle}>
Your Latest Data Sets Your Latest Published Data Sets
</h2> </h2>
)} )}

View File

@ -1,12 +1,28 @@
import React from 'react' import React from 'react'
import { NavLink } from 'react-router-dom' import { NavLink } from 'react-router-dom'
import { ReactComponent as Logo } from '@oceanprotocol/art/logo/logo.svg' import { ReactComponent as Logo } from '@oceanprotocol/art/logo/logo.svg'
import { User } from '../../context/User'
import AccountStatus from '../molecules/AccountStatus' import AccountStatus from '../molecules/AccountStatus'
import styles from './Header.module.scss' import styles from './Header.module.scss'
import menu from '../../data/menu.json' import menu from '../../data/menu.json'
import meta from '../../data/meta.json' import meta from '../../data/meta.json'
const MenuItem = ({ item, isWeb3 }: { item: any; isWeb3: boolean }) => {
if (item.web3 && !isWeb3) return null
return (
<NavLink
to={item.link}
className={styles.link}
activeClassName={styles.linkActive}
exact
>
{item.title}
</NavLink>
)
}
const Header = () => ( const Header = () => (
<header className={styles.header}> <header className={styles.header}>
<div className={styles.headerContent}> <div className={styles.headerContent}>
@ -16,17 +32,17 @@ const Header = () => (
</NavLink> </NavLink>
<nav className={styles.headerMenu}> <nav className={styles.headerMenu}>
{menu.map(item => ( <User.Consumer>
<NavLink {states =>
key={item.title} menu.map(item => (
to={item.link} <MenuItem
className={styles.link} key={item.title}
activeClassName={styles.linkActive} item={item}
exact isWeb3={states.isWeb3}
> />
{item.title} ))
</NavLink> }
))} </User.Consumer>
</nav> </nav>
<AccountStatus className={styles.accountStatus} /> <AccountStatus className={styles.accountStatus} />
</div> </div>

View File

@ -1,22 +1,21 @@
[ [
{ {
"title": "Publish", "title": "Publish",
"link": "/publish" "link": "/publish",
"web3": true
}, },
{ {
"title": "History", "title": "History",
"link": "/history" "link": "/history",
"web3": true
}, },
{ {
"title": "Faucet", "title": "Faucet",
"link": "/faucet" "link": "/faucet",
"web3": true
}, },
{ {
"title": "About", "title": "About",
"link": "/about" "link": "/about"
},
{
"title": "Styleguide",
"link": "/styleguide"
} }
] ]

View File

@ -10,6 +10,13 @@ interface AssetDetailsProps {
} }
export default class AssetDetails extends PureComponent<AssetDetailsProps> { export default class AssetDetails extends PureComponent<AssetDetailsProps> {
private datafilesLine = (files: any) => {
if (files.length === 1) {
return <span>{files.length} data file</span>
}
return <span>{files.length} data files</span>
}
public render() { public render() {
const { metadata, ddo } = this.props const { metadata, ddo } = this.props
const { base } = metadata const { base } = metadata
@ -32,18 +39,14 @@ export default class AssetDetails extends PureComponent<AssetDetailsProps> {
/> />
</span> </span>
{base.categories ? ( {base.categories && (
// TODO: Make this link to search for respective category // TODO: Make this link to search for respective category
<Link to={`/search?q=${base.categories[0]}`}> <Link to={`/search?q=${base.categories[0]}`}>
{base.categories[0]} {base.categories[0]}
</Link> </Link>
) : (
<Link to={'/search?q='}>Fake Category</Link>
)} )}
{base.files && ( {base.files && this.datafilesLine(base.files)}
<span>{base.files.length} data files</span>
)}
</div> </div>
</aside> </aside>
@ -77,9 +80,9 @@ export default class AssetDetails extends PureComponent<AssetDetailsProps> {
ddo={ddo} ddo={ddo}
/> />
<pre> {/* <pre>
<code>{JSON.stringify(metadata, null, 2)}</code> <code>{JSON.stringify(metadata, null, 2)}</code>
</pre> </pre> */}
</> </>
) )
} }

View File

@ -0,0 +1,60 @@
@import '../../styles/variables';
.buttonMain {
margin: auto;
margin-bottom: $spacer / 2;
display: block;
}
.error {
text-align: center;
color: $red;
font-size: $font-size-small;
}
.fileWrap {
margin-left: $spacer / 4;
margin-right: $spacer / 4;
margin-bottom: $spacer * $line-height;
flex: 1 1 100%;
@media (min-width: $break-point--small) {
flex-basis: calc(100% / 3 - #{$spacer} / 2);
}
}
.file {
display: inline-block;
background: $brand-grey;
padding: $spacer $spacer / 2;
margin-bottom: $spacer / 2;
text-align: left;
position: relative;
min-height: 100px;
&:before {
content: '';
position: absolute;
right: 0;
top: 0;
width: 0;
height: 0;
border-top: 1rem solid $body-background;
border-left: 1rem solid transparent;
}
li {
font-size: $font-size-small;
font-weight: $font-weight-bold;
color: $brand-white;
&:before {
display: none;
}
}
// move spinner a bit up
+ div {
margin-top: $spacer / 2;
}
}

View File

@ -0,0 +1,99 @@
import React, { PureComponent } from 'react'
import { Logger } from '@oceanprotocol/squid'
import filesize from 'filesize'
import { User } from '../../context/User'
import Button from '../../components/atoms/Button'
import Spinner from '../../components/atoms/Spinner'
import styles from './AssetFile.module.scss'
interface AssetFileProps {
file: any
ddo: any
}
interface AssetFileState {
isLoading: boolean
error: string
message: string
}
export default class AssetFile extends PureComponent<
AssetFileProps,
AssetFileState
> {
public state = {
isLoading: false,
error: '',
message: 'Decrypting file, please sign...'
}
private resetState = () => this.setState({ isLoading: true, error: '' })
private purchaseAsset = async (ddo: any, index: number) => {
this.resetState()
const { ocean } = this.context
const accounts = await ocean.accounts.list()
try {
const service = ddo.findServiceByType('Access')
const agreementId = await ocean.assets.order(
ddo.id,
service.serviceDefinitionId,
accounts[0]
)
const path = await ocean.assets.consume(
agreementId,
ddo.id,
service.serviceDefinitionId,
accounts[0],
'',
index
)
Logger.log('path', path)
this.setState({ isLoading: false })
} catch (error) {
Logger.log('error', error)
this.setState({ isLoading: false, error: error.message })
}
}
public render() {
const { ddo, file } = this.props
return (
<div className={styles.fileWrap}>
<ul key={file.index} className={styles.file}>
<li>
{file.contentType && file.contentType.split('/')[1]}
</li>
<li>
{file.contentLength && filesize(file.contentLength)}
</li>
{/* <li>{file.encoding}</li> */}
{/* <li>{file.compression}</li> */}
</ul>
{this.state.isLoading ? (
<Spinner message={this.state.message} />
) : (
<Button
primary
className={styles.buttonMain}
onClick={() => this.purchaseAsset(ddo, file.index)}
>
Get file
</Button>
)}
{this.state.error !== '' && (
<div className={styles.error}>{this.state.error}</div>
)}
</div>
)
}
}
AssetFile.contextType = User

View File

@ -1,36 +1,8 @@
@import '../../styles/variables'; @import '../../styles/variables';
.buttonMain {
margin: auto;
margin-bottom: $spacer / 2;
display: block;
}
.error {
text-align: center;
color: $red;
font-size: $font-size-small;
}
.files { .files {
text-align: center; text-align: center;
} display: flex;
flex-wrap: wrap;
.file { justify-content: center;
display: inline-block;
border: .1rem solid $brand-grey-light;
padding: $spacer $spacer / 2;
text-align: left;
margin-left: $spacer / 4;
margin-right: $spacer / 4;
li {
font-size: $font-size-small;
font-weight: $font-weight-bold;
color: $brand-grey-light;
&:before {
display: none;
}
}
} }

View File

@ -1,51 +1,11 @@
import React, { PureComponent } from 'react' import React, { PureComponent } from 'react'
import { Logger } from '@oceanprotocol/squid' import AssetFile from './AssetFile'
import filesize from 'filesize'
import { User } from '../../context/User'
import Button from '../../components/atoms/Button'
import Spinner from '../../components/atoms/Spinner'
import styles from './AssetFilesDetails.module.scss' import styles from './AssetFilesDetails.module.scss'
interface AssetFilesDetailsProps { export default class AssetFilesDetails extends PureComponent<{
files: any[] files: any[]
ddo: any ddo: any
} }> {
export default class AssetFilesDetails extends PureComponent<
AssetFilesDetailsProps
> {
public state = { isLoading: false, error: null }
private purchaseAsset = async (ddo: any) => {
this.setState({ isLoading: true, error: null })
const { ocean } = this.context
const accounts = await ocean.accounts.list()
try {
const service = ddo.findServiceByType('Access')
const agreementId = await ocean.assets.order(
ddo.id,
service.serviceDefinitionId,
accounts[0]
)
const path = await ocean.assets.consume(
agreementId,
ddo.id,
service.serviceDefinitionId,
accounts[0],
''
)
Logger.log('path', path)
this.setState({ isLoading: false })
} catch (error) {
Logger.log('error', error)
this.setState({ isLoading: false, error: error.message })
}
}
public render() { public render() {
const { files, ddo } = this.props const { files, ddo } = this.props
@ -53,41 +13,12 @@ export default class AssetFilesDetails extends PureComponent<
<> <>
<div className={styles.files}> <div className={styles.files}>
{files.map(file => ( {files.map(file => (
<ul key={file.index} className={styles.file}> <AssetFile key={file.index} ddo={ddo} file={file} />
<li>
{file.contentType &&
file.contentType.split('/')[1]}
</li>
<li>
{file.contentLength &&
filesize(file.contentLength)}
</li>
{/* <li>{file.encoding}</li> */}
{/* <li>{file.compression}</li> */}
</ul>
))} ))}
</div> </div>
{this.state.isLoading ? (
<Spinner message="Decrypting files, please sign with your wallet..." />
) : (
<Button
primary
className={styles.buttonMain}
onClick={() => this.purchaseAsset(ddo)}
>
Get asset files
</Button>
)}
{this.state.error && (
<div className={styles.error}>{this.state.error}</div>
)}
</> </>
) : ( ) : (
<div>No files attached.</div> <div>No files attached.</div>
) )
} }
} }
AssetFilesDetails.contextType = User

View File

@ -3,3 +3,35 @@
.message { .message {
margin-bottom: $spacer; margin-bottom: $spacer;
} }
.success {
composes: message;
background: $green;
padding: $spacer / 1.5;
border-radius: $border-radius;
color: $brand-white;
font-weight: $font-weight-bold;
text-align: center;
&,
a,
button {
color: $brand-white;
}
a,
button {
transition: color .2s ease-out;
&:hover,
&:focus {
color: $brand-pink;
transform: none;
}
}
a {
display: inline-block;
margin-right: $spacer;
}
}

View File

@ -1,6 +1,7 @@
import React, { PureComponent } from 'react' import React, { PureComponent } from 'react'
import Web3message from '../../components/organisms/Web3message' import Web3message from '../../components/organisms/Web3message'
import Spinner from '../../components/atoms/Spinner' import Spinner from '../../components/atoms/Spinner'
import Button from '../../components/atoms/Button'
import styles from './StepRegisterContent.module.scss' import styles from './StepRegisterContent.module.scss'
interface StepRegisterContentProps { interface StepRegisterContentProps {
@ -26,11 +27,14 @@ export default class StepRegisterContent extends PureComponent<
) )
public publishedState = () => ( public publishedState = () => (
<div className={styles.message}> <div className={styles.success}>
Your asset is published! See it{' '} <p>Your asset is published!</p>
<a href={'/asset/' + this.props.state.publishedDid}>here</a>, submit <Button link to={'/asset/' + this.props.state.publishedDid}>
another asset by clicking{' '} See published asset
<a onClick={() => this.props.toStart()}>here</a> </Button>
<Button link onClick={() => this.props.toStart()}>
Publish another asset
</Button>
</div> </div>
) )
@ -38,7 +42,6 @@ export default class StepRegisterContent extends PureComponent<
return ( return (
<> <>
<Web3message /> <Web3message />
{this.props.state.isPublishing ? ( {this.props.state.isPublishing ? (
this.publishingState() this.publishingState()
) : this.props.state.publishingError ? ( ) : this.props.state.publishingError ? (

View File

@ -18,6 +18,8 @@ $yellow: #eac146;
$brand-gradient: linear-gradient(to right bottom, $brand-purple, $brand-pink); $brand-gradient: linear-gradient(to right bottom, $brand-purple, $brand-pink);
$body-background: darken($brand-white, 1%);
// Fonts // Fonts
$font-family-base: 'Sharp Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', $font-family-base: 'Sharp Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI',
Helvetica, Arial, sans-serif; Helvetica, Arial, sans-serif;

View File

@ -29,7 +29,7 @@ body {
font-family: $font-family-base; font-family: $font-family-base;
font-weight: $font-weight-base; font-weight: $font-weight-base;
line-height: $line-height; line-height: $line-height;
background: darken($brand-white, 1%); background: $body-background;
-webkit-tap-highlight-color: rgba(0, 0, 0, 0); -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
-webkit-font-smoothing: antialiased; -webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale; -moz-osx-font-smoothing: grayscale;