fixes and move to typescript

This commit is contained in:
Matthias Kretschmann 2019-10-17 00:13:54 +02:00
parent e3623d00ae
commit f7895c5359
Signed by: m
GPG Key ID: 606EEEF3C479A91F
22 changed files with 202 additions and 101 deletions

32
.eslintrc Normal file
View File

@ -0,0 +1,32 @@
{
"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",
"@typescript-eslint/no-explicit-any": "off"
},
"env": {
"es6": true,
"browser": true,
"jest": true
},
"settings": {
"react": {
"version": "16"
}
}
}

View File

@ -1,24 +0,0 @@
export const title = 'Ocean Protocol 💖 IPFS'
export const description = `Ocean Protocol's public IPFS Node, setup to be a public gateway, and to provide some access to its HTTP API for everyone.<br /><a href="https://blog.oceanprotocol.com/ocean-and-ipfs-sitting-in-the-merkle-tree-43c623c356d7">Learn More →</a>`
export const ipfsGateway = 'https://ipfs.oceanprotocol.com'
export const ipfsNodeUri = 'https://ipfs.oceanprotocol.com:443'
export const links = [
{
name: 'Homepage',
url: 'https://oceanprotocol.com'
},
{
name: 'Blog',
url: 'https://blog.oceanprotocol.com'
},
{
name: 'Twitter',
url: 'https://twitter.com/oceanprotocol'
},
{
name: 'GitHub',
url: 'https://github.com/oceanprotocol'
}
]

2
next-env.d.ts vendored Normal file
View File

@ -0,0 +1,2 @@
/// <reference types="next" />
/// <reference types="next/types/global" />

View File

