consistent behavior regarding file uploads

This commit is contained in:
Régis Hanol 2013-04-05 01:06:52 +02:00
parent 6aaa0ffe5e
commit 82bd92dd46
5 changed files with 109 additions and 58 deletions

View File

@ -9,17 +9,10 @@ Discourse.Utilities = {
translateSize: function(size) { translateSize: function(size) {
switch (size) { switch (size) {
case 'tiny': case 'tiny': return 20;
size = 20; case 'small': return 25;
break; case 'medium': return 32;
case 'small': case 'large': return 45;
size = 25;
break;
case 'medium':
size = 32;
break;
case 'large':
size = 45;
} }
return size; return size;
}, },
@ -163,6 +156,45 @@ Discourse.Utilities = {
range.moveStart('character', pos); range.moveStart('character', pos);
return range.select(); return range.select();
} }
},
/**
validateFilesForUpload
**/
/**
Validate a list of files to be uploaded
@method validateFilesForUpload
@param {Array} files The list of files we want to upload
**/
validateFilesForUpload: function(files) {
if (files) {
// can only upload one file at a time
if (files.length > 1) {
bootbox.alert(Em.String.i18n('post.errors.upload_too_many_images'));
return false;
} else if (files.length > 0) {
// check that the uploaded file is an image
// TODO: we should provide support for other types of file
if (files[0].type && files[0].type.indexOf('image/') !== 0) {
bootbox.alert(Em.String.i18n('post.errors.only_images_are_supported'));
return false;
}
// check file size
if (files[0].size && files[0].size > 0) {
var fileSizeInKB = files[0].size / 1024;
if (fileSizeInKB > Discourse.SiteSettings.max_upload_size_kb) {
bootbox.alert(Em.String.i18n('post.errors.upload_too_large', { max_size_kb: Discourse.SiteSettings.max_upload_size_kb }));
return false;
}
// everything is fine
return true;
}
}
}
// there has been an error
return false;
} }
}; };

View File

