Comparing version 0.7.0 to 0.8.0
@@ -23,3 +23,3 @@ Our combined changelog and roadmap. It contains todos as well as dones. | ||
- [ ] build: investigate Rollup someday, for tree-shaking and smaller dist https://github.com/substack/node-browserify/issues/1379#issuecomment-183383199, https://github.com/nolanlawson/rollupify | ||
- [ ] core: Decouple rendering from Plugins and try to make Uppy work with React (add basic example) to remain aware of possible issues (@hedgerh), look at https://github.com/akiran/react-slick | ||
- [ ] core: Decouple rendering from Plugins and try to make Uppy work with React (add basic example) to remain aware of possible issues (@hedgerh), look at https://github.com/akiran/react-slick, https://github.com/nosir/cleave.js | ||
- [ ] core: Have base styles, be explicit about fonts, etc | ||
@@ -30,3 +30,4 @@ - [ ] core: Make sure Uppy works well in VR | ||
- [ ] meta: Use <waffle.io> instead of Markdown task tracking. Some discussion [here](https://transloadit.slack.com/archives/general/p1455693654000062) (@kvz) | ||
- [ ] modal: polish on mobile | ||
- [ ] dashboard: polish on mobile | ||
- [ ] dashboard: add ability to minimize Modal/Dashboard, while long upload is in progress? Uppy then becomes just a tiny progress indicator | ||
- [ ] presets: Add basic preset that mimics Transloadit's jQuery plugin (#28) | ||
@@ -40,20 +41,51 @@ - [ ] test: Human should check http://www.webpagetest.org, use it sometimes to test our website & Uppy? Which will show response/loading times and where big delays are | ||
- [ ] website: scrollbars on code samples (can’t reproduce!) (@arturi) | ||
- [ ] core: accessibility research | ||
- [ ] website: Would one really connect a own google drive or dropbox for testing purpose? => maybe one can give something like a testing account of google drive and dropbox to try uppy | ||
- [ ] dependencies: es6-promise --> lie https://github.com/calvinmetcalf/lie ? | ||
- [ ] core: accessibility research: https://chrome.google.com/webstore/detail/accessibility-developer-t/fpkknkljclfencbdbgkenhalefipecmb, http://khan.github.io/tota11y/ | ||
- [ ] test: working Uppy example on Require Bin — latest version straight from NPM (should be working, will check again when tus-js-client is updated) (@arturi @account) | ||
- [ ] meta: add cdn.rawgit.com bundled version to readme | ||
## 0.8.0 | ||
## 0.9.0 | ||
To be released: July 29, 2016 | ||
To be released: August 26, 2016. Releasemaster: Harry | ||
- [ ] meta: better readme on GitHub and NPM (@arturi) | ||
- [ ] meta: release “Uppy Begins” post + minor blog polish (@arturi) | ||
- [ ] modifier: A plugin to supply meta data (like width, tag, filename, user_id) (@arturi) | ||
- [ ] modifier: pass custom metadata with non-tus-upload. Maybe mimic meta behavior of tus here, too | ||
- [ ] modifier: pass custom metadata with tus-upload with tus-js-client (@arturi) | ||
- [ ] progress: better icons, style, file types (mime + extension) (@arturi) | ||
- [ ] modal: merge modal and dashboard (@arturi) | ||
- [ ] modal: try a workflow where import from external service slides over and takes up the whole modal screen (@arturi) | ||
Theme: ? | ||
- [ ] core: expose some events/APIs/callbacks to the user: `onFileUploaded`, `onFileSelected`, `onAllUploaded`, `addFile` api, open modal... (@arturi, @hedgerh) | ||
- [ ] core: how would Uppy work without the UI, if one only wants dragdrop + select from local disk | ||
- [ ] core: figure out race conditions with `yo-yo` when file uploads are in progress (@arturi) | ||
- [ ] test: Get IE4 on windows 3.11 to run Uppy and see it fall back to regular form upload (`api2.transloadit.com`) (@arturi) | ||
- [ ] test: working Uppy example on Require Bin — latest version straight from NPM (@arturi) | ||
- [ ] test: add next-update https://www.npmjs.com/package/next-update to check if packages we use can be safely updated | ||
- [ ] dashboard: message when all uploads are done? results of the upload — better links to uploaded files? (@arturi) | ||
- [ ] dashboard: file name + extension should fit on two lines, truncate in the middle (maybe https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/measureText) (@arturi) | ||
- [ ] dashboard: try to implement a circular progress indicator on top of the fileItem (@arturi) | ||
- [ ] dashboard: add perfect scrollbar https://github.com/noraesae/perfect-scrollbar (@arturi) | ||
- [ ] dashboard: see if the dashboard can be optionally rendered inline instead of as a modal (@arturi) | ||
- [ ] modifier: metadata — the aftermath (@arturi) | ||
## 0.8.0 | ||
Theme: The Webcam Edition | ||
To be released: July 29, 2016. Releasemaster: Artur | ||
- [x] core: fix bug: no meta information from uppy-server files (@hedgerh) | ||
- [x] core: fix bug: uppy-server file is treated as local and directly uploaded (@hedgerh) | ||
- [x] uppy-server: hammering out websockets/oauth (@hedgerh, @acconut) | ||
- [x] debugger: introduce MagicLog as a way to debug state changes in Uppy (@arturi) | ||
- [x] modifier: A MetaData plugin to supply meta data (like width, tag, filename, user_id) (@arturi) | ||
- [x] modifier: pass custom metadata with non-tus-upload. Maybe mimic meta behavior of tus here, too (@arturi) | ||
- [x] modifier: pass custom metadata with tus-upload with tus-js-client (@arturi) | ||
- [x] webcam: initial version: webcam light goes on (@hedgerh) | ||
- [x] progress: better icons, styles (@arturi) | ||
- [x] core: better mime/type detection (via mime + extension) (@arturi) | ||
- [x] core: add deep-freeze to getState so that we are sure we are not mutating state accidentally (@arturi) | ||
- [x] meta: release “Uppy Begins” post (@arturi @kvz) | ||
- [x] meta: better readme on GitHub and NPM (@arturi) | ||
- [x] test: add pre-commit & lint-staged (@arturi) | ||
- [x] test: add next-update https://www.npmjs.com/package/next-update to check if packages we use can be safely updated (@arturi) | ||
- [x] website: blog polish — add post authors and their gravatars (@arturi) | ||
- [x] dashboard: UI revamp, more prototypes, background image, make dashboard nicer (@arturi) | ||
- [x] dashboard: try a workflow where import from external service slides over and takes up the whole dashboard screen (@arturi) | ||
- [x] modal: merge modal and dashboard (@arturi) | ||
## 0.7.0 | ||
@@ -244,9 +276,9 @@ | ||
- core (@arturi) | ||
- dashboard (/modal) (@hedgerh) | ||
- docs (@arturi) | ||
- dragdrop (@arturi) | ||
- drive (@hedgerh) | ||
- dropbox (@hedgerh) | ||
- drive (@hedgerh) | ||
- instagram (@hedgerh) | ||
- meta (@kvz) | ||
- modal (@hedgerh) | ||
- presets (@arturi) | ||
@@ -253,0 +285,0 @@ - server (@hedgerh) |
@@ -29,2 +29,6 @@ 'use strict'; | ||
var _deepFreezeStrict = require('deep-freeze-strict'); | ||
var _deepFreezeStrict2 = _interopRequireDefault(_deepFreezeStrict); | ||
var _UppySocket = require('./UppySocket'); | ||
@@ -62,3 +66,3 @@ | ||
// Dictates in what order different plugin types are ran: | ||
this.types = ['presetter', 'orchestrator', 'progressindicator', 'acquirer', 'uploader', 'presenter']; | ||
this.types = ['presetter', 'orchestrator', 'progressindicator', 'acquirer', 'modifier', 'uploader', 'presenter', 'debugger']; | ||
@@ -72,2 +76,4 @@ this.type = 'core'; | ||
this.i18n = this.translator.translate.bind(this.translator); | ||
this.getState = this.getState.bind(this); | ||
this.updateMeta = this.updateMeta.bind(this); | ||
this.initSocket = this.initSocket.bind(this); | ||
@@ -95,3 +101,3 @@ | ||
Core.prototype.updateAll = function updateAll() { | ||
Core.prototype.updateAll = function updateAll(state) { | ||
var _this = this; | ||
@@ -101,3 +107,3 @@ | ||
_this.plugins[pluginType].forEach(function (plugin) { | ||
plugin.update(); | ||
plugin.update(state); | ||
}); | ||
@@ -114,7 +120,11 @@ }); | ||
Core.prototype.setState = function setState(newState) { | ||
this.log('Setting state to: '); | ||
Core.prototype.setState = function setState(stateUpdate) { | ||
var newState = _extends({}, this.state, stateUpdate); | ||
this.emitter.emit('state-update', this.state, newState, stateUpdate); | ||
this.state = newState; | ||
this.updateAll(this.state); | ||
this.log('Updating state with: '); | ||
this.log(newState); | ||
this.state = _extends({}, this.state, newState); | ||
this.updateAll(); | ||
}; | ||
@@ -130,13 +140,33 @@ | ||
Core.prototype.getState = function getState() { | ||
return this.state; | ||
return (0, _deepFreezeStrict2.default)(this.state); | ||
}; | ||
Core.prototype.addMeta = function addMeta(meta, fileID) { | ||
if (typeof fileID === 'undefined') { | ||
var updatedFiles = _extends({}, this.state.files); | ||
for (var file in updatedFiles) { | ||
updatedFiles[file].meta = meta; | ||
} | ||
this.setState({ files: updatedFiles }); | ||
} | ||
Core.prototype.updateMeta = function updateMeta(data, fileID) { | ||
// // if fileID is not specified, set meta data to all files | ||
// if (typeof fileID === 'undefined') { | ||
// const updatedFiles = Object.assign({}, this.getState().files) | ||
// Object.keys(updatedFiles).forEach((file) => { | ||
// const newMeta = Object.assign({}, updatedFiles[file].meta, data) | ||
// updatedFiles[file] = Object.assign({}, updatedFiles[file], { | ||
// meta: newMeta | ||
// }) | ||
// }) | ||
// this.setState({files: updatedFiles}) | ||
// | ||
// // if fileID is specified, set meta to that file | ||
// } else { | ||
// const updatedFiles = Object.assign({}, this.getState().files) | ||
// const newMeta = Object.assign({}, updatedFiles[fileID].meta, data) | ||
// updatedFiles[fileID] = Object.assign({}, updatedFiles[fileID], { | ||
// meta: newMeta | ||
// }) | ||
// this.setState({files: updatedFiles}) | ||
// } | ||
var updatedFiles = _extends({}, this.getState().files); | ||
var newMeta = _extends({}, updatedFiles[fileID].meta, data); | ||
updatedFiles[fileID] = _extends({}, updatedFiles[fileID], { | ||
meta: newMeta | ||
}); | ||
this.setState({ files: updatedFiles }); | ||
}; | ||
@@ -149,5 +179,8 @@ | ||
var fileType = file.type.split('/'); | ||
var fileType = _Utils2.default.getFileType(file) ? _Utils2.default.getFileType(file).split('/') : ['', '']; | ||
var fileTypeGeneral = fileType[0]; | ||
var fileTypeSpecific = fileType[1]; | ||
var fileExtension = _Utils2.default.getFileNameAndExtension(file.name)[1]; | ||
var isRemote = file.isRemote || false; | ||
var fileID = _Utils2.default.generateFileID(file.name); | ||
@@ -158,3 +191,7 @@ | ||
id: fileID, | ||
name: file.name, | ||
name: file.name || 'noname', | ||
extension: fileExtension || '', | ||
meta: { | ||
name: file.name || 'noname' | ||
}, | ||
type: { | ||
@@ -168,4 +205,4 @@ general: fileTypeGeneral, | ||
uploadedSize: 0, | ||
isRemote: file.isRemote || false, | ||
remote: file.remote | ||
isRemote: isRemote, | ||
remote: file.remote || '' | ||
}; | ||
@@ -175,5 +212,7 @@ | ||
if (fileTypeGeneral === 'image') { | ||
// this.addImgPreviewToFile(updatedFiles[fileID]) | ||
_Utils2.default.readImage(updatedFiles[fileID].data, function (imgEl) { | ||
if (fileTypeGeneral === 'image' && !isRemote) { | ||
_Utils2.default.readImage(updatedFiles[fileID].data, function (err, imgEl) { | ||
if (err) { | ||
return _this2.log(err); | ||
} | ||
var newImageWidth = 200; | ||
@@ -183,4 +222,8 @@ var newImageHeight = _Utils2.default.getProportionalImageHeight(imgEl, newImageWidth); | ||
var updatedFiles = _extends({}, _this2.state.files); | ||
updatedFiles[fileID].previewEl = (0, _yoYo2.default)(_templateObject, file.name, resizedImgSrc); | ||
var updatedFiles = _extends({}, _this2.getState().files); | ||
var updatedFile = _extends({}, updatedFiles[fileID], { | ||
previewEl: (0, _yoYo2.default)(_templateObject, file.name, resizedImgSrc), | ||
preview: resizedImgSrc | ||
}); | ||
updatedFiles[fileID] = updatedFile; | ||
_this2.setState({ files: updatedFiles }); | ||
@@ -190,2 +233,4 @@ }); | ||
this.emitter.emit('file-added', fileID); | ||
if (this.opts.autoProceed) { | ||
@@ -222,5 +267,8 @@ this.emitter.emit('next'); | ||
var updatedFiles = _extends({}, _this3.state.files); | ||
updatedFiles[data.id].progress = percentage; | ||
updatedFiles[data.id].uploadedSize = data.bytesUploaded ? (0, _prettyBytes2.default)(data.bytesUploaded) : '?'; | ||
var updatedFiles = _extends({}, _this3.getState().files); | ||
var updatedFile = _extends({}, updatedFiles[data.id], { | ||
progress: percentage, | ||
uploadedSize: data.bytesUploaded ? (0, _prettyBytes2.default)(data.bytesUploaded) : '?' | ||
}); | ||
updatedFiles[data.id] = updatedFile; | ||
@@ -247,10 +295,12 @@ var inProgress = Object.keys(updatedFiles).map(function (file) { | ||
// `upload-success` adds successfully uploaded file to `state.uploadedFiles` | ||
// and fires `remove-file` to remove it from `state.files` | ||
this.emitter.on('upload-success', function (file) { | ||
var updatedFiles = _extends({}, _this3.state.files); | ||
updatedFiles[file.id] = file; | ||
_this3.setState({ files: updatedFiles }); | ||
// this.log(this.state.uploadedFiles) | ||
// this.emitter.emit('file-remove', file.id) | ||
this.emitter.on('upload-success', function (fileID, uploadURL) { | ||
var updatedFiles = _extends({}, _this3.getState().files); | ||
var updatedFile = _extends({}, updatedFiles[fileID], { | ||
uploadURL: uploadURL | ||
}); | ||
updatedFiles[fileID] = updatedFile; | ||
_this3.setState({ | ||
files: updatedFiles | ||
}); | ||
}); | ||
@@ -341,3 +391,3 @@ }; | ||
} else { | ||
console.log('LOG↓'); | ||
// console.log('LOG↓') | ||
console.dir(msg); | ||
@@ -393,23 +443,2 @@ } | ||
return; | ||
// Each Plugin can have `run` and/or `install` methods. | ||
// `install` adds event listeners and does some non-blocking work, useful for `progressindicator`, | ||
// `run` waits for the previous step to finish (user selects files) before proceeding | ||
// ['install', 'run'].forEach((method) => { | ||
// // First we select only plugins of current type, | ||
// // then create an array of runType methods of this plugins | ||
// const typeMethods = this.types.filter((type) => this.plugins[type]) | ||
// .map((type) => this.runType.bind(this, type, method)) | ||
// // Run waterfall of typeMethods | ||
// return Utils.promiseWaterfall(typeMethods) | ||
// .then((result) => { | ||
// // If results are empty, don't log upload results. Hasn't run yet. | ||
// if (result[0] !== undefined) { | ||
// this.log(result) | ||
// this.log('Upload result -> success!') | ||
// return result | ||
// } | ||
// }) | ||
// .catch((error) => this.log('Upload result -> failed:', error)) | ||
// }) | ||
}; | ||
@@ -416,0 +445,0 @@ |
'use strict'; | ||
exports.__esModule = true; | ||
exports.$$ = $$; | ||
exports.$ = $; | ||
var _mimeTypes = require('mime-types'); | ||
var _mimeTypes2 = _interopRequireDefault(_mimeTypes); | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
/** | ||
@@ -37,10 +46,41 @@ * A collection of small utility functions that help with dom manipulation, adding listeners, | ||
function isTouchDevice() { | ||
return 'ontouchstart' in window || // works on most browsers | ||
navigator.maxTouchPoints; // works on IE10/11 and Surface | ||
}; | ||
/** | ||
* `querySelectorAll` that returns a normal array instead of fileList | ||
* Shorter and fast way to select multiple nodes in the DOM | ||
* @param { String|Array } selector - DOM selector or nodes list | ||
* @param { Object } ctx - DOM node where the targets of our search will is located | ||
* @returns { Object } dom nodes found | ||
*/ | ||
function qsa(selector, context) { | ||
return Array.prototype.slice.call((context || document).querySelectorAll(selector) || []); | ||
function $$(selector, ctx) { | ||
var els; | ||
if (typeof selector === 'string') { | ||
els = (ctx || document).querySelectorAll(selector); | ||
} else { | ||
els = selector; | ||
return Array.prototype.slice.call(els); | ||
} | ||
} | ||
/** | ||
* Shorter and fast way to select a single node in the DOM | ||
* @param { String } selector - unique dom selector | ||
* @param { Object } ctx - DOM node where the target of our search will is located | ||
* @returns { Object } dom node found | ||
*/ | ||
function $(selector, ctx) { | ||
return (ctx || document).querySelector(selector); | ||
} | ||
function truncateString(string, length) { | ||
if (string.length > length) { | ||
return string.substring(0, length) + '…'; | ||
} | ||
return string; | ||
} | ||
/** | ||
* Partition array by a grouping function. | ||
@@ -139,9 +179,12 @@ * @param {[type]} array Input array | ||
var img = new Image(); | ||
img.onload = function () { | ||
return cb(img); | ||
}; | ||
img.addEventListener('load', function () { | ||
return cb(null, img); | ||
}); | ||
img.addEventListener('error', function (err) { | ||
return cb(err); | ||
}); | ||
img.src = imgSrcBase64; | ||
}); | ||
reader.addEventListener('error', function (err) { | ||
console.log('FileReader error' + err); | ||
console.log('FileReader error ' + err); | ||
}); | ||
@@ -157,2 +200,17 @@ reader.readAsDataURL(imgObject); | ||
function getFileType(file) { | ||
if (file.type) { | ||
return file.type; | ||
} | ||
return _mimeTypes2.default.lookup(file.name); | ||
} | ||
// returns [fileName, fileExt] | ||
function getFileNameAndExtension(fullFileName) { | ||
var re = /(?:\.([^.]+))?$/; | ||
var fileExt = re.exec(fullFileName)[1]; | ||
var fileName = fullFileName.replace('.' + fileExt, ''); | ||
return [fileName, fileExt]; | ||
} | ||
/** | ||
@@ -177,2 +235,3 @@ * Resizes an image to specified width and height, using canvas | ||
// draw source image into the off-screen canvas: | ||
// ctx.clearRect(0, 0, width, height) | ||
ctx.drawImage(img, 0, 0, width, height); | ||
@@ -182,3 +241,3 @@ | ||
// canvas.toDataURL('image/jpeg', quality); // quality = [0.0, 1.0] | ||
return canvas.toDataURL(); | ||
return canvas.toDataURL('image/png'); | ||
} | ||
@@ -194,8 +253,13 @@ | ||
groupBy: groupBy, | ||
qsa: qsa, | ||
$: $, | ||
$$: $$, | ||
extend: extend, | ||
readImage: readImage, | ||
resizeImage: resizeImage, | ||
getProportionalImageHeight: getProportionalImageHeight | ||
getProportionalImageHeight: getProportionalImageHeight, | ||
isTouchDevice: isTouchDevice, | ||
getFileNameAndExtension: getFileNameAndExtension, | ||
truncateString: truncateString, | ||
getFileType: getFileType | ||
}; | ||
//# sourceMappingURL=Utils.js.map |
@@ -11,2 +11,10 @@ 'use strict'; | ||
var _pt_BR = require('./pt_BR'); | ||
var _pt_BR2 = _interopRequireDefault(_pt_BR); | ||
var _zh_CN = require('./zh_CN'); | ||
var _zh_CN2 = _interopRequireDefault(_zh_CN); | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
@@ -19,4 +27,6 @@ | ||
en_US: _en_US2.default, | ||
ru_RU: _ru_RU2.default | ||
ru_RU: _ru_RU2.default, | ||
pt_BR: _pt_BR2.default, | ||
zh_CN: _zh_CN2.default | ||
}; | ||
//# sourceMappingURL=index.js.map |
@@ -116,4 +116,2 @@ 'use strict'; | ||
}); | ||
this.core.addMeta({ bla: 'bla' }); | ||
}; | ||
@@ -120,0 +118,0 @@ |
@@ -56,2 +56,3 @@ 'use strict'; | ||
// this.core.socket.on('') | ||
// Logic | ||
@@ -78,49 +79,2 @@ _this.addFile = _this.addFile.bind(_this); | ||
_this.opts = _extends({}, defaultOptions, opts); | ||
var host = _this.opts.host.replace(/^https?:\/\//, ''); | ||
_this.socket = _this.core.initSocket({ | ||
target: 'ws://' + host + '/' | ||
}); | ||
_this.socket.on('google.auth.pass', function () { | ||
console.log('google.auth.pass'); | ||
_this.getFolder(_this.core.getState().googleDrive.directory.id); | ||
}); | ||
_this.socket.on('uppy.debug', function (payload) { | ||
console.log('GOOGLE DEBUG:'); | ||
console.log(payload); | ||
}); | ||
_this.socket.on('google.list.ok', function (data) { | ||
console.log('google.list.ok'); | ||
var folders = []; | ||
var files = []; | ||
data.items.forEach(function (item) { | ||
if (item.mimeType === 'application/vnd.google-apps.folder') { | ||
folders.push(item); | ||
} else { | ||
files.push(item); | ||
} | ||
}); | ||
_this.updateState({ | ||
folders: folders, | ||
files: files, | ||
authenticated: true | ||
}); | ||
}); | ||
_this.socket.on('google.list.fail', function (data) { | ||
console.log('google.list.fail'); | ||
console.log(data); | ||
}); | ||
_this.socket.on('google.auth.fail', function () { | ||
console.log('google.auth.fail'); | ||
_this.updateState({ | ||
authenticated: false | ||
}); | ||
}); | ||
return _this; | ||
@@ -305,10 +259,12 @@ } | ||
var tagFile = { | ||
source: this, | ||
source: this.id, | ||
data: file, | ||
name: file.title, | ||
type: this.getFileType(file), | ||
type: file.mimeType, | ||
isRemote: true, | ||
remote: { | ||
action: 'google.get', | ||
payload: { | ||
id: file.id | ||
host: this.opts.host, | ||
url: this.opts.host + '/google/get?fileId=' + file.id, | ||
body: { | ||
fileId: file.id | ||
} | ||
@@ -315,0 +271,0 @@ } |
@@ -7,5 +7,5 @@ 'use strict'; | ||
var _modal = require('./modal'); | ||
var _Modal = require('./Modal'); | ||
var _modal2 = _interopRequireDefault(_modal); | ||
var _Modal2 = _interopRequireDefault(_Modal); | ||
@@ -20,6 +20,2 @@ var _Dummy = require('./Dummy'); | ||
var _Dropbox = require('./Dropbox'); | ||
var _Dropbox2 = _interopRequireDefault(_Dropbox); | ||
var _Formtag = require('./Formtag'); | ||
@@ -68,3 +64,4 @@ | ||
// Orchestrators | ||
// Acquirers | ||
// Parent | ||
@@ -79,3 +76,2 @@ | ||
DragDrop: _DragDrop2.default, | ||
Dropbox: _Dropbox2.default, | ||
GoogleDrive: _GoogleDrive2.default, | ||
@@ -86,3 +82,3 @@ Formtag: _Formtag2.default, | ||
TransloaditBasic: _TransloaditBasic2.default, | ||
Modal: _modal2.default | ||
Modal: _Modal2.default | ||
}; | ||
@@ -93,4 +89,3 @@ | ||
// Acquirers | ||
// Parent | ||
// Orchestrators | ||
//# sourceMappingURL=index.js.map |
@@ -62,2 +62,7 @@ 'use strict'; | ||
Object.keys(file.meta).forEach(function (item) { | ||
console.log(file.meta, file.meta[item]); | ||
formPost.append(file.meta, file.meta[item]); | ||
}); | ||
var xhr = new XMLHttpRequest(); | ||
@@ -87,4 +92,6 @@ | ||
var resp = JSON.parse(xhr.response); | ||
file.uploadURL = resp[_this2.opts.responseUrlFieldName]; | ||
var uploadURL = resp[_this2.opts.responseUrlFieldName]; | ||
_this2.core.emitter.emit('upload-success', file.id, uploadURL); | ||
_this2.core.log('Download ' + file.name + ' from ' + file.uploadURL); | ||
@@ -91,0 +98,0 @@ return resolve(file); |
@@ -37,3 +37,3 @@ 'use strict'; | ||
Plugin.prototype.update = function update() { | ||
Plugin.prototype.update = function update(state) { | ||
if (typeof this.el === 'undefined') { | ||
@@ -43,3 +43,3 @@ return; | ||
var newEl = this.render(this.core.state); | ||
var newEl = this.render(state); | ||
_yoYo2.default.update(this.el, newEl); | ||
@@ -46,0 +46,0 @@ }; |
@@ -15,2 +15,6 @@ 'use strict'; | ||
var _UppySocket = require('../core/UppySocket'); | ||
var _UppySocket2 = _interopRequireDefault(_UppySocket); | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
@@ -71,2 +75,3 @@ | ||
// TODO merge this.opts or this.opts.tus here | ||
metadata: file.meta, | ||
resume: false, | ||
@@ -87,4 +92,3 @@ endpoint: _this2.opts.endpoint, | ||
onSuccess: function onSuccess() { | ||
file.uploadURL = upload.url; | ||
_this2.core.emitter.emit('upload-success', file); | ||
_this2.core.emitter.emit('upload-success', file.id, upload.url); | ||
@@ -104,5 +108,60 @@ _this2.core.log('Download ' + upload.file.name + ' from ' + upload.url); | ||
Tus10.prototype.uploadFiles = function uploadFiles(files) { | ||
Tus10.prototype.uploadRemote = function uploadRemote(file, current, total) { | ||
var _this3 = this; | ||
return new _Promise(function (resolve, reject) { | ||
console.log(file.remote.url); | ||
fetch(file.remote.url, { | ||
method: 'post', | ||
credentials: 'include', | ||
headers: { | ||
'Accept': 'application/json', | ||
'Content-Type': 'application/json' | ||
}, | ||
body: JSON.stringify(_extends({}, file.remote.body, { | ||
target: _this3.opts.endpoint, | ||
protocol: 'tus' | ||
})) | ||
}).then(function (res) { | ||
if (res.status < 200 && res.status > 300) { | ||
return reject(res.statusText); | ||
} | ||
res.json().then(function (data) { | ||
// get the host domain | ||
var regex = /^(?:https?:\/\/)?(?:[^@\/\n]+@)?(?:www\.)?([^:\/\n]+)/; | ||
var host = regex.exec(file.remote.host)[1]; | ||
var token = data.token; | ||
var socket = new _UppySocket2.default({ | ||
target: 'ws://' + host + ':3121/api/' + token | ||
}); | ||
socket.on('progress', function (progressData) { | ||
if (progressData.complete) { | ||
_this3.core.log('Remote upload of \'' + file.name + '\' successful'); | ||
_this3.core.emitter.emit('upload-success', file); | ||
return resolve('Success'); | ||
} | ||
if (progressData.progress) { | ||
_this3.core.log('Upload progress: ' + progressData.progress); | ||
// Dispatch progress event | ||
_this3.core.emitter.emit('upload-progress', { | ||
uploader: _this3, | ||
id: file.id, | ||
bytesUploaded: progressData.bytesUploaded, | ||
bytesTotal: progressData.bytesTotal | ||
}); | ||
} | ||
}); | ||
}); | ||
}); | ||
}); | ||
}; | ||
Tus10.prototype.uploadFiles = function uploadFiles(files) { | ||
var _this4 = this; | ||
var uploaders = []; | ||
@@ -114,5 +173,5 @@ files.forEach(function (file, index) { | ||
if (!file.isRemote) { | ||
uploaders.push(_this3.upload(file, current, total)); | ||
uploaders.push(_this4.upload(file, current, total)); | ||
} else { | ||
uploaders.push(_this3.upload(file, current, total)); | ||
uploaders.push(_this4.uploadRemote(file, current, total)); | ||
} | ||
@@ -128,25 +187,2 @@ }); | ||
Tus10.prototype.uploadRemote = function uploadRemote(file, current, total) { | ||
var _this4 = this; | ||
return new _Promise(function (resolve, reject) { | ||
var payload = _extends({}, file.remote.payload, { | ||
target: _this4.opts.endpoint, | ||
protocol: 'tus' | ||
}); | ||
_this4.core.socket.send(file.remote.action, payload); | ||
_this4.core.socket.once('upload-success', function () { | ||
console.log('success'); | ||
_this4.core.emitter.emit('upload-success', file); | ||
_this4.core.emitter.emit('upload-progress', { | ||
id: file.id, | ||
percentage: 100 | ||
}); | ||
resolve(); | ||
}); | ||
}); | ||
}; | ||
Tus10.prototype.selectForUpload = function selectForUpload(files) { | ||
@@ -153,0 +189,0 @@ // TODO: replace files[file].isRemote with some logic |
{ | ||
"name": "uppy", | ||
"version": "0.7.0", | ||
"version": "0.8.0", | ||
"description": "Almost as cute as a Puppy :dog:", | ||
@@ -24,2 +24,3 @@ "main": "lib/index.js", | ||
"lint": "eslint src test website/build-examples.js website/update.js website/themes/uppy/source/js/common.js", | ||
"lint-staged": "lint-staged", | ||
"release:major": "env SEMANTIC=major npm run release", | ||
@@ -35,2 +36,3 @@ "release:minor": "env SEMANTIC=minor npm run release", | ||
"test": "npm run lint && npm run test:unit", | ||
"test:next-update": "next-update", | ||
"travis:deletecache": "travis cache --delete", | ||
@@ -57,2 +59,6 @@ "watch:css": "nodemon --watch src --ext scss -x 'npm run build:css'", | ||
}, | ||
"lint-staged": { | ||
"*.js": "eslint" | ||
}, | ||
"pre-commit": "lint-staged", | ||
"repository": { | ||
@@ -69,21 +75,19 @@ "type": "git", | ||
"devDependencies": { | ||
"postcss": "5.0.21", | ||
"autoprefixer": "6.3.6", | ||
"cssnano": "3.6.2", | ||
"babel-cli": "6.9.0", | ||
"babel-core": "6.7.7", | ||
"babel-eslint": "6.0.2", | ||
"autoprefixer": "6.3.7", | ||
"babel-cli": "6.10.1", | ||
"babel-core": "6.10.4", | ||
"babel-eslint": "6.1.2", | ||
"babel-loader": "6.2.4", | ||
"babel-plugin-es6-promise": "1.0.0", | ||
"babel-plugin-transform-object-assign": "6.5.0", | ||
"babel-plugin-transform-proto-to-assign": "6.8.0", | ||
"babel-polyfill": "6.7.4", | ||
"babel-plugin-transform-object-assign": "6.8.0", | ||
"babel-plugin-transform-proto-to-assign": "6.9.0", | ||
"babel-polyfill": "6.9.1", | ||
"babel-preset-es2015": "6.9.0", | ||
"babel-preset-es2015-loose": "7.0.0", | ||
"babel-register": "6.7.2", | ||
"babel-register": "6.9.0", | ||
"babelify": "7.2.0", | ||
"browser-sync": "2.13.0", | ||
"browserify": "13.0.1", | ||
"watchify": "3.7.0", | ||
"chalk": "1.1.1", | ||
"chalk": "1.1.3", | ||
"cssnano": "3.7.3", | ||
"disc": "1.3.2", | ||
@@ -95,28 +99,34 @@ "eslint": "2.7.0", | ||
"exorcist": "0.4.0", | ||
"fakefile": "0.0.5", | ||
"glob": "7.0.3", | ||
"fakefile": "0.0.8", | ||
"glob": "7.0.5", | ||
"isomorphic-fetch": "2.2.1", | ||
"lint-staged": "2.0.2", | ||
"minifyify": "7.3.3", | ||
"mkdirp": "0.5.1", | ||
"multi-glob": "1.0.1", | ||
"next-update": "1.2.2", | ||
"nock": "8.0.0", | ||
"node-fetch": "1.5.0", | ||
"node-notifier": "4.4.0", | ||
"node-sass": "3.4.2", | ||
"node-notifier": "4.6.0", | ||
"node-sass": "3.8.0", | ||
"nodemon": "1.8.1", | ||
"npm-run-all": "2.1.1", | ||
"npm-run-all": "2.3.0", | ||
"postcss": "5.1.0", | ||
"pre-commit": "1.1.3", | ||
"sass": "0.5.0", | ||
"selenium-webdriver": "2.52.0", | ||
"selenium-webdriver": "2.53.3", | ||
"tap-spec": "4.1.1", | ||
"tape": "4.4.0", | ||
"uppy-server": "0.0.7" | ||
"uppy-server": "0.0.7", | ||
"watchify": "3.7.0" | ||
}, | ||
"dependencies": { | ||
"deep-freeze-strict": "1.1.1", | ||
"drag-drop": "2.11.0", | ||
"es6-promise": "3.1.2", | ||
"pretty-bytes": "^3.0.1", | ||
"tus-js-client": "1.1.3", | ||
"es6-promise": "3.2.1", | ||
"mime-types": "2.1.11", | ||
"pretty-bytes": "3.0.1", | ||
"tus-js-client": "1.1.4", | ||
"whatwg-fetch": "1.0.0", | ||
"yo-yo": "1.2.0" | ||
"yo-yo": "1.2.2" | ||
} | ||
} |
@@ -6,2 +6,3 @@ import Utils from '../core/Utils' | ||
import ee from 'events' | ||
import deepFreeze from 'deep-freeze-strict' | ||
import UppySocket from './UppySocket' | ||
@@ -28,3 +29,4 @@ | ||
// Dictates in what order different plugin types are ran: | ||
this.types = [ 'presetter', 'orchestrator', 'progressindicator', 'acquirer', 'uploader', 'presenter' ] | ||
this.types = [ 'presetter', 'orchestrator', 'progressindicator', | ||
'acquirer', 'modifier', 'uploader', 'presenter', 'debugger'] | ||
@@ -38,2 +40,4 @@ this.type = 'core' | ||
this.i18n = this.translator.translate.bind(this.translator) | ||
this.getState = this.getState.bind(this) | ||
this.updateMeta = this.updateMeta.bind(this) | ||
this.initSocket = this.initSocket.bind(this) | ||
@@ -59,6 +63,6 @@ | ||
*/ | ||
updateAll () { | ||
updateAll (state) { | ||
Object.keys(this.plugins).forEach((pluginType) => { | ||
this.plugins[pluginType].forEach((plugin) => { | ||
plugin.update() | ||
plugin.update(state) | ||
}) | ||
@@ -73,7 +77,11 @@ }) | ||
*/ | ||
setState (newState) { | ||
this.log('Setting state to: ') | ||
setState (stateUpdate) { | ||
const newState = Object.assign({}, this.state, stateUpdate) | ||
this.emitter.emit('state-update', this.state, newState, stateUpdate) | ||
this.state = newState | ||
this.updateAll(this.state) | ||
this.log('Updating state with: ') | ||
this.log(newState) | ||
this.state = Object.assign({}, this.state, newState) | ||
this.updateAll() | ||
} | ||
@@ -87,13 +95,33 @@ | ||
getState () { | ||
return this.state | ||
return deepFreeze(this.state) | ||
} | ||
addMeta (meta, fileID) { | ||
if (typeof fileID === 'undefined') { | ||
const updatedFiles = Object.assign({}, this.state.files) | ||
for (let file in updatedFiles) { | ||
updatedFiles[file].meta = meta | ||
} | ||
this.setState({files: updatedFiles}) | ||
} | ||
updateMeta (data, fileID) { | ||
// // if fileID is not specified, set meta data to all files | ||
// if (typeof fileID === 'undefined') { | ||
// const updatedFiles = Object.assign({}, this.getState().files) | ||
// Object.keys(updatedFiles).forEach((file) => { | ||
// const newMeta = Object.assign({}, updatedFiles[file].meta, data) | ||
// updatedFiles[file] = Object.assign({}, updatedFiles[file], { | ||
// meta: newMeta | ||
// }) | ||
// }) | ||
// this.setState({files: updatedFiles}) | ||
// | ||
// // if fileID is specified, set meta to that file | ||
// } else { | ||
// const updatedFiles = Object.assign({}, this.getState().files) | ||
// const newMeta = Object.assign({}, updatedFiles[fileID].meta, data) | ||
// updatedFiles[fileID] = Object.assign({}, updatedFiles[fileID], { | ||
// meta: newMeta | ||
// }) | ||
// this.setState({files: updatedFiles}) | ||
// } | ||
const updatedFiles = Object.assign({}, this.getState().files) | ||
const newMeta = Object.assign({}, updatedFiles[fileID].meta, data) | ||
updatedFiles[fileID] = Object.assign({}, updatedFiles[fileID], { | ||
meta: newMeta | ||
}) | ||
this.setState({files: updatedFiles}) | ||
} | ||
@@ -104,5 +132,8 @@ | ||
const fileType = file.type.split('/') | ||
const fileType = Utils.getFileType(file) ? Utils.getFileType(file).split('/') : ['', ''] | ||
const fileTypeGeneral = fileType[0] | ||
const fileTypeSpecific = fileType[1] | ||
const fileExtension = Utils.getFileNameAndExtension(file.name)[1] | ||
const isRemote = file.isRemote || false | ||
const fileID = Utils.generateFileID(file.name) | ||
@@ -113,3 +144,7 @@ | ||
id: fileID, | ||
name: file.name, | ||
name: file.name || 'noname', | ||
extension: fileExtension || '', | ||
meta: { | ||
name: file.name || 'noname' | ||
}, | ||
type: { | ||
@@ -123,4 +158,4 @@ general: fileTypeGeneral, | ||
uploadedSize: 0, | ||
isRemote: file.isRemote || false, | ||
remote: file.remote | ||
isRemote: isRemote, | ||
remote: file.remote || '' | ||
} | ||
@@ -130,5 +165,7 @@ | ||
if (fileTypeGeneral === 'image') { | ||
// this.addImgPreviewToFile(updatedFiles[fileID]) | ||
Utils.readImage(updatedFiles[fileID].data, (imgEl) => { | ||
if (fileTypeGeneral === 'image' && !isRemote) { | ||
Utils.readImage(updatedFiles[fileID].data, (err, imgEl) => { | ||
if (err) { | ||
return this.log(err) | ||
} | ||
const newImageWidth = 200 | ||
@@ -138,4 +175,8 @@ const newImageHeight = Utils.getProportionalImageHeight(imgEl, newImageWidth) | ||
const updatedFiles = Object.assign({}, this.state.files) | ||
updatedFiles[fileID].previewEl = yo`<img alt="${file.name}" src="${resizedImgSrc}">` | ||
const updatedFiles = Object.assign({}, this.getState().files) | ||
const updatedFile = Object.assign({}, updatedFiles[fileID], { | ||
previewEl: yo`<img alt="${file.name}" src="${resizedImgSrc}">`, | ||
preview: resizedImgSrc | ||
}) | ||
updatedFiles[fileID] = updatedFile | ||
this.setState({files: updatedFiles}) | ||
@@ -145,2 +186,4 @@ }) | ||
this.emitter.emit('file-added', fileID) | ||
if (this.opts.autoProceed) { | ||
@@ -173,5 +216,8 @@ this.emitter.emit('next') | ||
const updatedFiles = Object.assign({}, this.state.files) | ||
updatedFiles[data.id].progress = percentage | ||
updatedFiles[data.id].uploadedSize = data.bytesUploaded ? prettyBytes(data.bytesUploaded) : '?' | ||
const updatedFiles = Object.assign({}, this.getState().files) | ||
const updatedFile = Object.assign({}, updatedFiles[data.id], { | ||
progress: percentage, | ||
uploadedSize: data.bytesUploaded ? prettyBytes(data.bytesUploaded) : '?' | ||
}) | ||
updatedFiles[data.id] = updatedFile | ||
@@ -198,10 +244,12 @@ const inProgress = Object.keys(updatedFiles).map((file) => { | ||
// `upload-success` adds successfully uploaded file to `state.uploadedFiles` | ||
// and fires `remove-file` to remove it from `state.files` | ||
this.emitter.on('upload-success', (file) => { | ||
const updatedFiles = Object.assign({}, this.state.files) | ||
updatedFiles[file.id] = file | ||
this.setState({files: updatedFiles}) | ||
// this.log(this.state.uploadedFiles) | ||
// this.emitter.emit('file-remove', file.id) | ||
this.emitter.on('upload-success', (fileID, uploadURL) => { | ||
const updatedFiles = Object.assign({}, this.getState().files) | ||
const updatedFile = Object.assign({}, updatedFiles[fileID], { | ||
uploadURL: uploadURL | ||
}) | ||
updatedFiles[fileID] = updatedFile | ||
this.setState({ | ||
files: updatedFiles | ||
}) | ||
}) | ||
@@ -287,3 +335,3 @@ } | ||
} else { | ||
console.log('LOG↓') | ||
// console.log('LOG↓') | ||
console.dir(msg) | ||
@@ -332,23 +380,2 @@ } | ||
return | ||
// Each Plugin can have `run` and/or `install` methods. | ||
// `install` adds event listeners and does some non-blocking work, useful for `progressindicator`, | ||
// `run` waits for the previous step to finish (user selects files) before proceeding | ||
// ['install', 'run'].forEach((method) => { | ||
// // First we select only plugins of current type, | ||
// // then create an array of runType methods of this plugins | ||
// const typeMethods = this.types.filter((type) => this.plugins[type]) | ||
// .map((type) => this.runType.bind(this, type, method)) | ||
// // Run waterfall of typeMethods | ||
// return Utils.promiseWaterfall(typeMethods) | ||
// .then((result) => { | ||
// // If results are empty, don't log upload results. Hasn't run yet. | ||
// if (result[0] !== undefined) { | ||
// this.log(result) | ||
// this.log('Upload result -> success!') | ||
// return result | ||
// } | ||
// }) | ||
// .catch((error) => this.log('Upload result -> failed:', error)) | ||
// }) | ||
} | ||
@@ -355,0 +382,0 @@ |
@@ -0,1 +1,3 @@ | ||
import mime from 'mime-types' | ||
/** | ||
@@ -32,10 +34,41 @@ * A collection of small utility functions that help with dom manipulation, adding listeners, | ||
function isTouchDevice () { | ||
return 'ontouchstart' in window || // works on most browsers | ||
navigator.maxTouchPoints // works on IE10/11 and Surface | ||
}; | ||
/** | ||
* `querySelectorAll` that returns a normal array instead of fileList | ||
* Shorter and fast way to select multiple nodes in the DOM | ||
* @param { String|Array } selector - DOM selector or nodes list | ||
* @param { Object } ctx - DOM node where the targets of our search will is located | ||
* @returns { Object } dom nodes found | ||
*/ | ||
function qsa (selector, context) { | ||
return Array.prototype.slice.call((context || document).querySelectorAll(selector) || []) | ||
export function $$ (selector, ctx) { | ||
var els | ||
if (typeof selector === 'string') { | ||
els = (ctx || document).querySelectorAll(selector) | ||
} else { | ||
els = selector | ||
return Array.prototype.slice.call(els) | ||
} | ||
} | ||
/** | ||
* Shorter and fast way to select a single node in the DOM | ||
* @param { String } selector - unique dom selector | ||
* @param { Object } ctx - DOM node where the target of our search will is located | ||
* @returns { Object } dom node found | ||
*/ | ||
export function $ (selector, ctx) { | ||
return (ctx || document).querySelector(selector) | ||
} | ||
function truncateString (string, length) { | ||
if (string.length > length) { | ||
return string.substring(0, length) + '…' | ||
} | ||
return string | ||
} | ||
/** | ||
* Partition array by a grouping function. | ||
@@ -130,9 +163,12 @@ * @param {[type]} array Input array | ||
var img = new Image() | ||
img.onload = function () { | ||
return cb(img) | ||
} | ||
img.addEventListener('load', function () { | ||
return cb(null, img) | ||
}) | ||
img.addEventListener('error', function (err) { | ||
return cb(err) | ||
}) | ||
img.src = imgSrcBase64 | ||
}) | ||
reader.addEventListener('error', function (err) { | ||
console.log('FileReader error' + err) | ||
console.log('FileReader error ' + err) | ||
}) | ||
@@ -148,2 +184,17 @@ reader.readAsDataURL(imgObject) | ||
function getFileType (file) { | ||
if (file.type) { | ||
return file.type | ||
} | ||
return mime.lookup(file.name) | ||
} | ||
// returns [fileName, fileExt] | ||
function getFileNameAndExtension (fullFileName) { | ||
var re = /(?:\.([^.]+))?$/ | ||
var fileExt = re.exec(fullFileName)[1] | ||
var fileName = fullFileName.replace('.' + fileExt, '') | ||
return [fileName, fileExt] | ||
} | ||
/** | ||
@@ -168,2 +219,3 @@ * Resizes an image to specified width and height, using canvas | ||
// draw source image into the off-screen canvas: | ||
// ctx.clearRect(0, 0, width, height) | ||
ctx.drawImage(img, 0, 0, width, height) | ||
@@ -173,3 +225,3 @@ | ||
// canvas.toDataURL('image/jpeg', quality); // quality = [0.0, 1.0] | ||
return canvas.toDataURL() | ||
return canvas.toDataURL('image/png') | ||
} | ||
@@ -185,7 +237,12 @@ | ||
groupBy, | ||
qsa, | ||
$, | ||
$$, | ||
extend, | ||
readImage, | ||
resizeImage, | ||
getProportionalImageHeight | ||
getProportionalImageHeight, | ||
isTouchDevice, | ||
getFileNameAndExtension, | ||
truncateString, | ||
getFileType | ||
} |
// Parent | ||
import en_US from './en_US' | ||
import ru_RU from './ru_RU' | ||
import pt_BR from './pt_BR' | ||
import zh_CN from './zh_CN' | ||
module.exports = { | ||
en_US, | ||
ru_RU | ||
ru_RU, | ||
pt_BR, | ||
zh_CN | ||
} |
@@ -80,4 +80,2 @@ import Plugin from './Plugin' | ||
}) | ||
this.core.addMeta({bla: 'bla'}) | ||
} | ||
@@ -84,0 +82,0 @@ |
@@ -20,2 +20,3 @@ import Utils from '../core/Utils' | ||
// this.core.socket.on('') | ||
// Logic | ||
@@ -42,49 +43,2 @@ this.addFile = this.addFile.bind(this) | ||
this.opts = Object.assign({}, defaultOptions, opts) | ||
const host = this.opts.host.replace(/^https?:\/\//, '') | ||
this.socket = this.core.initSocket({ | ||
target: 'ws://' + host + '/' | ||
}) | ||
this.socket.on('google.auth.pass', () => { | ||
console.log('google.auth.pass') | ||
this.getFolder(this.core.getState().googleDrive.directory.id) | ||
}) | ||
this.socket.on('uppy.debug', (payload) => { | ||
console.log('GOOGLE DEBUG:') | ||
console.log(payload) | ||
}) | ||
this.socket.on('google.list.ok', (data) => { | ||
console.log('google.list.ok') | ||
let folders = [] | ||
let files = [] | ||
data.items.forEach((item) => { | ||
if (item.mimeType === 'application/vnd.google-apps.folder') { | ||
folders.push(item) | ||
} else { | ||
files.push(item) | ||
} | ||
}) | ||
this.updateState({ | ||
folders, | ||
files, | ||
authenticated: true | ||
}) | ||
}) | ||
this.socket.on('google.list.fail', (data) => { | ||
console.log('google.list.fail') | ||
console.log(data) | ||
}) | ||
this.socket.on('google.auth.fail', () => { | ||
console.log('google.auth.fail') | ||
this.updateState({ | ||
authenticated: false | ||
}) | ||
}) | ||
} | ||
@@ -251,10 +205,12 @@ | ||
const tagFile = { | ||
source: this, | ||
source: this.id, | ||
data: file, | ||
name: file.title, | ||
type: this.getFileType(file), | ||
type: file.mimeType, | ||
isRemote: true, | ||
remote: { | ||
action: 'google.get', | ||
payload: { | ||
id: file.id | ||
host: this.opts.host, | ||
url: `${this.opts.host}/google/get?fileId=${file.id}`, | ||
body: { | ||
fileId: file.id | ||
} | ||
@@ -261,0 +217,0 @@ } |
@@ -5,3 +5,3 @@ // Parent | ||
// Orchestrators | ||
import Modal from './modal' | ||
import Modal from './Modal' | ||
@@ -11,3 +11,2 @@ // Acquirers | ||
import DragDrop from './DragDrop' | ||
import Dropbox from './Dropbox' | ||
import Formtag from './Formtag' | ||
@@ -37,3 +36,2 @@ import GoogleDrive from './GoogleDrive' | ||
DragDrop, | ||
Dropbox, | ||
GoogleDrive, | ||
@@ -40,0 +38,0 @@ Formtag, |
@@ -36,2 +36,7 @@ import Plugin from './Plugin' | ||
Object.keys(file.meta).forEach((item) => { | ||
console.log(file.meta, file.meta[item]) | ||
formPost.append(file.meta, file.meta[item]) | ||
}) | ||
const xhr = new XMLHttpRequest() | ||
@@ -61,4 +66,6 @@ | ||
const resp = JSON.parse(xhr.response) | ||
file.uploadURL = resp[this.opts.responseUrlFieldName] | ||
const uploadURL = resp[this.opts.responseUrlFieldName] | ||
this.core.emitter.emit('upload-success', file.id, uploadURL) | ||
this.core.log(`Download ${file.name} from ${file.uploadURL}`) | ||
@@ -65,0 +72,0 @@ return resolve(file) |
@@ -25,3 +25,3 @@ import yo from 'yo-yo' | ||
update () { | ||
update (state) { | ||
if (typeof this.el === 'undefined') { | ||
@@ -31,3 +31,3 @@ return | ||
const newEl = this.render(this.core.state) | ||
const newEl = this.render(state) | ||
yo.update(this.el, newEl) | ||
@@ -34,0 +34,0 @@ } |
import Plugin from './Plugin' | ||
import tus from 'tus-js-client' | ||
import UppySocket from '../core/UppySocket' | ||
@@ -38,2 +39,3 @@ /** | ||
// TODO merge this.opts or this.opts.tus here | ||
metadata: file.meta, | ||
resume: false, | ||
@@ -54,4 +56,3 @@ endpoint: this.opts.endpoint, | ||
onSuccess: () => { | ||
file.uploadURL = upload.url | ||
this.core.emitter.emit('upload-success', file) | ||
this.core.emitter.emit('upload-success', file.id, upload.url) | ||
@@ -71,2 +72,57 @@ this.core.log(`Download ${upload.file.name} from ${upload.url}`) | ||
uploadRemote (file, current, total) { | ||
return new Promise((resolve, reject) => { | ||
console.log(file.remote.url) | ||
fetch(file.remote.url, { | ||
method: 'post', | ||
credentials: 'include', | ||
headers: { | ||
'Accept': 'application/json', | ||
'Content-Type': 'application/json' | ||
}, | ||
body: JSON.stringify(Object.assign({}, file.remote.body, { | ||
target: this.opts.endpoint, | ||
protocol: 'tus' | ||
})) | ||
}) | ||
.then((res) => { | ||
if (res.status < 200 && res.status > 300) { | ||
return reject(res.statusText) | ||
} | ||
res.json() | ||
.then((data) => { | ||
// get the host domain | ||
var regex = /^(?:https?:\/\/)?(?:[^@\/\n]+@)?(?:www\.)?([^:\/\n]+)/ | ||
var host = regex.exec(file.remote.host)[1] | ||
var token = data.token | ||
var socket = new UppySocket({ | ||
target: `ws://${host}:3121/api/${token}` | ||
}) | ||
socket.on('progress', (progressData) => { | ||
if (progressData.complete) { | ||
this.core.log(`Remote upload of '${file.name}' successful`) | ||
this.core.emitter.emit('upload-success', file) | ||
return resolve('Success') | ||
} | ||
if (progressData.progress) { | ||
this.core.log(`Upload progress: ${progressData.progress}`) | ||
// Dispatch progress event | ||
this.core.emitter.emit('upload-progress', { | ||
uploader: this, | ||
id: file.id, | ||
bytesUploaded: progressData.bytesUploaded, | ||
bytesTotal: progressData.bytesTotal | ||
}) | ||
} | ||
}) | ||
}) | ||
}) | ||
}) | ||
} | ||
uploadFiles (files) { | ||
@@ -81,3 +137,3 @@ const uploaders = [] | ||
} else { | ||
uploaders.push(this.upload(file, current, total)) | ||
uploaders.push(this.uploadRemote(file, current, total)) | ||
} | ||
@@ -93,23 +149,2 @@ }) | ||
uploadRemote (file, current, total) { | ||
return new Promise((resolve, reject) => { | ||
const payload = Object.assign({}, file.remote.payload, { | ||
target: this.opts.endpoint, | ||
protocol: 'tus' | ||
}) | ||
this.core.socket.send(file.remote.action, payload) | ||
this.core.socket.once('upload-success', () => { | ||
console.log('success') | ||
this.core.emitter.emit('upload-success', file) | ||
this.core.emitter.emit('upload-progress', { | ||
id: file.id, | ||
percentage: 100 | ||
}) | ||
resolve() | ||
}) | ||
}) | ||
} | ||
selectForUpload (files) { | ||
@@ -116,0 +151,0 @@ // TODO: replace files[file].isRemote with some logic |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
No README
QualityPackage does not have a README. This may indicate a failed publish or a low quality package.
Found 1 instance in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
564574
121
6367
0
74
8
44
14
8
+ Addeddeep-freeze-strict@1.1.1
+ Addedmime-types@2.1.11
+ Addeddeep-freeze-strict@1.1.1(transitive)
+ Addedes6-promise@3.2.1(transitive)
+ Addedmime-db@1.23.0(transitive)
+ Addedmime-types@2.1.11(transitive)
+ Addedtus-js-client@1.1.4(transitive)
+ Addedyo-yo@1.2.2(transitive)
- Removedes6-promise@3.1.2(transitive)
- Removedtus-js-client@1.1.3(transitive)
- Removedyo-yo@1.2.0(transitive)
Updatedes6-promise@3.2.1
Updatedpretty-bytes@3.0.1
Updatedtus-js-client@1.1.4
Updatedyo-yo@1.2.2