Browse Source

Refactor asset uploading

pull/261/head
Artur Arseniev 9 years ago
parent
commit
df5729aa89
  1. 19
      src/asset_manager/config/config.js
  2. 93
      src/asset_manager/view/FileUploader.js
  3. 31
      src/editor/index.js
  4. 2
      src/utils/fetch.js

19
src/asset_manager/config/config.js

@ -8,6 +8,25 @@ module.exports = {
// Url where uploads will be send, set false to disable upload // Url where uploads will be send, set false to disable upload
upload: 'http://localhost/assets/upload', upload: 'http://localhost/assets/upload',
// Custom headers to pass with the upload request
headers: {},
// Custom parameters to pass with the upload request, eg. csrf token
params: {},
// If true, tries to add automatically uploaded assets.
// To make it work the server should respond with a JSON containing assets
// in a data key, eg:
// {
// data: [
// 'https://.../image.png',
// ...
// {src: 'https://.../image2.png'},
// ...
// ]
// }
autoAdd: 1,
// Text on upload input // Text on upload input
uploadText: 'Drop files here or click to upload', uploadText: 'Drop files here or click to upload',

93
src/asset_manager/view/FileUploader.js

@ -1,15 +1,14 @@
var Backbone = require('backbone'); import fetch from 'utils/fetch';
var fileUploaderTemplate = `
<form>
<div id="<%= pfx %>title"><%= title %></div>
<input type="file" id="<%= uploadId %>" name="file" accept="image/*" <%= disabled ? 'disabled' : '' %> multiple/>
<div style="clear:both;"></div>
</form>
`;
module.exports = Backbone.View.extend({ module.exports = Backbone.View.extend({
template: _.template(fileUploaderTemplate), template: _.template(`
<form>
<div id="<%= pfx %>title"><%= title %></div>
<input type="file" id="<%= uploadId %>" name="file" accept="image/*" <%= disabled ? 'disabled' : '' %> multiple/>
<div style="clear:both;"></div>
</form>
`),
events: {}, events: {},
@ -32,18 +31,79 @@ module.exports = Backbone.View.extend({
this.delegateEvents(); this.delegateEvents();
}, },
onUploadStart() {
const em = this.config.em;
em && em.trigger('asset:upload:start');
},
onUploadEnd() {
const em = this.config.em;
em && em.trigger('asset:upload:end');
},
onUploadError(err) {
console.error(err);
this.onUploadEnd(err);
},
onUploadResponse(res) {
const em = this.config.em;
const config = this.config;
const target = this.target;
em && em.trigger('asset:upload:response', res);
if (config.autoAdd && target) {
if ((req.status/200|0) == 1) {
const json = JSON.parse(req.responseText);
target.add(json.data);
} else {
onUploadError(res);
return;
}
}
this.onUploadEnd(res);
},
/** /**
* Upload files * Upload files
* @param {Object} e Event * @param {Object} e Event
* @return {Promise}
* @private * @private
* */ * */
uploadFile(e) { uploadFile(e) {
var files = e.dataTransfer ? e.dataTransfer.files : e.target.files, const files = e.dataTransfer ? e.dataTransfer.files : e.target.files;
formData = new FormData(); const formData = new FormData();
for (var i = 0; i < files.length; i++) { const config = this.config;
formData.append('files[]', files[i]); const params = config.params;
}
for (let i = 0; i < files.length; i++) {
formData.append('files[]', files[i]);
}
for (let param in params) {
formData.append(param, params[param]);
}
var target = this.target; var target = this.target;
const url = config.upload;
if (url) {
this.onUploadStart();
return fetch(url, {
method: 'post',
credentials: 'include',
headers: config.headers,
body: formData,
}).then(this.onUploadResponse)
.catch(this.onUploadError);
}
//onStart upload:start
//onEnd upload:end
//onResponse upload:response
//autoAdd
/*
$.ajax({ $.ajax({
url : this.config.upload, url : this.config.upload,
type : 'POST', type : 'POST',
@ -53,7 +113,7 @@ module.exports = Backbone.View.extend({
xhrFields : { xhrFields : {
onprogress(e) { onprogress(e) {
if (e.lengthComputable) { if (e.lengthComputable) {
/*var result = e.loaded / e.total * 100 + '%';*/ var result = e.loaded / e.total * 100 + '%';
} }
}, },
onload(e) { onload(e) {
@ -66,6 +126,8 @@ module.exports = Backbone.View.extend({
}).always(() => { }).always(() => {
//turnOff loading //turnOff loading
}); });
*/
}, },
/** /**
@ -124,6 +186,7 @@ module.exports = Backbone.View.extend({
const onDrop = (e) => { const onDrop = (e) => {
cleanEditorElCls(); cleanEditorElCls();
e.preventDefault(); e.preventDefault();
e.stopPropagation();
this.uploadFile(e); this.uploadFile(e);
if (c.openAssetsOnDrop && editor) { if (c.openAssetsOnDrop && editor) {

31
src/editor/index.js

@ -32,20 +32,23 @@
* ``` * ```
* *
* **Available Events** * **Available Events**
* `component:add` - Triggered when a new component is added to the editor, the model is passed as an argument to the callback * * `component:add` - Triggered when a new component is added to the editor, the model is passed as an argument to the callback
* `component:update` - Triggered when a component is, generally, updated (moved, styled, etc.) * * `component:update` - Triggered when a component is, generally, updated (moved, styled, etc.)
* `component:update:{propertyName}` - Listen any property change * * `component:update:{propertyName}` - Listen any property change
* `component:styleUpdate` - Triggered when the style of the component is updated * * `component:styleUpdate` - Triggered when the style of the component is updated
* `component:styleUpdate:{propertyName}` - Listen for a specific style property change * * `component:styleUpdate:{propertyName}` - Listen for a specific style property change
* `styleManager:change` - Triggered on style property change from new selected component, the view of the property is passed as an argument to the callback * * `asset:upload:start` - Before the upload is started
* `styleManager:change:{propertyName}` - As above but for a specific style property * * `asset:upload:end` - After the upload is ended
* `storage:load` - Triggered when something was loaded from the storage, loaded object passed as an argumnet * * `asset:upload:response` - On upload response, passes a response object as the argument
* `storage:store` - Triggered when something is stored to the storage, stored object passed as an argumnet * * `styleManager:change` - Triggered on style property change from new selected component, the view of the property is passed as an argument to the callback
* `selector:add` - Triggers when a new selector/class is created * * `styleManager:change:{propertyName}` - As above but for a specific style property
* `canvasScroll` - Triggered when the canvas is scrolled * * `storage:load` - Triggered when something was loaded from the storage, loaded object passed as an argumnet
* `run:{commandName}` - Triggered when some command is called to run (eg. editor.runCommand('preview')) * * `storage:store` - Triggered when something is stored to the storage, stored object passed as an argumnet
* `stop:{commandName}` - Triggered when some command is called to stop (eg. editor.stopCommand('preview')) * * `selector:add` - Triggers when a new selector/class is created
* `load` - When the editor is loaded * * `canvasScroll` - Triggered when the canvas is scrolled
* * `run:{commandName}` - Triggered when some command is called to run (eg. editor.runCommand('preview'))
* * `stop:{commandName}` - Triggered when some command is called to stop (eg. editor.stopCommand('preview'))
* * `load` - When the editor is loaded
* *
* @module Editor * @module Editor
* @param {Object} config Configurations * @param {Object} config Configurations

2
src/utils/fetch.js

@ -12,7 +12,7 @@ export default typeof fetch == 'function' ? fetch.bind() : (url, options) => {
req.setRequestHeader(k, options.headers[k]); req.setRequestHeader(k, options.headers[k]);
} }
req.onload = e => res(e.target.responseText, req); req.onload = e => res(req);
req.onerror = rej; req.onerror = rej;
// Actually, fetch doesn't support onProgress feature // Actually, fetch doesn't support onProgress feature

Loading…
Cancel
Save