diff options
Diffstat (limited to 'src/components/services')
-rw-r--r-- | src/components/services/content/ServiceView.js | 77 | ||||
-rw-r--r-- | src/components/services/content/ServiceWebview.js | 20 | ||||
-rw-r--r-- | src/components/services/content/Services.js | 23 |
3 files changed, 104 insertions, 16 deletions
diff --git a/src/components/services/content/ServiceView.js b/src/components/services/content/ServiceView.js index e8df58a1e..74d8af0bc 100644 --- a/src/components/services/content/ServiceView.js +++ b/src/components/services/content/ServiceView.js | |||
@@ -1,8 +1,9 @@ | |||
1 | import React, { Component, Fragment } from 'react'; | 1 | import React, { Component, Fragment } from 'react'; |
2 | import PropTypes from 'prop-types'; | 2 | import PropTypes from 'prop-types'; |
3 | import { autorun } from 'mobx'; | 3 | import { autorun, reaction } from 'mobx'; |
4 | import { observer } from 'mobx-react'; | 4 | import { observer, inject } from 'mobx-react'; |
5 | import classnames from 'classnames'; | 5 | import classnames from 'classnames'; |
6 | import ms from 'ms'; | ||
6 | 7 | ||
7 | import ServiceModel from '../../../models/Service'; | 8 | import ServiceModel from '../../../models/Service'; |
8 | import StatusBarTargetUrl from '../../ui/StatusBarTargetUrl'; | 9 | import StatusBarTargetUrl from '../../ui/StatusBarTargetUrl'; |
@@ -10,11 +11,11 @@ import WebviewLoader from '../../ui/WebviewLoader'; | |||
10 | import WebviewCrashHandler from './WebviewCrashHandler'; | 11 | import WebviewCrashHandler from './WebviewCrashHandler'; |
11 | import WebviewErrorHandler from './ErrorHandlers/WebviewErrorHandler'; | 12 | import WebviewErrorHandler from './ErrorHandlers/WebviewErrorHandler'; |
12 | import ServiceDisabled from './ServiceDisabled'; | 13 | import ServiceDisabled from './ServiceDisabled'; |
13 | import ServiceRestricted from './ServiceRestricted'; | ||
14 | import ServiceWebview from './ServiceWebview'; | 14 | import ServiceWebview from './ServiceWebview'; |
15 | import SettingsStore from '../../../stores/SettingsStore'; | ||
15 | import WebControlsScreen from '../../../features/webControls/containers/WebControlsScreen'; | 16 | import WebControlsScreen from '../../../features/webControls/containers/WebControlsScreen'; |
16 | 17 | ||
17 | export default @observer class ServiceView extends Component { | 18 | export default @observer @inject('stores') class ServiceView extends Component { |
18 | static propTypes = { | 19 | static propTypes = { |
19 | service: PropTypes.instanceOf(ServiceModel).isRequired, | 20 | service: PropTypes.instanceOf(ServiceModel).isRequired, |
20 | setWebviewReference: PropTypes.func.isRequired, | 21 | setWebviewReference: PropTypes.func.isRequired, |
@@ -23,7 +24,9 @@ export default @observer class ServiceView extends Component { | |||
23 | edit: PropTypes.func.isRequired, | 24 | edit: PropTypes.func.isRequired, |
24 | enable: PropTypes.func.isRequired, | 25 | enable: PropTypes.func.isRequired, |
25 | isActive: PropTypes.bool, | 26 | isActive: PropTypes.bool, |
26 | upgrade: PropTypes.func.isRequired, | 27 | stores: PropTypes.shape({ |
28 | settings: PropTypes.instanceOf(SettingsStore).isRequired, | ||
29 | }).isRequired, | ||
27 | }; | 30 | }; |
28 | 31 | ||
29 | static defaultProps = { | 32 | static defaultProps = { |
@@ -34,12 +37,20 @@ export default @observer class ServiceView extends Component { | |||
34 | forceRepaint: false, | 37 | forceRepaint: false, |
35 | targetUrl: '', | 38 | targetUrl: '', |
36 | statusBarVisible: false, | 39 | statusBarVisible: false, |
40 | hibernate: false, | ||
41 | hibernationTimer: null, | ||
37 | }; | 42 | }; |
38 | 43 | ||
39 | autorunDisposer = null; | 44 | autorunDisposer = null; |
40 | 45 | ||
41 | forceRepaintTimeout = null; | 46 | forceRepaintTimeout = null; |
42 | 47 | ||
48 | constructor(props) { | ||
49 | super(props); | ||
50 | |||
51 | this.startHibernationTimer = this.startHibernationTimer.bind(this); | ||
52 | } | ||
53 | |||
43 | componentDidMount() { | 54 | componentDidMount() { |
44 | this.autorunDisposer = autorun(() => { | 55 | this.autorunDisposer = autorun(() => { |
45 | if (this.props.service.isActive) { | 56 | if (this.props.service.isActive) { |
@@ -49,6 +60,31 @@ export default @observer class ServiceView extends Component { | |||
49 | }, 100); | 60 | }, 100); |
50 | } | 61 | } |
51 | }); | 62 | }); |
63 | |||
64 | reaction( | ||
65 | () => this.props.service.isActive, | ||
66 | () => { | ||
67 | if (!this.props.service.isActive && this.props.stores.settings.all.app.hibernate) { | ||
68 | // Service is inactive - start hibernation countdown | ||
69 | this.startHibernationTimer(); | ||
70 | } else { | ||
71 | if (this.state.hibernationTimer) { | ||
72 | // Service is active but we have an active hibernation timer: Clear timeout | ||
73 | clearTimeout(this.state.hibernationTimer); | ||
74 | } | ||
75 | |||
76 | // Service is active, wake up service from hibernation | ||
77 | this.setState({ | ||
78 | hibernate: false, | ||
79 | }); | ||
80 | } | ||
81 | }, | ||
82 | ); | ||
83 | |||
84 | // Start hibernation counter if we are in background | ||
85 | if (!this.props.service.isActive && this.props.stores.settings.all.app.hibernate) { | ||
86 | this.startHibernationTimer(); | ||
87 | } | ||
52 | } | 88 | } |
53 | 89 | ||
54 | componentWillUnmount() { | 90 | componentWillUnmount() { |
@@ -67,6 +103,18 @@ export default @observer class ServiceView extends Component { | |||
67 | }); | 103 | }); |
68 | }; | 104 | }; |
69 | 105 | ||
106 | startHibernationTimer() { | ||
107 | const hibernationTimer = setTimeout(() => { | ||
108 | this.setState({ | ||
109 | hibernate: true, | ||
110 | }); | ||
111 | }, ms('5m')); | ||
112 | |||
113 | this.setState({ | ||
114 | hibernationTimer, | ||
115 | }); | ||
116 | } | ||
117 | |||
70 | render() { | 118 | render() { |
71 | const { | 119 | const { |
72 | detachService, | 120 | detachService, |
@@ -75,7 +123,6 @@ export default @observer class ServiceView extends Component { | |||
75 | reload, | 123 | reload, |
76 | edit, | 124 | edit, |
77 | enable, | 125 | enable, |
78 | upgrade, | ||
79 | } = this.props; | 126 | } = this.props; |
80 | 127 | ||
81 | const webviewClasses = classnames({ | 128 | const webviewClasses = classnames({ |
@@ -142,11 +189,19 @@ export default @observer class ServiceView extends Component { | |||
142 | {service.recipe.id === 'franz-custom-website' && ( | 189 | {service.recipe.id === 'franz-custom-website' && ( |
143 | <WebControlsScreen service={service} /> | 190 | <WebControlsScreen service={service} /> |
144 | )} | 191 | )} |
145 | <ServiceWebview | 192 | {!this.state.hibernate ? ( |
146 | service={service} | 193 | <ServiceWebview |
147 | setWebviewReference={setWebviewReference} | 194 | service={service} |
148 | detachService={detachService} | 195 | setWebviewReference={setWebviewReference} |
149 | /> | 196 | detachService={detachService} |
197 | /> | ||
198 | ) : ( | ||
199 | <div> | ||
200 | <span role="img" aria-label="Sleeping Emoji">😴</span> | ||
201 | {' '} | ||
202 | This service is currently hibernating. If this page doesn't close soon, please try reloading Ferdi. | ||
203 | </div> | ||
204 | )} | ||
150 | </> | 205 | </> |
151 | )} | 206 | )} |
152 | </> | 207 | </> |
diff --git a/src/components/services/content/ServiceWebview.js b/src/components/services/content/ServiceWebview.js index 07bd17d9c..03d6d5bcc 100644 --- a/src/components/services/content/ServiceWebview.js +++ b/src/components/services/content/ServiceWebview.js | |||
@@ -1,10 +1,13 @@ | |||
1 | import React, { Component } from 'react'; | 1 | import React, { Component } from 'react'; |
2 | import PropTypes from 'prop-types'; | 2 | import PropTypes from 'prop-types'; |
3 | import { observer } from 'mobx-react'; | 3 | import { observer } from 'mobx-react'; |
4 | import { observable, reaction } from 'mobx'; | ||
4 | import ElectronWebView from 'react-electron-web-view'; | 5 | import ElectronWebView from 'react-electron-web-view'; |
5 | 6 | ||
6 | import ServiceModel from '../../../models/Service'; | 7 | import ServiceModel from '../../../models/Service'; |
7 | 8 | ||
9 | const debug = require('debug')('Ferdi:Services'); | ||
10 | |||
8 | @observer | 11 | @observer |
9 | class ServiceWebview extends Component { | 12 | class ServiceWebview extends Component { |
10 | static propTypes = { | 13 | static propTypes = { |
@@ -13,7 +16,22 @@ class ServiceWebview extends Component { | |||
13 | detachService: PropTypes.func.isRequired, | 16 | detachService: PropTypes.func.isRequired, |
14 | }; | 17 | }; |
15 | 18 | ||
16 | webview = null; | 19 | @observable webview = null; |
20 | |||
21 | constructor(props) { | ||
22 | super(props); | ||
23 | |||
24 | reaction( | ||
25 | () => this.webview, | ||
26 | () => { | ||
27 | if (this.webview && this.webview.view) { | ||
28 | this.webview.view.addEventListener('console-message', (e) => { | ||
29 | debug('Service logged a message:', e.message); | ||
30 | }); | ||
31 | } | ||
32 | }, | ||
33 | ); | ||
34 | } | ||
17 | 35 | ||
18 | componentWillUnmount() { | 36 | componentWillUnmount() { |
19 | const { service, detachService } = this.props; | 37 | const { service, detachService } = this.props; |
diff --git a/src/components/services/content/Services.js b/src/components/services/content/Services.js index 73c27bfb6..1afbaabc4 100644 --- a/src/components/services/content/Services.js +++ b/src/components/services/content/Services.js | |||
@@ -13,12 +13,20 @@ import Appear from '../../ui/effects/Appear'; | |||
13 | const messages = defineMessages({ | 13 | const messages = defineMessages({ |
14 | welcome: { | 14 | welcome: { |
15 | id: 'services.welcome', | 15 | id: 'services.welcome', |
16 | defaultMessage: '!!!Welcome to Franz', | 16 | defaultMessage: '!!!Welcome to Ferdi', |
17 | }, | 17 | }, |
18 | getStarted: { | 18 | getStarted: { |
19 | id: 'services.getStarted', | 19 | id: 'services.getStarted', |
20 | defaultMessage: '!!!Get started', | 20 | defaultMessage: '!!!Get started', |
21 | }, | 21 | }, |
22 | login: { | ||
23 | id: 'services.login', | ||
24 | defaultMessage: '!!!Please login to use Ferdi.', | ||
25 | }, | ||
26 | serverInfo: { | ||
27 | id: 'services.serverInfo', | ||
28 | defaultMessage: '!!!Optionally, you can change your Ferdi server by clicking the cog in the bottom left corner.', | ||
29 | }, | ||
22 | }); | 30 | }); |
23 | 31 | ||
24 | 32 | ||
@@ -86,6 +94,7 @@ export default @observer @injectSheet(styles) class Services extends Component { | |||
86 | } = this.state; | 94 | } = this.state; |
87 | 95 | ||
88 | const { intl } = this.context; | 96 | const { intl } = this.context; |
97 | const isLoggedIn = Boolean(localStorage.getItem('authToken')); | ||
89 | 98 | ||
90 | return ( | 99 | return ( |
91 | <div className="services"> | 100 | <div className="services"> |
@@ -104,14 +113,20 @@ export default @observer @injectSheet(styles) class Services extends Component { | |||
104 | transitionName="slideUp" | 113 | transitionName="slideUp" |
105 | > | 114 | > |
106 | <div className="services__no-service"> | 115 | <div className="services__no-service"> |
107 | <img src="./assets/images/logo.svg" alt="" /> | 116 | <img src="./assets/images/logo.svg" alt="Logo" style={{ maxHeight: '50vh' }} /> |
108 | <h1>{intl.formatMessage(messages.welcome)}</h1> | 117 | <h1>{intl.formatMessage(messages.welcome)}</h1> |
118 | { !isLoggedIn && ( | ||
119 | <> | ||
120 | <p>{intl.formatMessage(messages.login)}</p> | ||
121 | <p>{intl.formatMessage(messages.serverInfo)}</p> | ||
122 | </> | ||
123 | ) } | ||
109 | <Appear | 124 | <Appear |
110 | timeout={300} | 125 | timeout={300} |
111 | transitionName="slideUp" | 126 | transitionName="slideUp" |
112 | > | 127 | > |
113 | <Link to="/settings/recipes" className="button"> | 128 | <Link to={isLoggedIn ? '/settings/services' : '/auth/welcome'} className="button"> |
114 | {intl.formatMessage(messages.getStarted)} | 129 | { isLoggedIn ? intl.formatMessage(messages.getStarted) : 'Login' } |
115 | </Link> | 130 | </Link> |
116 | </Appear> | 131 | </Appear> |
117 | </div> | 132 | </div> |