diff --git a/lib/gui/app.js b/lib/gui/app.js index 0e1bdd13..695fbcb4 100644 --- a/lib/gui/app.js +++ b/lib/gui/app.js @@ -146,7 +146,8 @@ app.controller('AppController', function( TooltipModalService, OSWindowProgressService, OSNotificationService, - OSDialogService + OSDialogService, + OSOpenExternalService ) { this.formats = SupportedFormatsModel; this.selection = SelectionStateModel; @@ -205,7 +206,15 @@ app.controller('AppController', function( } this.selection.setImage(image); - AnalyticsService.logEvent('Select image', image); + AnalyticsService.logEvent('Select image', _.omit(image, 'logo')); + }; + + this.openImageUrl = () => { + const imageUrl = this.selection.getImageUrl(); + + if (imageUrl) { + OSOpenExternalService.open(imageUrl); + } }; this.openImageSelector = () => { diff --git a/lib/gui/components/svg-icon/directives/svg-icon.js b/lib/gui/components/svg-icon/directives/svg-icon.js index 895e0175..0039904c 100644 --- a/lib/gui/components/svg-icon/directives/svg-icon.js +++ b/lib/gui/components/svg-icon/directives/svg-icon.js @@ -16,6 +16,7 @@ 'use strict'; +const _ = require('lodash'); const path = require('path'); const fs = require('fs'); @@ -45,21 +46,30 @@ module.exports = () => { height: '@' }, link: (scope, element) => { - - // This means the path to the icon should be - // relative to *this directory*. - // TODO: There might be a way to compute the path - // relatively to the `index.html`. - const imagePath = path.join(__dirname, scope.path); - - const contents = fs.readFileSync(imagePath, { - encoding: 'utf8' - }); - - element.html(contents); - element.css('width', scope.width || '40px'); element.css('height', scope.height || '40px'); + + scope.$watch('path', (value) => { + + // The path contains SVG contents + if (_.first(value) === '<') { + element.html(value); + + } else { + + // This means the path to the icon should be + // relative to *this directory*. + // TODO: There might be a way to compute the path + // relatively to the `index.html`. + const imagePath = path.join(__dirname, value); + + const contents = fs.readFileSync(imagePath, { + encoding: 'utf8' + }); + + element.html(contents); + } + }); } }; }; diff --git a/lib/gui/models/selection-state.js b/lib/gui/models/selection-state.js index 25477c50..a0c0805e 100644 --- a/lib/gui/models/selection-state.js +++ b/lib/gui/models/selection-state.js @@ -220,6 +220,48 @@ SelectionStateModel.service('SelectionStateModel', function() { return _.get(Store.getState().toJS(), 'selection.image.size'); }; + /** + * @summary Get image url + * @function + * @public + * + * @returns {String} image url + * + * @example + * const imageUrl = SelectionStateModel.getImageUrl(); + */ + this.getImageUrl = () => { + return _.get(Store.getState().toJS(), 'selection.image.url'); + }; + + /** + * @summary Get image name + * @function + * @public + * + * @returns {String} image name + * + * @example + * const imageName = SelectionStateModel.getImageName(); + */ + this.getImageName = () => { + return _.get(Store.getState().toJS(), 'selection.image.name'); + }; + + /** + * @summary Get image logo + * @function + * @public + * + * @returns {String} image logo + * + * @example + * const imageLogo = SelectionStateModel.getImageLogo(); + */ + this.getImageLogo = () => { + return _.get(Store.getState().toJS(), 'selection.image.logo'); + }; + /** * @summary Check if there is a selected drive * @function diff --git a/lib/gui/models/store.js b/lib/gui/models/store.js index fd1923f1..46a467ce 100644 --- a/lib/gui/models/store.js +++ b/lib/gui/models/store.js @@ -274,6 +274,18 @@ const storeReducer = (state, action) => { throw new Error(`Invalid image size: ${action.data.size}`); } + if (action.data.url && !_.isString(action.data.url)) { + throw new Error(`Invalid image url: ${action.data.url}`); + } + + if (action.data.name && !_.isString(action.data.name)) { + throw new Error(`Invalid image name: ${action.data.name}`); + } + + if (action.data.logo && !_.isString(action.data.logo)) { + throw new Error(`Invalid image logo: ${action.data.logo}`); + } + return state.setIn([ 'selection', 'image' ], Immutable.fromJS(action.data)); } diff --git a/lib/gui/os/dialog/services/dialog.js b/lib/gui/os/dialog/services/dialog.js index d064e6fe..76ee5156 100644 --- a/lib/gui/os/dialog/services/dialog.js +++ b/lib/gui/os/dialog/services/dialog.js @@ -71,10 +71,13 @@ module.exports = function($q, SupportedFormatsModel) { return resolve(); } - imageStream.getEstimatedFinalSize(imagePath).then((estimatedSize) => { + imageStream.getImageMetadata(imagePath).then((metadata) => { return resolve({ path: imagePath, - size: estimatedSize + size: metadata.estimatedSize, + name: metadata.name, + url: metadata.url, + logo: metadata.logo }); }).catch(reject); }); diff --git a/lib/gui/os/open-external/directives/open-external.js b/lib/gui/os/open-external/directives/open-external.js index 7a455e1b..b43a8d96 100644 --- a/lib/gui/os/open-external/directives/open-external.js +++ b/lib/gui/os/open-external/directives/open-external.js @@ -16,8 +16,6 @@ 'use strict'; -const electron = require('electron'); - /** * @summary OsOpenExternal directive * @function @@ -27,12 +25,13 @@ const electron = require('electron'); * This directive provides an attribute to open an external * resource with the default operating system action. * + * @param {Object} OSOpenExternalService - OSOpenExternalService * @returns {Object} directive * * @example * */ -module.exports = () => { +module.exports = (OSOpenExternalService) => { return { restrict: 'A', scope: false, @@ -43,7 +42,7 @@ module.exports = () => { element.css('cursor', 'pointer'); element.on('click', () => { - electron.shell.openExternal(attributes.osOpenExternal); + OSOpenExternalService.open(attributes.osOpenExternal); }); } }; diff --git a/lib/gui/os/open-external/open-external.js b/lib/gui/os/open-external/open-external.js index ebb25cae..1d6bcb0a 100644 --- a/lib/gui/os/open-external/open-external.js +++ b/lib/gui/os/open-external/open-external.js @@ -23,6 +23,7 @@ const angular = require('angular'); const MODULE_NAME = 'Etcher.OS.OpenExternal'; const OSOpenExternal = angular.module(MODULE_NAME, []); +OSOpenExternal.service('OSOpenExternalService', require('./services/open-external')); OSOpenExternal.directive('osOpenExternal', require('./directives/open-external')); module.exports = MODULE_NAME; diff --git a/lib/gui/os/open-external/services/open-external.js b/lib/gui/os/open-external/services/open-external.js new file mode 100644 index 00000000..1b9f5e92 --- /dev/null +++ b/lib/gui/os/open-external/services/open-external.js @@ -0,0 +1,35 @@ +/* + * 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 electron = require('electron'); + +module.exports = function() { + + /** + * @summary Open an external resource + * @function + * @public + * + * @param {String} url - url + * + * @example + * OSOpenExternalService.open('https://www.google.com'); + */ + this.open = electron.shell.openExternal; + +}; diff --git a/lib/gui/partials/main.html b/lib/gui/partials/main.html index 8be4912b..7f0d62f1 100644 --- a/lib/gui/partials/main.html +++ b/lib/gui/partials/main.html @@ -1,7 +1,7 @@
- + SELECT IMAGE 1 @@ -16,7 +16,8 @@

-
+