Skip to content
This repository was archived by the owner on Mar 10, 2020. It is now read-only.

Commit 0b8803f

Browse files
committed
feat: add file dom api support to files api
1 parent 17d49de commit 0b8803f

File tree

8 files changed

+72
-50
lines changed

8 files changed

+72
-50
lines changed

examples/upload-file-via-browser/.eslintrc

Lines changed: 0 additions & 11 deletions
This file was deleted.

examples/upload-file-via-browser/package.json

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
"version": "1.0.0",
44
"description": "Upload file to IPFS via browser using js-ipfs-http-client with Webpack",
55
"scripts": {
6-
"start": "node server.js"
6+
"start": "webpack-dev-server"
77
},
88
"author": "Harlan T Wood <code@harlantwood.net>",
99
"contributors": [
@@ -12,12 +12,26 @@
1212
"license": "MIT",
1313
"devDependencies": {
1414
"@babel/core": "^7.4.3",
15+
"@babel/preset-env": "^7.3.1",
16+
"@babel/preset-react": "^7.0.0",
17+
"eslint": "^5.16.0",
18+
"eslint-plugin-react": "^7.11.1",
1519
"ipfs-http-client": "../../",
1620
"pull-file-reader": "~1.0.2",
1721
"react": "~16.6.3",
1822
"react-dom": "~16.6.3",
19-
"react-hot-loader": "~4.3.12",
20-
"webpack": "~4.25.1",
21-
"webpack-dev-server": "~3.1.10"
22-
}
23+
"webpack": "~4.30.0",
24+
"webpack-dev-server": "~3.3.1"
25+
},
26+
"eslintConfig" : {
27+
"extends": "standard",
28+
"rules": {
29+
"react/jsx-uses-react": 2,
30+
"react/jsx-uses-vars": 2,
31+
"react/react-in-jsx-scope": 2
32+
},
33+
"plugins": [
34+
"react"
35+
]
36+
}
2337
}

examples/upload-file-via-browser/server.js

Lines changed: 0 additions & 13 deletions
This file was deleted.

examples/upload-file-via-browser/src/App.js

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
'use strict'
22
const React = require('react')
3-
const ipfsClient = require('ipfs-http-client')
3+
const ipfsClient = require('../../../src')
44

