mirror of
https://github.com/balena-io/etcher.git
synced 2025-07-19 09:16:38 +00:00
Add flashing info while showing webview
Change-type: patch Signed-off-by: Lorenzo Alberto Maria Ambrosi <lorenzoa@balena.io>
This commit is contained in:
parent
2017df9ec6
commit
76af6e975e
@ -17,28 +17,25 @@
|
||||
'use strict'
|
||||
|
||||
const React = require('react')
|
||||
const propTypes = require('prop-types')
|
||||
const SafeWebview = require('../safe-webview/safe-webview.jsx')
|
||||
const settings = require('../../models/settings')
|
||||
const analytics = require('../../modules/analytics')
|
||||
const endpoint = null
|
||||
|
||||
class FeaturedProject extends React.Component {
|
||||
constructor (props) {
|
||||
super(props)
|
||||
|
||||
this.state = {
|
||||
endpoint
|
||||
endpoint: null
|
||||
}
|
||||
}
|
||||
|
||||
componentDidMount () {
|
||||
return settings.load()
|
||||
.then(() => {
|
||||
if (settings.has('featuredProjectEndpoint')) {
|
||||
this.setState({ endpoint: settings.get('featuredProjectEndpoint') })
|
||||
} else {
|
||||
this.setState({ endpoint: 'https://assets.balena.io/etcher-featured/index.html' })
|
||||
}
|
||||
const endpoint = settings.get('featuredProjectEndpoint') || 'https://assets.balena.io/etcher-featured/index.html'
|
||||
this.setState({ endpoint })
|
||||
})
|
||||
.catch(analytics.logException)
|
||||
}
|
||||
@ -53,4 +50,8 @@ class FeaturedProject extends React.Component {
|
||||
}
|
||||
}
|
||||
|
||||
FeaturedProject.propTypes = {
|
||||
onWebviewShow: propTypes.func
|
||||
}
|
||||
|
||||
module.exports = FeaturedProject
|
||||
|
34
lib/gui/app/components/reduced-flashing-infos/index.js
Normal file
34
lib/gui/app/components/reduced-flashing-infos/index.js
Normal file
@ -0,0 +1,34 @@
|
||||
/*
|
||||
* 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.ReducedFlashingInfos
|
||||
*/
|
||||
|
||||
const angular = require('angular')
|
||||
const { react2angular } = require('react2angular')
|
||||
|
||||
const MODULE_NAME = 'Etcher.Components.ReducedFlashingInfos'
|
||||
const ReducedFlashingInfos = angular.module(MODULE_NAME, [])
|
||||
|
||||
ReducedFlashingInfos.component(
|
||||
'reducedFlashingInfos',
|
||||
react2angular(require('./reduced-flashing-infos.jsx'))
|
||||
)
|
||||
|
||||
module.exports = MODULE_NAME
|
@ -0,0 +1,68 @@
|
||||
/*
|
||||
* 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 React = require('react')
|
||||
const propTypes = require('prop-types')
|
||||
const styled = require('styled-components').default
|
||||
const SvgIcon = require('../svg-icon/svg-icon.jsx')
|
||||
|
||||
const Div = styled.div `
|
||||
position: absolute;
|
||||
top: 45px;
|
||||
left: 550px;
|
||||
|
||||
> span.step-name {
|
||||
justify-content: flex-start;
|
||||
|
||||
> span {
|
||||
margin-left: 5px;
|
||||
font-weight: normal;
|
||||
}
|
||||
}
|
||||
|
||||
.svg-icon[disabled] {
|
||||
opacity: 0.4;
|
||||
}
|
||||
`
|
||||
|
||||
const ReducedFlashingInfos = (props) => {
|
||||
return (props.shouldShow) ? (
|
||||
<Div>
|
||||
<span className="step-name">
|
||||
<SvgIcon disabled contents={[ props.imageLogo ]} paths={[ '../../assets/image.svg' ]} width='20px'></SvgIcon>
|
||||
<span>{ props.imageName }</span>
|
||||
<span style={{ color: '#7e8085' }}>{ props.imageSize }</span>
|
||||
</span>
|
||||
|
||||
<span className="step-name">
|
||||
<SvgIcon disabled paths={[ '../../assets/drive.svg' ]} width='20px'></SvgIcon>
|
||||
<span>{ props.driveTitle }</span>
|
||||
</span>
|
||||
</Div>
|
||||
) : null
|
||||
}
|
||||
|
||||
ReducedFlashingInfos.propTypes = {
|
||||
imageLogo: propTypes.string,
|
||||
imageName: propTypes.string,
|
||||
imageSize: propTypes.string,
|
||||
driveTitle: propTypes.string,
|
||||
shouldShow: propTypes.bool
|
||||
}
|
||||
|
||||
module.exports = ReducedFlashingInfos
|
@ -202,6 +202,9 @@ class SafeWebview extends react.PureComponent {
|
||||
this.setState({
|
||||
shouldShow: event.httpResponseCode === HTTP_OK
|
||||
})
|
||||
if (this.props.onWebviewShow) {
|
||||
this.props.onWebviewShow(event.httpResponseCode === HTTP_OK)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -265,7 +268,12 @@ SafeWebview.propTypes = {
|
||||
/**
|
||||
* @summary Refresh the webview
|
||||
*/
|
||||
refreshNow: propTypes.bool
|
||||
refreshNow: propTypes.bool,
|
||||
|
||||
/**
|
||||
* @summary Webview lifecycle event
|
||||
*/
|
||||
onWebviewShow: propTypes.func
|
||||
|
||||
}
|
||||
|
||||
|
@ -22,162 +22,11 @@
|
||||
* @module Etcher.Components.SVGIcon
|
||||
*/
|
||||
|
||||
const _ = require('lodash')
|
||||
const angular = require('angular')
|
||||
const react = require('react')
|
||||
const propTypes = require('prop-types')
|
||||
const react2angular = require('react2angular').react2angular
|
||||
const path = require('path')
|
||||
const fs = require('fs')
|
||||
const analytics = require('../modules/analytics')
|
||||
|
||||
const MODULE_NAME = 'Etcher.Components.SVGIcon'
|
||||
const angularSVGIcon = angular.module(MODULE_NAME, [])
|
||||
|
||||
const DEFAULT_SIZE = '40px'
|
||||
|
||||
const domParser = new window.DOMParser()
|
||||
|
||||
/**
|
||||
* @summary Try to parse SVG contents and return it data encoded
|
||||
*
|
||||
* @param {String} contents - SVG XML contents
|
||||
* @returns {String|null}
|
||||
*
|
||||
* @example
|
||||
* const encodedSVG = tryParseSVGContents('<svg><path></path></svg>')
|
||||
*
|
||||
* img.src = encodedSVG
|
||||
*/
|
||||
const tryParseSVGContents = (contents) => {
|
||||
const doc = domParser.parseFromString(contents, 'image/svg+xml')
|
||||
const parserError = doc.querySelector('parsererror')
|
||||
const svg = doc.querySelector('svg')
|
||||
|
||||
if (!parserError && svg) {
|
||||
return `data:image/svg+xml,${encodeURIComponent(svg.outerHTML)}`
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
/**
|
||||
* @summary SVG element that takes both filepaths and file contents
|
||||
* @type {Object}
|
||||
* @public
|
||||
*/
|
||||
class SVGIcon extends react.Component {
|
||||
/**
|
||||
* @summary Render the SVG
|
||||
* @returns {react.Element}
|
||||
*/
|
||||
render () {
|
||||
// __dirname behaves strangely inside a Webpack bundle,
|
||||
// so we need to provide different base directories
|
||||
// depending on whether __dirname is absolute or not,
|
||||
// which helps detecting a Webpack bundle.
|
||||
// We use global.__dirname inside a Webpack bundle since
|
||||
// that's the only way to get the "real" __dirname.
|
||||
const baseDirectory = path.isAbsolute(__dirname)
|
||||
? path.join(__dirname, '..')
|
||||
// eslint-disable-next-line no-underscore-dangle
|
||||
: global.__dirname
|
||||
|
||||
let svgData = ''
|
||||
|
||||
_.find(this.props.contents, (content) => {
|
||||
const attempt = tryParseSVGContents(content)
|
||||
|
||||
if (attempt) {
|
||||
svgData = attempt
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
})
|
||||
|
||||
if (!svgData) {
|
||||
_.find(this.props.paths, (relativePath) => {
|
||||
// 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(baseDirectory, 'assets', relativePath)
|
||||
|
||||
const contents = _.attempt(() => {
|
||||
return fs.readFileSync(imagePath, {
|
||||
encoding: 'utf8'
|
||||
})
|
||||
})
|
||||
|
||||
if (_.isError(contents)) {
|
||||
analytics.logException(contents)
|
||||
return false
|
||||
}
|
||||
|
||||
const parsed = _.attempt(tryParseSVGContents, contents)
|
||||
|
||||
if (parsed) {
|
||||
svgData = parsed
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
})
|
||||
}
|
||||
|
||||
const width = this.props.width || DEFAULT_SIZE
|
||||
const height = this.props.height || DEFAULT_SIZE
|
||||
|
||||
return react.createElement('img', {
|
||||
className: 'svg-icon',
|
||||
style: {
|
||||
width,
|
||||
height
|
||||
},
|
||||
src: svgData,
|
||||
disabled: this.props.disabled
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* @summary Cause a re-render due to changed element properties
|
||||
* @param {Object} nextProps - the new properties
|
||||
*/
|
||||
componentWillReceiveProps (nextProps) {
|
||||
// This will update the element if the properties change
|
||||
this.setState(nextProps)
|
||||
}
|
||||
}
|
||||
|
||||
SVGIcon.propTypes = {
|
||||
|
||||
/**
|
||||
* @summary Paths to SVG files to be tried in succession if any fails
|
||||
*/
|
||||
paths: propTypes.array,
|
||||
|
||||
/**
|
||||
* @summary List of embedded SVG contents to be tried in succession if any fails
|
||||
*/
|
||||
contents: propTypes.array,
|
||||
|
||||
/**
|
||||
* @summary SVG image width unit
|
||||
*/
|
||||
width: propTypes.string,
|
||||
|
||||
/**
|
||||
* @summary SVG image height unit
|
||||
*/
|
||||
height: propTypes.string,
|
||||
|
||||
/**
|
||||
* @summary Should the element visually appear grayed out and disabled?
|
||||
*/
|
||||
disabled: propTypes.bool
|
||||
|
||||
}
|
||||
|
||||
angularSVGIcon.component('svgIcon', react2angular(SVGIcon))
|
||||
angularSVGIcon.component('svgIcon', react2angular(require('./svg-icon/svg-icon.jsx')))
|
||||
module.exports = MODULE_NAME
|
||||
|
176
lib/gui/app/components/svg-icon/svg-icon.jsx
Normal file
176
lib/gui/app/components/svg-icon/svg-icon.jsx
Normal file
@ -0,0 +1,176 @@
|
||||
/*
|
||||
* Copyright 2018 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.SVGIcon
|
||||
*/
|
||||
|
||||
const _ = require('lodash')
|
||||
const react = require('react')
|
||||
const propTypes = require('prop-types')
|
||||
const path = require('path')
|
||||
const fs = require('fs')
|
||||
const analytics = require('../../modules/analytics')
|
||||
const domParser = new window.DOMParser()
|
||||
|
||||
const DEFAULT_SIZE = '40px'
|
||||
|
||||
/**
|
||||
* @summary Try to parse SVG contents and return it data encoded
|
||||
*
|
||||
* @param {String} contents - SVG XML contents
|
||||
* @returns {String|null}
|
||||
*
|
||||
* @example
|
||||
* const encodedSVG = tryParseSVGContents('<svg><path></path></svg>')
|
||||
*
|
||||
* img.src = encodedSVG
|
||||
*/
|
||||
const tryParseSVGContents = (contents) => {
|
||||
const doc = domParser.parseFromString(contents, 'image/svg+xml')
|
||||
const parserError = doc.querySelector('parsererror')
|
||||
const svg = doc.querySelector('svg')
|
||||
|
||||
if (!parserError && svg) {
|
||||
return `data:image/svg+xml,${encodeURIComponent(svg.outerHTML)}`
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
/* eslint-disable jsdoc/require-example */
|
||||
|
||||
/**
|
||||
* @summary SVG element that takes both filepaths and file contents
|
||||
* @type {Object}
|
||||
* @public
|
||||
*/
|
||||
class SVGIcon extends react.Component {
|
||||
/**
|
||||
* @summary Render the SVG
|
||||
* @returns {react.Element}
|
||||
*/
|
||||
render () {
|
||||
// __dirname behaves strangely inside a Webpack bundle,
|
||||
// so we need to provide different base directories
|
||||
// depending on whether __dirname is absolute or not,
|
||||
// which helps detecting a Webpack bundle.
|
||||
// We use global.__dirname inside a Webpack bundle since
|
||||
// that's the only way to get the "real" __dirname.
|
||||
const baseDirectory = path.isAbsolute(__dirname)
|
||||
? path.join(__dirname, '..')
|
||||
// eslint-disable-next-line no-underscore-dangle
|
||||
: global.__dirname
|
||||
|
||||
let svgData = ''
|
||||
|
||||
_.find(this.props.contents, (content) => {
|
||||
const attempt = tryParseSVGContents(content)
|
||||
|
||||
if (attempt) {
|
||||
svgData = attempt
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
})
|
||||
|
||||
if (!svgData) {
|
||||
_.find(this.props.paths, (relativePath) => {
|
||||
// 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(baseDirectory, 'assets', relativePath)
|
||||
|
||||
const contents = _.attempt(() => {
|
||||
return fs.readFileSync(imagePath, {
|
||||
encoding: 'utf8'
|
||||
})
|
||||
})
|
||||
|
||||
if (_.isError(contents)) {
|
||||
analytics.logException(contents)
|
||||
return false
|
||||
}
|
||||
|
||||
const parsed = _.attempt(tryParseSVGContents, contents)
|
||||
|
||||
if (parsed) {
|
||||
svgData = parsed
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
})
|
||||
}
|
||||
|
||||
const width = this.props.width || DEFAULT_SIZE
|
||||
const height = this.props.height || DEFAULT_SIZE
|
||||
|
||||
return react.createElement('img', {
|
||||
className: 'svg-icon',
|
||||
style: {
|
||||
width,
|
||||
height
|
||||
},
|
||||
src: svgData,
|
||||
disabled: this.props.disabled
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* @summary Cause a re-render due to changed element properties
|
||||
* @param {Object} nextProps - the new properties
|
||||
*/
|
||||
componentWillReceiveProps (nextProps) {
|
||||
// This will update the element if the properties change
|
||||
this.setState(nextProps)
|
||||
}
|
||||
}
|
||||
|
||||
SVGIcon.propTypes = {
|
||||
|
||||
/**
|
||||
* @summary Paths to SVG files to be tried in succession if any fails
|
||||
*/
|
||||
paths: propTypes.array,
|
||||
|
||||
/**
|
||||
* @summary List of embedded SVG contents to be tried in succession if any fails
|
||||
*/
|
||||
contents: propTypes.array,
|
||||
|
||||
/**
|
||||
* @summary SVG image width unit
|
||||
*/
|
||||
width: propTypes.string,
|
||||
|
||||
/**
|
||||
* @summary SVG image height unit
|
||||
*/
|
||||
height: propTypes.string,
|
||||
|
||||
/**
|
||||
* @summary Should the element visually appear grayed out and disabled?
|
||||
*/
|
||||
disabled: propTypes.bool
|
||||
|
||||
}
|
||||
|
||||
module.exports = SVGIcon
|
@ -115,7 +115,8 @@ const ACTIONS = _.fromPairs(_.map([
|
||||
'DESELECT_DRIVE',
|
||||
'DESELECT_IMAGE',
|
||||
'SET_APPLICATION_SESSION_UUID',
|
||||
'SET_FLASHING_WORKFLOW_UUID'
|
||||
'SET_FLASHING_WORKFLOW_UUID',
|
||||
'SET_WEBVIEW_SHOWING_STATUS'
|
||||
], (message) => {
|
||||
return [ message, message ]
|
||||
}))
|
||||
@ -511,6 +512,10 @@ const storeReducer = (state = DEFAULT_STATE, action) => {
|
||||
return state.set('flashingWorkflowUuid', action.data)
|
||||
}
|
||||
|
||||
case ACTIONS.SET_WEBVIEW_SHOWING_STATUS: {
|
||||
return state.set('isWebviewShowing', action.data)
|
||||
}
|
||||
|
||||
default: {
|
||||
return state
|
||||
}
|
||||
|
@ -16,6 +16,7 @@
|
||||
|
||||
'use strict'
|
||||
|
||||
const path = require('path')
|
||||
const store = require('../../../models/store')
|
||||
const settings = require('../../../models/settings')
|
||||
const flashState = require('../../../models/flash-state')
|
||||
@ -25,10 +26,12 @@ const availableDrives = require('../../../models/available-drives')
|
||||
const selectionState = require('../../../models/selection-state')
|
||||
const driveConstraints = require('../../../../../shared/drive-constraints')
|
||||
const messages = require('../../../../../shared/messages')
|
||||
const prettyBytes = require('pretty-bytes')
|
||||
|
||||
module.exports = function (
|
||||
TooltipModalService,
|
||||
OSOpenExternalService
|
||||
OSOpenExternalService,
|
||||
$filter
|
||||
) {
|
||||
// Expose several modules to the template for convenience
|
||||
this.selection = selectionState
|
||||
@ -38,6 +41,7 @@ module.exports = function (
|
||||
this.external = OSOpenExternalService
|
||||
this.constraints = driveConstraints
|
||||
this.progressMessage = messages.progress
|
||||
this.isWebviewShowing = Boolean(store.getState().toJS().isWebviewShowing)
|
||||
|
||||
/**
|
||||
* @summary Determine if the drive step should be disabled
|
||||
@ -93,4 +97,87 @@ module.exports = function (
|
||||
message: selectionState.getImagePath()
|
||||
}).catch(exceptionReporter.report)
|
||||
}
|
||||
|
||||
/**
|
||||
* @summary Get drive title based on device quantity
|
||||
* @function
|
||||
* @public
|
||||
*
|
||||
* @returns {String} - drives title
|
||||
*
|
||||
* @example
|
||||
* console.log(DriveSelectionController.getDrivesTitle())
|
||||
* > 'Multiple Drives (4)'
|
||||
*/
|
||||
this.getDrivesTitle = () => {
|
||||
const drives = this.selection.getSelectedDrives()
|
||||
|
||||
/* eslint-disable no-magic-numbers */
|
||||
if (drives.length === 1) {
|
||||
return drives[0].description || 'Untitled Device'
|
||||
}
|
||||
/* eslint-enable no-magic-numbers */
|
||||
|
||||
// eslint-disable-next-line no-magic-numbers
|
||||
if (drives.length === 0) {
|
||||
return 'No targets found'
|
||||
}
|
||||
|
||||
return `${drives.length} Targets`
|
||||
}
|
||||
|
||||
/**
|
||||
* @summary Get drive subtitle
|
||||
* @function
|
||||
* @public
|
||||
*
|
||||
* @returns {String} - drives subtitle
|
||||
*
|
||||
* @example
|
||||
* console.log(MainController.getDrivesSubtitle())
|
||||
* > '32 GB'
|
||||
*/
|
||||
this.getDrivesSubtitle = () => {
|
||||
const drive = this.selection.getCurrentDrive()
|
||||
|
||||
if (drive) {
|
||||
return prettyBytes(drive.size)
|
||||
}
|
||||
|
||||
return 'Please insert at least one target device'
|
||||
}
|
||||
|
||||
/**
|
||||
* @summary Get the basename of the selected image
|
||||
* @function
|
||||
* @public
|
||||
*
|
||||
* @returns {String} basename of the selected image
|
||||
*
|
||||
* @example
|
||||
* const imageBasename = ImageSelectionController.getImageBasename();
|
||||
*/
|
||||
this.getImageBasename = () => {
|
||||
if (!this.selection.hasImage()) {
|
||||
return ''
|
||||
}
|
||||
|
||||
return path.basename(this.selection.getImagePath())
|
||||
}
|
||||
|
||||
this.setWebviewShowing = (data) => {
|
||||
this.isWebviewShowing = data
|
||||
store.dispatch({
|
||||
type: 'SET_WEBVIEW_SHOWING_STATUS',
|
||||
data: Boolean(data)
|
||||
})
|
||||
}
|
||||
|
||||
this.getDriveTitle = () => {
|
||||
/* eslint-disable no-magic-numbers */
|
||||
const driveTitleRaw = (this.selection.getSelectedDevices().length === 1)
|
||||
? this.getDrivesSubtitle()
|
||||
: `${this.selection.getSelectedDevices().length} Targets`
|
||||
return $filter('middleEllipsis:20')(driveTitleRaw)
|
||||
}
|
||||
}
|
||||
|
@ -41,6 +41,7 @@ const MainPage = angular.module(MODULE_NAME, [
|
||||
require('../../components/warning-modal/warning-modal'),
|
||||
require('../../components/file-selector'),
|
||||
require('../../components/featured-project'),
|
||||
require('../../components/reduced-flashing-infos'),
|
||||
|
||||
require('../../os/open-external/open-external'),
|
||||
require('../../os/dropzone/dropzone'),
|
||||
|
@ -26,8 +26,8 @@
|
||||
|
||||
<div class="col-xs" ng-controller="DriveSelectionController as drive">
|
||||
<div class="box text-center relative">
|
||||
<div class="step-border-left" ng-disabled="main.shouldDriveStepBeDisabled()"></div>
|
||||
<div class="step-border-right" ng-disabled="main.shouldFlashStepBeDisabled()"></div>
|
||||
<div class="step-border-left" ng-disabled="main.shouldDriveStepBeDisabled()" ng-hide="main.state.isFlashing() && main.isWebviewShowing"></div>
|
||||
<div class="step-border-right" ng-disabled="main.shouldFlashStepBeDisabled()" ng-hide="main.state.isFlashing() && main.isWebviewShowing"></div>
|
||||
|
||||
<div class="center-block">
|
||||
<svg-icon paths="[ '../../assets/drive.svg' ]"
|
||||
@ -90,11 +90,24 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<featured-project
|
||||
ng-class="{
|
||||
isFlashing: main.state.isFlashing()
|
||||
}">
|
||||
</featured-project>
|
||||
<div>
|
||||
<featured-project
|
||||
ng-class="{
|
||||
'fp-visible': main.state.isFlashing() && main.isWebviewShowing
|
||||
}"
|
||||
on-webview-show="main.setWebviewShowing"
|
||||
></featured-project>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<reduced-flashing-infos
|
||||
image-logo="main.selection.getImageLogo()"
|
||||
image-name="main.selection.getImageName() || main.getImageBasename() | middleEllipsis:16"
|
||||
image-size="main.selection.getImageSize() | closestUnit"
|
||||
drive-title="main.getDrivesTitle() | middleEllipsis:16"
|
||||
should-show="main.state.isFlashing() && main.isWebviewShowing"
|
||||
></reduced-flashing-infos>
|
||||
</div>
|
||||
|
||||
<div class="col-xs" ng-controller="FlashController as flash">
|
||||
<div class="box text-center">
|
||||
|
@ -182,7 +182,7 @@ featured-project {
|
||||
width: 0;
|
||||
}
|
||||
|
||||
&.isFlashing webview {
|
||||
&.fp-visible webview {
|
||||
width: 480px;
|
||||
height: 360px;
|
||||
position: absolute;
|
||||
|
@ -9952,7 +9952,7 @@ featured-project webview {
|
||||
height: 0;
|
||||
width: 0; }
|
||||
|
||||
featured-project.isFlashing webview {
|
||||
featured-project.fp-visible webview {
|
||||
width: 480px;
|
||||
height: 360px;
|
||||
position: absolute;
|
||||
|
Loading…
x
Reference in New Issue
Block a user