Home Reference Source Repository

js/Managers/TransferManager.js

import Backbone from 'backbone';
import Radio from 'backbone.radio';
import RODAN_EVENTS from 'js/Shared/RODAN_EVENTS';

/**
 * File transfer manager. This manages all file (i.e. Resource) uploads and downloads.
 */
export default class TransferManager
{
///////////////////////////////////////////////////////////////////////////////////////
// PUBLIC METHODS
///////////////////////////////////////////////////////////////////////////////////////
    /**
     * Constructor.
     */
    constructor()
    {
        this._initializeRadio();
        this._uploadsPending = new Backbone.Collection();
        this._uploadsFailed = new Backbone.Collection();
        this._uploadsCompleted = new Backbone.Collection();
    }

///////////////////////////////////////////////////////////////////////////////////////
// PRIVATE METHODS
///////////////////////////////////////////////////////////////////////////////////////
    /**
     * Initialize Radio.
     */
    _initializeRadio()
    {
        Radio.channel('rodan').reply(RODAN_EVENTS.REQUEST__TRANSFERMANAGER_DOWNLOAD, options => this._handleRequestDownload(options));
        Radio.channel('rodan').reply(RODAN_EVENTS.REQUEST__TRANSFERMANAGER_GET_UPLOAD_COUNT, () => this._handleRequestGetUploadCount());
        Radio.channel('rodan').reply(RODAN_EVENTS.REQUEST__TRANSFERMANAGER_MONITOR_UPLOAD, options => this._handleRequestMonitorUpload(options));
    }

    /**
     * Handle download request.
     */
    _handleRequestDownload(options)
    {
        var request = new XMLHttpRequest();
        request.open('GET', options.url, true);
        request.responseType = 'blob';
        request.onreadystatechange = (event) => this._handleStateChange(event, options.filename, options.mimetype);
        request.onprogress = (event) => this._handleDownloadProgress(event);
        request.send();
    }

    /**
     * Return upload count.
     */
    _handleRequestGetUploadCount()
    {
        return {pending: this._uploadsPending.length, completed: this._uploadsCompleted.length, failed: this._uploadsFailed.length};
    }

    /**
     * Handle request monitor upload.
     */
    _handleRequestMonitorUpload(options)
    {
        var request = options.request;
        request.id = this._getRandomId();
        options.id = request.id;
        this._uploadsPending.add(options);
        request.done((response, code, jqXHR) => this._handleUploadSuccess(response, code, jqXHR));
        request.fail((jqXHR, code, error) => this._handleUploadFail(jqXHR, code, error));
    }

    /**
     * Handle upload success.
     */
    _handleUploadSuccess(response, code, jqXHR)
    {
        var upload = this._uploadsPending.remove(jqXHR.id);
        this._uploadsCompleted.add(upload);
        Radio.channel('rodan').trigger(RODAN_EVENTS.EVENT__TRANSFERMANAGER_UPLOAD_SUCCEEDED, {request: upload.jqXHR, file: upload.file});
    }

    /**
     * Handle upload fail.
     */
    _handleUploadFail(jqXHR, code, error)
    {
        var upload = this._uploadsPending.remove(jqXHR.id);
        this._uploadsFailed.add(upload);
        Radio.channel('rodan').trigger(RODAN_EVENTS.EVENT__TRANSFERMANAGER_UPLOAD_FAILED, {request: upload.jqXHR, file: upload.file});
    }

    /**
     * Handle request state change.
     */
    _handleStateChange(request, filename, mimetype)
    {
        var request = event.currentTarget;
        switch (request.readyState)
        {
            case 0: //UNSENT
            {
                break;
            }

            case 1: //OPENED
            {
                break;
            }

            case 2: //HEADERS_RECEIVED
            {
                break;
            }

            case 3: //LOADING
            {
                break;
            }

            case 4:
            {
                Radio.channel('rodan').request(RODAN_EVENTS.REQUEST__DOWNLOAD_START, {data: request.response, filename: filename, mimetype: mimetype});
                break;
            }

            default:
            {
                break;
            }
        }
    }

    /**
     * Handle download progress.
     */
    _handleDownloadProgress(event)
    {
    }

    /**
     * Returns random 8-digit ID.
     */
    _getRandomId()
    {
        return Math.floor((1 + Math.random()) * 10000000);
    }
}