mirror of
https://github.com/oceanprotocol/commons.git
synced 2023-03-15 18:03:00 +01:00
init network switcher component
This commit is contained in:
parent
70a3339f8b
commit
8023e30061
84
.eslintrc
84
.eslintrc
@ -1,43 +1,49 @@
|
|||||||
{
|
{
|
||||||
"parser": "@typescript-eslint/parser",
|
"parser": "@typescript-eslint/parser",
|
||||||
"parserOptions": {
|
"parserOptions": {
|
||||||
"project": [
|
"project": [
|
||||||
"./tsconfig.json",
|
"./tsconfig.json",
|
||||||
"./client/tsconfig.json",
|
"./client/tsconfig.json",
|
||||||
"./server/tsconfig.json",
|
"./server/tsconfig.json",
|
||||||
"./cypress/tsconfig.json"
|
"./cypress/tsconfig.json"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"extends": [
|
"extends": [
|
||||||
"oceanprotocol",
|
"oceanprotocol",
|
||||||
"oceanprotocol/react",
|
"oceanprotocol/react",
|
||||||
"plugin:@typescript-eslint/eslint-recommended",
|
"plugin:@typescript-eslint/eslint-recommended",
|
||||||
"plugin:@typescript-eslint/recommended",
|
"plugin:@typescript-eslint/recommended",
|
||||||
"plugin:prettier/recommended",
|
"plugin:prettier/recommended",
|
||||||
"prettier/react",
|
"prettier/react",
|
||||||
"prettier/standard",
|
"prettier/standard",
|
||||||
"prettier/@typescript-eslint",
|
"prettier/@typescript-eslint",
|
||||||
"plugin:cypress/recommended"
|
"plugin:cypress/recommended"
|
||||||
|
],
|
||||||
|
"plugins": ["@typescript-eslint", "prettier", "cypress"],
|
||||||
|
"rules": {
|
||||||
|
"@typescript-eslint/explicit-function-return-type": 0,
|
||||||
|
"@typescript-eslint/member-delimiter-style": [
|
||||||
|
"error",
|
||||||
|
{ "multiline": { "delimiter": "none" } }
|
||||||
],
|
],
|
||||||
"plugins": ["@typescript-eslint", "prettier", "cypress"],
|
"@typescript-eslint/no-explicit-any": "off",
|
||||||
"rules": {
|
"react/no-unescaped-entities": 0,
|
||||||
"@typescript-eslint/explicit-function-return-type": 0,
|
"react/self-closing-comp": 0,
|
||||||
"@typescript-eslint/member-delimiter-style": [
|
"react/void-dom-elements-no-children": 0,
|
||||||
"error",
|
"react/jsx-indent": 0,
|
||||||
{ "multiline": { "delimiter": "none" } }
|
"react/jsx-indent-props": 0,
|
||||||
],
|
"react/jsx-max-props-per-line": 0
|
||||||
"@typescript-eslint/no-explicit-any": "off"
|
},
|
||||||
},
|
"env": {
|
||||||
"env": {
|
"es6": true,
|
||||||
"es6": true,
|
"browser": true,
|
||||||
"browser": true,
|
"node": true,
|
||||||
"node": true,
|
"jest": true,
|
||||||
"jest": true,
|
"cypress/globals": true
|
||||||
"cypress/globals": true
|
},
|
||||||
},
|
"settings": {
|
||||||
"settings": {
|
"react": {
|
||||||
"react": {
|
"version": "16.10"
|
||||||
"version": "16.10"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
{
|
{
|
||||||
"semi": false,
|
"semi": false,
|
||||||
"singleQuote": true,
|
"singleQuote": true,
|
||||||
"trailingComma": "none"
|
"trailingComma": "none",
|
||||||
}
|
"tabWidth": 2
|
||||||
|
}
|
||||||
|
3
.vscode/settings.json
vendored
Normal file
3
.vscode/settings.json
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"typescript.tsdk": "node_modules/typescript/lib"
|
||||||
|
}
|
@ -5,33 +5,36 @@ import Footer from './components/organisms/Footer'
|
|||||||
import Spinner from './components/atoms/Spinner'
|
import Spinner from './components/atoms/Spinner'
|
||||||
import { User } from './context'
|
import { User } from './context'
|
||||||
import Routes from './Routes'
|
import Routes from './Routes'
|
||||||
|
import {commonsNetwork} from './components/molecules/NetworkSwitcher'
|
||||||
import './styles/global.scss'
|
import './styles/global.scss'
|
||||||
import styles from './App.module.scss'
|
import styles from './App.module.scss'
|
||||||
|
|
||||||
|
console.log(commonsNetwork)
|
||||||
|
|
||||||
export default class App extends Component {
|
export default class App extends Component {
|
||||||
public render() {
|
public render() {
|
||||||
return (
|
return (
|
||||||
<div className={styles.app}>
|
<div className={styles.app}>
|
||||||
<Router>
|
<Router>
|
||||||
<>
|
<>
|
||||||
<Header />
|
<Header />
|
||||||
|
|
||||||
<main className={styles.main}>
|
<main className={styles.main}>
|
||||||
{this.context.isLoading ? (
|
{this.context.isLoading ? (
|
||||||
<div className={styles.loader}>
|
<div className={styles.loader}>
|
||||||
<Spinner message={this.context.message} />
|
<Spinner message={this.context.message} />
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<Routes />
|
<Routes />
|
||||||
)}
|
)}
|
||||||
</main>
|
</main>
|
||||||
|
<Footer />
|
||||||
<Footer />
|
</>
|
||||||
</>
|
</Router>
|
||||||
</Router>
|
</div>
|
||||||
</div>
|
)
|
||||||
)
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
App.contextType = User
|
App.contextType = User
|
||||||
|
12
client/src/components/molecules/NetworkSwitcher.tsx
Normal file
12
client/src/components/molecules/NetworkSwitcher.tsx
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
import { CONNECTIONS } from '../../config'
|
||||||
|
|
||||||
|
/* TEMP NETWORK SWITCHER */
|
||||||
|
|
||||||
|
const urlParams = new URLSearchParams(window.location.search)
|
||||||
|
const network = urlParams.get('network') || 'pacific'
|
||||||
|
const idx = Object.keys(CONNECTIONS).indexOf(network)
|
||||||
|
const commonsNetwork = Object.values(CONNECTIONS)[idx]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
export { commonsNetwork }
|
@ -3,110 +3,109 @@ import { VersionNumbersState } from '.'
|
|||||||
import VersionTableRow from './VersionTableRow'
|
import VersionTableRow from './VersionTableRow'
|
||||||
import styles from './VersionTable.module.scss'
|
import styles from './VersionTable.module.scss'
|
||||||
import VersionNumber from './VersionNumber'
|
import VersionNumber from './VersionNumber'
|
||||||
|
import { useParams } from 'react-router-dom'
|
||||||
|
|
||||||
import {
|
import {
|
||||||
serviceUri,
|
serviceUri,
|
||||||
nodeUri,
|
nodeUri,
|
||||||
aquariusUri,
|
aquariusUri,
|
||||||
brizoUri,
|
brizoUri,
|
||||||
brizoAddress,
|
brizoAddress,
|
||||||
secretStoreUri,
|
secretStoreUri,
|
||||||
faucetUri
|
faucetUri,
|
||||||
|
CONNECTIONS
|
||||||
} from '../../../config'
|
} from '../../../config'
|
||||||
|
|
||||||
|
|
||||||
const commonsConfig = {
|
const commonsConfig = {
|
||||||
serviceUri,
|
serviceUri,
|
||||||
nodeUri,
|
nodeUri,
|
||||||
aquariusUri,
|
aquariusUri,
|
||||||
brizoUri,
|
brizoUri,
|
||||||
brizoAddress,
|
brizoAddress,
|
||||||
secretStoreUri,
|
secretStoreUri,
|
||||||
faucetUri
|
faucetUri
|
||||||
}
|
}
|
||||||
|
|
||||||
export const VersionTableContracts = ({
|
export const VersionTableContracts = ({
|
||||||
contracts,
|
contracts,
|
||||||
network,
|
network,
|
||||||
keeperVersion
|
keeperVersion
|
||||||
}: {
|
}: {
|
||||||
contracts: {
|
contracts: {
|
||||||
[contractName: string]: string
|
[contractName: string]: string
|
||||||
}
|
}
|
||||||
network: string
|
network: string
|
||||||
keeperVersion?: string
|
keeperVersion?: string
|
||||||
}) => (
|
}) => (
|
||||||
<table>
|
<table>
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
<strong>Keeper Contracts</strong>
|
<strong>Keeper Contracts</strong>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<VersionNumber
|
<VersionNumber name="Keeper Contracts" version={keeperVersion} />
|
||||||
name="Keeper Contracts"
|
</td>
|
||||||
version={keeperVersion}
|
</tr>
|
||||||
/>
|
{contracts &&
|
||||||
</td>
|
Object.keys(contracts)
|
||||||
</tr>
|
// sort alphabetically
|
||||||
{contracts &&
|
.sort((a, b) => a.localeCompare(b))
|
||||||
Object.keys(contracts)
|
.map(key => {
|
||||||
// sort alphabetically
|
const submarineLink = `https://submarine.${
|
||||||
.sort((a, b) => a.localeCompare(b))
|
network === 'pacific' ? 'oceanprotocol' : `${network}.dev-ocean`
|
||||||
.map(key => {
|
}.com/address/${contracts[key]}`
|
||||||
const submarineLink = `https://submarine.${
|
|
||||||
network === 'pacific'
|
|
||||||
? 'oceanprotocol'
|
|
||||||
: `${network}.dev-ocean`
|
|
||||||
}.com/address/${contracts[key]}`
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<tr key={key}>
|
|
||||||
<td>
|
<tr key={key}>
|
||||||
<code className={styles.label}>{key}</code>
|
<td>
|
||||||
</td>
|
<code className={styles.label}>{key}</code>
|
||||||
<td>
|
</td>
|
||||||
<a href={submarineLink}>
|
<td>
|
||||||
<code>{contracts[key]}</code>
|
<a href={submarineLink}>
|
||||||
</a>
|
<code>{contracts[key]}</code>
|
||||||
</td>
|
</a>
|
||||||
</tr>
|
</td>
|
||||||
)
|
</tr>
|
||||||
})}
|
)
|
||||||
</tbody>
|
})}
|
||||||
</table>
|
</tbody>
|
||||||
|
</table>
|
||||||
)
|
)
|
||||||
|
|
||||||
export const VersionTableCommons = () => (
|
export const VersionTableCommons = () => (
|
||||||
<table>
|
<table>
|
||||||
<tbody>
|
<tbody>
|
||||||
{Object.entries(commonsConfig).map(([key, value]) => (
|
{Object.entries(commonsConfig).map(([key, value]) => (
|
||||||
<tr key={key}>
|
<tr key={key}>
|
||||||
<td>
|
<td>
|
||||||
<code className={styles.label}>{key}</code>
|
<code className={styles.label}>{key}</code>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<code>{value}</code>
|
<code>{value}</code>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
))}
|
))}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
)
|
)
|
||||||
|
|
||||||
const VersionTable = ({ data }: { data: VersionNumbersState }) => {
|
const VersionTable = ({ data }: { data: VersionNumbersState }) => {
|
||||||
return (
|
return (
|
||||||
<div className={styles.tableWrap}>
|
<div className={styles.tableWrap}>
|
||||||
<table className={styles.table}>
|
<table className={styles.table}>
|
||||||
<tbody>
|
<tbody>
|
||||||
{Object.entries(data)
|
{Object.entries(data)
|
||||||
.filter(([key]) => key !== 'status')
|
.filter(([key]) => key !== 'status')
|
||||||
.map(([key, value]) => (
|
.map(([key, value]) => (
|
||||||
<VersionTableRow key={key} value={value} />
|
<VersionTableRow key={key} value={value} />
|
||||||
))}
|
))}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
export default VersionTable
|
export default VersionTable
|
||||||
|
@ -2,26 +2,26 @@
|
|||||||
// commons-server connection
|
// commons-server connection
|
||||||
//
|
//
|
||||||
export const serviceUri =
|
export const serviceUri =
|
||||||
process.env.REACT_APP_SERVICE_URI || 'http://localhost:4000'
|
process.env.REACT_APP_SERVICE_URI || 'http://localhost:4000'
|
||||||
|
|
||||||
//
|
//
|
||||||
// OCEAN REMOTE CONNECTIONS
|
// OCEAN REMOTE CONNECTIONS
|
||||||
//
|
//
|
||||||
export const nodeUri =
|
export const nodeUri =
|
||||||
process.env.REACT_APP_NODE_URI || 'https://pacific.oceanprotocol.com'
|
process.env.REACT_APP_NODE_URI || 'https://pacific.oceanprotocol.com'
|
||||||
export const aquariusUri =
|
export const aquariusUri =
|
||||||
process.env.REACT_APP_AQUARIUS_URI ||
|
process.env.REACT_APP_AQUARIUS_URI ||
|
||||||
'https://aquarius.commons.oceanprotocol.com'
|
'https://aquarius.commons.oceanprotocol.com'
|
||||||
export const brizoUri =
|
export const brizoUri =
|
||||||
process.env.REACT_APP_BRIZO_URI || 'https://brizo.commons.oceanprotocol.com'
|
process.env.REACT_APP_BRIZO_URI || 'https://brizo.commons.oceanprotocol.com'
|
||||||
export const brizoAddress =
|
export const brizoAddress =
|
||||||
process.env.REACT_APP_BRIZO_ADDRESS ||
|
process.env.REACT_APP_BRIZO_ADDRESS ||
|
||||||
'0x008c25ed3594e094db4592f4115d5fa74c4f41ea'
|
'0x008c25ed3594e094db4592f4115d5fa74c4f41ea'
|
||||||
export const secretStoreUri =
|
export const secretStoreUri =
|
||||||
process.env.REACT_APP_SECRET_STORE_URI ||
|
process.env.REACT_APP_SECRET_STORE_URI ||
|
||||||
'https://secret-store.oceanprotocol.com'
|
'https://secret-store.oceanprotocol.com'
|
||||||
export const faucetUri =
|
export const faucetUri =
|
||||||
process.env.REACT_APP_FAUCET_URI || 'https://faucet.oceanprotocol.com'
|
process.env.REACT_APP_FAUCET_URI || 'https://faucet.oceanprotocol.com'
|
||||||
|
|
||||||
//
|
//
|
||||||
// APP CONFIG
|
// APP CONFIG
|
||||||
@ -30,13 +30,40 @@ export const verbose = true
|
|||||||
export const analyticsId = 'UA-60614729-11'
|
export const analyticsId = 'UA-60614729-11'
|
||||||
|
|
||||||
export const showChannels =
|
export const showChannels =
|
||||||
process.env.REACT_APP_SHOW_CHANNELS === 'true' || false
|
process.env.REACT_APP_SHOW_CHANNELS === 'true' || false
|
||||||
export const allowPricing =
|
export const allowPricing =
|
||||||
process.env.REACT_APP_ALLOW_PRICING === 'true' || false
|
process.env.REACT_APP_ALLOW_PRICING === 'true' || false
|
||||||
export const showRequestTokens =
|
export const showRequestTokens =
|
||||||
process.env.REACT_APP_SHOW_REQUEST_TOKENS_BUTTON === 'true' || false
|
process.env.REACT_APP_SHOW_REQUEST_TOKENS_BUTTON === 'true' || false
|
||||||
// https://ipfs.github.io/public-gateway-checker/
|
// https://ipfs.github.io/public-gateway-checker/
|
||||||
export const ipfsGatewayUri =
|
export const ipfsGatewayUri =
|
||||||
process.env.REACT_APP_IPFS_GATEWAY_URI || 'https://gateway.ipfs.io'
|
process.env.REACT_APP_IPFS_GATEWAY_URI || 'https://gateway.ipfs.io'
|
||||||
export const ipfsNodeUri =
|
export const ipfsNodeUri =
|
||||||
process.env.REACT_APP_IPFS_NODE_URI || 'https://ipfs.infura.io:5001'
|
process.env.REACT_APP_IPFS_NODE_URI || 'https://ipfs.infura.io:5001'
|
||||||
|
|
||||||
|
export const CONNECTIONS = {
|
||||||
|
pacific: {
|
||||||
|
nodeUri: 'https://pacific.oceanprotocol.com',
|
||||||
|
aquariusUri: 'https://aquarius.commons.oceanprotocol.com',
|
||||||
|
brizoUri: 'https://brizo.commons.oceanprotocol.com',
|
||||||
|
brizoAddress: '0x008c25ed3594e094db4592f4115d5fa74c4f41ea',
|
||||||
|
secretStoreUri: 'https://secret-store.oceanprotocol.com',
|
||||||
|
faucetUri: 'https://faucet.oceanprotocol.com'
|
||||||
|
},
|
||||||
|
nile: {
|
||||||
|
nodeUri: 'https://nile.dev-ocean.com',
|
||||||
|
aquariusUri: 'https://aquarius.nile.dev-ocean.com',
|
||||||
|
brizoUri: 'https://brizo.nile.dev-ocean.com',
|
||||||
|
brizoAddress: '0x4aaab179035dc57b35e2ce066919048686f82972',
|
||||||
|
secretStoreUri: 'https://secret-store.nile.dev-ocean.com',
|
||||||
|
faucetUri: 'https://faucet.nile.dev-ocean.com'
|
||||||
|
},
|
||||||
|
duero: {
|
||||||
|
nodeUri: 'https://duero.dev-ocean.com',
|
||||||
|
aquariusUri: 'https://aquarius.duero.dev-ocean.com',
|
||||||
|
brizoUri: 'https://brizo.duero.dev-ocean.com',
|
||||||
|
brizoAddress: '0x9d4ed58293f71122ad6a733c1603927a150735d0',
|
||||||
|
secretStoreUri: 'https://secret-store.duero.dev-ocean.com',
|
||||||
|
faucetUri: 'https://faucet.duero.dev-ocean.com'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -21,6 +21,7 @@ export { renderToDOM }
|
|||||||
|
|
||||||
renderToDOM()
|
renderToDOM()
|
||||||
|
|
||||||
|
|
||||||
// If you want your app to work offline and load faster, you can change
|
// If you want your app to work offline and load faster, you can change
|
||||||
// unregister() to register() below. Note this comes with some pitfalls.
|
// unregister() to register() below. Note this comes with some pitfalls.
|
||||||
// Learn more about service workers: http://bit.ly/CRA-PWA
|
// Learn more about service workers: http://bit.ly/CRA-PWA
|
||||||
|
@ -1,55 +1,58 @@
|
|||||||
import { Ocean, Logger } from '@oceanprotocol/squid'
|
import { Ocean, Logger } from '@oceanprotocol/squid'
|
||||||
import Web3 from 'web3'
|
import Web3 from 'web3'
|
||||||
|
import { User } from './context'
|
||||||
|
|
||||||
import {
|
import {
|
||||||
|
aquariusUri,
|
||||||
|
brizoUri,
|
||||||
|
brizoAddress,
|
||||||
|
faucetUri,
|
||||||
|
nodeUri,
|
||||||
|
secretStoreUri,
|
||||||
|
verbose
|
||||||
|
} from './config'
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
export async function provideOcean(web3Provider: Web3) {
|
||||||
|
const config = {
|
||||||
|
web3Provider,
|
||||||
|
nodeUri,
|
||||||
aquariusUri,
|
aquariusUri,
|
||||||
brizoUri,
|
brizoUri,
|
||||||
brizoAddress,
|
brizoAddress,
|
||||||
faucetUri,
|
|
||||||
nodeUri,
|
|
||||||
secretStoreUri,
|
secretStoreUri,
|
||||||
verbose
|
verbose
|
||||||
} from './config'
|
}
|
||||||
|
const ocean: any = await Ocean.getInstance(config)
|
||||||
export async function provideOcean(web3Provider: Web3) {
|
return { ocean }
|
||||||
const config = {
|
|
||||||
web3Provider,
|
|
||||||
nodeUri,
|
|
||||||
aquariusUri,
|
|
||||||
brizoUri,
|
|
||||||
brizoAddress,
|
|
||||||
secretStoreUri,
|
|
||||||
verbose
|
|
||||||
}
|
|
||||||
const ocean: any = await Ocean.getInstance(config)
|
|
||||||
return { ocean }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Faucet
|
// Faucet
|
||||||
//
|
//
|
||||||
export interface FaucetResponse {
|
export interface FaucetResponse {
|
||||||
success: boolean
|
success: boolean
|
||||||
message: string
|
message: string
|
||||||
trxHash?: string
|
trxHash?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function requestFromFaucet(account: string) {
|
export async function requestFromFaucet(account: string) {
|
||||||
try {
|
try {
|
||||||
const url = `${faucetUri}/faucet`
|
const url = `${faucetUri}/faucet`
|
||||||
const response = await fetch(url, {
|
const response = await fetch(url, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: {
|
headers: {
|
||||||
Accept: 'application/json',
|
Accept: 'application/json',
|
||||||
'Content-Type': 'application/json'
|
'Content-Type': 'application/json'
|
||||||
},
|
},
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
address: account,
|
address: account,
|
||||||
agent: 'commons'
|
agent: 'commons'
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
return response.json()
|
return response.json()
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
Logger.error('requestFromFaucet', error.message)
|
Logger.error('requestFromFaucet', error.message)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
import React, {
|
import React, {
|
||||||
lazy,
|
lazy,
|
||||||
Suspense,
|
Suspense,
|
||||||
FormEvent,
|
FormEvent,
|
||||||
PureComponent,
|
PureComponent,
|
||||||
ChangeEvent
|
ChangeEvent
|
||||||
} from 'react'
|
} from 'react'
|
||||||
import axios from 'axios'
|
import axios from 'axios'
|
||||||
import { Logger, File } from '@oceanprotocol/squid'
|
import { Logger, File } from '@oceanprotocol/squid'
|
||||||
@ -21,202 +21,196 @@ import Spinner from '../../../components/atoms/Spinner'
|
|||||||
const Ipfs = lazy(() => import('./Ipfs'))
|
const Ipfs = lazy(() => import('./Ipfs'))
|
||||||
|
|
||||||
export interface FilePublish extends File {
|
export interface FilePublish extends File {
|
||||||
found: boolean // non-standard
|
found: boolean // non-standard
|
||||||
}
|
}
|
||||||
|
|
||||||
interface FilesProps {
|
interface FilesProps {
|
||||||
files: File[]
|
files: File[]
|
||||||
placeholder: string
|
placeholder: string
|
||||||
help?: string
|
help?: string
|
||||||
name: string
|
name: string
|
||||||
onChange(
|
onChange(
|
||||||
event:
|
event:
|
||||||
| ChangeEvent<HTMLInputElement>
|
| ChangeEvent<HTMLInputElement>
|
||||||
| FormEvent<HTMLInputElement>
|
| FormEvent<HTMLInputElement>
|
||||||
| ChangeEvent<HTMLSelectElement>
|
| ChangeEvent<HTMLSelectElement>
|
||||||
| ChangeEvent<HTMLTextAreaElement>
|
| ChangeEvent<HTMLTextAreaElement>
|
||||||
): void
|
): void
|
||||||
}
|
}
|
||||||
|
|
||||||
interface FilesStates {
|
interface FilesStates {
|
||||||
isFormShown: boolean
|
isFormShown: boolean
|
||||||
isIpfsFormShown: boolean
|
isIpfsFormShown: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
const buttons = [
|
const buttons = [
|
||||||
{
|
{
|
||||||
id: 'url',
|
id: 'url',
|
||||||
title: '+ From URL',
|
title: '+ From URL',
|
||||||
titleActive: '- Cancel'
|
titleActive: '- Cancel'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'ipfs',
|
id: 'ipfs',
|
||||||
title: '+ Add to IPFS',
|
title: '+ Add to IPFS',
|
||||||
titleActive: '- Cancel'
|
titleActive: '- Cancel'
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
export default class Files extends PureComponent<FilesProps, FilesStates> {
|
export default class Files extends PureComponent<FilesProps, FilesStates> {
|
||||||
public state: FilesStates = {
|
public state: FilesStates = {
|
||||||
|
isFormShown: false,
|
||||||
|
isIpfsFormShown: false
|
||||||
|
}
|
||||||
|
|
||||||
|
// for canceling axios requests
|
||||||
|
public signal = axios.CancelToken.source()
|
||||||
|
|
||||||
|
public componentWillUnmount() {
|
||||||
|
this.signal.cancel()
|
||||||
|
}
|
||||||
|
|
||||||
|
private toggleForm = (e: Event, form: string) => {
|
||||||
|
e.preventDefault()
|
||||||
|
|
||||||
|
this.setState({
|
||||||
|
isFormShown: form === 'url' ? !this.state.isFormShown : false,
|
||||||
|
isIpfsFormShown: form === 'ipfs' ? !this.state.isIpfsFormShown : false
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
private async getFile(url: string) {
|
||||||
|
const file: FilePublish = {
|
||||||
|
url,
|
||||||
|
contentType: '',
|
||||||
|
found: false // non-standard
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await axios({
|
||||||
|
method: 'POST',
|
||||||
|
headers: { 'Content-Type': 'application/json' },
|
||||||
|
url: `${serviceUri}/api/v1/urlcheck`,
|
||||||
|
data: { url },
|
||||||
|
cancelToken: this.signal.token
|
||||||
|
})
|
||||||
|
|
||||||
|
const { contentLength, contentType, found } = response.data.result
|
||||||
|
|
||||||
|
if (contentLength) file.contentLength = contentLength
|
||||||
|
if (contentType) {
|
||||||
|
file.contentType = contentType
|
||||||
|
file.compression = cleanupContentType(contentType)
|
||||||
|
}
|
||||||
|
|
||||||
|
file.found = found
|
||||||
|
|
||||||
|
return file
|
||||||
|
} catch (error) {
|
||||||
|
!axios.isCancel(error) && Logger.error(error.message)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private addFile = async (url: string) => {
|
||||||
|
// check for duplicate urls
|
||||||
|
const duplicateFiles = this.props.files.filter(props =>
|
||||||
|
url.includes(props.url)
|
||||||
|
)
|
||||||
|
|
||||||
|
if (duplicateFiles.length > 0) {
|
||||||
|
return this.setState({
|
||||||
isFormShown: false,
|
isFormShown: false,
|
||||||
isIpfsFormShown: false
|
isIpfsFormShown: false
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// for canceling axios requests
|
const file: FilePublish | undefined = await this.getFile(url)
|
||||||
public signal = axios.CancelToken.source()
|
file && this.props.files.push(file)
|
||||||
|
|
||||||
public componentWillUnmount() {
|
const event = {
|
||||||
this.signal.cancel()
|
currentTarget: {
|
||||||
|
name: 'files',
|
||||||
|
value: this.props.files
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
this.props.onChange(event as any)
|
||||||
|
|
||||||
private toggleForm = (e: Event, form: string) => {
|
this.setState({
|
||||||
e.preventDefault()
|
isFormShown: false,
|
||||||
|
isIpfsFormShown: false
|
||||||
|
})
|
||||||
|
|
||||||
this.setState({
|
this.forceUpdate()
|
||||||
isFormShown: form === 'url' ? !this.state.isFormShown : false,
|
}
|
||||||
isIpfsFormShown:
|
|
||||||
form === 'ipfs' ? !this.state.isIpfsFormShown : false
|
private removeFile = (index: number) => {
|
||||||
})
|
this.props.files.splice(index, 1)
|
||||||
|
const event = {
|
||||||
|
currentTarget: {
|
||||||
|
name: 'files',
|
||||||
|
value: this.props.files
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
this.props.onChange(event as any)
|
||||||
|
this.forceUpdate()
|
||||||
|
}
|
||||||
|
|
||||||
private async getFile(url: string) {
|
public render() {
|
||||||
const file: FilePublish = {
|
const { files, help, placeholder, name, onChange } = this.props
|
||||||
url,
|
const { isFormShown, isIpfsFormShown } = this.state
|
||||||
contentType: '',
|
|
||||||
found: false // non-standard
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
return (
|
||||||
const response = await axios({
|
<>
|
||||||
method: 'POST',
|
{help && <Help>{help}</Help>}
|
||||||
headers: { 'Content-Type': 'application/json' },
|
|
||||||
url: `${serviceUri}/api/v1/urlcheck`,
|
|
||||||
data: { url },
|
|
||||||
cancelToken: this.signal.token
|
|
||||||
})
|
|
||||||
|
|
||||||
const { contentLength, contentType, found } = response.data.result
|
{/* Use hidden input to collect files */}
|
||||||
|
<input
|
||||||
|
type="hidden"
|
||||||
|
name={name}
|
||||||
|
value={JSON.stringify(files)}
|
||||||
|
onChange={onChange}
|
||||||
|
data-testid="files"
|
||||||
|
/>
|
||||||
|
|
||||||
if (contentLength) file.contentLength = contentLength
|
<div className={styles.newItems}>
|
||||||
if (contentType) {
|
{files.length > 0 && (
|
||||||
file.contentType = contentType
|
<ul className={styles.itemsList}>
|
||||||
file.compression = cleanupContentType(contentType)
|
{files.map((item: any, index: number) => (
|
||||||
}
|
<Item
|
||||||
|
key={shortid.generate()}
|
||||||
file.found = found
|
item={item}
|
||||||
|
removeFile={() => this.removeFile(index)}
|
||||||
return file
|
|
||||||
} catch (error) {
|
|
||||||
!axios.isCancel(error) && Logger.error(error.message)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private addFile = async (url: string) => {
|
|
||||||
// check for duplicate urls
|
|
||||||
const duplicateFiles = this.props.files.filter(props =>
|
|
||||||
url.includes(props.url)
|
|
||||||
)
|
|
||||||
|
|
||||||
if (duplicateFiles.length > 0) {
|
|
||||||
return this.setState({
|
|
||||||
isFormShown: false,
|
|
||||||
isIpfsFormShown: false
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
const file: FilePublish | undefined = await this.getFile(url)
|
|
||||||
file && this.props.files.push(file)
|
|
||||||
|
|
||||||
const event = {
|
|
||||||
currentTarget: {
|
|
||||||
name: 'files',
|
|
||||||
value: this.props.files
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this.props.onChange(event as any)
|
|
||||||
|
|
||||||
this.setState({
|
|
||||||
isFormShown: false,
|
|
||||||
isIpfsFormShown: false
|
|
||||||
})
|
|
||||||
|
|
||||||
this.forceUpdate()
|
|
||||||
}
|
|
||||||
|
|
||||||
private removeFile = (index: number) => {
|
|
||||||
this.props.files.splice(index, 1)
|
|
||||||
const event = {
|
|
||||||
currentTarget: {
|
|
||||||
name: 'files',
|
|
||||||
value: this.props.files
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this.props.onChange(event as any)
|
|
||||||
this.forceUpdate()
|
|
||||||
}
|
|
||||||
|
|
||||||
public render() {
|
|
||||||
const { files, help, placeholder, name, onChange } = this.props
|
|
||||||
const { isFormShown, isIpfsFormShown } = this.state
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
{help && <Help>{help}</Help>}
|
|
||||||
|
|
||||||
{/* Use hidden input to collect files */}
|
|
||||||
<input
|
|
||||||
type="hidden"
|
|
||||||
name={name}
|
|
||||||
value={JSON.stringify(files)}
|
|
||||||
onChange={onChange}
|
|
||||||
data-testid="files"
|
|
||||||
/>
|
/>
|
||||||
|
))}
|
||||||
|
</ul>
|
||||||
|
)}
|
||||||
|
|
||||||
<div className={styles.newItems}>
|
{buttons.map(button => {
|
||||||
{files.length > 0 && (
|
const isActive =
|
||||||
<ul className={styles.itemsList}>
|
(button.id === 'url' && isFormShown) ||
|
||||||
{files.map((item: any, index: number) => (
|
(button.id === 'ipfs' && isIpfsFormShown)
|
||||||
<Item
|
|
||||||
key={shortid.generate()}
|
|
||||||
item={item}
|
|
||||||
removeFile={() => this.removeFile(index)}
|
|
||||||
/>
|
|
||||||
))}
|
|
||||||
</ul>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{buttons.map(button => {
|
return (
|
||||||
const isActive =
|
<Button
|
||||||
(button.id === 'url' && isFormShown) ||
|
key={shortid.generate()}
|
||||||
(button.id === 'ipfs' && isIpfsFormShown)
|
link
|
||||||
|
onClick={(e: Event) => this.toggleForm(e, button.id)}
|
||||||
|
>
|
||||||
|
{isActive ? button.titleActive : button.title}
|
||||||
|
</Button>
|
||||||
|
)
|
||||||
|
})}
|
||||||
|
|
||||||
return (
|
{isFormShown && (
|
||||||
<Button
|
<ItemForm placeholder={placeholder} addFile={this.addFile} />
|
||||||
key={shortid.generate()}
|
)}
|
||||||
link
|
|
||||||
onClick={(e: Event) =>
|
|
||||||
this.toggleForm(e, button.id)
|
|
||||||
}
|
|
||||||
>
|
|
||||||
{isActive ? button.titleActive : button.title}
|
|
||||||
</Button>
|
|
||||||
)
|
|
||||||
})}
|
|
||||||
|
|
||||||
{isFormShown && (
|
{isIpfsFormShown && (
|
||||||
<ItemForm
|
<Suspense fallback={<Spinner message="Loading..." />}>
|
||||||
placeholder={placeholder}
|
<Ipfs addFile={this.addFile} />
|
||||||
addFile={this.addFile}
|
</Suspense>
|
||||||
/>
|
)}
|
||||||
)}
|
</div>
|
||||||
|
</>
|
||||||
{isIpfsFormShown && (
|
)
|
||||||
<Suspense fallback={<Spinner message="Loading..." />}>
|
}
|
||||||
<Ipfs addFile={this.addFile} />
|
|
||||||
</Suspense>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user