55
// create a stream from a file, which enables uploads of big files without allocating memory twice
66
const fileReaderPullStream = require('pull-file-reader')
@@ -11,7 +11,7 @@ class App extends React.Component {
1111
this.state = {
1212
added_file_hash: null
1313
}
14-
this.ipfs = ipfsClient('localhost', '5001')
14+
this.ipfs = ipfsClient('localhost', '50895')
1515

1616
// bind methods
1717
this.captureFile = this.captureFile.bind(this)
@@ -22,25 +22,23 @@ class App extends React.Component {
2222
captureFile (event) {
2323
event.stopPropagation()
2424
event.preventDefault()
25-
const file = event.target.files[0]
2625
if (document.getElementById('keepFilename').checked) {
27-
this.saveToIpfsWithFilename(file)
26+
this.saveToIpfsWithFilename(event.target.files)
2827
} else {
29-
this.saveToIpfs(file)
28+
this.saveToIpfs(event.target.files)
3029
}
3130
}
3231

3332
// Example #1
3433
// Add file to IPFS and return a CID
35-
saveToIpfs (file) {
34+
saveToIpfs (files) {
3635
let ipfsId
37-
const fileStream = fileReaderPullStream(file)
38-
this.ipfs.add(fileStream, { progress: (prog) => console.log(`received: ${prog}`) })
36+
this.ipfs.add([...files][0], { progress: (prog) => console.log(`received: ${prog}`) })
3937
.then((response) => {
4038
console.log(response)
4139
ipfsId = response[0].hash
4240
console.log(ipfsId)
43-
this.setState({added_file_hash: ipfsId})
41+
this.setState({ added_file_hash: ipfsId })
4442
}).catch((err) => {
4543
console.error(err)
4644
})
@@ -65,7 +63,7 @@ class App extends React.Component {
6563
// CID of wrapping directory is returned last
6664
ipfsId = response[response.length - 1].hash
6765
console.log(ipfsId)
68-
this.setState({added_file_hash: ipfsId})
66+
this.setState({ added_file_hash: ipfsId })
6967
}).catch((err) => {
7068
console.error(err)
7169
})

examples/upload-file-via-browser/webpack.config.js

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,18 @@
11
'use strict'
22

33
const path = require('path')
4-
const webpack = require('webpack')
54

65
module.exports = {
76
mode: 'development',
87
devtool: 'eval',
98
entry: [
10-
'webpack-dev-server/client?http://localhost:3000',
11-
'webpack/hot/only-dev-server',
129
'./src/index'
1310
],
1411
output: {
1512
path: path.join(__dirname, 'dist'),
1613
filename: 'bundle.js',
1714
publicPath: '/static/'
1815
},
19-
plugins: [
20-
new webpack.HotModuleReplacementPlugin()
21-
],
2216
module: {
2317
rules: [
2418
{
@@ -28,8 +22,7 @@ module.exports = {
2822
{
2923
loader: 'babel-loader',
3024
options: {
31-
presets: ['@babel/preset-env', '@babel/preset-react'],
32-
plugins: ['react-hot-loader/babel']
25+
presets: ['@babel/preset-env', '@babel/preset-react']
3326
}
3427
}
3528
]

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
"iso-url": "~0.4.6",
4646
"just-kebab-case": "^1.1.0",
4747
"just-map-keys": "^1.1.0",
48+
"kind-of": "^6.0.2",
4849
"lru-cache": "^5.1.1",
4950
"multiaddr": "^6.0.6",
5051
"multibase": "~0.6.0",
@@ -79,7 +80,6 @@
7980
"chai": "^4.2.0",
8081
"cross-env": "^5.2.0",
8182
"dirty-chai": "^2.0.1",
82-
"eslint-plugin-react": "^7.11.1",
8383
"go-ipfs-dep": "~0.4.19",
8484
"interface-ipfs-core": "~0.99.0",
8585
"ipfsd-ctl": "~0.42.0",

src/files-regular/add.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
const promisify = require('promisify-es6')
44
const ConcatStream = require('concat-stream')
5+
const kindOf = require('kind-of')
56
const once = require('once')
67
const isStream = require('is-stream')
78
const isSource = require('is-pull-stream').isSource
@@ -16,7 +17,6 @@ module.exports = (send) => {
1617
_callback = options
1718
options = null
1819
}
19-
2020
const callback = once(_callback)
2121

2222
if (!options) {
@@ -35,7 +35,7 @@ module.exports = (send) => {
3535
return Boolean(obj.path) && typeof obj.path === 'string'
3636
}
3737
// An input atom: a buffer, stream or content object
38-
const isInput = obj => isBufferOrStream(obj) || isContentObject(obj)
38+
const isInput = obj => isBufferOrStream(obj) || isContentObject(obj) || kindOf(_files) === 'file'
3939
// All is ok if data isInput or data is an array of isInput
4040
const ok = isInput(_files) || (Array.isArray(_files) && _files.every(isInput))
4141

src/utils/prepare-file.js

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,11 @@
22

33
const isNode = require('detect-node')
44
const flatmap = require('flatmap')
5+
const { Readable } = require('stream')
6+
const kindOf = require('kind-of')
57

8+
// eslint-disable-next-line no-undef
9+
const supportsFileReader = FileReader in self
610
function loadPaths (opts, file) {
711
const path = require('path')
812
const fs = require('fs')
@@ -73,6 +77,34 @@ function loadPaths (opts, file) {
7377
}
7478
}
7579

80+
function streamFromFileReader (file) {
81+
class FileStream extends Readable {
82+
constructor (file, options = {}) {
83+
super(options)
84+
this.offset = 0
85+
this.chunkSize = 1024 * 1024
86+
this.fileReader = new self.FileReader(file)
87+
this.fileReader.onloadend = (event) => {
88+
const data = event.target.result
89+
if (data.byteLength === 0) {
90+
this.push(null)
91+
}
92+
this.push(new Uint8Array(data))
93+
}
94+
this.fileReader.onerror = (err) => this.emit('error', err)
95+
}
96+
97+
_read (size) {
98+
const end = this.offset + this.chunkSize
99+
const slice = file.slice(this.offset, end)
100+
this.fileReader.readAsArrayBuffer(slice)
101+
this.offset = end
102+
}
103+
}
104+
105+
return new FileStream(file)
106+
}
107+
76108
function prepareFile (file, opts) {
77109
let files = [].concat(file)
78110

@@ -94,6 +126,15 @@ function prepareFile (file, opts) {
94126
return file
95127
}
96128

129+
if (supportsFileReader && kindOf(file) === 'file') {
130+
return {
131+
path: '',
132+
symlink: false,
133+
dir: false,
134+
content: streamFromFileReader(file, opts)
135+
}
136+
}
137+
97138
return {
98139
path: '',
99140
symlink: false,

0 commit comments

Comments
 (0)