var EventEmitter = require('eventemitter3') var Promise = require('bluebird') Promise.longStackTraces() module.exports = function InstallService( $rootScope , $http , $filter , StorageService ) { var installService = Object.create(null) function Installation(state) { this.progress = 0 this.state = state this.settled = false this.success = false this.error = null this.href = null this.manifest = null this.launch = true } Installation.prototype = Object.create(EventEmitter.prototype) Installation.prototype.constructor = Installation Installation.prototype.apply = function($scope) { function changeListener() { $scope.safeApply() } this.on('change', changeListener) $scope.$on('$destroy', function() { this.removeListener('change', changeListener) }.bind(this)) return this } Installation.prototype.update = function(progress, state) { this.progress = Math.floor(progress) this.state = state this.emit('change') } Installation.prototype.okay = function(state) { this.settled = true this.progress = 100 this.success = true this.state = state this.emit('change') } Installation.prototype.fail = function(err) { this.settled = true this.progress = 100 this.success = false this.error = err this.emit('change') } installService.installUrl = function (control, url) { var installation = new Installation('downloading') $rootScope.$broadcast('installation', installation) return control.uploadUrl(url) .progressed(function (uploadResult) { installation.update(uploadResult.progress / 2, uploadResult.lastData) }) .then(function (uploadResult) { installation.update(uploadResult.progress / 2, uploadResult.lastData) installation.manifest = uploadResult.body return control.install({ href: installation.href , manifest: installation.manifest , launch: installation.launch }) .progressed(function (result) { installation.update(50 + result.progress / 2, result.lastData) }) }) .then(function() { installation.okay('installed') }) .catch(function(err) { installation.fail(err.code || err.message) }) } installService.installFile = function (control, $files) { var installation = new Installation('uploading') $rootScope.$broadcast('installation', installation) return StorageService.storeFile('apk', $files, { filter: function(file) { return /\.apk$/i.test(file.name) } }) .progressed(function(e) { if (e.lengthComputable) { installation.update(e.loaded / e.total * 100 / 2, 'uploading') } }) .then(function(res) { installation.update(100 / 2, 'processing') installation.href = res.data.resources.file.href return $http.get(installation.href + '/manifest') .then(function(res) { if (res.data.success) { installation.manifest = res.data.manifest return control.install({ href: installation.href , manifest: installation.manifest , launch: installation.launch }) .progressed(function (result) { installation.update(50 + result.progress / 2, result.lastData) }) } else { throw new Error('Unable to retrieve manifest') } }) }) .then(function() { installation.okay('installed') }) .catch(function(err) { installation.fail(err.code || err.message) }) } return installService }