Skip to content

Commit

Permalink
feat: upload screen improvements
Browse files Browse the repository at this point in the history
- display visual feedback for ongoing upload (realtime if possible)
- use streaming to solve a set of errors caused by big files and js-ipfs
  • Loading branch information
lidel committed May 22, 2018
1 parent bb2c58b commit 9fbe63f
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 8 deletions.
8 changes: 8 additions & 0 deletions add-on/_locales/en/messages.json
Original file line number Diff line number Diff line change
Expand Up @@ -366,6 +366,14 @@
"message": "drop it here to share",
"description": "Partial info stats beneath the header on the share files page (quickUpload_drop_it_here)"
},
"quickUpload_state_uploading": {
"message": "Upload in progress..",
"description": "Status label on the share files page (quickUpload_state_uploading)"
},
"quickUpload_state_buffering": {
"message": "(buffering, please wait)",
"description": "Status label on the share files page (quickUpload_state_buffering)"
},
"quickUpload_options_show": {
"message": "upload options",
"description": "Button on the share files page (quickUpload_options_show)"
Expand Down
45 changes: 38 additions & 7 deletions add-on/src/popup/quick-upload.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ const browser = require('webextension-polyfill')
const choo = require('choo')
const html = require('choo/html')
const logo = require('./logo')
const fileReaderPullStream = require('filereader-pull-stream')
const byteSize = require('byte-size')

document.title = browser.i18n.getMessage('panel_quickUpload')

Expand All @@ -14,13 +16,30 @@ app.use(quickUploadStore)
app.route('*', quickUploadPage)
app.mount('#root')

/* disabled in favor of fileReaderPullStream
function file2buffer (file) {
return new Promise((resolve, reject) => {
const reader = new FileReader()
reader.onloadend = () => resolve(Buffer.from(reader.result))
reader.onerror = reject
reader.readAsArrayBuffer(file)
})
} */

function progressHandler (doneBytes, totalBytes, state, emitter) {
state.message = browser.i18n.getMessage('quickUpload_state_uploading')
// console.log('Upload progress:', doneBytes)
if (doneBytes && doneBytes > 0) {
const done = byteSize(doneBytes, { units: 'iec', precision: 2 })
const total = byteSize(totalBytes, { units: 'iec', precision: 2 })
const percent = ((doneBytes / totalBytes) * 100).toFixed(0)
state.progress = `${done.value} ${done.unit} / ${total.value} ${total.unit} (${percent}%)`
} else {
// This is a gracefull fallback for environments in which progress reporting is delayed
// until entire file/chunk is bufferend into memory (eg. js-ipfs-api)
state.progress = browser.i18n.getMessage('quickUpload_state_buffering')
}
emitter.emit('render')
}

function quickUploadStore (state, emitter) {
Expand Down Expand Up @@ -55,25 +74,37 @@ function quickUploadStore (state, emitter) {
const { ipfsCompanion } = await browser.runtime.getBackgroundPage()
const uploadTab = await browser.tabs.getCurrent()
const files = []
let totalSize = 0
for (let file of event.target.files) {
const buffer = await file2buffer(file)
// const uploadContent = await file2buffer(file)
const uploadContent = fileReaderPullStream(file, {chunkSize: 32 * 1024 * 1024})
files.push({
path: file.name,
content: buffer
content: uploadContent
})
totalSize += file.size
}
progressHandler(0, totalSize, state, emitter)
emitter.emit('render')
// TODO: update flag below after wrapping support is released with new js-ipfs
// TODO: also enable multiple file selection in <input type=file> (blocked for js-ipfs for now)
const wrapFlag = (state.wrapWithDirectory || files.length > 1) && state.ipfsNodeType !== 'embedded'
const uploadOptions = {
wrapWithDirectory: state.wrapWithDirectory || files.length > 1,
progress: (len) => progressHandler(len, totalSize, state, emitter),
wrapWithDirectory: wrapFlag,
pin: state.pinUpload
}
console.log('Calling background.ipfsAddAndShow', files)
const result = await ipfsCompanion.ipfsAddAndShow(files, uploadOptions)
emitter.emit('render')
console.log('Upload result', result)
// close upload tab as it will be replaced with a new tab with uploaded content
browser.tabs.remove(uploadTab.id)
await browser.tabs.remove(uploadTab.id)
} catch (err) {
console.error('Unable to perform quick upload', err)
// keep upload tab and display error message in it
state.message = `Unable to upload to IPFS API: ${err}`
state.message = `Unable to upload to IPFS API: ${err.name ? err.name : err}`
state.progress = ''
emitter.emit('render')
}
})
Expand Down Expand Up @@ -129,7 +160,7 @@ function quickUploadPage (state, emit) {
</div>
</header>
<label for="quickUploadInput" class='db relative mt5 hover-inner-shadow' style="border:solid 2px #6ACAD1">
<input class="db absolute pointer w-100 h-100 top-0 o-0" type="file" id="quickUploadInput" multiple onchange=${onFileInputChange} />
<input class="db absolute pointer w-100 h-100 top-0 o-0" type="file" id="quickUploadInput" ${state.ipfsNodeType === 'external' ? 'multiple' : null} onchange=${onFileInputChange} />
<div class='dt dim' style='padding-left: 100px; height: 300px'>
<div class='dtc v-mid'>
<span class="f3 link dim br1 ph4 pv3 dib white" style="background: #6ACAD1">
Expand All @@ -141,7 +172,7 @@ function quickUploadPage (state, emit) {
</emph>
${browser.i18n.getMessage('quickUpload_drop_it_here')}
</span>
<p class='f4'>${state.message}</p>
<p class='f4 db relative'>${state.message}<span class='code db absolute fr pv2'>${state.progress}</span></p>
</div>
</div>
</label>
Expand Down
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -90,9 +90,11 @@
"web-ext": "2.6.0"
},
"dependencies": {
"byte-size": "4.0.3",
"choo": "6.8.0",
"doc-sniff": "1.0.1",
"file-type": "7.6.0",
"filereader-pull-stream": "1.0.0",
"ipfs": "0.28.2",
"ipfs-api": "21.0.0",
"ipfs-css": "0.3.0",
Expand Down
18 changes: 17 additions & 1 deletion yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1252,6 +1252,10 @@ bunyan@1.8.12:
mv "~2"
safe-json-stringify "~1"

byte-size@4.0.3:
version "4.0.3"
resolved "https://registry.yarnpkg.com/byte-size/-/byte-size-4.0.3.tgz#b7c095efc68eadf82985fccd9a2df43a74fa2ccd"

byteman@^1.3.5:
version "1.3.5"
resolved "https://registry.yarnpkg.com/byteman/-/byteman-1.3.5.tgz#d6061f7536c7e7c4bcb756037ef9c4c266ec51fd"
Expand Down Expand Up @@ -3188,6 +3192,12 @@ filename-regex@^2.0.0:
version "2.0.1"
resolved "https://registry.yarnpkg.com/filename-regex/-/filename-regex-2.0.1.tgz#c1c4b9bee3e09725ddb106b75c1e301fe2f18b26"

filereader-pull-stream@1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/filereader-pull-stream/-/filereader-pull-stream-1.0.0.tgz#9cd17b66a5085a8770ab58c2882396b3d4f2e030"
dependencies:
typedarray-to-buffer "^3.1.2"

filesize@^3.6.0:
version "3.6.0"
resolved "https://registry.yarnpkg.com/filesize/-/filesize-3.6.0.tgz#22d079615624bb6fd3c04026120628a41b3f4efa"
Expand Down Expand Up @@ -4999,7 +5009,7 @@ is-symbol@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.1.tgz#3cc59f00025194b6ab2e38dbae6689256b660572"

is-typedarray@~1.0.0:
is-typedarray@^1.0.0, is-typedarray@~1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a"

Expand Down Expand Up @@ -9881,6 +9891,12 @@ type-detect@^4.0.0, type-detect@^4.0.5:
version "4.0.8"
resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c"

typedarray-to-buffer@^3.1.2:
version "3.1.5"
resolved "https://registry.yarnpkg.com/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz#a97ee7a9ff42691b9f783ff1bc5112fe3fca9080"
dependencies:
is-typedarray "^1.0.0"

typedarray-to-buffer@~1.0.0:
version "1.0.4"
resolved "https://registry.yarnpkg.com/typedarray-to-buffer/-/typedarray-to-buffer-1.0.4.tgz#9bb8ba0e841fb3f4cf1fe7c245e9f3fa8a5fe99c"
Expand Down

0 comments on commit 9fbe63f

Please sign in to comment.