@ -276,43 +276,18 @@ Discourse.ComposerView = Discourse.View.extend({
formData: { topic_id: 1234 } formData: { topic_id: 1234 }
}); });
var addFiles = function (e, data) { // submit - this event is triggered for each upload
// can only upload one file at a time $uploadTarget.on('fileuploadsubmit', function (e, data) {
if (data.files.length > 1) { var result = Discourse.Utilities.validateFilesForUpload(data.files);
bootbox.alert(Em.String.i18n('post.errors.upload_too_many_images')); // reset upload status when everything is ok
return false; if (result) _this.setProperties({ uploadProgress: 0, loadingImage: true });
} else if (data.files.length > 0) { return result;
// check file size });
var fileSizeInKB = data.files[0].size / 1024;
if (fileSizeInKB > Discourse.SiteSettings.max_upload_size_kb) {
bootbox.alert(Em.String.i18n('post.errors.upload_too_large', { max_size_kb: Discourse.SiteSettings.max_upload_size_kb }));
return false;
}
// check that the uploaded file is an image
// TODO: we should provide support for other types of file
if (data.files[0].type.indexOf('image/') !== 0) {
bootbox.alert(Em.String.i18n('post.errors.only_images_are_supported'));
return false;
}
// everything is fine, reset upload status
_this.setProperties({
uploadProgress: 0,
loadingImage: true
});
return true;
}
// we need to return true here, otherwise it prevents the default paste behavior
return true;
};
// paste // send - this event is triggered when the upload request is about to start
$uploadTarget.on('fileuploadpaste', addFiles);
// drop
$uploadTarget.on('fileuploaddrop', addFiles);
// send
$uploadTarget.on('fileuploadsend', function (e, data) { $uploadTarget.on('fileuploadsend', function (e, data) {
// hide the "image selector" modal
$('#discourse-modal').modal('hide');
// cf. https://github.com/blueimp/jQuery-File-Upload/wiki/API#how-to-cancel-an-upload // cf. https://github.com/blueimp/jQuery-File-Upload/wiki/API#how-to-cancel-an-upload
var jqXHR = data.xhr(); var jqXHR = data.xhr();
// need to wait for the link to show up in the DOM // need to wait for the link to show up in the DOM

View File

@ -13,30 +13,27 @@ Discourse.ImageSelectorView = Discourse.View.extend({
init: function() { init: function() {
this._super(); this._super();
return this.set('localSelected', true); this.set('localSelected', true);
}, },
selectLocal: function() { selectLocal: function() {
return this.set('localSelected', true); this.set('localSelected', true);
}, },
selectRemote: function() { selectRemote: function() {
return this.set('localSelected', false); this.set('localSelected', false);
}, },
remoteSelected: (function() { remoteSelected: function() {
return !this.get('localSelected'); return !this.get('localSelected');
}).property('localSelected'), }.property('localSelected'),
upload: function() { upload: function() {
this.get('uploadTarget').fileupload('send', { fileInput: $('#filename-input') }); this.get('uploadTarget').fileupload('add', { fileInput: $('#filename-input') });
return $('#discourse-modal').modal('hide');
}, },
add: function() { add: function() {
this.get('composer').addMarkdown("![image](" + ($('#fileurl-input').val()) + ")"); this.get('composer').addMarkdown("![image](" + $('#fileurl-input').val() + ")");
return $('#discourse-modal').modal('hide'); $('#discourse-modal').modal('hide');
} }
}); });

View File

@ -1,4 +1,4 @@
/*global waitsFor:true expect:true describe:true beforeEach:true it:true */ /*global waitsFor:true expect:true describe:true beforeEach:true it:true spyOn:true */
describe("Discourse.Utilities", function() { describe("Discourse.Utilities", function() {
@ -30,4 +30,50 @@ describe("Discourse.Utilities", function() {
}); });
describe("validateFilesForUpload", function() {
it("returns false when file is undefined", function() {
expect(Discourse.Utilities.validateFilesForUpload(null)).toBe(false);
expect(Discourse.Utilities.validateFilesForUpload(undefined)).toBe(false);
});
it("returns false when file there is no file", function() {
expect(Discourse.Utilities.validateFilesForUpload([])).toBe(false);
});
it("supports only one file", function() {
spyOn(bootbox, 'alert');
spyOn(Em.String, 'i18n');
expect(Discourse.Utilities.validateFilesForUpload([1, 2])).toBe(false);
expect(bootbox.alert).toHaveBeenCalled();
expect(Em.String.i18n).toHaveBeenCalledWith('post.errors.upload_too_many_images');
});
it("supports only an image", function() {
var html = { type: "text/html" };
spyOn(bootbox, 'alert');
spyOn(Em.String, 'i18n');
expect(Discourse.Utilities.validateFilesForUpload([html])).toBe(false);
expect(bootbox.alert).toHaveBeenCalled();
expect(Em.String.i18n).toHaveBeenCalledWith('post.errors.only_images_are_supported');
});
it("prevents the upload of a too large image", function() {
var image = { type: "image/png", size: 10 * 1024 };
Discourse.SiteSettings.max_upload_size_kb = 5;
spyOn(bootbox, 'alert');
spyOn(Em.String, 'i18n');
expect(Discourse.Utilities.validateFilesForUpload([image])).toBe(false);
expect(bootbox.alert).toHaveBeenCalled();
expect(Em.String.i18n).toHaveBeenCalledWith('post.errors.upload_too_large', { max_size_kb: 5 });
});
it("works", function() {
var image = { type: "image/png", size: 10 * 1024 };
Discourse.SiteSettings.max_upload_size_kb = 15;
expect(Discourse.Utilities.validateFilesForUpload([image])).toBe(true);
});
});
}); });

View File

@ -18,6 +18,7 @@
// The rest of the externals // The rest of the externals
//= require_tree ../../app/assets/javascripts/external //= require_tree ../../app/assets/javascripts/external
//= require ../../app/assets/javascripts/locales/i18n
//= require ../../app/assets/javascripts/discourse/helpers/i18n_helpers //= require ../../app/assets/javascripts/discourse/helpers/i18n_helpers
//= require ../../app/assets/javascripts/discourse //= require ../../app/assets/javascripts/discourse