aboutsummaryrefslogtreecommitdiffstats
path: root/src/components
diff options
context:
space:
mode:
authorLibravatar Stefan Malzner <stefan@adlk.io>2018-12-09 13:24:17 +0100
committerLibravatar Stefan Malzner <stefan@adlk.io>2018-12-09 13:24:17 +0100
commit898d54cd0034bbb2727bc5b5eaf9d5a4f2a852de (patch)
tree9816c013f9a9453dae07d9dd8d4a862c77c23064 /src/components
parentUpgrade to react 16 (diff)
downloadferdium-app-898d54cd0034bbb2727bc5b5eaf9d5a4f2a852de.tar.gz
ferdium-app-898d54cd0034bbb2727bc5b5eaf9d5a4f2a852de.tar.zst
ferdium-app-898d54cd0034bbb2727bc5b5eaf9d5a4f2a852de.zip
Add React 16 didCatch/ErrorBoundary component
Diffstat (limited to 'src/components')
-rw-r--r--src/components/layout/AppLayout.js134
-rw-r--r--src/components/services/content/ServiceWebview.js1
-rw-r--r--src/components/settings/SettingsLayout.js21
-rw-r--r--src/components/util/ErrorBoundary/index.js54
-rw-r--r--src/components/util/ErrorBoundary/styles.js13
5 files changed, 149 insertions, 74 deletions
diff --git a/src/components/layout/AppLayout.js b/src/components/layout/AppLayout.js
index 3ababe54a..e526f6b1f 100644
--- a/src/components/layout/AppLayout.js
+++ b/src/components/layout/AppLayout.js
@@ -6,6 +6,8 @@ import { TitleBar } from 'electron-react-titlebar';
6 6
7import InfoBar from '../ui/InfoBar'; 7import InfoBar from '../ui/InfoBar';
8import { Component as DelayApp } from '../../features/delayApp'; 8import { Component as DelayApp } from '../../features/delayApp';
9import ErrorBoundary from '../util/ErrorBoundary';
10
9import globalMessages from '../../i18n/globalMessages'; 11import globalMessages from '../../i18n/globalMessages';
10 12
11import { isWindows } from '../../environment'; 13import { isWindows } from '../../environment';
@@ -94,74 +96,76 @@ export default @observer class AppLayout extends Component {
94 const { intl } = this.context; 96 const { intl } = this.context;
95 97
96 return ( 98 return (
97 <div className={(darkMode ? 'theme__dark' : '')}> 99 <ErrorBoundary>
98 <div className="app"> 100 <div className={(darkMode ? 'theme__dark' : '')}>
99 {isWindows && !isFullScreen && <TitleBar menu={window.franz.menu.template} icon={'assets/images/logo.svg'} />} 101 <div className="app">
100 <div className="app__content"> 102 {isWindows && !isFullScreen && <TitleBar menu={window.franz.menu.template} icon={'assets/images/logo.svg'} />}
101 {sidebar} 103 <div className="app__content">
102 <div className="app__service"> 104 {sidebar}
103 {news.length > 0 && news.map(item => ( 105 <div className="app__service">
104 <InfoBar 106 {news.length > 0 && news.map(item => (
105 key={item.id} 107 <InfoBar
106 position="top" 108 key={item.id}
107 type={item.type} 109 position="top"
108 sticky={item.sticky} 110 type={item.type}
109 onHide={() => removeNewsItem({ newsId: item.id })} 111 sticky={item.sticky}
110 > 112 onHide={() => removeNewsItem({ newsId: item.id })}
111 <span dangerouslySetInnerHTML={createMarkup(item.message)} /> 113 >
112 </InfoBar> 114 <span dangerouslySetInnerHTML={createMarkup(item.message)} />
113 ))} 115 </InfoBar>
114 {!isOnline && ( 116 ))}
115 <InfoBar 117 {!isOnline && (
116 type="danger" 118 <InfoBar
117 > 119 type="danger"
118 <span className="mdi mdi-flash" /> 120 >
119 {intl.formatMessage(globalMessages.notConnectedToTheInternet)} 121 <span className="mdi mdi-flash" />
120 </InfoBar> 122 {intl.formatMessage(globalMessages.notConnectedToTheInternet)}
121 )} 123 </InfoBar>
122 {!areRequiredRequestsSuccessful && showRequiredRequestsError && ( 124 )}
123 <InfoBar 125 {!areRequiredRequestsSuccessful && showRequiredRequestsError && (
124 type="danger" 126 <InfoBar
125 ctaLabel="Try again" 127 type="danger"
126 ctaLoading={areRequiredRequestsLoading} 128 ctaLabel="Try again"
127 sticky 129 ctaLoading={areRequiredRequestsLoading}
128 onClick={retryRequiredRequests} 130 sticky
129 > 131 onClick={retryRequiredRequests}
130 <span className="mdi mdi-flash" /> 132 >
131 {intl.formatMessage(messages.requiredRequestsFailed)} 133 <span className="mdi mdi-flash" />
132 </InfoBar> 134 {intl.formatMessage(messages.requiredRequestsFailed)}
133 )} 135 </InfoBar>
134 {showServicesUpdatedInfoBar && ( 136 )}
135 <InfoBar 137 {showServicesUpdatedInfoBar && (
136 type="primary" 138 <InfoBar
137 ctaLabel={intl.formatMessage(messages.buttonReloadServices)} 139 type="primary"
138 onClick={reloadServicesAfterUpdate} 140 ctaLabel={intl.formatMessage(messages.buttonReloadServices)}
139 sticky 141 onClick={reloadServicesAfterUpdate}
140 > 142 sticky
141 <span className="mdi mdi-power-plug" /> 143 >
142 {intl.formatMessage(messages.servicesUpdated)} 144 <span className="mdi mdi-power-plug" />
143 </InfoBar> 145 {intl.formatMessage(messages.servicesUpdated)}
144 )} 146 </InfoBar>
145 {appUpdateIsDownloaded && ( 147 )}
146 <InfoBar 148 {appUpdateIsDownloaded && (
147 type="primary" 149 <InfoBar
148 ctaLabel={intl.formatMessage(messages.buttonInstallUpdate)} 150 type="primary"
149 onClick={installAppUpdate} 151 ctaLabel={intl.formatMessage(messages.buttonInstallUpdate)}
150 sticky 152 onClick={installAppUpdate}
151 > 153 sticky
152 <span className="mdi mdi-information" /> 154 >
153 {intl.formatMessage(messages.updateAvailable)} <a href="https://meetfranz.com/changelog" target="_blank"> 155 <span className="mdi mdi-information" />
154 <u>{intl.formatMessage(messages.changelog)}</u> 156 {intl.formatMessage(messages.updateAvailable)} <a href="https://meetfranz.com/changelog" target="_blank">
155 </a> 157 <u>{intl.formatMessage(messages.changelog)}</u>
156 </InfoBar> 158 </a>
157 )} 159 </InfoBar>
158 {isDelayAppScreenVisible && (<DelayApp />)} 160 )}
159 {services} 161 {isDelayAppScreenVisible && (<DelayApp />)}
162 {services}
163 </div>
160 </div> 164 </div>
161 </div> 165 </div>
166 {children}
162 </div> 167 </div>
163 {children} 168 </ErrorBoundary>
164 </div>
165 ); 169 );
166 } 170 }
167} 171}
diff --git a/src/components/services/content/ServiceWebview.js b/src/components/services/content/ServiceWebview.js
index f59205c0e..98daf9b9f 100644
--- a/src/components/services/content/ServiceWebview.js
+++ b/src/components/services/content/ServiceWebview.js
@@ -59,6 +59,7 @@ export default @observer class ServiceWebview extends Component {
59 } 59 }
60 60
61 autorunDisposer = null; 61 autorunDisposer = null;
62
62 webview = null; 63 webview = null;
63 64
64 render() { 65 render() {
diff --git a/src/components/settings/SettingsLayout.js b/src/components/settings/SettingsLayout.js
index 3cb08feb1..d5d8f0bb0 100644
--- a/src/components/settings/SettingsLayout.js
+++ b/src/components/settings/SettingsLayout.js
@@ -2,6 +2,7 @@ import React, { Component } from 'react';
2import PropTypes from 'prop-types'; 2import PropTypes from 'prop-types';
3import { observer } from 'mobx-react'; 3import { observer } from 'mobx-react';
4 4
5import ErrorBoundary from '../util/ErrorBoundary';
5import { oneOrManyChildElements } from '../../prop-types'; 6import { oneOrManyChildElements } from '../../prop-types';
6import Appear from '../ui/effects/Appear'; 7import Appear from '../ui/effects/Appear';
7 8
@@ -36,18 +37,20 @@ export default @observer class SettingsLayout extends Component {
36 return ( 37 return (
37 <Appear transitionName="fadeIn-fast"> 38 <Appear transitionName="fadeIn-fast">
38 <div className="settings-wrapper"> 39 <div className="settings-wrapper">
39 <button 40 <ErrorBoundary>
40 className="settings-wrapper__action"
41 onClick={closeSettings}
42 />
43 <div className="settings franz-form">
44 {navigation}
45 {children}
46 <button 41 <button
47 className="settings__close mdi mdi-close" 42 className="settings-wrapper__action"
48 onClick={closeSettings} 43 onClick={closeSettings}
49 /> 44 />
50 </div> 45 <div className="settings franz-form">
46 {navigation}
47 {children}
48 <button
49 className="settings__close mdi mdi-close"
50 onClick={closeSettings}
51 />
52 </div>
53 </ErrorBoundary>
51 </div> 54 </div>
52 </Appear> 55 </Appear>
53 ); 56 );
diff --git a/src/components/util/ErrorBoundary/index.js b/src/components/util/ErrorBoundary/index.js
new file mode 100644
index 000000000..def01c74f
--- /dev/null
+++ b/src/components/util/ErrorBoundary/index.js
@@ -0,0 +1,54 @@
1import React, { Component } from 'react';
2import injectSheet from 'react-jss';
3import { defineMessages, intlShape } from 'react-intl';
4
5import Button from '../../ui/Button';
6
7import styles from './styles';
8
9const messages = defineMessages({
10 headline: {
11 id: 'app.errorHandler.headline',
12 defaultMessage: '!!!Something went wrong.',
13 },
14 action: {
15 id: 'app.errorHandler.action',
16 defaultMessage: '!!!Reload',
17 },
18});
19
20export default @injectSheet(styles) class ErrorBoundary extends Component {
21 state = {
22 hasError: false,
23 }
24
25 static contextTypes = {
26 intl: intlShape,
27 };
28
29 componentDidCatch(error, info) {
30 this.setState({ hasError: true });
31 }
32
33 render() {
34 const { classes } = this.props;
35 const { intl } = this.context;
36
37 if (this.state.hasError) {
38 return (
39 <div className={classes.component}>
40 <h1 className={classes.title}>
41 {intl.formatMessage(messages.headline)}
42 </h1>
43 <Button
44 label={intl.formatMessage(messages.action)}
45 buttonType="inverted"
46 onClick={() => location.reload()}
47 />
48 </div>
49 );
50 }
51
52 return this.props.children;
53 }
54} \ No newline at end of file
diff --git a/src/components/util/ErrorBoundary/styles.js b/src/components/util/ErrorBoundary/styles.js
new file mode 100644
index 000000000..8d62767f6
--- /dev/null
+++ b/src/components/util/ErrorBoundary/styles.js
@@ -0,0 +1,13 @@
1export default (theme) => ({
2 component: {
3 display: 'flex',
4 width: '100%',
5 alignItems: 'center',
6 justifyContent: 'center',
7 flexDirection: 'column',
8 },
9 title: {
10 fontSize: 20,
11 color: theme.colorText,
12 }
13});