diff options
Diffstat (limited to 'src/components/services/content')
-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, 102 insertions, 18 deletions
diff --git a/src/components/services/content/ServiceView.js b/src/components/services/content/ServiceView.js index 3b09518c5..273653ea2 100644 --- a/src/components/services/content/ServiceView.js +++ b/src/components/services/content/ServiceView.js | |||
@@ -1,7 +1,7 @@ | |||
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 | 6 | ||
7 | import ServiceModel from '../../../models/Service'; | 7 | import ServiceModel from '../../../models/Service'; |
@@ -10,12 +10,12 @@ import WebviewLoader from '../../ui/WebviewLoader'; | |||
10 | import WebviewCrashHandler from './WebviewCrashHandler'; | 10 | import WebviewCrashHandler from './WebviewCrashHandler'; |
11 | import WebviewErrorHandler from './ErrorHandlers/WebviewErrorHandler'; | 11 | import WebviewErrorHandler from './ErrorHandlers/WebviewErrorHandler'; |
12 | import ServiceDisabled from './ServiceDisabled'; | 12 | import ServiceDisabled from './ServiceDisabled'; |
13 | import ServiceRestricted from './ServiceRestricted'; | ||
14 | import ServiceWebview from './ServiceWebview'; | 13 | import ServiceWebview from './ServiceWebview'; |
14 | import SettingsStore from '../../../stores/SettingsStore'; | ||
15 | import WebControlsScreen from '../../../features/webControls/containers/WebControlsScreen'; | 15 | import WebControlsScreen from '../../../features/webControls/containers/WebControlsScreen'; |
16 | import { CUSTOM_WEBSITE_ID } from '../../../features/webControls/constants'; | 16 | import { CUSTOM_WEBSITE_ID } from '../../../features/webControls/constants'; |
17 | 17 | ||
18 | export default @observer class ServiceView extends Component { | 18 | export default @observer @inject('stores') class ServiceView extends Component { |
19 | static propTypes = { | 19 | static propTypes = { |
20 | service: PropTypes.instanceOf(ServiceModel).isRequired, | 20 | service: PropTypes.instanceOf(ServiceModel).isRequired, |
21 | setWebviewReference: PropTypes.func.isRequired, | 21 | setWebviewReference: PropTypes.func.isRequired, |
@@ -24,7 +24,9 @@ export default @observer class ServiceView extends Component { | |||
24 | edit: PropTypes.func.isRequired, | 24 | edit: PropTypes.func.isRequired, |
25 | enable: PropTypes.func.isRequired, | 25 | enable: PropTypes.func.isRequired, |
26 | isActive: PropTypes.bool, | 26 | isActive: PropTypes.bool, |
27 | upgrade: PropTypes.func.isRequired, | 27 | stores: PropTypes.shape({ |
28 | settings: PropTypes.instanceOf(SettingsStore).isRequired, | ||
29 | }).isRequired, | ||
28 | }; | 30 | }; |
29 | 31 | ||
30 | static defaultProps = { | 32 | static defaultProps = { |
@@ -35,12 +37,20 @@ export default @observer class ServiceView extends Component { | |||
35 | forceRepaint: false, | 37 | forceRepaint: false, |
36 | targetUrl: '', | 38 | targetUrl: '', |
37 | statusBarVisible: false, | 39 | statusBarVisible: false, |
40 | hibernate: false, | ||
41 | hibernationTimer: null, | ||
38 | }; | 42 | }; |
39 | 43 | ||
40 | autorunDisposer = null; | 44 | autorunDisposer = null; |
41 | 45 | ||
42 | forceRepaintTimeout = null; | 46 | forceRepaintTimeout = null; |
43 | 47 | ||
48 | constructor(props) { | ||
49 | super(props); | ||
50 | |||
51 | this.startHibernationTimer = this.startHibernationTimer.bind(this); | ||
52 | } | ||
53 | |||
44 | componentDidMount() { | 54 | componentDidMount() { |
45 | this.autorunDisposer = autorun(() => { | 55 | this.autorunDisposer = autorun(() => { |
46 | if (this.props.service.isActive) { | 56 | if (this.props.service.isActive) { |
@@ -50,6 +60,31 @@ export default @observer class ServiceView extends Component { | |||
50 | }, 100); | 60 | }, 100); |
51 | } | 61 | } |
52 | }); | 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 | } | ||
53 | } | 88 | } |
54 | 89 | ||
55 | componentWillUnmount() { | 90 | componentWillUnmount() { |
@@ -68,6 +103,20 @@ export default @observer class ServiceView extends Component { | |||
68 | }); | 103 | }); |
69 | }; | 104 | }; |
70 | 105 | ||
106 | startHibernationTimer() { | ||
107 | const timerDuration = (Number(this.props.stores.settings.all.app.hibernationStrategy) || 300) * 1000; | ||
108 | |||
109 | const hibernationTimer = setTimeout(() => { | ||
110 | this.setState({ | ||
111 | hibernate: true, | ||
112 | }); | ||
113 | }, timerDuration); | ||
114 | |||
115 | this.setState({ | ||
116 | hibernationTimer, | ||
117 | }); | ||
118 | } | ||
119 | |||
71 | render() { | 120 | render() { |
72 | const { | 121 | const { |
73 | detachService, | 122 | detachService, |
@@ -76,7 +125,6 @@ export default @observer class ServiceView extends Component { | |||
76 | reload, | 125 | reload, |
77 | edit, | 126 | edit, |
78 | enable, | 127 | enable, |
79 | upgrade, | ||
80 | } = this.props; | 128 | } = this.props; |
81 | 129 | ||
82 | const webviewClasses = classnames({ | 130 | const webviewClasses = classnames({ |
@@ -132,13 +180,10 @@ export default @observer class ServiceView extends Component { | |||
132 | </Fragment> | 180 | </Fragment> |
133 | ) : ( | 181 | ) : ( |
134 | <> | 182 | <> |
135 | {service.isServiceAccessRestricted ? ( | 183 | {service.recipe.id === 'franz-custom-website' && ( |
136 | <ServiceRestricted | 184 | <WebControlsScreen service={service} /> |
137 | name={service.recipe.name} | 185 | )} |
138 | upgrade={upgrade} | 186 | {!this.state.hibernate ? ( |
139 | type={service.restrictionType} | ||
140 | /> | ||
141 | ) : ( | ||
142 | <> | 187 | <> |
143 | {service.recipe.id === CUSTOM_WEBSITE_ID && ( | 188 | {service.recipe.id === CUSTOM_WEBSITE_ID && ( |
144 | <WebControlsScreen service={service} /> | 189 | <WebControlsScreen service={service} /> |
@@ -149,6 +194,12 @@ export default @observer class ServiceView extends Component { | |||
149 | detachService={detachService} | 194 | detachService={detachService} |
150 | /> | 195 | /> |
151 | </> | 196 | </> |
197 | ) : ( | ||
198 | <div> | ||
199 | <span role="img" aria-label="Sleeping Emoji">😴</span> | ||
200 | {' '} | ||
201 | This service is currently hibernating. If this page doesn't close soon, please try reloading Ferdi. | ||
202 | </div> | ||
152 | )} | 203 | )} |
153 | </> | 204 | </> |
154 | )} | 205 | )} |
diff --git a/src/components/services/content/ServiceWebview.js b/src/components/services/content/ServiceWebview.js index 4bab4a964..e6ebb6afb 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 b6291666b..edff29ae8 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 | ||
@@ -94,6 +102,7 @@ export default @observer @injectSheet(styles) class Services extends Component { | |||
94 | } = this.state; | 102 | } = this.state; |
95 | 103 | ||
96 | const { intl } = this.context; | 104 | const { intl } = this.context; |
105 | const isLoggedIn = Boolean(localStorage.getItem('authToken')); | ||
97 | 106 | ||
98 | return ( | 107 | return ( |
99 | <div className="services"> | 108 | <div className="services"> |
@@ -112,14 +121,20 @@ export default @observer @injectSheet(styles) class Services extends Component { | |||
112 | transitionName="slideUp" | 121 | transitionName="slideUp" |
113 | > | 122 | > |
114 | <div className="services__no-service"> | 123 | <div className="services__no-service"> |
115 | <img src="./assets/images/logo.svg" alt="" /> | 124 | <img src="./assets/images/logo.svg" alt="Logo" style={{ maxHeight: '50vh' }} /> |
116 | <h1>{intl.formatMessage(messages.welcome)}</h1> | 125 | <h1>{intl.formatMessage(messages.welcome)}</h1> |
126 | { !isLoggedIn && ( | ||
127 | <> | ||
128 | <p>{intl.formatMessage(messages.login)}</p> | ||
129 | <p>{intl.formatMessage(messages.serverInfo)}</p> | ||
130 | </> | ||
131 | ) } | ||
117 | <Appear | 132 | <Appear |
118 | timeout={300} | 133 | timeout={300} |
119 | transitionName="slideUp" | 134 | transitionName="slideUp" |
120 | > | 135 | > |
121 | <Link to="/settings/recipes" className="button"> | 136 | <Link to={isLoggedIn ? '/settings/services' : '/auth/welcome'} className="button"> |
122 | {intl.formatMessage(messages.getStarted)} | 137 | { isLoggedIn ? intl.formatMessage(messages.getStarted) : 'Login' } |
123 | </Link> | 138 | </Link> |
124 | </Appear> | 139 | </Appear> |
125 | </div> | 140 | </div> |