From dd307e3deb14f1738029ea38f7c1de7893455283 Mon Sep 17 00:00:00 2001 From: Stefan Malzner Date: Tue, 7 Nov 2017 15:29:31 +0100 Subject: feature(Service): Add webview crash handler to display a user friendly message --- src/components/services/content/ServiceWebview.js | 10 +++ src/components/services/content/Services.js | 3 + .../services/content/WebviewCrashHandler.js | 81 ++++++++++++++++++++++ 3 files changed, 94 insertions(+) create mode 100644 src/components/services/content/WebviewCrashHandler.js (limited to 'src/components') diff --git a/src/components/services/content/ServiceWebview.js b/src/components/services/content/ServiceWebview.js index 3ee3155be..cd59e0a8a 100644 --- a/src/components/services/content/ServiceWebview.js +++ b/src/components/services/content/ServiceWebview.js @@ -7,12 +7,14 @@ import classnames from 'classnames'; import ServiceModel from '../../../models/Service'; import StatusBarTargetUrl from '../../ui/StatusBarTargetUrl'; +import WebviewCrashHandler from './WebviewCrashHandler'; @observer export default class ServiceWebview extends Component { static propTypes = { service: PropTypes.instanceOf(ServiceModel).isRequired, setWebviewReference: PropTypes.func.isRequired, + reload: PropTypes.func.isRequired, }; static defaultProps = { @@ -53,6 +55,7 @@ export default class ServiceWebview extends Component { const { service, setWebviewReference, + reload, } = this.props; const webviewClasses = classnames({ @@ -70,6 +73,13 @@ export default class ServiceWebview extends Component { return (
+ {service.hasCrashed && ( + + )} { this.webview = element; }} diff --git a/src/components/services/content/Services.js b/src/components/services/content/Services.js index 03c68b06f..bad525d22 100644 --- a/src/components/services/content/Services.js +++ b/src/components/services/content/Services.js @@ -25,6 +25,7 @@ export default class Services extends Component { setWebviewReference: PropTypes.func.isRequired, handleIPCMessage: PropTypes.func.isRequired, openWindow: PropTypes.func.isRequired, + reload: PropTypes.func.isRequired, }; static defaultProps = { @@ -42,6 +43,7 @@ export default class Services extends Component { handleIPCMessage, setWebviewReference, openWindow, + reload, } = this.props; const { intl } = this.context; @@ -73,6 +75,7 @@ export default class Services extends Component { handleIPCMessage={handleIPCMessage} setWebviewReference={setWebviewReference} openWindow={openWindow} + reload={() => reload({ serviceId: service.id })} /> ))}
diff --git a/src/components/services/content/WebviewCrashHandler.js b/src/components/services/content/WebviewCrashHandler.js new file mode 100644 index 000000000..24903f3c5 --- /dev/null +++ b/src/components/services/content/WebviewCrashHandler.js @@ -0,0 +1,81 @@ +import React, { Component } from 'react'; +import PropTypes from 'prop-types'; +import { observer } from 'mobx-react'; +import { defineMessages, intlShape } from 'react-intl'; + +import Button from '../../ui/Button'; + +const messages = defineMessages({ + headline: { + id: 'service.crashHandler.headline', + defaultMessage: '!!!Oh no!', + }, + text: { + id: 'service.crashHandler.text', + defaultMessage: '!!!{name} has caused an error.', + }, + action: { + id: 'service.crashHandler.action', + defaultMessage: '!!!Reload {name}', + }, + autoReload: { + id: 'service.crashHandler.autoReload', + defaultMessage: '!!!Trying to automatically restore {name} in {seconds} seconds', + }, +}); + +@observer +export default class ServiceWebview extends Component { + static propTypes = { + name: PropTypes.string.isRequired, + reload: PropTypes.func.isRequired, + }; + + static contextTypes = { + intl: intlShape, + }; + + state = { + countdown: 10000, + } + + componentDidMount() { + const { reload } = this.props; + + this.countdownInterval = setInterval(() => { + this.setState({ + countdown: this.state.countdown - this.countdownIntervalTimeout, + }); + + if (this.state.countdown <= 0) { + reload(); + clearInterval(this.countdownInterval); + } + }, this.countdownIntervalTimeout); + } + + countdownInterval = null; + countdownIntervalTimeout = 1000; + + render() { + const { name, reload } = this.props; + const { intl } = this.context; + + return ( +
+

{intl.formatMessage(messages.headline)}

+

{intl.formatMessage(messages.text, { name })}

+
+ ); + } +} -- cgit v1.2.3-70-g09d2