Skip to content

Commit

Permalink
conflate state functionality; shouldLoad -> shouldShow
Browse files Browse the repository at this point in the history
  • Loading branch information
Shou committed May 17, 2017
1 parent 9fe0e4d commit a6dad66
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 63 deletions.
20 changes: 12 additions & 8 deletions lib/gui/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -301,15 +301,19 @@ app.controller('HeaderController', function(SelectionStateModel, OSOpenExternalS
app.controller('StateController', function($rootScope, $state) {

/**
* @param {string} state - state page
*/
this.is = $state.is;

/**
* @param {function} func - function to pass $rootScope to
* @summary Get the current state name
* @function
* @public
*
* @returns {String} current state name
*
* @example
* if (StateController.currentName() === 'main') {
* console.log('We are on the main screen!');
* }
*/
this.onStateChange = (func) => {
$rootScope.$on('$stateChangeSuccess', func);
this.currentName = () => {
return $state.current.name;
};

});
113 changes: 61 additions & 52 deletions lib/gui/components/safe-webview/safe-webview.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ class SafeWebview extends react.PureComponent {
super(props);

this.state = {
shouldLoad: true
shouldShow: true
};

// Events steal 'this'
Expand All @@ -54,71 +54,64 @@ class SafeWebview extends react.PureComponent {
* @returns {react.Element}
*/
render() {
if (this.state.shouldLoad) {
const url = new URL(this.props.src);

// We set the 'etcher-version' GET parameter here.
url.searchParams.set('etcher-version', packageJSON.version);

return react.createElement('webview', {
ref: 'webview',
src: url.href
}, []);
}

// We have to return null explicitly, undefined is an error in React.
return null;
return react.createElement('webview', {
ref: 'webview',
src: this.makeURL().href,
style: {
flex: this.state.shouldShow ? null : '0 1',
width: this.state.shouldShow ? null : '0',
height: this.state.shouldShow ? null : '0'
}
}, []);
}

/**
* @summary Add the Webview events if there is an element
* @summary Add the Webview events
*/
componentDidMount() {

// There is no element to add events to if 'shouldLoad' is false.
if (this.state.shouldLoad) {

// Events React is unaware of have to be handled manually
this.refs.webview.addEventListener('did-fail-load', this.didFailLoad);
this.refs.webview.addEventListener('did-get-response-details', this.didGetResponseDetails);
this.refs.webview.addEventListener('new-window', this.constructor.newWindow);
this.refs.webview.addEventListener('console-message', this.constructor.consoleMessage);

if (this.props.onStateChange) {
this.props.onStateChange((event, toState, toParams, fromState) => {
if (fromState.name === 'success' && this.state.shouldLoad) {
this.refs.webview.src = this.props.src;
this.refs.webview.reload();
}
});
}
}
// Events React is unaware of have to be handled manually
this.refs.webview.addEventListener('did-fail-load', this.didFailLoad);
this.refs.webview.addEventListener('did-get-response-details', this.didGetResponseDetails);
this.refs.webview.addEventListener('new-window', this.constructor.newWindow);
this.refs.webview.addEventListener('console-message', this.constructor.consoleMessage);
}

/**
* @summary Remove the Webview events if there is an element
* @summary Refresh the webview if we are navigating away from the success page
* @param {Object} nextProps - upcoming properties
*/
componentWillUnmount() {

// There is no element to remove events from if 'shouldLoad' is false.
if (this.state.shouldLoad) {
componentWillReceiveProps(nextProps) {
if (this.props.currentStateName === 'success' && nextProps.currentStateName !== 'success') {

// Events React is unaware of have to be handled manually
this.refs.webview.removeEventListener('did-fail-load', this.didFailLoad);
this.refs.webview.removeEventListener('did-get-response-details', this.didGetResponseDetails);
this.refs.webview.removeEventListener('new-window', this.constructor.newWindow);
this.refs.webview.removeEventListener('console-message', this.constructor.consoleMessage);
// Reset URL to initial
this.refs.webview.src = this.makeURL().href;
this.refs.webview.reload();

this.setState({
shouldShow: true
});
}
}

/**
* @summary Remove the Webview events
*/
componentWillUnmount() {

// Events React is unaware of have to be handled manually
this.refs.webview.removeEventListener('did-fail-load', this.didFailLoad);
this.refs.webview.removeEventListener('did-get-response-details', this.didGetResponseDetails);
this.refs.webview.removeEventListener('new-window', this.constructor.newWindow);
this.refs.webview.removeEventListener('console-message', this.constructor.consoleMessage);
}

/**
* @summary Set the element state to hidden
*/
didFailLoad() {
this.setState({
shouldLoad: false
shouldShow: false
});
}

Expand All @@ -130,14 +123,13 @@ class SafeWebview extends react.PureComponent {
const HTTP_OK = 200;
const HTTP_ERR = 400;

if (event.httpResponseCode < HTTP_OK || event.httpResponseCode >= HTTP_ERR) {
this.setState({
shouldLoad: false
});
}
this.setState({
shouldShow: event.httpResponseCode >= HTTP_OK && event.httpResponseCode < HTTP_ERR
});
}

/**
* @summary Open link in browser if it's opened as a 'foreground-tab'
* @param {Event} event - event object
*/
static newWindow(event) {
Expand All @@ -152,6 +144,7 @@ class SafeWebview extends react.PureComponent {
}

/**
* @summary Forward console messages from the webview to analytics module
* @param {Event} event - event object
*/
static consoleMessage(event) {
Expand All @@ -165,6 +158,22 @@ class SafeWebview extends react.PureComponent {
}
}

/**
* @summary Parse the 'src' prop into an URL and append metadata as GET parameters
* @function
* @public
*
* @returns {URL} url object
*/
makeURL() {
const url = new URL(this.props.src);

// We set the 'etcher-version' GET parameter here.
url.searchParams.set('etcher-version', packageJSON.version);

return url;
}

}

SafeWebview.propTypes = {
Expand All @@ -175,9 +184,9 @@ SafeWebview.propTypes = {
src: propTypes.string.isRequired,

/**
* @summary Inject Angular functionality
* @summary Current Angular $state name
*/
onStateChange: propTypes.func
currentStateName: propTypes.string

};

Expand Down
6 changes: 3 additions & 3 deletions lib/gui/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
<main class="wrapper" ui-view></main>

<footer class="section-footer" ng-controller="StateController as state"
ng-hide="state.is('success')">
ng-hide="state.currentName() === 'success'">
<svg-icon path="../../../assets/etcher.svg"
width="83px"
height="13px"
Expand All @@ -54,11 +54,11 @@
<div class="section-loader"
ng-controller="StateController as state"
ng-class="{
isFinish: state.is('success')
isFinish: state.currentName() === 'success'
}">
<safe-webview
src="'https://etcher.io/success-banner/'"
on-state-change="state.onStateChange"></safe-webview>
current-state-name="state.currentName()"></safe-webview>
</div>
</body>
</html>

0 comments on commit a6dad66

Please sign in to comment.