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) {
|
export default function useIpfsApi(config: IpfsConfig) {
|
||||||
const [isIpfsReady, setIpfsReady] = useState(Boolean(ipfs))
|
const [isIpfsReady, setIpfsReady] = useState(Boolean(ipfs))
|
||||||
const [ipfsError, setIpfsError] = useState(null)
|
const [ipfsError, setIpfsError] = useState('')
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
async function initIpfs() {
|
async function initIpfs() {
|
||||||
@ -49,7 +49,7 @@ export default function useIpfsApi(config: IpfsConfig) {
|
|||||||
ipfs = null
|
ipfs = null
|
||||||
ipfsMessage = ''
|
ipfsMessage = ''
|
||||||
ipfsVersion = ''
|
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 {
|
.ipfsForm {
|
||||||
margin-top: $spacer / 2;
|
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 */
|
/* eslint-disable no-console */
|
||||||
import React, { useState, useEffect } from 'react'
|
import React, { useState, useEffect } from 'react'
|
||||||
import useIpfsApi, { IpfsConfig } from '../../../hooks/use-ipfs-api'
|
import useIpfsApi, { IpfsConfig } from '../../../../hooks/use-ipfs-api'
|
||||||
import Label from '../../../components/atoms/Form/Label'
|
import Spinner from '../../../../components/atoms/Spinner'
|
||||||
import Spinner from '../../../components/atoms/Spinner'
|
import Dropzone from '../../../../components/molecules/Dropzone'
|
||||||
import Dropzone from '../../../components/molecules/Dropzone'
|
import { formatBytes, pingUrl, readFileAsync } from '../../../../utils/utils'
|
||||||
import { formatBytes, pingUrl, readFileAsync } from '../../../utils/utils'
|
import { ipfsGatewayUri } from '../../../../config'
|
||||||
import { ipfsGatewayUri } from '../../../config'
|
import Form from './Form'
|
||||||
import styles from './Ipfs.module.scss'
|
|
||||||
|
|
||||||
const config: IpfsConfig = {
|
const config: IpfsConfig = {
|
||||||
host: 'ipfs.infura.io',
|
host: 'ipfs.infura.io',
|
||||||
@ -15,34 +14,26 @@ const config: IpfsConfig = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export default function Ipfs({ addFile }: { addFile(url: string): void }) {
|
export default function Ipfs({ addFile }: { addFile(url: string): void }) {
|
||||||
const {
|
const { ipfs, isIpfsReady, ipfsError, ipfsMessage } = useIpfsApi(config)
|
||||||
ipfs,
|
|
||||||
ipfsVersion,
|
|
||||||
isIpfsReady,
|
|
||||||
ipfsError,
|
|
||||||
ipfsMessage
|
|
||||||
} = useIpfsApi(config)
|
|
||||||
|
|
||||||
const [loading, setLoading] = useState(false)
|
const [loading, setLoading] = useState(false)
|
||||||
const [message, setMessage] = useState('')
|
const [message, setMessage] = useState('')
|
||||||
const [fileSize, setFileSize] = useState('')
|
const [fileSize, setFileSize] = useState('')
|
||||||
const [fileSizeReceived, setFileSizeReceived] = useState('')
|
const [fileSizeReceived, setFileSizeReceived] = useState('')
|
||||||
|
const [error, setError] = useState('')
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setMessage(
|
setMessage(
|
||||||
`Adding to IPFS<br />
|
`Adding to IPFS<br />
|
||||||
<small>${fileSizeReceived || 0}/${fileSize}</small><br />`
|
<small>${fileSizeReceived || 0}/${fileSize}</small><br />`
|
||||||
)
|
)
|
||||||
})
|
}, [fileSize, fileSizeReceived])
|
||||||
|
|
||||||
async function addToIpfs(data: any) {
|
async function addToIpfs(data: any) {
|
||||||
try {
|
try {
|
||||||
const response = await ipfs.add(data, {
|
const response = await ipfs.add(data, {
|
||||||
wrapWithDirectory: true,
|
wrapWithDirectory: true,
|
||||||
progress: (length: number) => {
|
progress: (length: number) =>
|
||||||
console.log(`Received: ${formatBytes(length, 0)}`)
|
|
||||||
setFileSizeReceived(formatBytes(length, 0))
|
setFileSizeReceived(formatBytes(length, 0))
|
||||||
}
|
|
||||||
})
|
})
|
||||||
|
|
||||||
// CID of wrapping directory is returned last
|
// 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}`)
|
console.log(`File added: ${cid}`)
|
||||||
return cid
|
return cid
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(`Adding to IPFS failed: ${error.message}`)
|
setError(`Adding to IPFS failed: ${error.message}`)
|
||||||
setLoading(false)
|
setLoading(false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function handleOnDrop(acceptedFiles: File[]) {
|
async function handleOnDrop(acceptedFiles: any) {
|
||||||
if (!acceptedFiles[0]) return
|
if (!acceptedFiles[0]) return
|
||||||
|
|
||||||
const { name, size } = acceptedFiles[0]
|
|
||||||
const totalSize = formatBytes(size, 0)
|
|
||||||
|
|
||||||
setLoading(true)
|
setLoading(true)
|
||||||
|
setError('')
|
||||||
|
|
||||||
|
const { path, size } = acceptedFiles[0]
|
||||||
|
const totalSize = formatBytes(size, 0)
|
||||||
setFileSize(totalSize)
|
setFileSize(totalSize)
|
||||||
|
|
||||||
// Add file to IPFS node
|
// Add file to IPFS node
|
||||||
const content: any = await readFileAsync(acceptedFiles[0])
|
const content: any = await readFileAsync(acceptedFiles[0])
|
||||||
const data = Buffer.from(content)
|
const data = Buffer.from(content)
|
||||||
const fileDetails = {
|
const fileDetails = {
|
||||||
path: name,
|
path,
|
||||||
content: data
|
content: data
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -77,8 +69,8 @@ export default function Ipfs({ addFile }: { addFile(url: string): void }) {
|
|||||||
|
|
||||||
// Ping gateway url to make it globally available,
|
// Ping gateway url to make it globally available,
|
||||||
// but store native url in DDO.
|
// but store native url in DDO.
|
||||||
const urlGateway = `${ipfsGatewayUri}/ipfs/${cid}/${name}`
|
const urlGateway = `${ipfsGatewayUri}/ipfs/${cid}/${path}`
|
||||||
const url = `ipfs://${cid}/${name}`
|
const url = `ipfs://${cid}/${path}`
|
||||||
|
|
||||||
setMessage('Checking IPFS gateway URL')
|
setMessage('Checking IPFS gateway URL')
|
||||||
await pingUrl(urlGateway)
|
await pingUrl(urlGateway)
|
||||||
@ -88,10 +80,7 @@ export default function Ipfs({ addFile }: { addFile(url: string): void }) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={styles.ipfsForm}>
|
<Form error={error} ipfsMessage={ipfsMessage} ipfsError={ipfsError}>
|
||||||
<Label htmlFor="fileUpload" required>
|
|
||||||
Add File To IPFS
|
|
||||||
</Label>
|
|
||||||
{loading ? (
|
{loading ? (
|
||||||
<Spinner message={message} />
|
<Spinner message={message} />
|
||||||
) : (
|
) : (
|
||||||
@ -101,12 +90,6 @@ export default function Ipfs({ addFile }: { addFile(url: string): void }) {
|
|||||||
disabled={!isIpfsReady}
|
disabled={!isIpfsReady}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{ipfsMessage !== '' && (
|
</Form>
|
||||||
<div className={styles.message} title={ipfsVersion}>
|
|
||||||
{ipfsMessage}
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
{ipfsError && <div className={styles.error}>{ipfsError}</div>}
|
|
||||||
</div>
|
|
||||||
)
|
)
|
||||||
}
|
}
|
@ -74,9 +74,6 @@ describe('Files', () => {
|
|||||||
await waitForElement(() => getByText('- Cancel'))
|
await waitForElement(() => getByText('- Cancel'))
|
||||||
expect(container.querySelector('.ipfsForm')).toBeInTheDocument()
|
expect(container.querySelector('.ipfsForm')).toBeInTheDocument()
|
||||||
|
|
||||||
// wait for IPFS node
|
|
||||||
await findByText(/Connected to /)
|
|
||||||
|
|
||||||
// close
|
// close
|
||||||
fireEvent.click(getByText('- Cancel'))
|
fireEvent.click(getByText('- Cancel'))
|
||||||
await waitForElement(() => getByText('+ Add to IPFS'))
|
await waitForElement(() => getByText('+ Add to IPFS'))
|
||||||
|
Loading…
Reference in New Issue
Block a user