Merge pull request #110 from oceanprotocol/feature/events

Consume feedback mesages
This commit is contained in:
Matthias Kretschmann 2019-05-21 16:17:41 +02:00 committed by GitHub
commit f432ce4b2d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 2018 additions and 2258 deletions

2467
client/package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -13,7 +13,7 @@
},
"dependencies": {
"@oceanprotocol/art": "^2.2.0",
"@oceanprotocol/squid": "^0.5.10",
"@oceanprotocol/squid": "^0.5.11",
"@oceanprotocol/typographies": "^0.1.0",
"classnames": "^2.2.6",
"ethereum-blockies": "MyEtherWallet/blockies",

View File

@ -5,6 +5,7 @@
text-align: center;
margin-top: $spacer * $line-height;
margin-bottom: $spacer / 2;
line-height: 1.3;
&:before {
content: '';
@ -25,6 +26,7 @@
.spinnerMessage {
color: $brand-grey-light;
padding-top: $spacer / 4;
}
@keyframes spinner {

View File

@ -3,7 +3,12 @@ import styles from './Spinner.module.scss'
const Spinner = ({ message }: { message?: string }) => (
<div className={styles.spinner}>
{message && <div className={styles.spinnerMessage}>{message}</div>}
{message && (
<div
className={styles.spinnerMessage}
dangerouslySetInnerHTML={{ __html: message }}
/>
)}
</div>
)

View File

@ -6,7 +6,7 @@ import { DDO } from '@oceanprotocol/squid'
import { StateMock } from '@react-mock/state'
import ReactGA from 'react-ga'
import { User } from '../../context'
import AssetFile from './AssetFile'
import AssetFile, { messages } from './AssetFile'
const file = {
index: 0,
@ -57,6 +57,72 @@ describe('AssetFile', () => {
fireEvent.click(button)
})
it('renders feedback message: initial', async () => {
const { container } = render(
<StateMock state={{ isLoading: true, step: null }}>
<AssetFile file={file} ddo={ddo} />
</StateMock>
)
expect(container.querySelector('.spinner')).toHaveTextContent(
messages.start
)
})
it('renders feedback message: CreatingAgreement', async () => {
const { container } = render(
<StateMock state={{ isLoading: true, step: 0 }}>
<AssetFile file={file} ddo={ddo} />
</StateMock>
)
expect(container.querySelector('.spinner')).toHaveTextContent(
messages[0].replace(/<(?:.|\n)*?>/gm, '')
)
})
it('renders feedback message: AgreementInitialized', async () => {
const { container } = render(
<StateMock state={{ isLoading: true, step: 1 }}>
<AssetFile file={file} ddo={ddo} />
</StateMock>
)
expect(container.querySelector('.spinner')).toHaveTextContent(
messages[1].replace(/<(?:.|\n)*?>/gm, '')
)
})
it('renders feedback message: LockingPayment', async () => {
const { container } = render(
<StateMock state={{ isLoading: true, step: 2 }}>
<AssetFile file={file} ddo={ddo} />
</StateMock>
)
expect(container.querySelector('.spinner')).toHaveTextContent(
messages[2].replace(/<(?:.|\n)*?>/gm, '')
)
})
it('renders feedback message: LockedPayment', async () => {
const { container } = render(
<StateMock state={{ isLoading: true, step: 3 }}>
<AssetFile file={file} ddo={ddo} />
</StateMock>
)
expect(container.querySelector('.spinner')).toHaveTextContent(
messages[3].replace(/<(?:.|\n)*?>/gm, '')
)
})
it('renders feedback message: before consume', async () => {
const { container } = render(
<StateMock state={{ isLoading: true, step: 4 }}>
<AssetFile file={file} ddo={ddo} />
</StateMock>
)
expect(container.querySelector('.spinner')).toHaveTextContent(
messages[4].replace(/<(?:.|\n)*?>/gm, '')
)
})
it('renders loading state', async () => {
const { container } = render(
<StateMock state={{ isLoading: true }}>

View File

@ -7,6 +7,15 @@ import { User } from '../../context'
import styles from './AssetFile.module.scss'
import ReactGA from 'react-ga'
export const messages = {
start: 'Decrypting file URL...',
0: '1/3<br />Asking for agreement signature...',
1: '1/3<br />Agreement initialized.',
2: '2/3<br />Asking for two payment confirmations...',
3: '2/3<br />Payment confirmed. Requesting access...',
4: '3/3<br /> Access granted. Consuming file...'
}
interface AssetFileProps {
file: File
ddo: DDO
@ -15,7 +24,7 @@ interface AssetFileProps {
interface AssetFileState {
isLoading: boolean
error: string
message: string
step: number | null
}
export default class AssetFile extends PureComponent<
@ -25,10 +34,15 @@ export default class AssetFile extends PureComponent<
public state = {
isLoading: false,
error: '',
message: 'Decrypting file URL, please sign...'
step: null
}
private resetState = () => this.setState({ isLoading: true, error: '' })
private resetState = () =>
this.setState({
isLoading: true,
error: '',
step: null
})
private purchaseAsset = async (ddo: DDO, index: number) => {
this.resetState()
@ -43,11 +57,13 @@ export default class AssetFile extends PureComponent<
try {
const accounts = await ocean.accounts.list()
const service = ddo.findServiceByType('Access')
const agreementId = await ocean.assets.order(
ddo.id,
service.serviceDefinitionId,
accounts[0]
)
const agreementId = await ocean.assets
.order(ddo.id, service.serviceDefinitionId, accounts[0])
.next((step: number) => this.setState({ step }))
// manually add another step here for better UX
this.setState({ step: 4 })
const path = await ocean.assets.consume(
agreementId,
@ -64,8 +80,11 @@ export default class AssetFile extends PureComponent<
})
this.setState({ isLoading: false })
} catch (error) {
Logger.log('error', error)
this.setState({ isLoading: false, error: error.message })
Logger.log('error', error.message)
this.setState({
isLoading: false,
error: `${error.message}. Sorry about that, can you try again?`
})
ReactGA.event({
category: 'Purchase',
action: 'purchaseAsset-error ' + error.message
@ -75,7 +94,7 @@ export default class AssetFile extends PureComponent<
public render() {
const { ddo, file } = this.props
const { isLoading, message, error } = this.state
const { isLoading, error, step } = this.state
const { isLogged, isOceanNetwork } = this.context
const { index } = file
@ -93,14 +112,16 @@ export default class AssetFile extends PureComponent<
</ul>
{isLoading ? (
<Spinner message={message} />
<Spinner
message={
step === null ? messages.start : messages[step]
}
/>
) : (
<Button
primary
className={styles.buttonMain}
// TODO: remove the || 0 once hack
// https://github.com/oceanprotocol/squid-js/pull/221
// is released
// weird 0 hack so TypeScript is happy
onClick={() => this.purchaseAsset(ddo, index || 0)}
disabled={!isLogged || !isOceanNetwork}
>

View File

@ -7,11 +7,11 @@
"dependencies": [
{
"name": "keeper-contracts",
"version": "~0.9.1"
"version": "~0.9.7"
},
{
"name": "brizo",
"version": "~0.3.5"
"version": "~0.3.6"
},
{
"name": "aquarius",
@ -19,7 +19,7 @@
},
{
"name": "squid-js",
"version": "~0.5.10"
"version": "~0.5.11"
},
{
"name": "faucet",

602
package-lock.json generated

File diff suppressed because it is too large Load Diff

1071
server/package-lock.json generated

File diff suppressed because it is too large Load Diff