aboutsummaryrefslogtreecommitdiffstats
path: root/src/components/services/content/ServiceView.js
diff options
context:
space:
mode:
Diffstat (limited to 'src/components/services/content/ServiceView.js')
-rw-r--r--src/components/services/content/ServiceView.js104
1 files changed, 90 insertions, 14 deletions
diff --git a/src/components/services/content/ServiceView.js b/src/components/services/content/ServiceView.js
index 3b09518c5..49ee24361 100644
--- a/src/components/services/content/ServiceView.js
+++ b/src/components/services/content/ServiceView.js
@@ -1,7 +1,7 @@
1import React, { Component, Fragment } from 'react'; 1import React, { Component, Fragment } from 'react';
2import PropTypes from 'prop-types'; 2import PropTypes from 'prop-types';
3import { autorun } from 'mobx'; 3import { autorun, reaction } from 'mobx';
4import { observer } from 'mobx-react'; 4import { observer, inject } from 'mobx-react';
5import classnames from 'classnames'; 5import classnames from 'classnames';
6 6
7import ServiceModel from '../../../models/Service'; 7import ServiceModel from '../../../models/Service';
@@ -10,12 +10,12 @@ import WebviewLoader from '../../ui/WebviewLoader';
10import WebviewCrashHandler from './WebviewCrashHandler'; 10import WebviewCrashHandler from './WebviewCrashHandler';
11import WebviewErrorHandler from './ErrorHandlers/WebviewErrorHandler'; 11import WebviewErrorHandler from './ErrorHandlers/WebviewErrorHandler';
12import ServiceDisabled from './ServiceDisabled'; 12import ServiceDisabled from './ServiceDisabled';
13import ServiceRestricted from './ServiceRestricted';
14import ServiceWebview from './ServiceWebview'; 13import ServiceWebview from './ServiceWebview';
14import SettingsStore from '../../../stores/SettingsStore';
15import WebControlsScreen from '../../../features/webControls/containers/WebControlsScreen'; 15import WebControlsScreen from '../../../features/webControls/containers/WebControlsScreen';
16import { CUSTOM_WEBSITE_ID } from '../../../features/webControls/constants'; 16import { CUSTOM_WEBSITE_ID } from '../../../features/webControls/constants';
17 17
18export default @observer class ServiceView extends Component { 18export default @inject('stores', 'actions') @observer 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,14 @@ 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,
30 actions: PropTypes.shape({
31 service: PropTypes.shape({
32 setHibernation: PropTypes.func.isRequired,
33 }).isRequired,
34 }).isRequired,
28 }; 35 };
29 36
30 static defaultProps = { 37 static defaultProps = {
@@ -35,12 +42,20 @@ export default @observer class ServiceView extends Component {
35 forceRepaint: false, 42 forceRepaint: false,
36 targetUrl: '', 43 targetUrl: '',
37 statusBarVisible: false, 44 statusBarVisible: false,
45 hibernate: false,
46 hibernationTimer: null,
38 }; 47 };
39 48
40 autorunDisposer = null; 49 autorunDisposer = null;
41 50
42 forceRepaintTimeout = null; 51 forceRepaintTimeout = null;
43 52
53 constructor(props) {
54 super(props);
55
56 this.startHibernationTimer = this.startHibernationTimer.bind(this);
57 }
58
44 componentDidMount() { 59 componentDidMount() {
45 this.autorunDisposer = autorun(() => { 60 this.autorunDisposer = autorun(() => {
46 if (this.props.service.isActive) { 61 if (this.props.service.isActive) {
@@ -50,6 +65,45 @@ export default @observer class ServiceView extends Component {
50 }, 100); 65 }, 100);
51 } 66 }
52 }); 67 });
68
69 reaction(
70 () => this.props.service.isActive,
71 () => {
72 if (!this.props.service.isActive && this.props.stores.settings.all.app.hibernate) {
73 // Service is inactive - start hibernation countdown
74 this.startHibernationTimer();
75 } else {
76 if (this.state.hibernationTimer) {
77 // Service is active but we have an active hibernation timer: Clear timeout
78 clearTimeout(this.state.hibernationTimer);
79 }
80
81 // Service is active, wake up service from hibernation
82 this.setState({
83 hibernate: false,
84 });
85 this.props.actions.service.setHibernation({
86 serviceId: this.props.service.id,
87 hibernating: false,
88 });
89 }
90 },
91 );
92
93 // Store hibernation status to state, otherwise the webview won't get unloaded correctly
94 reaction(
95 () => this.props.service.isHibernating,
96 () => {
97 this.setState({
98 hibernate: this.props.service.isHibernating,
99 });
100 },
101 );
102
103 // Start hibernation counter if we are in background
104 if (!this.props.service.isActive && this.props.stores.settings.all.app.hibernate) {
105 this.startHibernationTimer();
106 }
53 } 107 }
54 108
55 componentWillUnmount() { 109 componentWillUnmount() {
@@ -68,6 +122,24 @@ export default @observer class ServiceView extends Component {
68 }); 122 });
69 }; 123 };
70 124
125 startHibernationTimer() {
126 const timerDuration = (Number(this.props.stores.settings.all.app.hibernationStrategy) || 300) * 1000;
127
128 const hibernationTimer = setTimeout(() => {
129 this.setState({
130 hibernate: true,
131 });
132 this.props.actions.service.setHibernation({
133 serviceId: this.props.service.id,
134 hibernating: true,
135 });
136 }, timerDuration);
137
138 this.setState({
139 hibernationTimer,
140 });
141 }
142
71 render() { 143 render() {
72 const { 144 const {
73 detachService, 145 detachService,
@@ -76,9 +148,13 @@ export default @observer class ServiceView extends Component {
76 reload, 148 reload,
77 edit, 149 edit,
78 enable, 150 enable,
79 upgrade, 151 stores,
80 } = this.props; 152 } = this.props;
81 153
154 const {
155 showServiceNavigationBar,
156 } = stores.settings.app;
157
82 const webviewClasses = classnames({ 158 const webviewClasses = classnames({
83 services__webview: true, 159 services__webview: true,
84 'services__webview-wrapper': true, 160 'services__webview-wrapper': true,
@@ -132,15 +208,9 @@ export default @observer class ServiceView extends Component {
132 </Fragment> 208 </Fragment>
133 ) : ( 209 ) : (
134 <> 210 <>
135 {service.isServiceAccessRestricted ? ( 211 {!this.state.hibernate ? (
136 <ServiceRestricted
137 name={service.recipe.name}
138 upgrade={upgrade}
139 type={service.restrictionType}
140 />
141 ) : (
142 <> 212 <>
143 {service.recipe.id === CUSTOM_WEBSITE_ID && ( 213 {(service.recipe.id === CUSTOM_WEBSITE_ID || showServiceNavigationBar) && (
144 <WebControlsScreen service={service} /> 214 <WebControlsScreen service={service} />
145 )} 215 )}
146 <ServiceWebview 216 <ServiceWebview
@@ -149,6 +219,12 @@ export default @observer class ServiceView extends Component {
149 detachService={detachService} 219 detachService={detachService}
150 /> 220 />
151 </> 221 </>
222 ) : (
223 <div>
224 <span role="img" aria-label="Sleeping Emoji">😴</span>
225 {' '}
226 This service is currently hibernating. If this page doesn&#x27;t close soon, please try reloading Ferdi.
227 </div>
152 )} 228 )}
153 </> 229 </>
154 )} 230 )}