aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLibravatar kytwb <412895+kytwb@users.noreply.github.com>2021-07-23 10:04:43 +0100
committerLibravatar GitHub <noreply@github.com>2021-07-23 11:04:43 +0200
commit012e55ebf87559f2d782e5400fb885df8b80a445 (patch)
tree1966e58defe2bcd9541ca9a3f4db67a95a6b4249 /src
parentRemoved references to 'premium' i18n keys that are no longer used. (diff)
downloadferdium-app-012e55ebf87559f2d782e5400fb885df8b80a445.tar.gz
ferdium-app-012e55ebf87559f2d782e5400fb885df8b80a445.tar.zst
ferdium-app-012e55ebf87559f2d782e5400fb885df8b80a445.zip
Fix hibernation mode (#1486)
* Use hibernation strategy from settings instead of hardcoded 5 minutes * Fix conditions with isHibernationEnabled, previously disableHibernation * Make service hibernation obey global setting Also refactors hibernation to move some hibernation enablement logic into the Service model * Remove global hibernation enable switch Implements option 4 from https://github.com/getferdi/ferdi/pull/1486#issuecomment-860290992 according to https://github.com/getferdi/ferdi/pull/1486#issuecomment-876558694 * Implements #865 : Add 'hibernate service' and 'wake up service' in the sidebar context menu. * Removed 'hibernationEnabled' check on main settings screen Since this is an (imo) incongruous behavior for the first time user. They will see a message, but with no ability to choose the hibernation strategy. * Autogenerated files from conflict fixes Co-authored-by: Kristóf Marussy <kristof@marussy.com> Co-authored-by: Vijay A <avijayr@protonmail.com>
Diffstat (limited to 'src')
-rw-r--r--src/components/layout/Sidebar.js12
-rw-r--r--src/components/services/content/ServiceView.js16
-rw-r--r--src/components/services/tabs/TabBarSortableList.js6
-rw-r--r--src/components/services/tabs/TabItem.js18
-rw-r--r--src/components/services/tabs/Tabbar.js16
-rw-r--r--src/components/settings/services/EditServiceForm.js14
-rw-r--r--src/components/settings/settings/EditSettingsForm.js11
-rw-r--r--src/containers/layout/AppLayoutContainer.js4
-rw-r--r--src/containers/settings/EditServiceScreen.js3
-rw-r--r--src/containers/settings/EditSettingsScreen.js10
-rw-r--r--src/environment.js1
-rw-r--r--src/i18n/locales/defaultMessages.json34
-rw-r--r--src/i18n/locales/en-US.json2
-rw-r--r--src/i18n/messages/src/components/services/tabs/TabItem.json34
-rw-r--r--src/i18n/messages/src/containers/settings/EditSettingsScreen.json129
-rw-r--r--src/i18n/messages/src/features/workspaces/components/WorkspaceDrawer.json2
-rw-r--r--src/models/Service.js21
-rw-r--r--src/stores/ServicesStore.js14
18 files changed, 211 insertions, 136 deletions
diff --git a/src/components/layout/Sidebar.js b/src/components/layout/Sidebar.js
index 802538eba..9f3cacd38 100644
--- a/src/components/layout/Sidebar.js
+++ b/src/components/layout/Sidebar.js
@@ -58,6 +58,18 @@ const messages = defineMessages({
58export default @inject('stores', 'actions') @observer class Sidebar extends Component { 58export default @inject('stores', 'actions') @observer class Sidebar extends Component {
59 static propTypes = { 59 static propTypes = {
60 openSettings: PropTypes.func.isRequired, 60 openSettings: PropTypes.func.isRequired,
61 closeSettings: PropTypes.func.isRequired,
62 setActive: PropTypes.func.isRequired,
63 reorder: PropTypes.func.isRequired,
64 reload: PropTypes.func.isRequired,
65 toggleNotifications: PropTypes.func.isRequired,
66 toggleAudio: PropTypes.func.isRequired,
67 showMessageBadgeWhenMutedSetting: PropTypes.bool.isRequired,
68 showMessageBadgesEvenWhenMuted: PropTypes.bool.isRequired,
69 deleteService: PropTypes.func.isRequired,
70 updateService: PropTypes.func.isRequired,
71 hibernateService: PropTypes.func.isRequired,
72 wakeUpService: PropTypes.func.isRequired,
61 toggleMuteApp: PropTypes.func.isRequired, 73 toggleMuteApp: PropTypes.func.isRequired,
62 isAppMuted: PropTypes.bool.isRequired, 74 isAppMuted: PropTypes.bool.isRequired,
63 isWorkspaceDrawerOpen: PropTypes.bool.isRequired, 75 isWorkspaceDrawerOpen: PropTypes.bool.isRequired,
diff --git a/src/components/services/content/ServiceView.js b/src/components/services/content/ServiceView.js
index 17d2db5a0..3fc084ff0 100644
--- a/src/components/services/content/ServiceView.js
+++ b/src/components/services/content/ServiceView.js
@@ -145,19 +145,17 @@ export default @inject('stores', 'actions') @observer class ServiceView extends
145 </> 145 </>
146 ) : ( 146 ) : (
147 <> 147 <>
148 {(!service.isHibernating || service.isHibernationEnabled) ? ( 148 {!service.isHibernating ? (
149 <> 149 <>
150 {showNavBar && ( 150 {showNavBar && (
151 <WebControlsScreen service={service} /> 151 <WebControlsScreen service={service} />
152 )} 152 )}
153 {!service.isHibernating && ( 153 <ServiceWebview
154 <ServiceWebview 154 service={service}
155 service={service} 155 setWebviewReference={setWebviewReference}
156 setWebviewReference={setWebviewReference} 156 detachService={detachService}
157 detachService={detachService} 157 isSpellcheckerEnabled={isSpellcheckerEnabled}
158 isSpellcheckerEnabled={isSpellcheckerEnabled} 158 />
159 />
160 )}
161 </> 159 </>
162 ) : ( 160 ) : (
163 <div> 161 <div>
diff --git a/src/components/services/tabs/TabBarSortableList.js b/src/components/services/tabs/TabBarSortableList.js
index 489027d57..f12d90602 100644
--- a/src/components/services/tabs/TabBarSortableList.js
+++ b/src/components/services/tabs/TabBarSortableList.js
@@ -17,6 +17,8 @@ class TabBarSortableList extends Component {
17 deleteService: PropTypes.func.isRequired, 17 deleteService: PropTypes.func.isRequired,
18 disableService: PropTypes.func.isRequired, 18 disableService: PropTypes.func.isRequired,
19 enableService: PropTypes.func.isRequired, 19 enableService: PropTypes.func.isRequired,
20 hibernateService: PropTypes.func.isRequired,
21 wakeUpService: PropTypes.func.isRequired,
20 showMessageBadgeWhenMutedSetting: PropTypes.bool.isRequired, 22 showMessageBadgeWhenMutedSetting: PropTypes.bool.isRequired,
21 showMessageBadgesEvenWhenMuted: PropTypes.bool.isRequired, 23 showMessageBadgesEvenWhenMuted: PropTypes.bool.isRequired,
22 } 24 }
@@ -31,6 +33,8 @@ class TabBarSortableList extends Component {
31 deleteService, 33 deleteService,
32 disableService, 34 disableService,
33 enableService, 35 enableService,
36 hibernateService,
37 wakeUpService,
34 openSettings, 38 openSettings,
35 showMessageBadgeWhenMutedSetting, 39 showMessageBadgeWhenMutedSetting,
36 showMessageBadgesEvenWhenMuted, 40 showMessageBadgesEvenWhenMuted,
@@ -53,6 +57,8 @@ class TabBarSortableList extends Component {
53 deleteService={() => deleteService({ serviceId: service.id })} 57 deleteService={() => deleteService({ serviceId: service.id })}
54 disableService={() => disableService({ serviceId: service.id })} 58 disableService={() => disableService({ serviceId: service.id })}
55 enableService={() => enableService({ serviceId: service.id })} 59 enableService={() => enableService({ serviceId: service.id })}
60 hibernateService={() => hibernateService({ serviceId: service.id })}
61 wakeUpService={() => wakeUpService({ serviceId: service.id })}
56 openSettings={openSettings} 62 openSettings={openSettings}
57 showMessageBadgeWhenMutedSetting={showMessageBadgeWhenMutedSetting} 63 showMessageBadgeWhenMutedSetting={showMessageBadgeWhenMutedSetting}
58 showMessageBadgesEvenWhenMuted={showMessageBadgesEvenWhenMuted} 64 showMessageBadgesEvenWhenMuted={showMessageBadgesEvenWhenMuted}
diff --git a/src/components/services/tabs/TabItem.js b/src/components/services/tabs/TabItem.js
index 5c3149a11..ccf3333f8 100644
--- a/src/components/services/tabs/TabItem.js
+++ b/src/components/services/tabs/TabItem.js
@@ -49,6 +49,14 @@ const messages = defineMessages({
49 id: 'tabs.item.enableService', 49 id: 'tabs.item.enableService',
50 defaultMessage: '!!!Enable Service', 50 defaultMessage: '!!!Enable Service',
51 }, 51 },
52 hibernateService: {
53 id: 'tabs.item.hibernateService',
54 defaultMessage: '!!!Hibernate Service',
55 },
56 wakeUpService: {
57 id: 'tabs.item.wakeUpService',
58 defaultMessage: '!!!Wake Up Service',
59 },
52 deleteService: { 60 deleteService: {
53 id: 'tabs.item.deleteService', 61 id: 'tabs.item.deleteService',
54 defaultMessage: '!!!Delete Service', 62 defaultMessage: '!!!Delete Service',
@@ -101,6 +109,8 @@ const styles = {
101 deleteService: PropTypes.func.isRequired, 109 deleteService: PropTypes.func.isRequired,
102 disableService: PropTypes.func.isRequired, 110 disableService: PropTypes.func.isRequired,
103 enableService: PropTypes.func.isRequired, 111 enableService: PropTypes.func.isRequired,
112 hibernateService: PropTypes.func.isRequired,
113 wakeUpService: PropTypes.func.isRequired,
104 showMessageBadgeWhenMutedSetting: PropTypes.bool.isRequired, 114 showMessageBadgeWhenMutedSetting: PropTypes.bool.isRequired,
105 showMessageBadgesEvenWhenMuted: PropTypes.bool.isRequired, 115 showMessageBadgesEvenWhenMuted: PropTypes.bool.isRequired,
106 }; 116 };
@@ -145,6 +155,8 @@ const styles = {
145 deleteService, 155 deleteService,
146 disableService, 156 disableService,
147 enableService, 157 enableService,
158 hibernateService,
159 wakeUpService,
148 openSettings, 160 openSettings,
149 showMessageBadgeWhenMutedSetting, 161 showMessageBadgeWhenMutedSetting,
150 showMessageBadgesEvenWhenMuted, 162 showMessageBadgesEvenWhenMuted,
@@ -181,6 +193,10 @@ const styles = {
181 label: intl.formatMessage(service.isEnabled ? messages.disableService : messages.enableService), 193 label: intl.formatMessage(service.isEnabled ? messages.disableService : messages.enableService),
182 click: () => (service.isEnabled ? disableService() : enableService()), 194 click: () => (service.isEnabled ? disableService() : enableService()),
183 }, { 195 }, {
196 label: intl.formatMessage(service.isHibernating ? messages.wakeUpService : messages.hibernateService),
197 click: () => (service.isHibernating ? wakeUpService() : hibernateService()),
198 enabled: service.canHibernate,
199 }, {
184 type: 'separator', 200 type: 'separator',
185 }, { 201 }, {
186 label: intl.formatMessage(messages.deleteService), 202 label: intl.formatMessage(messages.deleteService),
@@ -217,7 +233,7 @@ const styles = {
217 233
218 </span> 234 </span>
219 )} 235 )}
220 {service.isHibernating && !service.isHibernationEnabled && ( 236 {service.isHibernating && (
221 <span className="tab-item__message-count hibernating"> 237 <span className="tab-item__message-count hibernating">
222 238
223 </span> 239 </span>
diff --git a/src/components/services/tabs/Tabbar.js b/src/components/services/tabs/Tabbar.js
index 5e8260ad0..db7a69bfc 100644
--- a/src/components/services/tabs/Tabbar.js
+++ b/src/components/services/tabs/Tabbar.js
@@ -17,6 +17,8 @@ export default @observer class TabBar extends Component {
17 toggleAudio: PropTypes.func.isRequired, 17 toggleAudio: PropTypes.func.isRequired,
18 deleteService: PropTypes.func.isRequired, 18 deleteService: PropTypes.func.isRequired,
19 updateService: PropTypes.func.isRequired, 19 updateService: PropTypes.func.isRequired,
20 hibernateService: PropTypes.func.isRequired,
21 wakeUpService: PropTypes.func.isRequired,
20 showMessageBadgeWhenMutedSetting: PropTypes.bool.isRequired, 22 showMessageBadgeWhenMutedSetting: PropTypes.bool.isRequired,
21 showMessageBadgesEvenWhenMuted: PropTypes.bool.isRequired, 23 showMessageBadgesEvenWhenMuted: PropTypes.bool.isRequired,
22 }; 24 };
@@ -55,6 +57,18 @@ export default @observer class TabBar extends Component {
55 this.toggleService({ serviceId, isEnabled: true }); 57 this.toggleService({ serviceId, isEnabled: true });
56 } 58 }
57 59
60 hibernateService({ serviceId }) {
61 if (serviceId) {
62 this.props.hibernateService({ serviceId });
63 }
64 }
65
66 wakeUpService({ serviceId }) {
67 if (serviceId) {
68 this.props.wakeUpService({ serviceId });
69 }
70 }
71
58 render() { 72 render() {
59 const { 73 const {
60 services, 74 services,
@@ -83,6 +97,8 @@ export default @observer class TabBar extends Component {
83 deleteService={deleteService} 97 deleteService={deleteService}
84 disableService={args => this.disableService(args)} 98 disableService={args => this.disableService(args)}
85 enableService={args => this.enableService(args)} 99 enableService={args => this.enableService(args)}
100 hibernateService={args => this.hibernateService(args)}
101 wakeUpService={args => this.wakeUpService(args)}
86 openSettings={openSettings} 102 openSettings={openSettings}
87 distance={20} 103 distance={20}
88 axis="y" 104 axis="y"
diff --git a/src/components/settings/services/EditServiceForm.js b/src/components/settings/services/EditServiceForm.js
index 0f7c29de5..56e5f9c94 100644
--- a/src/components/settings/services/EditServiceForm.js
+++ b/src/components/settings/services/EditServiceForm.js
@@ -145,7 +145,6 @@ export default @observer class EditServiceForm extends Component {
145 isSaving: PropTypes.bool.isRequired, 145 isSaving: PropTypes.bool.isRequired,
146 isDeleting: PropTypes.bool.isRequired, 146 isDeleting: PropTypes.bool.isRequired,
147 isProxyFeatureEnabled: PropTypes.bool.isRequired, 147 isProxyFeatureEnabled: PropTypes.bool.isRequired,
148 isHibernationFeatureActive: PropTypes.bool.isRequired,
149 }; 148 };
150 149
151 static defaultProps = { 150 static defaultProps = {
@@ -208,7 +207,6 @@ export default @observer class EditServiceForm extends Component {
208 onDelete, 207 onDelete,
209 openRecipeFile, 208 openRecipeFile,
210 isProxyFeatureEnabled, 209 isProxyFeatureEnabled,
211 isHibernationFeatureActive,
212 } = this.props; 210 } = this.props;
213 const { intl } = this.context; 211 const { intl } = this.context;
214 212
@@ -341,14 +339,10 @@ export default @observer class EditServiceForm extends Component {
341 <div className="settings__settings-group"> 339 <div className="settings__settings-group">
342 <h3>{intl.formatMessage(messages.headlineGeneral)}</h3> 340 <h3>{intl.formatMessage(messages.headlineGeneral)}</h3>
343 <Toggle field={form.$('isEnabled')} /> 341 <Toggle field={form.$('isEnabled')} />
344 {isHibernationFeatureActive && ( 342 <Toggle field={form.$('isHibernationEnabled')} />
345 <> 343 <p className="settings__help indented__help">
346 <Toggle field={form.$('isHibernationEnabled')} /> 344 {intl.formatMessage(messages.isHibernationEnabledInfo)}
347 <p className="settings__help indented__help"> 345 </p>
348 {intl.formatMessage(messages.isHibernationEnabledInfo)}
349 </p>
350 </>
351 )}
352 <Toggle field={form.$('isDarkModeEnabled')} /> 346 <Toggle field={form.$('isDarkModeEnabled')} />
353 {form.$('isDarkModeEnabled').value 347 {form.$('isDarkModeEnabled').value
354 && ( 348 && (
diff --git a/src/components/settings/settings/EditSettingsForm.js b/src/components/settings/settings/EditSettingsForm.js
index a8ba8748d..d2a9eb6e0 100644
--- a/src/components/settings/settings/EditSettingsForm.js
+++ b/src/components/settings/settings/EditSettingsForm.js
@@ -171,7 +171,6 @@ export default @observer class EditSettingsForm extends Component {
171 isTodosActivated: PropTypes.bool.isRequired, 171 isTodosActivated: PropTypes.bool.isRequired,
172 isWorkspaceEnabled: PropTypes.bool.isRequired, 172 isWorkspaceEnabled: PropTypes.bool.isRequired,
173 automaticUpdates: PropTypes.bool.isRequired, 173 automaticUpdates: PropTypes.bool.isRequired,
174 hibernationEnabled: PropTypes.bool.isRequired,
175 isDarkmodeEnabled: PropTypes.bool.isRequired, 174 isDarkmodeEnabled: PropTypes.bool.isRequired,
176 isAdaptableDarkModeEnabled: PropTypes.bool.isRequired, 175 isAdaptableDarkModeEnabled: PropTypes.bool.isRequired,
177 isNightlyEnabled: PropTypes.bool.isRequired, 176 isNightlyEnabled: PropTypes.bool.isRequired,
@@ -225,7 +224,6 @@ export default @observer class EditSettingsForm extends Component {
225 isTodosEnabled, 224 isTodosEnabled,
226 isWorkspaceEnabled, 225 isWorkspaceEnabled,
227 automaticUpdates, 226 automaticUpdates,
228 hibernationEnabled,
229 isDarkmodeEnabled, 227 isDarkmodeEnabled,
230 isTodosActivated, 228 isTodosActivated,
231 isNightlyEnabled, 229 isNightlyEnabled,
@@ -336,13 +334,8 @@ export default @observer class EditSettingsForm extends Component {
336 334
337 <Hr /> 335 <Hr />
338 336
339 <Toggle field={form.$('hibernate')} /> 337 <Select field={form.$('hibernationStrategy')} />
340 {hibernationEnabled && ( 338 <Toggle field={form.$('hibernateOnStartup')} />
341 <>
342 <Select field={form.$('hibernationStrategy')} />
343 <Toggle field={form.$('hibernateOnStartup')} />
344 </>
345 )}
346 <p 339 <p
347 className="settings__message" 340 className="settings__message"
348 style={{ 341 style={{
diff --git a/src/containers/layout/AppLayoutContainer.js b/src/containers/layout/AppLayoutContainer.js
index 9cdb20727..21be9d9d1 100644
--- a/src/containers/layout/AppLayoutContainer.js
+++ b/src/containers/layout/AppLayoutContainer.js
@@ -56,6 +56,8 @@ export default @inject('stores', 'actions') @observer class AppLayoutContainer e
56 toggleAudio, 56 toggleAudio,
57 deleteService, 57 deleteService,
58 updateService, 58 updateService,
59 hibernate,
60 awake,
59 } = this.props.actions.service; 61 } = this.props.actions.service;
60 62
61 const { hide } = this.props.actions.news; 63 const { hide } = this.props.actions.news;
@@ -109,6 +111,8 @@ export default @inject('stores', 'actions') @observer class AppLayoutContainer e
109 toggleAudio={toggleAudio} 111 toggleAudio={toggleAudio}
110 deleteService={deleteService} 112 deleteService={deleteService}
111 updateService={updateService} 113 updateService={updateService}
114 hibernateService={hibernate}
115 wakeUpService={awake}
112 toggleMuteApp={toggleMuteApp} 116 toggleMuteApp={toggleMuteApp}
113 toggleWorkspaceDrawer={workspaceActions.toggleWorkspaceDrawer} 117 toggleWorkspaceDrawer={workspaceActions.toggleWorkspaceDrawer}
114 isWorkspaceDrawerOpen={workspaceStore.isWorkspaceDrawerOpen} 118 isWorkspaceDrawerOpen={workspaceStore.isWorkspaceDrawerOpen}
diff --git a/src/containers/settings/EditServiceScreen.js b/src/containers/settings/EditServiceScreen.js
index e22e91822..0fe84792f 100644
--- a/src/containers/settings/EditServiceScreen.js
+++ b/src/containers/settings/EditServiceScreen.js
@@ -345,7 +345,7 @@ export default @inject('stores', 'actions') @observer class EditServiceScreen ex
345 345
346 render() { 346 render() {
347 const { 347 const {
348 recipes, services, user, settings, 348 recipes, services, user,
349 } = this.props.stores; 349 } = this.props.stores;
350 const { action } = this.props.router.params; 350 const { action } = this.props.router.params;
351 351
@@ -398,7 +398,6 @@ export default @inject('stores', 'actions') @observer class EditServiceScreen ex
398 onDelete={() => this.deleteService()} 398 onDelete={() => this.deleteService()}
399 openRecipeFile={file => this.openRecipeFile(file)} 399 openRecipeFile={file => this.openRecipeFile(file)}
400 isProxyFeatureEnabled={proxyFeature.isEnabled} 400 isProxyFeatureEnabled={proxyFeature.isEnabled}
401 isHibernationFeatureActive={settings.app.hibernate}
402 /> 401 />
403 </ErrorBoundary> 402 </ErrorBoundary>
404 ); 403 );
diff --git a/src/containers/settings/EditSettingsScreen.js b/src/containers/settings/EditSettingsScreen.js
index 3b8f03ae4..5f29ee385 100644
--- a/src/containers/settings/EditSettingsScreen.js
+++ b/src/containers/settings/EditSettingsScreen.js
@@ -87,10 +87,6 @@ const messages = defineMessages({
87 id: 'settings.app.form.sentry', 87 id: 'settings.app.form.sentry',
88 defaultMessage: '!!!Send telemetry data', 88 defaultMessage: '!!!Send telemetry data',
89 }, 89 },
90 hibernate: {
91 id: 'settings.app.form.hibernate',
92 defaultMessage: '!!!Enable service hibernation',
93 },
94 hibernateOnStartup: { 90 hibernateOnStartup: {
95 id: 'settings.app.form.hibernateOnStartup', 91 id: 'settings.app.form.hibernateOnStartup',
96 defaultMessage: '!!!Keep services in hibernation on startup', 92 defaultMessage: '!!!Keep services in hibernation on startup',
@@ -432,11 +428,6 @@ export default @inject('stores', 'actions') @observer class EditSettingsScreen e
432 value: settings.all.app.sentry, 428 value: settings.all.app.sentry,
433 default: DEFAULT_APP_SETTINGS.sentry, 429 default: DEFAULT_APP_SETTINGS.sentry,
434 }, 430 },
435 hibernate: {
436 label: intl.formatMessage(messages.hibernate),
437 value: settings.all.app.hibernate,
438 default: DEFAULT_APP_SETTINGS.hibernate,
439 },
440 hibernateOnStartup: { 431 hibernateOnStartup: {
441 label: intl.formatMessage(messages.hibernateOnStartup), 432 label: intl.formatMessage(messages.hibernateOnStartup),
442 value: settings.all.app.hibernateOnStartup, 433 value: settings.all.app.hibernateOnStartup,
@@ -653,7 +644,6 @@ export default @inject('stores', 'actions') @observer class EditSettingsScreen e
653 isWorkspaceEnabled={workspaces.isFeatureActive} 644 isWorkspaceEnabled={workspaces.isFeatureActive}
654 lockingFeatureEnabled={lockingFeatureEnabled} 645 lockingFeatureEnabled={lockingFeatureEnabled}
655 automaticUpdates={this.props.stores.settings.app.automaticUpdates} 646 automaticUpdates={this.props.stores.settings.app.automaticUpdates}
656 hibernationEnabled={this.props.stores.settings.app.hibernate}
657 isDarkmodeEnabled={this.props.stores.settings.app.darkMode} 647 isDarkmodeEnabled={this.props.stores.settings.app.darkMode}
658 isAdaptableDarkModeEnabled={this.props.stores.settings.app.adaptableDarkMode} 648 isAdaptableDarkModeEnabled={this.props.stores.settings.app.adaptableDarkMode}
659 isTodosActivated={this.props.stores.todos.isFeatureEnabledByUser} 649 isTodosActivated={this.props.stores.todos.isFeatureEnabledByUser}
diff --git a/src/environment.js b/src/environment.js
index e13e5f676..6a126e0c6 100644
--- a/src/environment.js
+++ b/src/environment.js
@@ -132,7 +132,6 @@ export const DEFAULT_APP_SETTINGS = {
132 scheduledDNDEnabled: false, 132 scheduledDNDEnabled: false,
133 scheduledDNDStart: '17:00', 133 scheduledDNDStart: '17:00',
134 scheduledDNDEnd: '09:00', 134 scheduledDNDEnd: '09:00',
135 hibernate: false,
136 hibernateOnStartup: true, 135 hibernateOnStartup: true,
137 hibernationStrategy: 300, 136 hibernationStrategy: 300,
138 inactivityLock: 0, 137 inactivityLock: 0,
diff --git a/src/i18n/locales/defaultMessages.json b/src/i18n/locales/defaultMessages.json
index 0cedeb4cb..7d4a0fe06 100644
--- a/src/i18n/locales/defaultMessages.json
+++ b/src/i18n/locales/defaultMessages.json
@@ -1867,29 +1867,55 @@
1867 } 1867 }
1868 }, 1868 },
1869 { 1869 {
1870 "defaultMessage": "!!!Delete Service", 1870 "defaultMessage": "!!!Hibernate Service",
1871 "end": { 1871 "end": {
1872 "column": 3, 1872 "column": 3,
1873 "line": 55 1873 "line": 55
1874 }, 1874 },
1875 "file": "src/components/services/tabs/TabItem.js", 1875 "file": "src/components/services/tabs/TabItem.js",
1876 "id": "tabs.item.hibernateService",
1877 "start": {
1878 "column": 20,
1879 "line": 52
1880 }
1881 },
1882 {
1883 "defaultMessage": "!!!Wake Up Service",
1884 "end": {
1885 "column": 3,
1886 "line": 59
1887 },
1888 "file": "src/components/services/tabs/TabItem.js",
1889 "id": "tabs.item.wakeUpService",
1890 "start": {
1891 "column": 17,
1892 "line": 56
1893 }
1894 },
1895 {
1896 "defaultMessage": "!!!Delete Service",
1897 "end": {
1898 "column": 3,
1899 "line": 63
1900 },
1901 "file": "src/components/services/tabs/TabItem.js",
1876 "id": "tabs.item.deleteService", 1902 "id": "tabs.item.deleteService",
1877 "start": { 1903 "start": {
1878 "column": 17, 1904 "column": 17,
1879 "line": 52 1905 "line": 60
1880 } 1906 }
1881 }, 1907 },
1882 { 1908 {
1883 "defaultMessage": "!!!Do you really want to delete the {serviceName} service?", 1909 "defaultMessage": "!!!Do you really want to delete the {serviceName} service?",
1884 "end": { 1910 "end": {
1885 "column": 3, 1911 "column": 3,
1886 "line": 59 1912 "line": 67
1887 }, 1913 },
1888 "file": "src/components/services/tabs/TabItem.js", 1914 "file": "src/components/services/tabs/TabItem.js",
1889 "id": "tabs.item.confirmDeleteService", 1915 "id": "tabs.item.confirmDeleteService",
1890 "start": { 1916 "start": {
1891 "column": 24, 1917 "column": 24,
1892 "line": 56 1918 "line": 64
1893 } 1919 }
1894 } 1920 }
1895 ], 1921 ],
diff --git a/src/i18n/locales/en-US.json b/src/i18n/locales/en-US.json
index 5ff146ea5..76fc7cfc2 100644
--- a/src/i18n/locales/en-US.json
+++ b/src/i18n/locales/en-US.json
@@ -453,7 +453,9 @@
453 "tabs.item.enableAudio": "Enable audio", 453 "tabs.item.enableAudio": "Enable audio",
454 "tabs.item.enableNotification": "Enable notifications", 454 "tabs.item.enableNotification": "Enable notifications",
455 "tabs.item.enableService": "Enable service", 455 "tabs.item.enableService": "Enable service",
456 "tabs.item.hibernateService": "Hibernate service",
456 "tabs.item.reload": "Reload", 457 "tabs.item.reload": "Reload",
458 "tabs.item.wakeUpService": "Wake up service",
457 "validation.email": "{field} is not valid", 459 "validation.email": "{field} is not valid",
458 "validation.minLength": "{field} should be at least {length} characters long", 460 "validation.minLength": "{field} should be at least {length} characters long",
459 "validation.oneRequired": "At least one is required", 461 "validation.oneRequired": "At least one is required",
diff --git a/src/i18n/messages/src/components/services/tabs/TabItem.json b/src/i18n/messages/src/components/services/tabs/TabItem.json
index a1b0d2435..6d4d5f6fd 100644
--- a/src/i18n/messages/src/components/services/tabs/TabItem.json
+++ b/src/i18n/messages/src/components/services/tabs/TabItem.json
@@ -104,15 +104,41 @@
104 } 104 }
105 }, 105 },
106 { 106 {
107 "id": "tabs.item.hibernateService",
108 "defaultMessage": "!!!Hibernate Service",
109 "file": "src/components/services/tabs/TabItem.js",
110 "start": {
111 "line": 52,
112 "column": 20
113 },
114 "end": {
115 "line": 55,
116 "column": 3
117 }
118 },
119 {
120 "id": "tabs.item.wakeUpService",
121 "defaultMessage": "!!!Wake Up Service",
122 "file": "src/components/services/tabs/TabItem.js",
123 "start": {
124 "line": 56,
125 "column": 17
126 },
127 "end": {
128 "line": 59,
129 "column": 3
130 }
131 },
132 {
107 "id": "tabs.item.deleteService", 133 "id": "tabs.item.deleteService",
108 "defaultMessage": "!!!Delete Service", 134 "defaultMessage": "!!!Delete Service",
109 "file": "src/components/services/tabs/TabItem.js", 135 "file": "src/components/services/tabs/TabItem.js",
110 "start": { 136 "start": {
111 "line": 52, 137 "line": 60,
112 "column": 17 138 "column": 17
113 }, 139 },
114 "end": { 140 "end": {
115 "line": 55, 141 "line": 63,
116 "column": 3 142 "column": 3
117 } 143 }
118 }, 144 },
@@ -121,11 +147,11 @@
121 "defaultMessage": "!!!Do you really want to delete the {serviceName} service?", 147 "defaultMessage": "!!!Do you really want to delete the {serviceName} service?",
122 "file": "src/components/services/tabs/TabItem.js", 148 "file": "src/components/services/tabs/TabItem.js",
123 "start": { 149 "start": {
124 "line": 56, 150 "line": 64,
125 "column": 24 151 "column": 24
126 }, 152 },
127 "end": { 153 "end": {
128 "line": 59, 154 "line": 67,
129 "column": 3 155 "column": 3
130 } 156 }
131 } 157 }
diff --git a/src/i18n/messages/src/containers/settings/EditSettingsScreen.json b/src/i18n/messages/src/containers/settings/EditSettingsScreen.json
index 5c15933e4..33bcde0de 100644
--- a/src/i18n/messages/src/containers/settings/EditSettingsScreen.json
+++ b/src/i18n/messages/src/containers/settings/EditSettingsScreen.json
@@ -195,28 +195,15 @@
195 } 195 }
196 }, 196 },
197 { 197 {
198 "id": "settings.app.form.hibernate",
199 "defaultMessage": "!!!Enable service hibernation",
200 "file": "src/containers/settings/EditSettingsScreen.js",
201 "start": {
202 "line": 90,
203 "column": 13
204 },
205 "end": {
206 "line": 93,
207 "column": 3
208 }
209 },
210 {
211 "id": "settings.app.form.hibernateOnStartup", 198 "id": "settings.app.form.hibernateOnStartup",
212 "defaultMessage": "!!!Keep services in hibernation on startup", 199 "defaultMessage": "!!!Keep services in hibernation on startup",
213 "file": "src/containers/settings/EditSettingsScreen.js", 200 "file": "src/containers/settings/EditSettingsScreen.js",
214 "start": { 201 "start": {
215 "line": 94, 202 "line": 90,
216 "column": 22 203 "column": 22
217 }, 204 },
218 "end": { 205 "end": {
219 "line": 97, 206 "line": 93,
220 "column": 3 207 "column": 3
221 } 208 }
222 }, 209 },
@@ -225,11 +212,11 @@
225 "defaultMessage": "!!!Hibernation strategy", 212 "defaultMessage": "!!!Hibernation strategy",
226 "file": "src/containers/settings/EditSettingsScreen.js", 213 "file": "src/containers/settings/EditSettingsScreen.js",
227 "start": { 214 "start": {
228 "line": 98, 215 "line": 94,
229 "column": 23 216 "column": 23
230 }, 217 },
231 "end": { 218 "end": {
232 "line": 101, 219 "line": 97,
233 "column": 3 220 "column": 3
234 } 221 }
235 }, 222 },
@@ -238,11 +225,11 @@
238 "defaultMessage": "!!!Todo Server", 225 "defaultMessage": "!!!Todo Server",
239 "file": "src/containers/settings/EditSettingsScreen.js", 226 "file": "src/containers/settings/EditSettingsScreen.js",
240 "start": { 227 "start": {
241 "line": 102, 228 "line": 98,
242 "column": 24 229 "column": 24
243 }, 230 },
244 "end": { 231 "end": {
245 "line": 105, 232 "line": 101,
246 "column": 3 233 "column": 3
247 } 234 }
248 }, 235 },
@@ -251,11 +238,11 @@
251 "defaultMessage": "!!!Custom TodoServer", 238 "defaultMessage": "!!!Custom TodoServer",
252 "file": "src/containers/settings/EditSettingsScreen.js", 239 "file": "src/containers/settings/EditSettingsScreen.js",
253 "start": { 240 "start": {
254 "line": 106, 241 "line": 102,
255 "column": 20 242 "column": 20
256 }, 243 },
257 "end": { 244 "end": {
258 "line": 109, 245 "line": 105,
259 "column": 3 246 "column": 3
260 } 247 }
261 }, 248 },
@@ -264,11 +251,11 @@
264 "defaultMessage": "!!!Enable Password Lock", 251 "defaultMessage": "!!!Enable Password Lock",
265 "file": "src/containers/settings/EditSettingsScreen.js", 252 "file": "src/containers/settings/EditSettingsScreen.js",
266 "start": { 253 "start": {
267 "line": 110, 254 "line": 106,
268 "column": 14 255 "column": 14
269 }, 256 },
270 "end": { 257 "end": {
271 "line": 113, 258 "line": 109,
272 "column": 3 259 "column": 3
273 } 260 }
274 }, 261 },
@@ -277,11 +264,11 @@
277 "defaultMessage": "!!!Password", 264 "defaultMessage": "!!!Password",
278 "file": "src/containers/settings/EditSettingsScreen.js", 265 "file": "src/containers/settings/EditSettingsScreen.js",
279 "start": { 266 "start": {
280 "line": 114, 267 "line": 110,
281 "column": 16 268 "column": 16
282 }, 269 },
283 "end": { 270 "end": {
284 "line": 117, 271 "line": 113,
285 "column": 3 272 "column": 3
286 } 273 }
287 }, 274 },
@@ -290,11 +277,11 @@
290 "defaultMessage": "!!!Allow using Touch ID to unlock", 277 "defaultMessage": "!!!Allow using Touch ID to unlock",
291 "file": "src/containers/settings/EditSettingsScreen.js", 278 "file": "src/containers/settings/EditSettingsScreen.js",
292 "start": { 279 "start": {
293 "line": 118, 280 "line": 114,
294 "column": 22 281 "column": 22
295 }, 282 },
296 "end": { 283 "end": {
297 "line": 121, 284 "line": 117,
298 "column": 3 285 "column": 3
299 } 286 }
300 }, 287 },
@@ -303,11 +290,11 @@
303 "defaultMessage": "!!!Lock after inactivity", 290 "defaultMessage": "!!!Lock after inactivity",
304 "file": "src/containers/settings/EditSettingsScreen.js", 291 "file": "src/containers/settings/EditSettingsScreen.js",
305 "start": { 292 "start": {
306 "line": 122, 293 "line": 118,
307 "column": 18 294 "column": 18
308 }, 295 },
309 "end": { 296 "end": {
310 "line": 125, 297 "line": 121,
311 "column": 3 298 "column": 3
312 } 299 }
313 }, 300 },
@@ -316,11 +303,11 @@
316 "defaultMessage": "!!!Enable scheduled Do-not-Disturb", 303 "defaultMessage": "!!!Enable scheduled Do-not-Disturb",
317 "file": "src/containers/settings/EditSettingsScreen.js", 304 "file": "src/containers/settings/EditSettingsScreen.js",
318 "start": { 305 "start": {
319 "line": 126, 306 "line": 122,
320 "column": 23 307 "column": 23
321 }, 308 },
322 "end": { 309 "end": {
323 "line": 129, 310 "line": 125,
324 "column": 3 311 "column": 3
325 } 312 }
326 }, 313 },
@@ -329,11 +316,11 @@
329 "defaultMessage": "!!!From", 316 "defaultMessage": "!!!From",
330 "file": "src/containers/settings/EditSettingsScreen.js", 317 "file": "src/containers/settings/EditSettingsScreen.js",
331 "start": { 318 "start": {
332 "line": 130, 319 "line": 126,
333 "column": 21 320 "column": 21
334 }, 321 },
335 "end": { 322 "end": {
336 "line": 133, 323 "line": 129,
337 "column": 3 324 "column": 3
338 } 325 }
339 }, 326 },
@@ -342,11 +329,11 @@
342 "defaultMessage": "!!!To", 329 "defaultMessage": "!!!To",
343 "file": "src/containers/settings/EditSettingsScreen.js", 330 "file": "src/containers/settings/EditSettingsScreen.js",
344 "start": { 331 "start": {
345 "line": 134, 332 "line": 130,
346 "column": 19 333 "column": 19
347 }, 334 },
348 "end": { 335 "end": {
349 "line": 137, 336 "line": 133,
350 "column": 3 337 "column": 3
351 } 338 }
352 }, 339 },
@@ -355,11 +342,11 @@
355 "defaultMessage": "!!!Language", 342 "defaultMessage": "!!!Language",
356 "file": "src/containers/settings/EditSettingsScreen.js", 343 "file": "src/containers/settings/EditSettingsScreen.js",
357 "start": { 344 "start": {
358 "line": 138, 345 "line": 134,
359 "column": 12 346 "column": 12
360 }, 347 },
361 "end": { 348 "end": {
362 "line": 141, 349 "line": 137,
363 "column": 3 350 "column": 3
364 } 351 }
365 }, 352 },
@@ -368,11 +355,11 @@
368 "defaultMessage": "!!!Dark Mode", 355 "defaultMessage": "!!!Dark Mode",
369 "file": "src/containers/settings/EditSettingsScreen.js", 356 "file": "src/containers/settings/EditSettingsScreen.js",
370 "start": { 357 "start": {
371 "line": 142, 358 "line": 138,
372 "column": 12 359 "column": 12
373 }, 360 },
374 "end": { 361 "end": {
375 "line": 145, 362 "line": 141,
376 "column": 3 363 "column": 3
377 } 364 }
378 }, 365 },
@@ -381,11 +368,11 @@
381 "defaultMessage": "!!!Synchronize dark mode with my OS's dark mode setting", 368 "defaultMessage": "!!!Synchronize dark mode with my OS's dark mode setting",
382 "file": "src/containers/settings/EditSettingsScreen.js", 369 "file": "src/containers/settings/EditSettingsScreen.js",
383 "start": { 370 "start": {
384 "line": 146, 371 "line": 142,
385 "column": 21 372 "column": 21
386 }, 373 },
387 "end": { 374 "end": {
388 "line": 149, 375 "line": 145,
389 "column": 3 376 "column": 3
390 } 377 }
391 }, 378 },
@@ -394,11 +381,11 @@
394 "defaultMessage": "!!!Enable universal Dark Mode", 381 "defaultMessage": "!!!Enable universal Dark Mode",
395 "file": "src/containers/settings/EditSettingsScreen.js", 382 "file": "src/containers/settings/EditSettingsScreen.js",
396 "start": { 383 "start": {
397 "line": 150, 384 "line": 146,
398 "column": 21 385 "column": 21
399 }, 386 },
400 "end": { 387 "end": {
401 "line": 153, 388 "line": 149,
402 "column": 3 389 "column": 3
403 } 390 }
404 }, 391 },
@@ -407,11 +394,11 @@
407 "defaultMessage": "!!!Sidebar width", 394 "defaultMessage": "!!!Sidebar width",
408 "file": "src/containers/settings/EditSettingsScreen.js", 395 "file": "src/containers/settings/EditSettingsScreen.js",
409 "start": { 396 "start": {
410 "line": 154, 397 "line": 150,
411 "column": 22 398 "column": 22
412 }, 399 },
413 "end": { 400 "end": {
414 "line": 157, 401 "line": 153,
415 "column": 3 402 "column": 3
416 } 403 }
417 }, 404 },
@@ -420,11 +407,11 @@
420 "defaultMessage": "!!!Service icon size", 407 "defaultMessage": "!!!Service icon size",
421 "file": "src/containers/settings/EditSettingsScreen.js", 408 "file": "src/containers/settings/EditSettingsScreen.js",
422 "start": { 409 "start": {
423 "line": 158, 410 "line": 154,
424 "column": 12 411 "column": 12
425 }, 412 },
426 "end": { 413 "end": {
427 "line": 161, 414 "line": 157,
428 "column": 3 415 "column": 3
429 } 416 }
430 }, 417 },
@@ -433,11 +420,11 @@
433 "defaultMessage": "!!!Use vertical style", 420 "defaultMessage": "!!!Use vertical style",
434 "file": "src/containers/settings/EditSettingsScreen.js", 421 "file": "src/containers/settings/EditSettingsScreen.js",
435 "start": { 422 "start": {
436 "line": 162, 423 "line": 158,
437 "column": 20 424 "column": 20
438 }, 425 },
439 "end": { 426 "end": {
440 "line": 165, 427 "line": 161,
441 "column": 3 428 "column": 3
442 } 429 }
443 }, 430 },
@@ -446,11 +433,11 @@
446 "defaultMessage": "!!!Always show workspace drawer", 433 "defaultMessage": "!!!Always show workspace drawer",
447 "file": "src/containers/settings/EditSettingsScreen.js", 434 "file": "src/containers/settings/EditSettingsScreen.js",
448 "start": { 435 "start": {
449 "line": 166, 436 "line": 162,
450 "column": 24 437 "column": 24
451 }, 438 },
452 "end": { 439 "end": {
453 "line": 169, 440 "line": 165,
454 "column": 3 441 "column": 3
455 } 442 }
456 }, 443 },
@@ -459,11 +446,11 @@
459 "defaultMessage": "!!!Accent color", 446 "defaultMessage": "!!!Accent color",
460 "file": "src/containers/settings/EditSettingsScreen.js", 447 "file": "src/containers/settings/EditSettingsScreen.js",
461 "start": { 448 "start": {
462 "line": 170, 449 "line": 166,
463 "column": 15 450 "column": 15
464 }, 451 },
465 "end": { 452 "end": {
466 "line": 173, 453 "line": 169,
467 "column": 3 454 "column": 3
468 } 455 }
469 }, 456 },
@@ -472,11 +459,11 @@
472 "defaultMessage": "!!!Display disabled services tabs", 459 "defaultMessage": "!!!Display disabled services tabs",
473 "file": "src/containers/settings/EditSettingsScreen.js", 460 "file": "src/containers/settings/EditSettingsScreen.js",
474 "start": { 461 "start": {
475 "line": 174, 462 "line": 170,
476 "column": 24 463 "column": 24
477 }, 464 },
478 "end": { 465 "end": {
479 "line": 177, 466 "line": 173,
480 "column": 3 467 "column": 3
481 } 468 }
482 }, 469 },
@@ -485,11 +472,11 @@
485 "defaultMessage": "!!!Show unread message badge when notifications are disabled", 472 "defaultMessage": "!!!Show unread message badge when notifications are disabled",
486 "file": "src/containers/settings/EditSettingsScreen.js", 473 "file": "src/containers/settings/EditSettingsScreen.js",
487 "start": { 474 "start": {
488 "line": 178, 475 "line": 174,
489 "column": 29 476 "column": 29
490 }, 477 },
491 "end": { 478 "end": {
492 "line": 181, 479 "line": 177,
493 "column": 3 480 "column": 3
494 } 481 }
495 }, 482 },
@@ -498,11 +485,11 @@
498 "defaultMessage": "!!!Show draggable area on window", 485 "defaultMessage": "!!!Show draggable area on window",
499 "file": "src/containers/settings/EditSettingsScreen.js", 486 "file": "src/containers/settings/EditSettingsScreen.js",
500 "start": { 487 "start": {
501 "line": 182, 488 "line": 178,
502 "column": 16 489 "column": 16
503 }, 490 },
504 "end": { 491 "end": {
505 "line": 185, 492 "line": 181,
506 "column": 3 493 "column": 3
507 } 494 }
508 }, 495 },
@@ -511,11 +498,11 @@
511 "defaultMessage": "!!!Enable spell checking", 498 "defaultMessage": "!!!Enable spell checking",
512 "file": "src/containers/settings/EditSettingsScreen.js", 499 "file": "src/containers/settings/EditSettingsScreen.js",
513 "start": { 500 "start": {
514 "line": 186, 501 "line": 182,
515 "column": 23 502 "column": 23
516 }, 503 },
517 "end": { 504 "end": {
518 "line": 189, 505 "line": 185,
519 "column": 3 506 "column": 3
520 } 507 }
521 }, 508 },
@@ -524,11 +511,11 @@
524 "defaultMessage": "!!!Enable GPU Acceleration", 511 "defaultMessage": "!!!Enable GPU Acceleration",
525 "file": "src/containers/settings/EditSettingsScreen.js", 512 "file": "src/containers/settings/EditSettingsScreen.js",
526 "start": { 513 "start": {
527 "line": 190, 514 "line": 186,
528 "column": 25 515 "column": 25
529 }, 516 },
530 "end": { 517 "end": {
531 "line": 193, 518 "line": 189,
532 "column": 3 519 "column": 3
533 } 520 }
534 }, 521 },
@@ -537,11 +524,11 @@
537 "defaultMessage": "!!!Include beta versions", 524 "defaultMessage": "!!!Include beta versions",
538 "file": "src/containers/settings/EditSettingsScreen.js", 525 "file": "src/containers/settings/EditSettingsScreen.js",
539 "start": { 526 "start": {
540 "line": 194, 527 "line": 190,
541 "column": 8 528 "column": 8
542 }, 529 },
543 "end": { 530 "end": {
544 "line": 197, 531 "line": 193,
545 "column": 3 532 "column": 3
546 } 533 }
547 }, 534 },
@@ -550,11 +537,11 @@
550 "defaultMessage": "!!!Enable updates", 537 "defaultMessage": "!!!Enable updates",
551 "file": "src/containers/settings/EditSettingsScreen.js", 538 "file": "src/containers/settings/EditSettingsScreen.js",
552 "start": { 539 "start": {
553 "line": 198, 540 "line": 194,
554 "column": 20 541 "column": 20
555 }, 542 },
556 "end": { 543 "end": {
557 "line": 201, 544 "line": 197,
558 "column": 3 545 "column": 3
559 } 546 }
560 }, 547 },
@@ -563,11 +550,11 @@
563 "defaultMessage": "!!!Enable Franz Todos", 550 "defaultMessage": "!!!Enable Franz Todos",
564 "file": "src/containers/settings/EditSettingsScreen.js", 551 "file": "src/containers/settings/EditSettingsScreen.js",
565 "start": { 552 "start": {
566 "line": 202, 553 "line": 198,
567 "column": 15 554 "column": 15
568 }, 555 },
569 "end": { 556 "end": {
570 "line": 205, 557 "line": 201,
571 "column": 3 558 "column": 3
572 } 559 }
573 }, 560 },
@@ -576,11 +563,11 @@
576 "defaultMessage": "!!!Keep all workspaces loaded", 563 "defaultMessage": "!!!Keep all workspaces loaded",
577 "file": "src/containers/settings/EditSettingsScreen.js", 564 "file": "src/containers/settings/EditSettingsScreen.js",
578 "start": { 565 "start": {
579 "line": 206, 566 "line": 202,
580 "column": 27 567 "column": 27
581 }, 568 },
582 "end": { 569 "end": {
583 "line": 209, 570 "line": 205,
584 "column": 3 571 "column": 3
585 } 572 }
586 } 573 }
diff --git a/src/i18n/messages/src/features/workspaces/components/WorkspaceDrawer.json b/src/i18n/messages/src/features/workspaces/components/WorkspaceDrawer.json
index a8ccb5a39..431f12710 100644
--- a/src/i18n/messages/src/features/workspaces/components/WorkspaceDrawer.json
+++ b/src/i18n/messages/src/features/workspaces/components/WorkspaceDrawer.json
@@ -64,4 +64,4 @@
64 "column": 3 64 "column": 3
65 } 65 }
66 } 66 }
67] 67] \ No newline at end of file
diff --git a/src/models/Service.js b/src/models/Service.js
index 397950787..162dcea65 100644
--- a/src/models/Service.js
+++ b/src/models/Service.js
@@ -37,8 +37,6 @@ export default class Service {
37 37
38 @observable isMuted = false; 38 @observable isMuted = false;
39 39
40 @observable isHibernating = false;
41
42 @observable team = ''; 40 @observable team = '';
43 41
44 @observable customUrl = ''; 42 @observable customUrl = '';
@@ -77,7 +75,7 @@ export default class Service {
77 75
78 @observable isHibernationEnabled = false; 76 @observable isHibernationEnabled = false;
79 77
80 @observable isHibernating = false; 78 @observable isHibernationRequested = false;
81 79
82 @observable lastUsed = Date.now(); // timestamp 80 @observable lastUsed = Date.now(); // timestamp
83 81
@@ -145,14 +143,11 @@ export default class Service {
145 this.recipe = recipe; 143 this.recipe = recipe;
146 144
147 // Check if "Hibernate on Startup" is enabled and hibernate all services except active one 145 // Check if "Hibernate on Startup" is enabled and hibernate all services except active one
148 const { 146 const { hibernateOnStartup } = window.ferdi.stores.settings.app;
149 hibernate,
150 hibernateOnStartup,
151 } = window.ferdi.stores.settings.app;
152 // The service store is probably not loaded yet so we need to use localStorage data to get active service 147 // The service store is probably not loaded yet so we need to use localStorage data to get active service
153 const isActive = window.localStorage.service && JSON.parse(window.localStorage.service).activeService === this.id; 148 const isActive = window.localStorage.service && JSON.parse(window.localStorage.service).activeService === this.id;
154 if (hibernate && hibernateOnStartup && !isActive) { 149 if (hibernateOnStartup && !isActive) {
155 this.isHibernating = true; 150 this.isHibernationRequested = true;
156 } 151 }
157 152
158 autorun(() => { 153 autorun(() => {
@@ -185,6 +180,14 @@ export default class Service {
185 return this.recipe.id === todosStore.todoRecipeId; 180 return this.recipe.id === todosStore.todoRecipeId;
186 } 181 }
187 182
183 @computed get canHibernate() {
184 return this.isHibernationEnabled;
185 }
186
187 @computed get isHibernating() {
188 return this.canHibernate && this.isHibernationRequested;
189 }
190
188 get webview() { 191 get webview() {
189 if (this.isTodosService) { 192 if (this.isTodosService) {
190 return todosStore.webview; 193 return todosStore.webview;
diff --git a/src/stores/ServicesStore.js b/src/stores/ServicesStore.js
index 9521f8493..6064b9929 100644
--- a/src/stores/ServicesStore.js
+++ b/src/stores/ServicesStore.js
@@ -166,8 +166,8 @@ export default class ServicesStore extends Store {
166 _serviceMaintenance() { 166 _serviceMaintenance() {
167 this.all.forEach((service) => { 167 this.all.forEach((service) => {
168 // Defines which services should be hibernated. 168 // Defines which services should be hibernated.
169 if (!service.isActive && (Date.now() - service.lastUsed > ms('5m'))) { 169 if (!service.isActive && (Date.now() - service.lastUsed > ms(`${this.stores.settings.all.app.hibernationStrategy}s`))) {
170 // If service is stale for 5 min, hibernate it. 170 // If service is stale, hibernate it.
171 this._hibernate({ serviceId: service.id }); 171 this._hibernate({ serviceId: service.id });
172 } 172 }
173 173
@@ -820,19 +820,23 @@ export default class ServicesStore extends Store {
820 820
821 @action _hibernate({ serviceId }) { 821 @action _hibernate({ serviceId }) {
822 const service = this.one(serviceId); 822 const service = this.one(serviceId);
823 if (service.isActive || !service.isHibernationEnabled) { 823 if (!service.canHibernate) {
824 return;
825 }
826 if (service.isActive) {
824 debug('Skipping service hibernation'); 827 debug('Skipping service hibernation');
825 return; 828 return;
826 } 829 }
827 830
828 debug(`Hibernate ${service.name}`); 831 debug(`Hibernate ${service.name}`);
829 832
830 service.isHibernating = true; 833 service.isHibernationRequested = true;
831 } 834 }
832 835
833 @action _awake({ serviceId }) { 836 @action _awake({ serviceId }) {
837 debug('Waking up from service hibernation');
834 const service = this.one(serviceId); 838 const service = this.one(serviceId);
835 service.isHibernating = false; 839 service.isHibernationRequested = false;
836 service.liveFrom = Date.now(); 840 service.liveFrom = Date.now();
837 } 841 }
838 842