/** * Base class for uploads and transfers. * * @private */Ext.define("Ext.space.files.Transfer", { /** * Object reference to the transfer management object for this item. * @private */ manager: null, /** * Internal promise that tracks transfer completion * @type {Ext.space.Promise} * @private */ done: null, /** * Internal event handlers * @type {Object} * @private */ events: null, /** * Field name for the internal identifier for this transfer * @type {String} */ idField: null, /** * File key for the saved file * @type {Number} */ fileKey: null, /** * Source/Destination URL * @type {String} */ url: null, /** * Progress so far * @type {Number} */ bytesTransferred: 0, /** * Final size * @type {Number} */ totalBytes: 0, /** * transfer status * @type {Boolean} */ isComplete: false, /** * Transfer status, that lags behind isComplete (so we can check to see if the * Transfer just finished, or has been complete for a little while) * @type {Boolean} * @private */ everCompleted: false, /** * When the transfer initiated * @type {Date} */ dateStarted: null, /** * @private */ constructor: function(args) { this.done = new Ext.space.Promise(); this.events = { progress: new Ext.space.Observable() }; this._updateWith(args); }, /** * Create handlers for transfer completion and/or error. * * @param {Function} onsuccess (optional) Callback invoked when the transfer is * completed. Receives two parameters: the file on * disk, and the transfer object (the Upload or * Download) itself. * @param {Function} onerror (optional) Callback invoked when the transfer is * canceled or errors out for some reason. * @return {Ext.space.Promise} Promise that resolves after the transfer itself is * resolved and the onsuccess/onerror callback is fired * (as in regular promise chaining). */ then: function(onsuccess, onerror) { return this.done.then(onsuccess, onerror); }, /** * Check this transfer's progress. * * @return {Ext.space.Promise} Promise which will fulfill when progress is fetched and * updated into this object (and which is resolved with this * transfer as a parameter too). */ getProgress: function() { return this.manager ? this.manager.getProgress(this) : null; }, /** * Cancel this transfer. * * @return {Ext.space.Promise} Promise which will fulfills when the transfer is * successfully canceled. If the transfer is already done, * the promise will reject. */ cancel: function() { return this.manager ? this.manager.cancel(this) : null; }, /** * Bulk update this transfer with the data provided. * * @private * @param {Object} source Object with data to overwrite onto this transfer */ _updateWith: function(source) { if (source) { if (source[this.idField]) { this[this.idField] = source[this.idField]; } if (source.fileKey) { this.fileKey = source.fileKey; } if (source.url) { this.url = source.url; } if (source[this.bytesTransferredField]) { this[this.bytesTransferredField] = source[this.bytesTransferredField]; } if (source.totalBytes) { this.totalBytes = source.totalBytes; } if (source.isComplete) { this.isComplete = true; } if (source.dateStarted) { this.dateStarted = new Date(source.dateStarted * 1000); } // fire a progress event if we have sufficient data and we're not done if (this[this.idField] && !this.everCompleted) { this.events.progress.invokeListeners(this); this.everCompleted = this.isComplete; } } return this; }, /** * Wire up event listeners for the transfer. * * There is currently only one event applications can listen for: 'progress', * which means something has been updated. * * @param {String} event Event name to listen for (start, progress) * @param {Function} callback Callback to invoke when the event fires * @return {Object} The download object, to facilitate method chaining */ on: function(event, callback) { var events = this.events; // only register events we support; otherwise just silently swallow it if (events[event]) { events[event].addListener(callback); } return this; }});