@ -5,9 +5,9 @@
"scripts": { "scripts": {
"start": "next dev", "start": "next dev",
"build": "next build", "build": "next build",
"server": "next start", "serve": "next start",
"test": "eslint ./src/**/*.{js,jsx}", "test": "eslint --ignore-path .gitignore --ext .ts,.tsx ./src",
"format": "prettier ./src/**/*.{css,yml,js,jsx,json} --write" "format": "prettier ./src/**/*.{css,yml,js,jsx,ts,tsx,json} --write"
}, },
"author": "Matthias Kretschmann <matthias@oceanprotocol.com>", "author": "Matthias Kretschmann <matthias@oceanprotocol.com>",
"license": "Apache-2.0", "license": "Apache-2.0",
@ -23,12 +23,17 @@
"react-dropzone": "^10.1.10" "react-dropzone": "^10.1.10"
}, },
"devDependencies": { "devDependencies": {
"@types/node": "^12.11.1",
"@types/react": "^16.9.9",
"@typescript-eslint/eslint-plugin": "^2.4.0",
"@typescript-eslint/parser": "^2.4.0",
"eslint": "^6.5.1", "eslint": "^6.5.1",
"eslint-config-oceanprotocol": "^1.5.0", "eslint-config-oceanprotocol": "^1.5.0",
"eslint-config-prettier": "^6.4.0", "eslint-config-prettier": "^6.4.0",
"eslint-plugin-prettier": "^3.1.1", "eslint-plugin-prettier": "^3.1.1",
"eslint-plugin-react": "^7.16.0", "eslint-plugin-react": "^7.16.0",
"prettier": "^1.18.2" "prettier": "^1.18.2",
"typescript": "^3.6.4"
}, },
"eslintConfig": { "eslintConfig": {
"extends": [ "extends": [

24
site.config.js Normal file
View File

@ -0,0 +1,24 @@
module.exports = {
title: 'Ocean Protocol 💖 IPFS',
description: `Ocean Protocol's public IPFS Node, setup to be a public gateway, and to provide some access to its HTTP API for everyone.<br /><a href="https://blog.oceanprotocol.com/ocean-and-ipfs-sitting-in-the-merkle-tree-43c623c356d7">Learn More →</a>`,
ipfsGateway: 'https://ipfs.oceanprotocol.com',
ipfsNodeUri: 'https://ipfs.oceanprotocol.com:443',
links: [
{
name: 'Homepage',
url: 'https://oceanprotocol.com'
},
{
name: 'Blog',
url: 'https://blog.oceanprotocol.com'
},
{
name: 'Twitter',
url: 'https://twitter.com/oceanprotocol'
},
{
name: 'GitHub',
url: 'https://github.com/oceanprotocol'
}
]
}

15
src/@types/global.d.ts vendored Normal file
View File

@ -0,0 +1,15 @@
declare module '*.module.css' {
const classes: { readonly [key: string]: string }
export default classes
}
declare module '*.svg' {
import * as React from 'react'
export const ReactComponent: React.FunctionComponent<
React.SVGProps<SVGSVGElement>
>
const src: string
export default src
}
declare module 'ipfs-http-client'

17
src/Layout.module.css Normal file
View File

@ -0,0 +1,17 @@
@import './styles/_variables.css';
.app {
padding: var(--spacer);
background: var(--brand-black);
height: 100%;
display: flex;
flex-wrap: wrap;
justify-content: center;
}
@media screen and (min-width: 640px) {
.app {
height: auto;
min-height: calc(100vh - (var(--page-frame) * 2) - (var(--spacer) * 2));
}
}

26
src/Layout.tsx Normal file
View File

@ -0,0 +1,26 @@
import React from 'react'
import Head from 'next/head'
import Footer from './components/Footer'
import styles from './Layout.module.css'
import { title } from '../site.config'
export default function Layout({
children,
pageTitle = title
}: {
children: any
pageTitle?: string
}) {
return (
<div className={styles.app}>
<Head>
<title>{pageTitle}</title>
<link rel="icon" href="/favicon.ico" />
</Head>
{children}
<Footer />
</div>
)
}

View File

@ -1,15 +1,15 @@
import React, { useState } from 'react' import React, { useState } from 'react'
import { saveToIpfs } from '../ipfs' import { saveToIpfs } from '../ipfs'
import { ipfsGateway } from '../../config' import { ipfsGateway } from '../../site.config'
import Dropzone from './Dropzone' import Dropzone from './Dropzone'
import styles from './Add.css' import styles from './Add.module.css'
import Spinner from './Spinner' import Spinner from './Spinner'
export default function Add() { export default function Add() {
const [fileHash, setFileHash] = useState(null) const [fileHash, setFileHash] = useState()
const [loading, setLoading] = useState(false) const [loading, setLoading] = useState(false)
const handleCaptureFile = async files => { const handleCaptureFile = async (files: File[]) => {
setLoading(true) setLoading(true)
const cid = await saveToIpfs(files) const cid = await saveToIpfs(files)
setFileHash(cid) setFileHash(cid)

View File

@ -1,15 +1,16 @@
import React, { useCallback } from 'react' import React, { useCallback } from 'react'
import PropTypes from 'prop-types'
import { useDropzone } from 'react-dropzone' import { useDropzone } from 'react-dropzone'
import styles from './Dropzone.css' import styles from './Dropzone.module.css'
Dropzone.propTypes = { export default function Dropzone({
handleOnDrop: PropTypes.func.isRequired, handleOnDrop,
disabled: PropTypes.bool, disabled,
multiple: PropTypes.bool multiple
} }: {
handleOnDrop(files: File[]): void
export default function Dropzone({ handleOnDrop, disabled, multiple }) { disabled?: boolean
multiple?: boolean
}) {
const onDrop = useCallback(acceptedFiles => handleOnDrop(acceptedFiles), [ const onDrop = useCallback(acceptedFiles => handleOnDrop(acceptedFiles), [
handleOnDrop handleOnDrop
]) ])

View File

@ -1,6 +1,6 @@
import React from 'react' import React from 'react'
import { links } from '../../config' import { links } from '../../site.config'
import styles from './Footer.css' import styles from './Footer.module.css'
export default function Footer() { export default function Footer() {
const year = new Date().getFullYear() const year = new Date().getFullYear()

View File

@ -1,5 +1,5 @@
import React from 'react' import React from 'react'
import styles from './Spinner.css' import styles from './Spinner.module.css'
export default function Spinner() { export default function Spinner() {
return <div className={styles.spinner} /> return <div className={styles.spinner} />

View File

@ -1,7 +1,7 @@
import ipfsClient from 'ipfs-http-client' import ipfsClient from 'ipfs-http-client'
import { ipfsNodeUri } from '../config' import { ipfsNodeUri } from '../site.config'
export async function saveToIpfs(files) { export async function saveToIpfs(files: File[]) {
const { hostname, port, protocol } = new URL(ipfsNodeUri) const { hostname, port, protocol } = new URL(ipfsNodeUri)
const ipfsConfig = { const ipfsConfig = {
@ -20,7 +20,7 @@ export async function saveToIpfs(files) {
} }
const options = { const options = {
wrapWithDirectory: true, wrapWithDirectory: true,
progress: prog => console.log(`received: ${prog}`) progress: (prog: number) => console.log(`received: ${prog}`)
} }
try { try {

View File

@ -1,33 +0,0 @@
import React from 'react'
import Head from 'next/head'
import '@oceanprotocol/typographies/css/ocean-typo.css'
import '../styles/global.css'
import styles from './index.css'
import Add from '../components/Add'
import Logo from '@oceanprotocol/art/logo/logo-white.svg'
import { title, description } from '../../config'
import Footer from '../components/Footer'
const Home = () => (
<div className={styles.app}>
<Head>
<title>Ocean Protocol 💖 IPFS</title>
<link rel="icon" href="/favicon.ico" />
</Head>
<header className={styles.header}>
<Logo className={styles.logo} />
<h1 className={styles.appTitle}>{title}</h1>
<p
className={styles.appDescription}
dangerouslySetInnerHTML={{ __html: description }}
/>
</header>
<Add />
<Footer />
</div>
)
export default Home

View File

@ -1,38 +1,22 @@
@import '../styles/_variables.css'; @import '../styles/_variables.css';
.app {
padding: var(--spacer);
background: var(--brand-black);
height: 100%;
display: flex;
flex-wrap: wrap;
justify-content: center;
}
@media screen and (min-width: 640px) {
.app {
height: auto;
min-height: calc(100vh - (var(--page-frame) * 2) - (var(--spacer) * 2));
}
}
.header { .header {
width: 100%; width: 100%;
margin-top: var(--spacer); margin-top: var(--spacer);
} }
.appTitle { .title {
margin-top: var(--spacer); margin-top: var(--spacer);
font-size: var(--font-size-h2); font-size: var(--font-size-h2);
} }
@media screen and (min-width: 640px) { @media screen and (min-width: 640px) {
.appTitle { .title {
font-size: var(--font-size-h1); font-size: var(--font-size-h1);
} }
} }
.appDescription { .description {
font-size: var(--font-size-large); font-size: var(--font-size-large);
color: var(--brand-grey-lighter); color: var(--brand-grey-lighter);
max-width: 40rem; max-width: 40rem;
@ -40,7 +24,7 @@
margin-right: auto; margin-right: auto;
} }
.logo { .header svg {
width: 80px; width: 80px;
height: 80px; height: 80px;
} }

27
src/pages/index.tsx Normal file
View File

@ -0,0 +1,27 @@
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 { title, description } from '../../site.config'
import styles from './index.module.css'
import Layout from '../Layout'
const Home = () => (
<Layout>
<header className={styles.header}>
<Logo />
<h1 className={styles.title}>{title}</h1>
<p
className={styles.description}
dangerouslySetInnerHTML={{ __html: description }}
/>
</header>
<Add />
</Layout>
)
export default Home

View File

@ -2,7 +2,7 @@
html, html,
body, body,
#root { #__next {
height: 100%; height: 100%;
max-height: calc(100vh - (var(--page-frame) * 2)); max-height: calc(100vh - (var(--page-frame) * 2));
} }

25
tsconfig.json Normal file
View File

@ -0,0 +1,25 @@
{
"compilerOptions": {
"allowJs": true,
"allowSyntheticDefaultImports": true,
"jsx": "preserve",
"lib": ["dom", "es2017"],
"module": "esnext",
"moduleResolution": "node",
"noEmit": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"preserveConstEnums": true,
"removeComments": false,
"skipLibCheck": true,
"sourceMap": true,
"strict": true,
"target": "esnext",
"forceConsistentCasingInFileNames": true,
"esModuleInterop": true,
"resolveJsonModule": true,
"isolatedModules": true
},
"exclude": ["node_modules"],
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"]
}