mirror of
https://github.com/oceanprotocol/commons.git
synced 2023-03-15 18:03:00 +01:00
more error output in UI
This commit is contained in:
parent
483cc35de3
commit
60a570892b
@ -15,7 +15,7 @@ export interface IpfsConfig {
|
||||
|
||||
export default function useIpfsApi(config: IpfsConfig) {
|
||||
const [isIpfsReady, setIpfsReady] = useState(Boolean(ipfs))
|
||||
const [ipfsError, setIpfsError] = useState(null)
|
||||
const [ipfsError, setIpfsError] = useState('')
|
||||
|
||||
useEffect(() => {
|
||||
async function initIpfs() {
|
||||
@ -49,7 +49,7 @@ export default function useIpfsApi(config: IpfsConfig) {
|
||||
ipfs = null
|
||||
ipfsMessage = ''
|
||||
ipfsVersion = ''
|
||||
setIpfsError(null)
|
||||
setIpfsError('')
|
||||
}
|
||||
}
|
||||
}, [])
|
||||
|
@ -1,32 +0,0 @@
|
||||
import React from 'react'
|
||||
import { render, fireEvent } from '@testing-library/react'
|
||||
import Ipfs from './Ipfs'
|
||||
|
||||
const addFile = jest.fn()
|
||||
|
||||
describe('Ipfs', () => {
|
||||
const ui = <Ipfs addFile={addFile} />
|
||||
|
||||
it('renders without crashing', async () => {
|
||||
const { container, findByText } = render(ui)
|
||||
expect(container.firstChild).toBeInTheDocument()
|
||||
|
||||
// wait for IPFS node
|
||||
await findByText(/Connected to /)
|
||||
})
|
||||
|
||||
it('files can be dropped', async () => {
|
||||
const { container, findByText } = render(ui)
|
||||
|
||||
// wait for IPFS node
|
||||
await findByText(/Connected to /)
|
||||
|
||||
const file = new File(['(⌐□_□)'], 'chucknorris.png', {
|
||||
type: 'image/png'
|
||||
})
|
||||
|
||||
// drop a file
|
||||
const dropzoneInput = container.querySelector('.dropzone input')
|
||||
dropzoneInput && fireEvent.change(dropzoneInput, { target: [file] })
|
||||
})
|
||||
})
|
@ -1,4 +1,4 @@
|
||||
@import '../../../styles/variables';
|
||||
@import '../../../../styles/variables';
|
||||
|
||||
.ipfsForm {
|
||||
margin-top: $spacer / 2;
|
||||
@ -23,30 +23,3 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.message {
|
||||
font-size: $font-size-small;
|
||||
margin-top: $spacer / 2;
|
||||
color: $brand-grey-light;
|
||||
|
||||
&:before {
|
||||
content: '';
|
||||
width: .5rem;
|
||||
height: .5rem;
|
||||
display: inline-block;
|
||||
background: $green;
|
||||
border-radius: 50%;
|
||||
margin-right: $spacer / 4;
|
||||
margin-bottom: .05rem;
|
||||
}
|
||||
}
|
||||
|
||||
.error {
|
||||
composes: message;
|
||||
color: $red;
|
||||
|
||||
&:before {
|
||||
border-radius: 0;
|
||||
background: $red;
|
||||
}
|
||||
}
|
26
client/src/routes/Publish/Files/Ipfs/Form.tsx
Normal file
26
client/src/routes/Publish/Files/Ipfs/Form.tsx
Normal file
@ -0,0 +1,26 @@
|
||||
import React from 'react'
|
||||
import Label from '../../../../components/atoms/Form/Label'
|
||||
import Status from './Status'
|
||||
import styles from './Form.module.scss'
|
||||
|
||||
export default function Form({
|
||||
children,
|
||||
ipfsMessage,
|
||||
ipfsError,
|
||||
error
|
||||
}: {
|
||||
children: any
|
||||
ipfsMessage: string
|
||||
ipfsError?: string
|
||||
error?: string
|
||||
}) {
|
||||
return (
|
||||
<div className={styles.ipfsForm}>
|
||||
<Label htmlFor="fileUpload" required>
|
||||
Add File To IPFS
|
||||
</Label>
|
||||
{children}
|
||||
<Status message={ipfsMessage} error={ipfsError || error} />
|
||||
</div>
|
||||
)
|
||||
}
|
28
client/src/routes/Publish/Files/Ipfs/Status.module.scss
Normal file
28
client/src/routes/Publish/Files/Ipfs/Status.module.scss
Normal file
@ -0,0 +1,28 @@
|
||||
@import '../../../../styles/variables';
|
||||
|
||||
.message {
|
||||
font-size: $font-size-small;
|
||||
margin-top: $spacer / 2;
|
||||
color: $brand-grey-light;
|
||||
|
||||
&:before {
|
||||
content: '';
|
||||
width: .5rem;
|
||||
height: .5rem;
|
||||
display: inline-block;
|
||||
background: $green;
|
||||
border-radius: 50%;
|
||||
margin-right: $spacer / 4;
|
||||
margin-bottom: .05rem;
|
||||
}
|
||||
}
|
||||
|
||||
.error {
|
||||
composes: message;
|
||||
color: $red;
|
||||
|
||||
&:before {
|
||||
border-radius: 0;
|
||||
background: $red;
|
||||
}
|
||||
}
|
13
client/src/routes/Publish/Files/Ipfs/Status.tsx
Normal file
13
client/src/routes/Publish/Files/Ipfs/Status.tsx
Normal file
@ -0,0 +1,13 @@
|
||||
import React from 'react'
|
||||
import styles from './Status.module.scss'
|
||||
|
||||
export default function Status({
|
||||
message,
|
||||
error
|
||||
}: {
|
||||
message: string
|
||||
error?: string
|
||||
}) {
|
||||
const classes = error ? styles.error : styles.message
|
||||
return <div className={classes}>{message}</div>
|
||||
}
|
44
client/src/routes/Publish/Files/Ipfs/index.test.tsx
Normal file
44
client/src/routes/Publish/Files/Ipfs/index.test.tsx
Normal file
@ -0,0 +1,44 @@
|
||||
import React from 'react'
|
||||
import { render, fireEvent, waitForElement, act } from '@testing-library/react'
|
||||
import Ipfs from '.'
|
||||
|
||||
const addFile = jest.fn()
|
||||
|
||||
describe('IPFS', () => {
|
||||
const ui = <Ipfs addFile={addFile} />
|
||||
const file = new File(['(⌐□_□)'], 'chucknorris.png', {
|
||||
type: 'image/png'
|
||||
})
|
||||
|
||||
it('HTTP API: files can be dropped', async () => {
|
||||
const { container, findByText, getByText } = render(ui)
|
||||
expect(container).toBeInTheDocument()
|
||||
|
||||
// wait for IPFS node
|
||||
await findByText(/Connected to /)
|
||||
|
||||
// drop a file
|
||||
const dropzoneInput = container.querySelector('.dropzone')
|
||||
Object.defineProperty(dropzoneInput, 'files', { value: [file] })
|
||||
act(() => {
|
||||
dropzoneInput && fireEvent.drop(dropzoneInput)
|
||||
})
|
||||
const addingText = await waitForElement(() => getByText(/Adding /))
|
||||
expect(addingText).toBeDefined()
|
||||
})
|
||||
|
||||
// it('Local Node: files can be dropped', async () => {
|
||||
// const { debug, container, findByText, getByText } = render(
|
||||
// <Ipfs addFile={addFile} node />
|
||||
// )
|
||||
// expect(container).toBeInTheDocument()
|
||||
// // wait for IPFS node
|
||||
// await findByText(/IPFS started/)
|
||||
// // drop a file
|
||||
// const dropzoneInput = container.querySelector('.dropzone input')
|
||||
// Object.defineProperty(dropzoneInput, 'files', { value: [file] })
|
||||
// dropzoneInput && fireEvent.drop(dropzoneInput)
|
||||
// await waitForElement(() => getByText(/File found/), { timeout: 100000 })
|
||||
// expect(addFile).toHaveBeenCalledTimes(1)
|
||||
// })
|
||||
})
|
@ -1,12 +1,11 @@
|
||||
/* eslint-disable no-console */
|
||||
import React, { useState, useEffect } from 'react'
|
||||
import useIpfsApi, { IpfsConfig } from '../../../hooks/use-ipfs-api'
|
||||
import Label from '../../../components/atoms/Form/Label'
|
||||
import Spinner from '../../../components/atoms/Spinner'
|
||||
import Dropzone from '../../../components/molecules/Dropzone'
|
||||
import { formatBytes, pingUrl, readFileAsync } from '../../../utils/utils'
|
||||
import { ipfsGatewayUri } from '../../../config'
|
||||
import styles from './Ipfs.module.scss'
|
||||
import useIpfsApi, { IpfsConfig } from '../../../../hooks/use-ipfs-api'
|
||||
import Spinner from '../../../../components/atoms/Spinner'
|
||||
import Dropzone from '../../../../components/molecules/Dropzone'
|
||||
import { formatBytes, pingUrl, readFileAsync } from '../../../../utils/utils'
|
||||
import { ipfsGatewayUri } from '../../../../config'
|
||||
import Form from './Form'
|
||||
|
||||
const config: IpfsConfig = {
|
||||
host: 'ipfs.infura.io',
|
||||
@ -15,34 +14,26 @@ const config: IpfsConfig = {
|
||||
}
|
||||
|
||||
export default function Ipfs({ addFile }: { addFile(url: string): void }) {
|
||||
const {
|
||||
ipfs,
|
||||
ipfsVersion,
|
||||
isIpfsReady,
|
||||
ipfsError,
|
||||
ipfsMessage
|
||||
} = useIpfsApi(config)
|
||||
|
||||
const { ipfs, isIpfsReady, ipfsError, ipfsMessage } = useIpfsApi(config)
|
||||
const [loading, setLoading] = useState(false)
|
||||
const [message, setMessage] = useState('')
|
||||
const [fileSize, setFileSize] = useState('')
|
||||
const [fileSizeReceived, setFileSizeReceived] = useState('')
|
||||
const [error, setError] = useState('')
|
||||
|
||||
useEffect(() => {
|
||||
setMessage(
|
||||
`Adding to IPFS<br />
|
||||
<small>${fileSizeReceived || 0}/${fileSize}</small><br />`
|
||||
)
|
||||
})
|
||||
}, [fileSize, fileSizeReceived])
|
||||
|
||||
async function addToIpfs(data: any) {
|
||||
try {
|
||||
const response = await ipfs.add(data, {
|
||||
wrapWithDirectory: true,
|
||||
progress: (length: number) => {
|
||||
console.log(`Received: ${formatBytes(length, 0)}`)
|
||||
progress: (length: number) =>
|
||||
setFileSizeReceived(formatBytes(length, 0))
|
||||
}
|
||||
})
|
||||
|
||||
// CID of wrapping directory is returned last
|
||||
@ -50,25 +41,26 @@ export default function Ipfs({ addFile }: { addFile(url: string): void }) {
|
||||
console.log(`File added: ${cid}`)
|
||||
return cid
|
||||
} catch (error) {
|
||||
console.error(`Adding to IPFS failed: ${error.message}`)
|
||||
setError(`Adding to IPFS failed: ${error.message}`)
|
||||
setLoading(false)
|
||||
}
|
||||
}
|
||||
|
||||
async function handleOnDrop(acceptedFiles: File[]) {
|
||||
async function handleOnDrop(acceptedFiles: any) {
|
||||
if (!acceptedFiles[0]) return
|
||||
|
||||
const { name, size } = acceptedFiles[0]
|
||||
const totalSize = formatBytes(size, 0)
|
||||
|
||||
setLoading(true)
|
||||
setError('')
|
||||
|
||||
const { path, size } = acceptedFiles[0]
|
||||
const totalSize = formatBytes(size, 0)
|
||||
setFileSize(totalSize)
|
||||
|
||||
// Add file to IPFS node
|
||||
const content: any = await readFileAsync(acceptedFiles[0])
|
||||
const data = Buffer.from(content)
|
||||
const fileDetails = {
|
||||
path: name,
|
||||
path,
|
||||
content: data
|
||||
}
|
||||
|
||||
@ -77,8 +69,8 @@ export default function Ipfs({ addFile }: { addFile(url: string): void }) {
|
||||
|
||||
// Ping gateway url to make it globally available,
|
||||
// but store native url in DDO.
|
||||
const urlGateway = `${ipfsGatewayUri}/ipfs/${cid}/${name}`
|
||||
const url = `ipfs://${cid}/${name}`
|
||||
const urlGateway = `${ipfsGatewayUri}/ipfs/${cid}/${path}`
|
||||
const url = `ipfs://${cid}/${path}`
|
||||
|
||||
setMessage('Checking IPFS gateway URL')
|
||||
await pingUrl(urlGateway)
|
||||
@ -88,10 +80,7 @@ export default function Ipfs({ addFile }: { addFile(url: string): void }) {
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={styles.ipfsForm}>
|
||||
<Label htmlFor="fileUpload" required>
|
||||
Add File To IPFS
|
||||
</Label>
|
||||
<Form error={error} ipfsMessage={ipfsMessage} ipfsError={ipfsError}>
|
||||
{loading ? (
|
||||
<Spinner message={message} />
|
||||
) : (
|
||||
@ -101,12 +90,6 @@ export default function Ipfs({ addFile }: { addFile(url: string): void }) {
|
||||
disabled={!isIpfsReady}
|
||||
/>
|
||||
)}
|
||||
{ipfsMessage !== '' && (
|
||||
<div className={styles.message} title={ipfsVersion}>
|
||||
{ipfsMessage}
|
||||
</div>
|
||||
)}
|
||||
{ipfsError && <div className={styles.error}>{ipfsError}</div>}
|
||||
</div>
|
||||
</Form>
|
||||
)
|
||||
}
|
@ -74,9 +74,6 @@ describe('Files', () => {
|
||||
await waitForElement(() => getByText('- Cancel'))
|
||||
expect(container.querySelector('.ipfsForm')).toBeInTheDocument()
|
||||
|
||||
// wait for IPFS node
|
||||
await findByText(/Connected to /)
|
||||
|
||||
// close
|
||||
fireEvent.click(getByText('- Cancel'))
|
||||
await waitForElement(() => getByText('+ Add to IPFS'))
|
||||
|
Loading…
Reference in New Issue
Block a user