Merge pull request #1 from michaelmerrill/multi-file-upload

- New multiple file upload example.
- Added a database to track uploads.
- Replaced the placeholder query with one that gets all the uploaded files.
- New component that list all the uploaded files.
This commit is contained in:
Jayden Seric 2017-04-07 00:48:35 +10:00 committed by GitHub
commit e0ed74e0f4
8 changed files with 103 additions and 10 deletions

1
.gitignore vendored
View File

@ -3,3 +3,4 @@ node_modules
yarn.lock yarn.lock
.env .env
.DS_Store .DS_Store
db.json

View File

@ -16,6 +16,7 @@
"koa-bodyparser": "^4.2.0", "koa-bodyparser": "^4.2.0",
"koa-compress": "^2.0.0", "koa-compress": "^2.0.0",
"koa-router": "^7.1.1", "koa-router": "^7.1.1",
"lowdb": "^0.16.0",
"source-map-support": "^0.4.14", "source-map-support": "^0.4.14",
"webpack": "^2.3.3", "webpack": "^2.3.3",
"zoo": "^0.1.9" "zoo": "^0.1.9"

View File

@ -1,13 +1,35 @@
import low from 'lowdb'
import fileAsync from 'lowdb/lib/storages/file-async'
// Start database using file-async storage
const db = low('db.json', {
storage: fileAsync
})
db.defaults({uploads: []})
.write()
const saveFile = (file) => {
return db.get('uploads')
.push(file)
.last()
.write()
.then((result) => result)
}
export default { export default {
Query: { Query: {
ignore () { allUploads () {
return null return db.get('uploads').value()
} }
}, },
Mutation: { Mutation: {
singleUpload (root, {file}) { singleUpload (_, {file}) {
console.log('Uploaded file:', file) return saveFile(file)
return file },
multiUpload (_, {files}) {
return Promise.all(files.map((file) => {
return saveFile(file)
})).then((results) => results)
} }
} }
} }

View File

@ -13,10 +13,10 @@ input Upload {
} }
type Query { type Query {
# GraphQL will not work without defining a query. allUploads: [File]
ignore: Boolean
} }
type Mutation { type Mutation {
singleUpload (file: Upload!): File! singleUpload (file: Upload!): File!
multiUpload (files: [Upload!]!): [File!]!
} }

View File

@ -0,0 +1,31 @@
import {Component} from 'react'
import {graphql, gql} from 'react-apollo'
class MultiUploader extends Component {
handleChange = ({target}) => {
if (target.validity.valid) {
this.props
.mutate({
variables: {
files: target.files
}
})
.then(({data}) => console.log('Mutation response:', data))
}
}
render () {
return <input type='file' accept={'image/jpeg,image/png'} multiple required onChange={this.handleChange} />
}
}
export default graphql(gql`
mutation multiUpload ($files: [Upload!]!) {
multiUpload (files: $files) {
name
type
size
path
}
}
`)(MultiUploader)

View File

@ -0,0 +1,22 @@
import {graphql, gql} from 'react-apollo'
const UploadList = ({data: {allUploads, loading}}) => {
return (
<ul>
{allUploads.map((file, i) => {
return <li key={i}>{file.name}</li>
})}
</ul>
)
}
export default graphql(gql`
query allUploads {
allUploads {
name
type
size
path
}
}
`)(UploadList)

View File

@ -1,6 +1,8 @@
import Head from 'next/head' import Head from 'next/head'
import withData from '../helpers/with-data' import withData from '../helpers/with-data'
import SingleUploader from '../components/single-uploader' import SingleUploader from '../components/single-uploader'
import MultiUploader from '../components/multi-uploader'
import UploadList from '../components/upload-list'
export default withData(props => ( export default withData(props => (
<div> <div>
@ -13,10 +15,24 @@ export default withData(props => (
body { body {
margin: 2em; margin: 2em;
} }
section {
padding-top: 3em;
}
`}</style> `}</style>
</Head> </Head>
<h1>Apollo upload example</h1> <h1>Apollo upload example</h1>
<p>Select an image to upload and view the response in the console.</p> <section>
<SingleUploader /> <h2>Single file upload</h2>
<p>Select an image to upload and view the response in the console.</p>
<SingleUploader />
</section>
<section>
<h2>Multiple file upload</h2>
<p>Select multiple images to upload and view the response in the console.</p>
<MultiUploader />
</section>
<section>
<UploadList />
</section>
</div> </div>
)) ))

View File

@ -5,7 +5,7 @@ An example web application using [Next.js](https://github.com/zeit/next.js), [Re
## Setup ## Setup
1. Install the latest [Node.js](https://nodejs.org). 1. Install the latest [Node.js](https://nodejs.org).
2. Run `npm install` within the `api` directory in Terminal. 2. Run `npm install` within the `app` directory in Terminal.
3. Copy `.env.example`, rename it `.env` and customize. 3. Copy `.env.example`, rename it `.env` and customize.
For development run `npm run dev`. For development run `npm run dev`.