diff options
author | Stefan Malzner <stefan@adlk.io> | 2018-12-08 17:08:58 +0100 |
---|---|---|
committer | Stefan Malzner <stefan@adlk.io> | 2018-12-08 17:08:58 +0100 |
commit | a5e7171402eb27a4527a238d186c88ac03f8ffd7 (patch) | |
tree | 897708a2cfc88569c04f4896bacf2c9d390c7b39 /src/components/services/content | |
parent | Add service spellchecker language strings (diff) | |
download | ferdium-app-a5e7171402eb27a4527a238d186c88ac03f8ffd7.tar.gz ferdium-app-a5e7171402eb27a4527a238d186c88ac03f8ffd7.tar.zst ferdium-app-a5e7171402eb27a4527a238d186c88ac03f8ffd7.zip |
feat(Service): Add error screen for services that failed to load
Diffstat (limited to 'src/components/services/content')
4 files changed, 125 insertions, 0 deletions
diff --git a/src/components/services/content/ErrorHandlers/WebviewErrorHandler.js b/src/components/services/content/ErrorHandlers/WebviewErrorHandler.js new file mode 100644 index 000000000..05a64209b --- /dev/null +++ b/src/components/services/content/ErrorHandlers/WebviewErrorHandler.js | |||
@@ -0,0 +1,79 @@ | |||
1 | import React, { Component } from 'react'; | ||
2 | import PropTypes from 'prop-types'; | ||
3 | import { observer } from 'mobx-react'; | ||
4 | import { defineMessages, intlShape } from 'react-intl'; | ||
5 | import injectSheet from 'react-jss'; | ||
6 | |||
7 | import Button from '../../../ui/Button'; | ||
8 | |||
9 | import styles from './styles'; | ||
10 | |||
11 | const messages = defineMessages({ | ||
12 | headline: { | ||
13 | id: 'service.errorHandler.headline', | ||
14 | defaultMessage: '!!!Oh no!', | ||
15 | }, | ||
16 | text: { | ||
17 | id: 'service.errorHandler.text', | ||
18 | defaultMessage: '!!!{name} has failed to load.', | ||
19 | }, | ||
20 | action: { | ||
21 | id: 'service.errorHandler.action', | ||
22 | defaultMessage: '!!!Reload {name}', | ||
23 | }, | ||
24 | editAction: { | ||
25 | id: 'service.errorHandler.editAction', | ||
26 | defaultMessage: '!!!Edit {name}', | ||
27 | }, | ||
28 | errorMessage: { | ||
29 | id: 'service.errorHandler.message', | ||
30 | defaultMessage: '!!!Error: {error}', | ||
31 | }, | ||
32 | }); | ||
33 | |||
34 | export default @injectSheet(styles) @observer class WebviewCrashHandler extends Component { | ||
35 | static propTypes = { | ||
36 | name: PropTypes.string.isRequired, | ||
37 | reload: PropTypes.func.isRequired, | ||
38 | edit: PropTypes.func.isRequired, | ||
39 | errorMessage: PropTypes.string.isRequired, | ||
40 | classes: PropTypes.object.isRequired, | ||
41 | }; | ||
42 | |||
43 | static contextTypes = { | ||
44 | intl: intlShape, | ||
45 | }; | ||
46 | |||
47 | render() { | ||
48 | const { | ||
49 | name, | ||
50 | reload, | ||
51 | edit, | ||
52 | errorMessage, | ||
53 | classes, | ||
54 | } = this.props; | ||
55 | const { intl } = this.context; | ||
56 | |||
57 | return ( | ||
58 | <div className={classes.component}> | ||
59 | <h1>{intl.formatMessage(messages.headline)}</h1> | ||
60 | <p>{intl.formatMessage(messages.text, { name })}</p> | ||
61 | <p>{intl.formatMessage(messages.errorMessage, { | ||
62 | error: errorMessage, | ||
63 | })}</p> | ||
64 | <div className={classes.buttonContainer}> | ||
65 | <Button | ||
66 | label={intl.formatMessage(messages.editAction, { name })} | ||
67 | buttonType="inverted" | ||
68 | onClick={() => edit()} | ||
69 | /> | ||
70 | <Button | ||
71 | label={intl.formatMessage(messages.action, { name })} | ||
72 | buttonType="inverted" | ||
73 | onClick={() => reload()} | ||
74 | /> | ||
75 | </div> | ||
76 | </div> | ||
77 | ); | ||
78 | } | ||
79 | } | ||
diff --git a/src/components/services/content/ErrorHandlers/styles.js b/src/components/services/content/ErrorHandlers/styles.js new file mode 100644 index 000000000..f11386798 --- /dev/null +++ b/src/components/services/content/ErrorHandlers/styles.js | |||
@@ -0,0 +1,25 @@ | |||
1 | export default { | ||
2 | component: { | ||
3 | left: 0, | ||
4 | position: 'absolute', | ||
5 | top: 0, | ||
6 | width: '100%', | ||
7 | zIndex: 0, | ||
8 | alignItems: 'center', | ||
9 | // background: $theme-gray-lighter; | ||
10 | display: 'flex', | ||
11 | flexDirection: 'column', | ||
12 | justifyContent: 'center', | ||
13 | textAlign: 'center', | ||
14 | }, | ||
15 | buttonContainer: { | ||
16 | display: 'flex', | ||
17 | flexDirection: 'row', | ||
18 | height: 'auto', | ||
19 | margin: [40, 0, 20], | ||
20 | |||
21 | '& button': { | ||
22 | margin: [0, 10, 0, 10], | ||
23 | }, | ||
24 | }, | ||
25 | }; | ||
diff --git a/src/components/services/content/ServiceWebview.js b/src/components/services/content/ServiceWebview.js index 6e56de92f..b3def3fa5 100644 --- a/src/components/services/content/ServiceWebview.js +++ b/src/components/services/content/ServiceWebview.js | |||
@@ -7,7 +7,9 @@ import classnames from 'classnames'; | |||
7 | 7 | ||
8 | import ServiceModel from '../../../models/Service'; | 8 | import ServiceModel from '../../../models/Service'; |
9 | import StatusBarTargetUrl from '../../ui/StatusBarTargetUrl'; | 9 | import StatusBarTargetUrl from '../../ui/StatusBarTargetUrl'; |
10 | import WebviewLoader from '../../ui/WebviewLoader'; | ||
10 | import WebviewCrashHandler from './WebviewCrashHandler'; | 11 | import WebviewCrashHandler from './WebviewCrashHandler'; |
12 | import WebviewErrorHandler from './ErrorHandlers/WebviewErrorHandler'; | ||
11 | import ServiceDisabled from './ServiceDisabled'; | 13 | import ServiceDisabled from './ServiceDisabled'; |
12 | 14 | ||
13 | export default @observer class ServiceWebview extends Component { | 15 | export default @observer class ServiceWebview extends Component { |
@@ -15,6 +17,7 @@ export default @observer class ServiceWebview extends Component { | |||
15 | service: PropTypes.instanceOf(ServiceModel).isRequired, | 17 | service: PropTypes.instanceOf(ServiceModel).isRequired, |
16 | setWebviewReference: PropTypes.func.isRequired, | 18 | setWebviewReference: PropTypes.func.isRequired, |
17 | reload: PropTypes.func.isRequired, | 19 | reload: PropTypes.func.isRequired, |
20 | edit: PropTypes.func.isRequired, | ||
18 | isAppMuted: PropTypes.bool.isRequired, | 21 | isAppMuted: PropTypes.bool.isRequired, |
19 | enable: PropTypes.func.isRequired, | 22 | enable: PropTypes.func.isRequired, |
20 | }; | 23 | }; |
@@ -58,6 +61,7 @@ export default @observer class ServiceWebview extends Component { | |||
58 | service, | 61 | service, |
59 | setWebviewReference, | 62 | setWebviewReference, |
60 | reload, | 63 | reload, |
64 | edit, | ||
61 | isAppMuted, | 65 | isAppMuted, |
62 | enable, | 66 | enable, |
63 | } = this.props; | 67 | } = this.props; |
@@ -85,6 +89,20 @@ export default @observer class ServiceWebview extends Component { | |||
85 | reload={reload} | 89 | reload={reload} |
86 | /> | 90 | /> |
87 | )} | 91 | )} |
92 | {service.isLoading && ( | ||
93 | <WebviewLoader | ||
94 | loaded={!service.isLoading} | ||
95 | name={service.name} | ||
96 | /> | ||
97 | )} | ||
98 | {service.isError && ( | ||
99 | <WebviewErrorHandler | ||
100 | name={service.recipe.name} | ||
101 | errorMessage={service.errorMessage} | ||
102 | reload={reload} | ||
103 | edit={edit} | ||
104 | /> | ||
105 | )} | ||
88 | {!service.isEnabled ? ( | 106 | {!service.isEnabled ? ( |
89 | <ServiceDisabled | 107 | <ServiceDisabled |
90 | name={service.recipe.name} | 108 | name={service.recipe.name} |
diff --git a/src/components/services/content/Services.js b/src/components/services/content/Services.js index 4cbd51043..0d4d778cd 100644 --- a/src/components/services/content/Services.js +++ b/src/components/services/content/Services.js | |||
@@ -25,6 +25,7 @@ export default @observer class Services extends Component { | |||
25 | handleIPCMessage: PropTypes.func.isRequired, | 25 | handleIPCMessage: PropTypes.func.isRequired, |
26 | openWindow: PropTypes.func.isRequired, | 26 | openWindow: PropTypes.func.isRequired, |
27 | reload: PropTypes.func.isRequired, | 27 | reload: PropTypes.func.isRequired, |
28 | openSettings: PropTypes.func.isRequired, | ||
28 | isAppMuted: PropTypes.bool.isRequired, | 29 | isAppMuted: PropTypes.bool.isRequired, |
29 | update: PropTypes.func.isRequired, | 30 | update: PropTypes.func.isRequired, |
30 | }; | 31 | }; |
@@ -45,6 +46,7 @@ export default @observer class Services extends Component { | |||
45 | setWebviewReference, | 46 | setWebviewReference, |
46 | openWindow, | 47 | openWindow, |
47 | reload, | 48 | reload, |
49 | openSettings, | ||
48 | isAppMuted, | 50 | isAppMuted, |
49 | update, | 51 | update, |
50 | } = this.props; | 52 | } = this.props; |
@@ -79,6 +81,7 @@ export default @observer class Services extends Component { | |||
79 | setWebviewReference={setWebviewReference} | 81 | setWebviewReference={setWebviewReference} |
80 | openWindow={openWindow} | 82 | openWindow={openWindow} |
81 | reload={() => reload({ serviceId: service.id })} | 83 | reload={() => reload({ serviceId: service.id })} |
84 | edit={() => openSettings({ path: `services/edit/${service.id}` })} | ||
82 | isAppMuted={isAppMuted} | 85 | isAppMuted={isAppMuted} |
83 | enable={() => update({ | 86 | enable={() => update({ |
84 | serviceId: service.id, | 87 | serviceId: service.id, |