diff --git a/lib/gui/components/drive-selector/drive-selector.js b/lib/gui/components/drive-selector/drive-selector.js index 873d40ef..37b73600 100644 --- a/lib/gui/components/drive-selector/drive-selector.js +++ b/lib/gui/components/drive-selector/drive-selector.js @@ -23,7 +23,7 @@ const angular = require('angular'); const MODULE_NAME = 'Etcher.Components.DriveSelector'; const DriveSelector = angular.module(MODULE_NAME, [ - require('angular-ui-bootstrap'), + require('../modal/modal'), require('../../models/drives'), require('../../models/selection-state'), require('../../utils/byte-size/byte-size') diff --git a/lib/gui/components/drive-selector/services/drive-selector.js b/lib/gui/components/drive-selector/services/drive-selector.js index f371f0a7..ed65ecf2 100644 --- a/lib/gui/components/drive-selector/services/drive-selector.js +++ b/lib/gui/components/drive-selector/services/drive-selector.js @@ -16,7 +16,7 @@ 'use strict'; -module.exports = function($uibModal, $q) { +module.exports = function(ModalService, $q) { let modal = null; @@ -34,11 +34,9 @@ module.exports = function($uibModal, $q) { * }); */ this.open = () => { - modal = $uibModal.open({ - animation: true, - templateUrl: './components/drive-selector/templates/drive-selector-modal.tpl.html', - controller: 'DriveSelectorController as modal', - size: 'sm' + modal = ModalService.open({ + template: './components/drive-selector/templates/drive-selector-modal.tpl.html', + controller: 'DriveSelectorController as modal' }); return modal.result; diff --git a/lib/gui/components/modal/modal.js b/lib/gui/components/modal/modal.js new file mode 100644 index 00000000..f05af557 --- /dev/null +++ b/lib/gui/components/modal/modal.js @@ -0,0 +1,31 @@ +/* + * Copyright 2016 Resin.io + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +'use strict'; + +/** + * @module Etcher.Components.Modal + */ + +const angular = require('angular'); +const MODULE_NAME = 'Etcher.Components.Modal'; +const Modal = angular.module(MODULE_NAME, [ + require('angular-ui-bootstrap') +]); + +Modal.service('ModalService', require('./services/modal')); + +module.exports = MODULE_NAME; diff --git a/lib/gui/components/modal/services/modal.js b/lib/gui/components/modal/services/modal.js new file mode 100644 index 00000000..5192b6f0 --- /dev/null +++ b/lib/gui/components/modal/services/modal.js @@ -0,0 +1,74 @@ +/* + * Copyright 2016 Resin.io + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +'use strict'; + +const _ = require('lodash'); + +module.exports = function($uibModal, $q) { + + /** + * @summary Open a modal + * @function + * @public + * + * @param {Object} options - options + * @param {String} options.template - template path + * @param {String} options.controller - controller + * @param {String} [options.size='sm'] - modal size + * @param {Object} options.resolve - modal resolves + * @returns {Object} modal + * + * @example + * ModalService.open({ + * template: './path/to/modal.tpl.html', + * controller: 'DriveSelectorController as modal', + * }); + */ + this.open = (options = {}) => { + + _.defaults(options, { + size: 'sm' + }); + + const modal = $uibModal.open({ + animation: true, + templateUrl: options.template, + controller: options.controller, + size: options.size, + resolve: options.resolve + }); + + return { + close: modal.close, + result: $q((resolve, reject) => { + modal.result + .then(resolve) + .catch((error) => { + + // For some annoying reason, UI Bootstrap Modal rejects + // the result reason if the user clicks on the backdrop + // (e.g: the area surrounding the modal). + if (error !== 'backdrop click') { + return reject(error); + } + + }); + }) + }; + }; + +}; diff --git a/lib/gui/components/tooltip-modal/services/tooltip-modal.js b/lib/gui/components/tooltip-modal/services/tooltip-modal.js index 5bdb080b..b92c80c2 100644 --- a/lib/gui/components/tooltip-modal/services/tooltip-modal.js +++ b/lib/gui/components/tooltip-modal/services/tooltip-modal.js @@ -18,7 +18,7 @@ const _ = require('lodash'); -module.exports = function($uibModal) { +module.exports = function(ModalService) { /** * @summary Open the tooltip modal @@ -37,9 +37,8 @@ module.exports = function($uibModal) { * }); */ this.show = (options) => { - return $uibModal.open({ - animation: true, - templateUrl: './components/tooltip-modal/templates/tooltip-modal.tpl.html', + return ModalService.open({ + template: './components/tooltip-modal/templates/tooltip-modal.tpl.html', controller: 'TooltipModalController as modal', size: 'tooltip-modal', resolve: { diff --git a/lib/gui/components/tooltip-modal/tooltip-modal.js b/lib/gui/components/tooltip-modal/tooltip-modal.js index a0c0e36f..9be5da53 100644 --- a/lib/gui/components/tooltip-modal/tooltip-modal.js +++ b/lib/gui/components/tooltip-modal/tooltip-modal.js @@ -23,7 +23,7 @@ const angular = require('angular'); const MODULE_NAME = 'Etcher.Components.TooltipModal'; const TooltipModal = angular.module(MODULE_NAME, [ - require('angular-ui-bootstrap') + require('../modal/modal') ]); TooltipModal.controller('TooltipModalController', require('./controllers/tooltip-modal')); diff --git a/lib/gui/components/update-notifier/services/update-notifier.js b/lib/gui/components/update-notifier/services/update-notifier.js index a71f2af7..652d904a 100644 --- a/lib/gui/components/update-notifier/services/update-notifier.js +++ b/lib/gui/components/update-notifier/services/update-notifier.js @@ -19,7 +19,7 @@ const semver = require('semver'); const etcherLatestVersion = require('etcher-latest-version'); -module.exports = function($uibModal, $http, $q, UPDATE_NOTIFIER_SLEEP_TIME, ManifestBindService, SettingsModel) { +module.exports = function($http, $q, ModalService, UPDATE_NOTIFIER_SLEEP_TIME, ManifestBindService, SettingsModel) { /** * @summary Get the latest available Etcher version @@ -111,9 +111,8 @@ module.exports = function($uibModal, $http, $q, UPDATE_NOTIFIER_SLEEP_TIME, Mani * UpdateNotifierService.notify(); */ this.notify = () => { - return $uibModal.open({ - animation: true, - templateUrl: './components/update-notifier/templates/update-notifier-modal.tpl.html', + return ModalService.open({ + template: './components/update-notifier/templates/update-notifier-modal.tpl.html', controller: 'UpdateNotifierController as modal', size: 'update-notifier' }).result; diff --git a/lib/gui/components/update-notifier/update-notifier.js b/lib/gui/components/update-notifier/update-notifier.js index 4a7c5f2c..cfa38cbf 100644 --- a/lib/gui/components/update-notifier/update-notifier.js +++ b/lib/gui/components/update-notifier/update-notifier.js @@ -23,7 +23,7 @@ const angular = require('angular'); const MODULE_NAME = 'Etcher.Components.UpdateNotifier'; const UpdateNotifier = angular.module(MODULE_NAME, [ - require('angular-ui-bootstrap'), + require('../modal/modal'), require('../../models/settings'), require('../../utils/manifest-bind/manifest-bind'), require('../../os/open-external/open-external') diff --git a/lib/gui/pages/settings/controllers/settings.js b/lib/gui/pages/settings/controllers/settings.js index e2d8f25c..ac50d9a2 100644 --- a/lib/gui/pages/settings/controllers/settings.js +++ b/lib/gui/pages/settings/controllers/settings.js @@ -18,7 +18,7 @@ const _ = require('lodash'); -module.exports = function($uibModal, SettingsModel) { +module.exports = function(ModalService, SettingsModel) { /** * @summary Refresh current settings @@ -62,9 +62,8 @@ module.exports = function($uibModal, SettingsModel) { return this.refreshSettings(); } - $uibModal.open({ - animation: true, - templateUrl: './pages/settings/templates/settings-dangerous-modal.tpl.html', + ModalService.open({ + template: './pages/settings/templates/settings-dangerous-modal.tpl.html', controller: 'SettingsDangerousModalController as modal', size: 'settings-dangerous-modal', resolve: { diff --git a/lib/gui/pages/settings/settings.js b/lib/gui/pages/settings/settings.js index b7fb6af8..6662f71c 100644 --- a/lib/gui/pages/settings/settings.js +++ b/lib/gui/pages/settings/settings.js @@ -24,6 +24,7 @@ const angular = require('angular'); const MODULE_NAME = 'Etcher.Pages.Settings'; const SettingsPage = angular.module(MODULE_NAME, [ require('angular-ui-router'), + require('../../components/modal/modal'), require('../../models/settings') ]);