diff options
Diffstat (limited to 'src/components/services/content/WebviewCrashHandler.tsx')
-rw-r--r-- | src/components/services/content/WebviewCrashHandler.tsx | 90 |
1 files changed, 90 insertions, 0 deletions
diff --git a/src/components/services/content/WebviewCrashHandler.tsx b/src/components/services/content/WebviewCrashHandler.tsx new file mode 100644 index 000000000..e9b17e8aa --- /dev/null +++ b/src/components/services/content/WebviewCrashHandler.tsx | |||
@@ -0,0 +1,90 @@ | |||
1 | import { Component, ReactElement } from 'react'; | ||
2 | import { observer } from 'mobx-react'; | ||
3 | import { defineMessages, injectIntl, WrappedComponentProps } from 'react-intl'; | ||
4 | import ms from 'ms'; | ||
5 | import Button from '../../ui/button'; | ||
6 | import { H1 } from '../../ui/headline'; | ||
7 | |||
8 | const messages = defineMessages({ | ||
9 | headline: { | ||
10 | id: 'service.crashHandler.headline', | ||
11 | defaultMessage: 'Oh no!', | ||
12 | }, | ||
13 | text: { | ||
14 | id: 'service.crashHandler.text', | ||
15 | defaultMessage: '{name} has caused an error.', | ||
16 | }, | ||
17 | action: { | ||
18 | id: 'service.crashHandler.action', | ||
19 | defaultMessage: 'Reload {name}', | ||
20 | }, | ||
21 | autoReload: { | ||
22 | id: 'service.crashHandler.autoReload', | ||
23 | defaultMessage: | ||
24 | 'Trying to automatically restore {name} in {seconds} seconds', | ||
25 | }, | ||
26 | }); | ||
27 | |||
28 | interface IProps extends WrappedComponentProps { | ||
29 | name: string; | ||
30 | reload: () => void; | ||
31 | } | ||
32 | |||
33 | interface IState { | ||
34 | countdown: number; | ||
35 | } | ||
36 | |||
37 | @observer | ||
38 | class WebviewCrashHandler extends Component<IProps, IState> { | ||
39 | countdownInterval: NodeJS.Timer | undefined; | ||
40 | |||
41 | countdownIntervalTimeout = ms('1s'); | ||
42 | |||
43 | constructor(props: IProps) { | ||
44 | super(props); | ||
45 | |||
46 | this.state = { | ||
47 | countdown: ms('10s'), | ||
48 | }; | ||
49 | } | ||
50 | |||
51 | componentDidMount(): void { | ||
52 | const { reload } = this.props; | ||
53 | |||
54 | this.countdownInterval = setInterval(() => { | ||
55 | this.setState(prevState => ({ | ||
56 | countdown: prevState.countdown - this.countdownIntervalTimeout, | ||
57 | })); | ||
58 | |||
59 | if (this.state.countdown <= 0) { | ||
60 | reload(); | ||
61 | clearInterval(this.countdownInterval!); | ||
62 | } | ||
63 | }, this.countdownIntervalTimeout); | ||
64 | } | ||
65 | |||
66 | render(): ReactElement { | ||
67 | const { name, reload, intl } = this.props; | ||
68 | |||
69 | return ( | ||
70 | <div className="services__info-layer"> | ||
71 | <H1>{intl.formatMessage(messages.headline)}</H1> | ||
72 | <p>{intl.formatMessage(messages.text, { name })}</p> | ||
73 | <Button | ||
74 | // label={`Reload ${name}`} | ||
75 | label={intl.formatMessage(messages.action, { name })} | ||
76 | buttonType="inverted" | ||
77 | onClick={() => reload()} | ||
78 | /> | ||
79 | <p className="footnote"> | ||
80 | {intl.formatMessage(messages.autoReload, { | ||
81 | name, | ||
82 | seconds: this.state.countdown / ms('1s'), | ||
83 | })} | ||
84 | </p> | ||
85 | </div> | ||
86 | ); | ||
87 | } | ||
88 | } | ||
89 | |||
90 | export default injectIntl(WebviewCrashHandler); | ||