johnspackman/UploadMgr

Initiate upload when autoUpload disabled.

MakotoNinja opened this issue · 1 comments

I use an upload button as a child control and have a member function that runs on the addFile event.

The addFile member function does some checking of the file to meet file size and extension restrictions before calling uploader.getUploadHandler().beginUploads(). It is clear that the addFile event is executing when I add a file, but it appears the the upload handler's __queue is empty when beginUploads() executes.

So, adding one file does nothing, but adding a second file just afterwards ends up uploading both files, even when the multiple flag is set to false.

Here is a trace in the console after adding the first file:

016872 project.sections.user.Profile[362-0]: NAME: IcoNinja_b.jpg SIZE: 32291
016873 project.sections.user.Profile[362-0]: QUEUE: [  ]

So you can see that the addFile event is firing normally but the uploader's queue is an empty array; this may be why no uploads occur. However, upon the second (different) file added, I get:

024531 project.sections.user.Profile[362-0]: NAME: IcoNinja_p.png SIZE: 15785
024532 project.sections.user.Profile[362-0]: QUEUE: [ File[613-0] ]

And we can see the uploader's queue is length 1 (I'm guessing the previously added file) but the two files are in fact uploaded.

024544 com.zenesis.qx.upload.XhrHandler[389-0]: onprogress: lengthComputable=true, total=32748, loaded=32748, headerLength=374
024564 com.zenesis.qx.upload.XhrHandler[389-0]: onprogress: lengthComputable=true, total=16241, loaded=16241, headerLength=374

Child control code:

_createChildControlImpl : function(id)
{
    var control;
    var btnMinMax = 160;
    var imgMinMax = 150;

    switch(id)
    {
        case 'profileBtn' :
            control = new com.zenesis.qx.upload.UploadButton;
            control.set({
                minWidth : btnMinMax,
                maxWidth : btnMinMax,
                minHeight : btnMinMax,
                maxHeight : btnMinMax,
                padding : 5,
                acceptUpload : '.jpg,.png,.gif'
            });
            var img = control.getChildControl('icon');
            img.set({
                minWidth : imgMinMax,
                maxWidth : imgMinMax,
                minHeight : imgMinMax,
                maxHeight : imgMinMax,
                scale : true
            });
            this.add(control);
            this.__uploader = new com.zenesis.qx.upload.UploadMgr(control, "/uploads");
            this.__uploader.set({
                autoUpload : false,
                multiple : false
            });
            this.__uploader.addListener('addFile', this.__addFile, this);
        break;
    }
    return control || this.base(arguments, id);
}

The member function that runs on the addFile event

__addFile : function(e)
{
    var file = e.getData();
    var fileName = file.getFilename();
    var fileSize = file.getSize();

    var ext = fileName.split('.').pop().toLowerCase();
    if(!qx.lang.Array.contains(['jpg', 'jpeg', 'png', 'gif'], ext))
    {
        project.Alert.getInstance().setMessage('Invalid file format!</br>Must be of type JPEG, PNG or GIF.');
        this.__uploader.getUploadHandler().cancelAll();
        //this.info('UPLOADER:', this.__uploader.getUploadHandler().__queue);
        return;
    }
    if(fileSize > 2000000) // 2 MB
    {
        project.Alert.getInstance().setMessage('File too large!</br>Must be 1 MB or smaller.');
        this.__uploader.getUploadHandler().cancelAll();
        //this.info('UPLOADER:', this.__uploader.getUploadHandler().__queue);
        return;
    }
    this.info('NAME:', fileName, 'SIZE:', fileSize);
    this.info('QUEUE:', this.__uploader.getUploadHandler().__queue);

    this.__uploader.setParam("fileName", fileName);
    this.__uploader.setParam("sessionId", project.Model.getInstance().getSessionInfo().SESSION_ID);
    this.__uploader.getUploadHandler().beginUploads();
    var stateListener = file.addListener("changeState", function(evt) {
        var state = evt.getData();
        var file = evt.getTarget();
        if(state == 'uploaded')
        {
            var btn = this.getChildControl('profileBtn');
            btn.setIcon('/uploads/user/' + file.getResponse() + '?nocache=' + Math.random());
        }

        // Remove the listeners
        if (state == 'uploaded' || state == 'cancelled')
        {
            file.removeListenerById(stateListener);
        }
    }, this);
}

Looks like I may have found the culprit.
On line 115 in AbstractHandler.js we have the addFile method:

/**
 * Adds a file to the outbound queue
 * 
 * @param file
 *          {com.zenesis.qx.upload.File} the file to add
 */
_addFile: function(file) {
  if (this.__uploader.fireDataEvent("addFile", file, null, true))
	this.__queue.push(file);
},

It looks to me like the the addFile event is being fired before the file is added to the queue.
I've changed it to the following and it seems to be working fine:

/**
 * Adds a file to the outbound queue
 * 
 * @param file
 *          {com.zenesis.qx.upload.File} the file to add
 */
/*_addFile: function(file) {
  if (this.__uploader.fireDataEvent("addFile", file, null, true))
	this.__queue.push(file);
},*/
_addFile: function(file) {
    this.__queue.push(file)
    this.__uploader.fireDataEvent("addFile", file, null, true);
},