Upload.js 8.14 KB
define(function(require) {
    'use strict';

    var $ = require('jquery');
    var Backbone = require('backbone');
    var Flow = require('flow');
    var api = require('api');

    var Status = Backbone.Model.extend({
        defaults: function() {
            return {
                result: 'pending',
                resultData: null,
                sent: null,
                completion: null,
                total: null,
            };
        },
    });
    var Upload = Backbone.Model.extend({
        defaults: function() {
            return {
                name: null,
                status: new Status(),
                date: null,
                size: null,
            };
        },
        initialize: function() {
            Upload.__super__.initialize.apply(this, arguments);
            _.each(['retry', 'pause', 'resume', 'cancel'], function(methodName) {
                this[methodName] = _.bind(function(e) {
                    if (e) {
                        e.preventDefault();
                    }
                    var flowFile = this.flowFile;
                    if (flowFile) {
                        flowFile[methodName].call(flowFile);
                    }
                    if (flowFile.paused) {
                        this.get('status').set({
                            result: 'paused',
                            resultData: null,
                        });
                    }
                    return false;
                }, this);
            }, this);
        },
        parse: function(data, options) {
            data = _.extend({}, data);
            var status = data.status;
            if (!(status instanceof Backbone.Model)) {
                data.status = new Status(status);
            }
            return data;
        },
    });
    var Uploads = Backbone.Collection.extend({
        model: Upload,
        initialize: function initialize(data, options) {
            Uploads.__super__.initialize.apply(this, arguments);
        },
    });

    function makeFallbackFlowEventHandler(eventName) {
        return function() {
            console.log('flow.' + eventName, arguments);
        };
    }

    _.extend(Upload, {
        Uploads: Uploads,
        Status: Status,
        flowEventHandlers: {
            uploadStart: function() {
                if (this.model.get('handlers') && this.model.get('handlers').uploadStart !== undefined) {
                    this.model.get('handlers').uploadStart();
                }
            },
            fileAdded: function(flowFile) {
                var model = flowFile._model;
                if (!model) {
                    model = flowFile._model = new Upload({
                        name: flowFile.name,
                        size: flowFile.size,
                        startDate: new Date(),
                    });
                    model.flowFile = flowFile;
                    this.model.get('collection').add(model);
                }

                if (this.model.get('handlers') && this.model.get('handlers').fileAdded !== undefined) {
                    this.model.get('handlers').fileAdded(flowFile);
                }
                return true;
            },
            filesAdded: function() {
                return true;
            },
            filesSubmitted: function() {
                // this.flow.upload();
            },
            fileProgress: function(flowFile) {
                var model = flowFile._model;
                if (model) {
                    model.get('status').set({
                        result: 'uploading',
                        resultData: null,
                        completion: Math.floor(flowFile.progress() * 100),
                        size: flowFile.sizeUploaded(),
                    });
                }
            },
            fileSuccess: function(flowFile, message, chunk) {
                var model = flowFile._model;
                if (model) {
                    model.get('status').set({
                        result: 'success',
                        resultData: message,
                    });

                    console.log('UPLOAD COMPLETE', flowFile.flowObj.ownerContent);
                    flowFile.flowObj.ownerContent.set('statusId', 'CTNT_AVAILABLE');
                    flowFile.flowObj.ownerContent.save(function() {
                        console.log('MARKED', flowFile.flowObj.ownerContent, ' AVAILABLE');
                        if (this.model.get('handlers') && this.model.get('handlers').fileSuccess !== undefined) {
                            this.model.get('handlers').fileSuccess(flowFile);
                        }
                    });
                }
            },
            fileError: function(flowFile, message, chunk) {
                var model = flowFile._model;
                if (model) {
                    model.get('status').set({
                        result: 'error',
                        resultData: message,
                    });
                }
            },
            fileRemoved: function(flowFile) {
                var model = flowFile._model;
                if (model) {
                    this.model.get('collection').remove(model);
                }
            },
        },
        rivetsComponent: {
            static: [
                'accept',
                'allowDuplicateUploads',
                'maxChunkRetries',
                'maxFilesize',
                'prioritizeFirstAndLastChunk',
                'simultaneousUploads',
            ],
            template: function() {
                return this.el.innerHTML;
            },
            initialize: function initialize(el, locals) {
                var instance = {el: el};
                var model = instance.model = new Backbone.Model(locals);
                _.each(this.observers, function(observer, key) {
                    sightglass(observer.obj, observer.keypath, function() {
                        model.set(key, observer.value());
                    }, observer.options);
                });
                var flow = instance.flow = new Flow({
                    target: _.bind(function(flowFile, flowChunk, isTest) {
                        var model = this.model;
                        var target = model.get('target');
                        var sessionId = model.get('sessionId');
                        if (target) {
                            if (target.indexOf('?') !== -1) {
                                target += '&';
                            } else {
                                target += '?';
                            }
                        } else {
                            target = '?';
                        }
                        return target + 'sessionId=' + sessionId;
                    }, instance),
                    allowDuplicateUploads: locals.allowDuplicateUploads,
                    maxChunkRetries: locals.maxChunkRetries,
                    maxFilesize: locals.maxFilesize,
                    prioritizeFirstAndLastChunk: locals.prioritizeFirstAndLastChunk,
                    simultaneousUploads: locals.simultaneousUploads,
                });
                _.each([
                    'fileSuccess',
                    'fileProgress',
                    'fileAdded',
                    'filesAdded',
                    'filesSubmitted',
                    'fileRemoved',
                    'fileRetry',
                    'fileError',
                    'uploadStart',
                    'complete',
                    //'progress',
                    //'error',
                ], function(eventName) {
                    var eventHandler = Upload.flowEventHandlers[eventName] || makeFallbackFlowEventHandler(eventName);
                    flow.on(eventName, _.bind(eventHandler, instance));
                });
                var assignOptions = {};
                if (locals.accept) {
                    assignOptions.accept = locals.accept;
                }
                flow.assignBrowse(el, false, false, assignOptions);
                flow.assignDrop(el);
                instance.view = rivets.bind($(el).contents(), this.view.models);
                return {};
            },
        },
    });

    return Upload;
});