diff --git a/res/app/components/stf/install/index.js b/res/app/components/stf/install/index.js index 4f2e1b46..792f4425 100644 --- a/res/app/components/stf/install/index.js +++ b/res/app/components/stf/install/index.js @@ -2,3 +2,4 @@ module.exports = angular.module('stf.install-service', [ require('gettext').name ]) .filter('installError', require('./install-error-filter')) + .factory('InstallService', require('./install-service')) diff --git a/res/app/components/stf/install/install-service.js b/res/app/components/stf/install/install-service.js new file mode 100644 index 00000000..58aee780 --- /dev/null +++ b/res/app/components/stf/install/install-service.js @@ -0,0 +1,133 @@ +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 +} diff --git a/res/app/components/stf/screen/screen-controller.js b/res/app/components/stf/screen/screen-controller.js index 79478953..eab3cafc 100644 --- a/res/app/components/stf/screen/screen-controller.js +++ b/res/app/components/stf/screen/screen-controller.js @@ -1,4 +1,13 @@ -module.exports = function DeviceScreenCtrl($scope, $rootScope, ScalingService) { +module.exports = function DeviceScreenCtrl( + $scope +, $rootScope +, ScalingService +, InstallService +) { $scope.displayError = false $scope.ScalingService = ScalingService + + $scope.installFile = function ($files) { + return InstallService.installFile($scope.control, $files) + } } diff --git a/res/app/control-panes/dashboard/install/install-controller.js b/res/app/control-panes/dashboard/install/install-controller.js index 8332451a..bd45c76d 100644 --- a/res/app/control-panes/dashboard/install/install-controller.js +++ b/res/app/control-panes/dashboard/install/install-controller.js @@ -1,113 +1,25 @@ module.exports = function InstallCtrl( $scope -, $http -, $filter -, StorageService +, InstallService ) { - function Installation(progress, state) { - this.progress = progress - this.state = state - this.settled = false - this.success = false - this.error = null - this.href = null - this.manifest = null - this.launch = true - - this.update = function(progress, state) { - console.log('UPDATE', progress, state) - $scope.safeApply(function () { - this.progress = Math.floor(progress) - this.state = state - }.bind(this)) - } - - this.okay = function(state) { - console.log('OKAY', state) - $scope.safeApply(function () { - this.settled = true - this.progress = 100 - this.success = true - this.state = state - }.bind(this)) - } - - this.fail = function(err) { - console.log('FAIL', err, this) - $scope.safeApply(function () { - this.settled = true - this.progress = 100 - this.success = false - this.error = err - }.bind(this)) - } - } - - function install(installation) { - return $scope.control.install(installation) - .progressed(function (result) { - installation.update(50 + result.progress / 2, result.lastData) - }) - } - $scope.accordionOpen = true + $scope.installation = null $scope.clear = function () { $scope.installation = null $scope.accordionOpen = false } + $scope.$on('installation', function(e, installation) { + $scope.installation = installation.apply($scope) + }) + $scope.installUrl = function (url) { - var installation = $scope.installation = new Installation(0, 'uploading') - return $scope.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 install(installation) - }) - .then(function() { - installation.okay('installed') - }) - .catch(function(err) { - installation.fail(err.code || err.message) - }) + return InstallService.installUrl($scope.control, url) } $scope.installFile = function ($files) { - var installation = $scope.installation = new Installation(0, 'uploading') - 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 install(installation) - } - else { - throw new Error('Unable to retrieve manifest') - } - }) - }) - .then(function() { - installation.okay('installed') - }) - .catch(function(err) { - installation.fail(err.code || err.message) - }) + return InstallService.installFile($scope.control, $files) } $scope.uninstall = function (packageName) { diff --git a/res/app/control-panes/device-control/device-control.jade b/res/app/control-panes/device-control/device-control.jade index 25febaf9..4d49d435 100644 --- a/res/app/control-panes/device-control/device-control.jade +++ b/res/app/control-panes/device-control/device-control.jade @@ -35,8 +35,8 @@ span.pull-right(ng-click='kickDevice(groupDevice); $event.stopPropagation()').kick-device i.fa.fa-times - .as-row.fill-height(ng-file-drop='installFileForced($files)') - div(ng-controller='DeviceScreenCtrl').fill-height + .as-row.fill-height + div(ng-controller='DeviceScreenCtrl', ng-file-drop='installFile($files)', ng-file-drag-over-class='dragover').fill-height device-screen(style='width: 100%; height: 100%; background: gray') .stf-vnc-bottom.as-row