diff --git a/.eslintrc b/.eslintrc index f364f0a..6aeddaa 100644 --- a/.eslintrc +++ b/.eslintrc @@ -1,31 +1,33 @@ { - "parser": "@typescript-eslint/parser", - "parserOptions": { - "project": ["./tsconfig.json"] - }, - "extends": [ - "oceanprotocol", - "oceanprotocol/react", - "plugin:@typescript-eslint/eslint-recommended", - "plugin:@typescript-eslint/recommended", - "plugin:prettier/recommended", - "prettier/react", - "prettier/standard", - "prettier/@typescript-eslint" - ], - "plugins": ["@typescript-eslint", "prettier"], - "rules": { - "react/prop-types": "off", - "@typescript-eslint/explicit-function-return-type": "off" - }, - "env": { - "es6": true, - "browser": true, - "jest": true - }, + "extends": ["eslint:recommended", "prettier"], + "env": { "es6": true, "browser": true, "node": true }, "settings": { "react": { "version": "detect" } - } + }, + "overrides": [ + { + "files": ["**/*.ts", "**/*.tsx"], + "parser": "@typescript-eslint/parser", + "parserOptions": { + "project": ["./tsconfig.json"] + }, + "extends": [ + "oceanprotocol", + "oceanprotocol/react", + "plugin:@typescript-eslint/eslint-recommended", + "plugin:@typescript-eslint/recommended", + "plugin:prettier/recommended", + "prettier/react", + "prettier/standard", + "prettier/@typescript-eslint" + ], + "plugins": ["@typescript-eslint", "prettier"], + "rules": { + "react/prop-types": "off", + "@typescript-eslint/explicit-function-return-type": "off" + } + } + ] } diff --git a/.gitignore b/.gitignore index cd28e47..01b9265 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,7 @@ node_modules npm-debug.log .DS_Store -/.next/ -/out/ -/build +.next +out +build package-lock.json \ No newline at end of file diff --git a/next.config.js b/next.config.js index a259af2..5e2cfab 100644 --- a/next.config.js +++ b/next.config.js @@ -1,6 +1,7 @@ const withCSS = require('@zeit/next-css') const withMDX = require('@next/mdx')() +// eslint-disable-next-line no-unused-vars const withSvgr = (nextConfig = {}, nextComposePlugins = {}) => { return Object.assign({}, nextConfig, { webpack(config, options) { @@ -30,7 +31,6 @@ module.exports = withSvgr( withCSS({ cssModules: true, cssLoaderOptions: { - importLoaders: 1, localIdentName: '[local]___[hash:base64:5]' } }) diff --git a/package.json b/package.json index 872c246..65913ba 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,7 @@ "start": "next dev", "build": "next build", "serve": "next start", - "test": "eslint --ignore-path .gitignore 'src/**/*.{ts,tsx}'", + "test": "eslint --ignore-path .gitignore 'src/**/*.{js,jsx,ts,tsx}'", "format": "prettier ./src/**/*.{css,yml,js,jsx,ts,tsx,json} --write" }, "author": "Matthias Kretschmann ", @@ -32,15 +32,23 @@ "@types/react": "^16.9.9", "@typescript-eslint/eslint-plugin": "^2.4.0", "@typescript-eslint/parser": "^2.4.0", + "cssnano": "^4.1.10", "eslint": "^6.5.1", "eslint-config-oceanprotocol": "^1.5.0", "eslint-config-prettier": "^6.4.0", "eslint-plugin-prettier": "^3.1.1", "eslint-plugin-react": "^7.16.0", + "postcss-preset-env": "^6.7.0", "prettier": "^1.18.2", "typescript": "^3.6.4" }, "engines": { "node": "10.x" - } + }, + "browserslist": [ + ">0.2%", + "not dead", + "not ie <= 11", + "not op_mini all" + ] } diff --git a/postcss.config.js b/postcss.config.js new file mode 100644 index 0000000..7330924 --- /dev/null +++ b/postcss.config.js @@ -0,0 +1,8 @@ +module.exports = { + plugins: { + 'postcss-preset-env': { + importFrom: './src/styles/_variables.css' + }, + cssnano: {} + } +} diff --git a/src/Layout.module.css b/src/Layout.module.css index dd93ecd..08afd3d 100644 --- a/src/Layout.module.css +++ b/src/Layout.module.css @@ -1,5 +1,3 @@ -@import './styles/_variables.css'; - .app { padding: var(--spacer); background: var(--brand-black); diff --git a/src/components/Add.module.css b/src/components/Add.module.css index 1a297fb..ec84bc1 100644 --- a/src/components/Add.module.css +++ b/src/components/Add.module.css @@ -1,5 +1,3 @@ -@import '../styles/_variables.css'; - .add { width: 100%; overflow-wrap: break-word; diff --git a/src/components/Add.tsx b/src/components/Add.tsx index 4b9a51a..d53bda1 100644 --- a/src/components/Add.tsx +++ b/src/components/Add.tsx @@ -1,18 +1,10 @@ import React, { useState, useEffect } from 'react' +import useIpfsApi, { IpfsConfig } from '../hooks/use-ipfs-api' +import { formatBytes, addToIpfs } from '../utils' import { ipfsNodeUri, ipfsGateway } from '../../site.config' import Dropzone from './Dropzone' import styles from './Add.module.css' import Spinner from './Spinner' -import useIpfsApi, { IpfsConfig } from '../hooks/use-ipfs-api' - -export function formatBytes(a: number, b: number) { - if (a === 0) return '0 Bytes' - const c = 1024 - const d = b || 2 - const e = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'] - const f = Math.floor(Math.log(a) / Math.log(c)) - return parseFloat((a / Math.pow(c, f)).toFixed(d)) + ' ' + e[f] -} const { hostname, port, protocol } = new URL(ipfsNodeUri) @@ -22,24 +14,6 @@ const ipfsConfig: IpfsConfig = { port: port || '443' } -async function addToIpfs( - files: File[], - setFileSizeReceived: (size: string) => void, - ipfs: any -) { - const file = [...files][0] - const fileDetails = { path: file.name, content: file } - - const response = await ipfs.add(fileDetails, { - wrapWithDirectory: true, - progress: (length: number) => setFileSizeReceived(formatBytes(length, 0)) - }) - - // CID of wrapping directory is returned last - const cid = `${response[response.length - 1].hash}/${file.name}` - return cid -} - export default function Add() { const { ipfs, isIpfsReady, ipfsError } = useIpfsApi(ipfsConfig) const [fileHash, setFileHash] = useState() diff --git a/src/components/Dropzone.module.css b/src/components/Dropzone.module.css index e7987f4..5248bf8 100644 --- a/src/components/Dropzone.module.css +++ b/src/components/Dropzone.module.css @@ -1,5 +1,3 @@ -@import '../styles/_variables.css'; - .dropzone { border: 0.2rem dashed var(--brand-grey-light); border-radius: calc(var(--border-radius) * 2); diff --git a/src/components/Footer.module.css b/src/components/Footer.module.css index 996ccf9..0b24e14 100644 --- a/src/components/Footer.module.css +++ b/src/components/Footer.module.css @@ -1,5 +1,3 @@ -@import '../styles/_variables.css'; - .footer { width: 100%; font-size: var(--font-size-mini); diff --git a/src/components/Info.module.css b/src/components/Info.module.css index a8db777..6a5a97a 100644 --- a/src/components/Info.module.css +++ b/src/components/Info.module.css @@ -1,5 +1,3 @@ -@import '../styles/_variables.css'; - .info { font-size: var(--font-size-small); opacity: 0.8; diff --git a/src/components/Spinner.module.css b/src/components/Spinner.module.css index d92db25..a69dee2 100644 --- a/src/components/Spinner.module.css +++ b/src/components/Spinner.module.css @@ -1,5 +1,3 @@ -@import '../styles/_variables.css'; - .spinner { position: relative; text-align: center; diff --git a/src/components/Status.module.css b/src/components/Status.module.css index 12ac537..6bbec19 100644 --- a/src/components/Status.module.css +++ b/src/components/Status.module.css @@ -1,5 +1,3 @@ -@import '../styles/_variables.css'; - /* default: red square */ .status { width: var(--font-size-mini); diff --git a/src/hooks/use-ipfs-api.tsx b/src/hooks/use-ipfs-api.tsx index 1fa91f7..34ed5d4 100644 --- a/src/hooks/use-ipfs-api.tsx +++ b/src/hooks/use-ipfs-api.tsx @@ -1,5 +1,6 @@ import { useEffect, useState } from 'react' import ipfsClient from 'ipfs-http-client' +import { parseHTML } from '../utils' let ipfs: any = null let ipfsVersion = '' @@ -10,12 +11,6 @@ export interface IpfsConfig { port: string } -function parseHTML(str: string) { - const tmp = document.implementation.createHTMLDocument() - tmp.body.innerHTML = str - return tmp.body.children -} - export default function useIpfsApi(config: IpfsConfig) { const [isIpfsReady, setIpfsReady] = useState(Boolean(ipfs)) const [ipfsError, setIpfsError] = useState('') diff --git a/src/pages/_app.tsx b/src/pages/_app.tsx new file mode 100644 index 0000000..338772a --- /dev/null +++ b/src/pages/_app.tsx @@ -0,0 +1,11 @@ +import '@oceanprotocol/typographies/css/ocean-typo.css' +import '../styles/global.css' +import App from 'next/app' +import React from 'react' + +export default class MyApp extends App { + render() { + const { Component, pageProps } = this.props + return + } +} diff --git a/src/pages/index.module.css b/src/pages/index.module.css index 9164088..a21e48b 100644 --- a/src/pages/index.module.css +++ b/src/pages/index.module.css @@ -1,5 +1,3 @@ -@import '../styles/_variables.css'; - .grid { display: grid; gap: calc(var(--spacer) * 2); diff --git a/src/pages/index.tsx b/src/pages/index.tsx index 3d4f3aa..6847c32 100644 --- a/src/pages/index.tsx +++ b/src/pages/index.tsx @@ -1,15 +1,13 @@ import React from 'react' - -import '@oceanprotocol/typographies/css/ocean-typo.css' -import '../styles/global.css' - -import Add from '../components/Add' -import Logo from '@oceanprotocol/art/logo/logo-white.svg' +import dynamic from 'next/dynamic' import { title, description, learnMore } from '../../site.config' +import Layout from '../Layout' import styles from './index.module.css' -import Layout from '../Layout' -import Info from '../components/Info.mdx' +import Logo from '@oceanprotocol/art/logo/logo-white.svg' + +const Add = dynamic(() => import('../components/Add')) +const Info = dynamic(() => import('../components/Info.mdx')) const Home = () => ( diff --git a/src/utils.ts b/src/utils.ts index ced6785..3a83bf5 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -1,5 +1,32 @@ import axios from 'axios' +export function formatBytes(a: number, b: number) { + if (a === 0) return '0 Bytes' + const c = 1024 + const d = b || 2 + const e = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'] + const f = Math.floor(Math.log(a) / Math.log(c)) + return parseFloat((a / Math.pow(c, f)).toFixed(d)) + ' ' + e[f] +} + +export async function addToIpfs( + files: File[], + setFileSizeReceived: (size: string) => void, + ipfs: any +) { + const file = [...files][0] + const fileDetails = { path: file.name, content: file } + + const response = await ipfs.add(fileDetails, { + wrapWithDirectory: true, + progress: (length: number) => setFileSizeReceived(formatBytes(length, 0)) + }) + + // CID of wrapping directory is returned last + const cid = `${response[response.length - 1].hash}/${file.name}` + return cid +} + export async function pingUrl(url: string) { try { const response = await axios(url, { timeout: 5000 }) @@ -10,3 +37,9 @@ export async function pingUrl(url: string) { return false } } + +export function parseHTML(str: string) { + const tmp = document.implementation.createHTMLDocument() + tmp.body.innerHTML = str + return tmp.body.children +} diff --git a/tsconfig.json b/tsconfig.json index 5bdd590..4ea272c 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -20,6 +20,6 @@ "resolveJsonModule": true, "isolatedModules": true }, - "exclude": ["node_modules"], + "exclude": ["node_modules", ".next"], "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", "**/*.mdx"] }