aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/components/services/content/ServiceWebview.jsx (renamed from src/components/services/content/ServiceWebview.js)8
-rw-r--r--src/features/serviceProxy/index.ts8
-rw-r--r--src/features/webControls/containers/WebControlsScreen.jsx (renamed from src/features/webControls/containers/WebControlsScreen.js)20
-rw-r--r--src/features/workspaces/store.js100
-rw-r--r--src/lib/Menu.js8
-rw-r--r--src/models/Service.ts80
-rw-r--r--src/stores/AppStore.ts22
-rw-r--r--src/stores/RequestStore.ts16
-rw-r--r--src/stores/ServicesStore.ts21
-rw-r--r--src/stores/SettingsStore.ts11
-rw-r--r--src/stores/lib/Request.js24
-rw-r--r--src/stores/lib/TypedStore.ts14
12 files changed, 212 insertions, 120 deletions
diff --git a/src/components/services/content/ServiceWebview.js b/src/components/services/content/ServiceWebview.jsx
index 502f87225..835c5125e 100644
--- a/src/components/services/content/ServiceWebview.js
+++ b/src/components/services/content/ServiceWebview.jsx
@@ -1,7 +1,7 @@
1import { Component } from 'react'; 1import { Component } from 'react';
2import PropTypes from 'prop-types'; 2import PropTypes from 'prop-types';
3import { observer } from 'mobx-react'; 3import { observer } from 'mobx-react';
4import { makeObservable, observable, reaction } from 'mobx'; 4import { action, makeObservable, observable, reaction } from 'mobx';
5import ElectronWebView from 'react-electron-web-view'; 5import ElectronWebView from 'react-electron-web-view';
6import { join } from 'path'; 6import { join } from 'path';
7 7
@@ -69,6 +69,10 @@ class ServiceWebview extends Component {
69 } 69 }
70 }; 70 };
71 71
72 @action _setWebview(webview) {
73 this.webview = webview;
74 }
75
72 render() { 76 render() {
73 const { service, setWebviewReference, isSpellcheckerEnabled } = this.props; 77 const { service, setWebviewReference, isSpellcheckerEnabled } = this.props;
74 78
@@ -84,7 +88,7 @@ class ServiceWebview extends Component {
84 return ( 88 return (
85 <ElectronWebView 89 <ElectronWebView
86 ref={webview => { 90 ref={webview => {
87 this.webview = webview; 91 this._setWebview(webview);
88 if (webview && webview.view) { 92 if (webview && webview.view) {
89 webview.view.addEventListener( 93 webview.view.addEventListener(
90 'did-stop-loading', 94 'did-stop-loading',
diff --git a/src/features/serviceProxy/index.ts b/src/features/serviceProxy/index.ts
index 51e67feca..eb3b89ece 100644
--- a/src/features/serviceProxy/index.ts
+++ b/src/features/serviceProxy/index.ts
@@ -1,4 +1,4 @@
1import { autorun, observable } from 'mobx'; 1import { autorun, action, observable } from 'mobx';
2import { session } from '@electron/remote'; 2import { session } from '@electron/remote';
3 3
4const debug = require('../../preload-safe-debug')( 4const debug = require('../../preload-safe-debug')(
@@ -15,8 +15,12 @@ export default function init(stores: {
15}) { 15}) {
16 debug('Initializing `serviceProxy` feature'); 16 debug('Initializing `serviceProxy` feature');
17 17
18 const setIsEnabled = action((value: boolean) => {
19 config.isEnabled = value;
20 });
21
18 autorun(() => { 22 autorun(() => {
19 config.isEnabled = true; 23 setIsEnabled(true);
20 24
21 const services = stores.services.enabled; 25 const services = stores.services.enabled;
22 const proxySettings = stores.settings.proxy; 26 const proxySettings = stores.settings.proxy;
diff --git a/src/features/webControls/containers/WebControlsScreen.js b/src/features/webControls/containers/WebControlsScreen.jsx
index e5567eec5..25e14060d 100644
--- a/src/features/webControls/containers/WebControlsScreen.js
+++ b/src/features/webControls/containers/WebControlsScreen.jsx
@@ -2,7 +2,7 @@ import { Component } from 'react';
2import { observer, inject } from 'mobx-react'; 2import { observer, inject } from 'mobx-react';
3import PropTypes from 'prop-types'; 3import PropTypes from 'prop-types';
4 4
5import { autorun, makeObservable, observable } from 'mobx'; 5import { autorun, action, makeObservable, observable } from 'mobx';
6import WebControls from '../components/WebControls'; 6import WebControls from '../components/WebControls';
7import ServicesStore from '../../../stores/ServicesStore'; 7import ServicesStore from '../../../stores/ServicesStore';
8import Service from '../../../models/Service'; 8import Service from '../../../models/Service';
@@ -27,6 +27,16 @@ class WebControlsScreen extends Component {
27 27
28 autorunDisposer = null; 28 autorunDisposer = null;
29 29
30 @action _setUrl(value) {
31 this.url = value;
32 }
33
34 @action _setUrlAndHistory(value) {
35 this._setUrl(value);
36 this.canGoBack = this.webview.canGoBack();
37 this.canGoForward = this.webview.canGoForward();
38 }
39
30 constructor(props) { 40 constructor(props) {
31 super(props); 41 super(props);
32 42
@@ -39,15 +49,13 @@ class WebControlsScreen extends Component {
39 this.autorunDisposer = autorun(() => { 49 this.autorunDisposer = autorun(() => {
40 if (service.isAttached) { 50 if (service.isAttached) {
41 this.webview = service.webview; 51 this.webview = service.webview;
42 this.url = this.webview.getURL(); 52 this._setUrl(this.webview.getURL());
43 53
44 for (const event of URL_EVENTS) { 54 for (const event of URL_EVENTS) {
45 this.webview.addEventListener(event, e => { 55 this.webview.addEventListener(event, e => {
46 if (!e.isMainFrame) return; 56 if (!e.isMainFrame) return;
47 57
48 this.url = e.url; 58 this._setUrlAndHistory(e.url);
49 this.canGoBack = this.webview.canGoBack();
50 this.canGoForward = this.webview.canGoForward();
51 }); 59 });
52 } 60 }
53 } 61 }
@@ -101,7 +109,7 @@ class WebControlsScreen extends Component {
101 } 109 }
102 110
103 this.webview.loadURL(url); 111 this.webview.loadURL(url);
104 this.url = url; 112 this._setUrl(url);
105 } 113 }
106 114
107 openInBrowser() { 115 openInBrowser() {
diff --git a/src/features/workspaces/store.js b/src/features/workspaces/store.js
index a8fb493df..2323019fe 100644
--- a/src/features/workspaces/store.js
+++ b/src/features/workspaces/store.js
@@ -90,7 +90,7 @@ export default class WorkspacesStore extends FeatureStore {
90 [workspaceActions.create, this._create], 90 [workspaceActions.create, this._create],
91 [workspaceActions.delete, this._delete], 91 [workspaceActions.delete, this._delete],
92 [workspaceActions.update, this._update], 92 [workspaceActions.update, this._update],
93 [workspaceActions.activate, this._setActiveWorkspace], 93 [workspaceActions.activate, this._setActivateWorkspace],
94 [workspaceActions.deactivate, this._deactivateActiveWorkspace], 94 [workspaceActions.deactivate, this._deactivateActiveWorkspace],
95 [ 95 [
96 workspaceActions.toggleKeepAllWorkspacesLoadedSetting, 96 workspaceActions.toggleKeepAllWorkspacesLoadedSetting,
@@ -114,10 +114,10 @@ export default class WorkspacesStore extends FeatureStore {
114 } 114 }
115 115
116 @action reset() { 116 @action reset() {
117 this.activeWorkspace = null; 117 this._setActiveWorkspace(null);
118 this.nextWorkspace = null; 118 this._setNextWorkspace(null);
119 this.workspaceBeingEdited = null; 119 this.workspaceBeingEdited = null;
120 this.isSwitchingWorkspace = false; 120 this._setIsSwitchingWorkspace(false);
121 this.isWorkspaceDrawerOpen = false; 121 this.isWorkspaceDrawerOpen = false;
122 } 122 }
123 123
@@ -181,19 +181,31 @@ export default class WorkspacesStore extends FeatureStore {
181 this.stores.router.push('/settings/workspaces'); 181 this.stores.router.push('/settings/workspaces');
182 }; 182 };
183 183
184 @action _setActiveWorkspace = ({ workspace }) => { 184 @action _setNextWorkspace(workspace) {
185 // Indicate that we are switching to another workspace
186 this.isSwitchingWorkspace = true;
187 this.nextWorkspace = workspace; 185 this.nextWorkspace = workspace;
186 }
187
188 @action _setIsSwitchingWorkspace(bool) {
189 this.isSwitchingWorkspace = bool;
190 }
191
192 @action _setActiveWorkspace(workspace) {
193 this.activeWorkspace = workspace;
194 }
195
196 @action _setActivateWorkspace = ({ workspace }) => {
197 // Indicate that we are switching to another workspace
198 this._setIsSwitchingWorkspace(true);
199 this._setNextWorkspace(workspace);
188 // Delay switching to next workspace so that the services loading does not drag down UI 200 // Delay switching to next workspace so that the services loading does not drag down UI
189 setTimeout(() => { 201 setTimeout(() => {
190 this.activeWorkspace = workspace; 202 this._setActiveWorkspace(workspace);
191 this._updateSettings({ lastActiveWorkspace: workspace.id }); 203 this._updateSettings({ lastActiveWorkspace: workspace.id });
192 }, 100); 204 }, 100);
193 // Indicate that we are done switching to the next workspace 205 // Indicate that we are done switching to the next workspace
194 setTimeout(() => { 206 setTimeout(() => {
195 this.isSwitchingWorkspace = false; 207 this._setIsSwitchingWorkspace(false);
196 this.nextWorkspace = null; 208 this._setNextWorkspace(null);
197 if (this.stores.settings.app.splitMode) { 209 if (this.stores.settings.app.splitMode) {
198 const serviceNames = new Set( 210 const serviceNames = new Set(
199 this.getWorkspaceServices(workspace).map(service => service.name), 211 this.getWorkspaceServices(workspace).map(service => service.name),
@@ -211,16 +223,16 @@ export default class WorkspacesStore extends FeatureStore {
211 223
212 @action _deactivateActiveWorkspace = () => { 224 @action _deactivateActiveWorkspace = () => {
213 // Indicate that we are switching to default workspace 225 // Indicate that we are switching to default workspace
214 this.isSwitchingWorkspace = true; 226 this._setIsSwitchingWorkspace(true);
215 this.nextWorkspace = null; 227 this._setNextWorkspace(null);
216 this._updateSettings({ lastActiveWorkspace: null }); 228 this._updateSettings({ lastActiveWorkspace: null });
217 // Delay switching to next workspace so that the services loading does not drag down UI 229 // Delay switching to next workspace so that the services loading does not drag down UI
218 setTimeout(() => { 230 setTimeout(() => {
219 this.activeWorkspace = null; 231 this._setActiveWorkspace(null);
220 }, 100); 232 }, 100);
221 // Indicate that we are done switching to the default workspace 233 // Indicate that we are done switching to the default workspace
222 setTimeout(() => { 234 setTimeout(() => {
223 this.isSwitchingWorkspace = false; 235 this._setIsSwitchingWorkspace(false);
224 if (this.stores.settings.app.splitMode) { 236 if (this.stores.settings.app.splitMode) {
225 for (const wrapper of document.querySelectorAll( 237 for (const wrapper of document.querySelectorAll(
226 '.services__webview-wrapper', 238 '.services__webview-wrapper',
@@ -247,6 +259,37 @@ export default class WorkspacesStore extends FeatureStore {
247 await updateWorkspaceRequest.execute(activeWorkspace); 259 await updateWorkspaceRequest.execute(activeWorkspace);
248 }; 260 };
249 261
262 @action _setOpenDrawerWithSettings() {
263 const { router } = this.stores;
264 const isWorkspaceSettingsRoute = router.location.pathname.includes(
265 WORKSPACES_ROUTES.ROOT,
266 );
267 const isSwitchingToSettingsRoute =
268 !this.isSettingsRouteActive && isWorkspaceSettingsRoute;
269 const isLeavingSettingsRoute =
270 !isWorkspaceSettingsRoute && this.isSettingsRouteActive;
271
272 if (isSwitchingToSettingsRoute) {
273 this.isSettingsRouteActive = true;
274 this._wasDrawerOpenBeforeSettingsRoute = this.isWorkspaceDrawerOpen;
275 if (!this._wasDrawerOpenBeforeSettingsRoute) {
276 workspaceActions.toggleWorkspaceDrawer();
277 }
278 } else if (isLeavingSettingsRoute) {
279 this.isSettingsRouteActive = false;
280 if (
281 !this._wasDrawerOpenBeforeSettingsRoute &&
282 this.isWorkspaceDrawerOpen
283 ) {
284 workspaceActions.toggleWorkspaceDrawer();
285 }
286 }
287 }
288
289 @action _setWorkspaceBeingEdited(match) {
290 this.workspaceBeingEdited = this._getWorkspaceById(match.id);
291 }
292
250 _toggleKeepAllWorkspacesLoadedSetting = async () => { 293 _toggleKeepAllWorkspacesLoadedSetting = async () => {
251 this._updateSettings({ 294 this._updateSettings({
252 keepAllWorkspacesLoaded: !this.settings.keepAllWorkspacesLoaded, 295 keepAllWorkspacesLoaded: !this.settings.keepAllWorkspacesLoaded,
@@ -259,7 +302,7 @@ export default class WorkspacesStore extends FeatureStore {
259 const { pathname } = this.stores.router.location; 302 const { pathname } = this.stores.router.location;
260 const match = matchRoute('/settings/workspaces/edit/:id', pathname); 303 const match = matchRoute('/settings/workspaces/edit/:id', pathname);
261 if (match) { 304 if (match) {
262 this.workspaceBeingEdited = this._getWorkspaceById(match.id); 305 this._setWorkspaceBeingEdited(match);
263 } 306 }
264 }; 307 };
265 308
@@ -286,36 +329,13 @@ export default class WorkspacesStore extends FeatureStore {
286 const { lastActiveWorkspace } = this.settings; 329 const { lastActiveWorkspace } = this.settings;
287 if (lastActiveWorkspace) { 330 if (lastActiveWorkspace) {
288 const workspace = this._getWorkspaceById(lastActiveWorkspace); 331 const workspace = this._getWorkspaceById(lastActiveWorkspace);
289 if (workspace) this._setActiveWorkspace({ workspace }); 332 if (workspace) this._setActivateWorkspace({ workspace });
290 } 333 }
291 } 334 }
292 }; 335 };
293 336
294 _openDrawerWithSettingsReaction = () => { 337 _openDrawerWithSettingsReaction = () => {
295 const { router } = this.stores; 338 this._setOpenDrawerWithSettings();
296 const isWorkspaceSettingsRoute = router.location.pathname.includes(
297 WORKSPACES_ROUTES.ROOT,
298 );
299 const isSwitchingToSettingsRoute =
300 !this.isSettingsRouteActive && isWorkspaceSettingsRoute;
301 const isLeavingSettingsRoute =
302 !isWorkspaceSettingsRoute && this.isSettingsRouteActive;
303
304 if (isSwitchingToSettingsRoute) {
305 this.isSettingsRouteActive = true;
306 this._wasDrawerOpenBeforeSettingsRoute = this.isWorkspaceDrawerOpen;
307 if (!this._wasDrawerOpenBeforeSettingsRoute) {
308 workspaceActions.toggleWorkspaceDrawer();
309 }
310 } else if (isLeavingSettingsRoute) {
311 this.isSettingsRouteActive = false;
312 if (
313 !this._wasDrawerOpenBeforeSettingsRoute &&
314 this.isWorkspaceDrawerOpen
315 ) {
316 workspaceActions.toggleWorkspaceDrawer();
317 }
318 }
319 }; 339 };
320 340
321 _cleanupInvalidServiceReferences = () => { 341 _cleanupInvalidServiceReferences = () => {
diff --git a/src/lib/Menu.js b/src/lib/Menu.js
index 41b4aa9f7..b8826f12e 100644
--- a/src/lib/Menu.js
+++ b/src/lib/Menu.js
@@ -7,7 +7,7 @@ import {
7 systemPreferences, 7 systemPreferences,
8 getCurrentWindow, 8 getCurrentWindow,
9} from '@electron/remote'; 9} from '@electron/remote';
10import { autorun, makeObservable, observable } from 'mobx'; 10import { autorun, action, makeObservable, observable } from 'mobx';
11import { defineMessages } from 'react-intl'; 11import { defineMessages } from 'react-intl';
12import osName from 'os-name'; 12import osName from 'os-name';
13import { fromJS } from 'immutable'; 13import { fromJS } from 'immutable';
@@ -635,6 +635,10 @@ class FranzMenu {
635 }, 10); 635 }, 10);
636 } 636 }
637 637
638 @action _setCurrentTemplate(tpl) {
639 this.currentTemplate = tpl;
640 }
641
638 rebuild() { 642 rebuild() {
639 this._build(); 643 this._build();
640 } 644 }
@@ -989,7 +993,7 @@ class FranzMenu {
989 ...this.debugMenu(), 993 ...this.debugMenu(),
990 ); 994 );
991 } 995 }
992 this.currentTemplate = tpl; 996 this._setCurrentTemplate(tpl);
993 const menu = Menu.buildFromTemplate(tpl); 997 const menu = Menu.buildFromTemplate(tpl);
994 Menu.setApplicationMenu(menu); 998 Menu.setApplicationMenu(menu);
995 } 999 }
diff --git a/src/models/Service.ts b/src/models/Service.ts
index 21fa65f69..fb594a6f4 100644
--- a/src/models/Service.ts
+++ b/src/models/Service.ts
@@ -1,4 +1,4 @@
1import { autorun, computed, makeObservable, observable } from 'mobx'; 1import { autorun, action, computed, makeObservable, observable } from 'mobx';
2import { ipcRenderer } from 'electron'; 2import { ipcRenderer } from 'electron';
3import { webContents } from '@electron/remote'; 3import { webContents } from '@electron/remote';
4import normalizeUrl from 'normalize-url'; 4import normalizeUrl from 'normalize-url';
@@ -124,6 +124,19 @@ export default class Service {
124 124
125 @observable proxy: string | null = null; 125 @observable proxy: string | null = null;
126 126
127 @action _setAutoRun() {
128 if (!this.isEnabled) {
129 this.webview = null;
130 this.isAttached = false;
131 this.unreadDirectMessageCount = 0;
132 this.unreadIndirectMessageCount = 0;
133 }
134
135 if (this.recipe.hasCustomUrl && this.customUrl) {
136 this.isUsingCustomUrl = true;
137 }
138 }
139
127 constructor(data, recipe: IRecipe) { 140 constructor(data, recipe: IRecipe) {
128 if (!data) { 141 if (!data) {
129 throw new Error('Service config not valid'); 142 throw new Error('Service config not valid');
@@ -212,19 +225,42 @@ export default class Service {
212 } 225 }
213 226
214 autorun((): void => { 227 autorun((): void => {
215 if (!this.isEnabled) { 228 this._setAutoRun();
216 this.webview = null;
217 this.isAttached = false;
218 this.unreadDirectMessageCount = 0;
219 this.unreadIndirectMessageCount = 0;
220 }
221
222 if (this.recipe.hasCustomUrl && this.customUrl) {
223 this.isUsingCustomUrl = true;
224 }
225 }); 229 });
226 } 230 }
227 231
232 @action _didStartLoading(): void {
233 this.hasCrashed = false;
234 this.isLoading = true;
235 this.isLoadingPage = true;
236 this.isError = false;
237 }
238
239 @action _didStopLoading(): void {
240 this.isLoading = false;
241 this.isLoadingPage = false;
242 }
243
244 @action _didLoad(): void {
245 this.isLoading = false;
246 this.isLoadingPage = false;
247
248 if (!this.isError) {
249 this.isFirstLoad = false;
250 }
251 }
252
253 @action _didFailLoad(event: { errorDescription: string }): void {
254 this.isError = false;
255 this.errorMessage = event.errorDescription;
256 this.isLoading = false;
257 this.isLoadingPage = false;
258 }
259
260 @action _hasCrashed(): void {
261 this.hasCrashed = true;
262 }
263
228 @computed get shareWithWebview(): object { 264 @computed get shareWithWebview(): object {
229 return { 265 return {
230 id: this.id, 266 id: this.id,
@@ -420,27 +456,18 @@ export default class Service {
420 this.webview.addEventListener('did-start-loading', event => { 456 this.webview.addEventListener('did-start-loading', event => {
421 debug('Did start load', this.name, event); 457 debug('Did start load', this.name, event);
422 458
423 this.hasCrashed = false; 459 this._didStartLoading();
424 this.isLoading = true;
425 this.isLoadingPage = true;
426 this.isError = false;
427 }); 460 });
428 461
429 this.webview.addEventListener('did-stop-loading', event => { 462 this.webview.addEventListener('did-stop-loading', event => {
430 debug('Did stop load', this.name, event); 463 debug('Did stop load', this.name, event);
431 464
432 this.isLoading = false; 465 this._didStopLoading();
433 this.isLoadingPage = false;
434 }); 466 });
435 467
436 // eslint-disable-next-line unicorn/consistent-function-scoping 468 // eslint-disable-next-line unicorn/consistent-function-scoping
437 const didLoad = () => { 469 const didLoad = () => {
438 this.isLoading = false; 470 this._didLoad();
439 this.isLoadingPage = false;
440
441 if (!this.isError) {
442 this.isFirstLoad = false;
443 }
444 }; 471 };
445 472
446 this.webview.addEventListener('did-frame-finish-load', didLoad.bind(this)); 473 this.webview.addEventListener('did-frame-finish-load', didLoad.bind(this));
@@ -453,16 +480,13 @@ export default class Service {
453 event.errorCode !== -21 && 480 event.errorCode !== -21 &&
454 event.errorCode !== -3 481 event.errorCode !== -3
455 ) { 482 ) {
456 this.isError = true; 483 this._didFailLoad(event);
457 this.errorMessage = event.errorDescription;
458 this.isLoading = false;
459 this.isLoadingPage = false;
460 } 484 }
461 }); 485 });
462 486
463 this.webview.addEventListener('crashed', () => { 487 this.webview.addEventListener('crashed', () => {
464 debug('Service crashed', this.name); 488 debug('Service crashed', this.name);
465 this.hasCrashed = true; 489 this._hasCrashed();
466 }); 490 });
467 491
468 this.webview.addEventListener('found-in-page', ({ result }) => { 492 this.webview.addEventListener('found-in-page', ({ result }) => {
diff --git a/src/stores/AppStore.ts b/src/stores/AppStore.ts
index af1a0daae..08d2f718c 100644
--- a/src/stores/AppStore.ts
+++ b/src/stores/AppStore.ts
@@ -503,6 +503,17 @@ export default class AppStore extends TypedStore {
503 this.isClearingAllCache = false; 503 this.isClearingAllCache = false;
504 } 504 }
505 505
506 @action _setLocale() {
507 if (this.stores.user?.isLoggedIn && this.stores.user?.data.locale) {
508 this.locale = this.stores.user.data.locale;
509 } else if (!this.locale) {
510 this.locale = this._getDefaultLocale();
511 }
512
513 moment.locale(this.locale);
514 debug(`Set locale to "${this.locale}"`);
515 }
516
506 // Reactions 517 // Reactions
507 _offlineCheck() { 518 _offlineCheck() {
508 if (!this.isOnline) { 519 if (!this.isOnline) {
@@ -516,17 +527,6 @@ export default class AppStore extends TypedStore {
516 } 527 }
517 } 528 }
518 529
519 _setLocale() {
520 if (this.stores.user?.isLoggedIn && this.stores.user?.data.locale) {
521 this.locale = this.stores.user.data.locale;
522 } else if (!this.locale) {
523 this.locale = this._getDefaultLocale();
524 }
525
526 moment.locale(this.locale);
527 debug(`Set locale to "${this.locale}"`);
528 }
529
530 _getDefaultLocale() { 530 _getDefaultLocale() {
531 return getLocale({ 531 return getLocale({
532 locale: ferdiumLocale, 532 locale: ferdiumLocale,
diff --git a/src/stores/RequestStore.ts b/src/stores/RequestStore.ts
index 59982c05a..279615e50 100644
--- a/src/stores/RequestStore.ts
+++ b/src/stores/RequestStore.ts
@@ -44,12 +44,7 @@ export default class RequestStore extends TypedStore {
44 this.servicesRequest = this.stores.services.allServicesRequest; 44 this.servicesRequest = this.stores.services.allServicesRequest;
45 45
46 ipcRenderer.on('localServerPort', (_, data) => { 46 ipcRenderer.on('localServerPort', (_, data) => {
47 if (data.port) { 47 this.setData(data);
48 this.localServerPort = data.port;
49 }
50 if (data.token) {
51 this.localServerToken = data.token;
52 }
53 }); 48 });
54 } 49 }
55 50
@@ -70,6 +65,15 @@ export default class RequestStore extends TypedStore {
70 this.servicesRequest.reload(); 65 this.servicesRequest.reload();
71 } 66 }
72 67
68 @action setData(data: { port: number; token: string | undefined }): void {
69 if (data.port) {
70 this.localServerPort = data.port;
71 }
72 if (data.token) {
73 this.localServerToken = data.token;
74 }
75 }
76
73 // Reactions 77 // Reactions
74 _autoRetry(): void { 78 _autoRetry(): void {
75 const delay = (this.retries <= 10 ? this.retries : 10) * this.retryDelay; 79 const delay = (this.retries <= 10 ? this.retries : 10) * this.retryDelay;
diff --git a/src/stores/ServicesStore.ts b/src/stores/ServicesStore.ts
index 7812d5aee..83ec7d18e 100644
--- a/src/stores/ServicesStore.ts
+++ b/src/stores/ServicesStore.ts
@@ -618,6 +618,10 @@ export default class ServicesStore extends TypedStore {
618 await request._promise; 618 await request._promise;
619 } 619 }
620 620
621 @action _setIsActive(service: Service, state: boolean): void {
622 service.isActive = state;
623 }
624
621 @action _setActive({ serviceId, keepActiveRoute = null }) { 625 @action _setActive({ serviceId, keepActiveRoute = null }) {
622 if (!keepActiveRoute) this.stores.router.push('/'); 626 if (!keepActiveRoute) this.stores.router.push('/');
623 const service = this.one(serviceId); 627 const service = this.one(serviceId);
@@ -625,10 +629,10 @@ export default class ServicesStore extends TypedStore {
625 for (const s of this.all) { 629 for (const s of this.all) {
626 if (s.isActive) { 630 if (s.isActive) {
627 s.lastUsed = Date.now(); 631 s.lastUsed = Date.now();
628 s.isActive = false; 632 this._setIsActive(s, false);
629 } 633 }
630 } 634 }
631 service.isActive = true; 635 this._setIsActive(service, true);
632 this._awake({ serviceId: service.id }); 636 this._awake({ serviceId: service.id });
633 637
634 if ( 638 if (
@@ -650,7 +654,7 @@ export default class ServicesStore extends TypedStore {
650 @action _blurActive() { 654 @action _blurActive() {
651 const service = this.active; 655 const service = this.active;
652 if (service) { 656 if (service) {
653 service.isActive = false; 657 this._setIsActive(service, false);
654 } else { 658 } else {
655 debug('No service is active'); 659 debug('No service is active');
656 } 660 }
@@ -1194,13 +1198,14 @@ export default class ServicesStore extends TypedStore {
1194 _mapActiveServiceToServiceModelReaction() { 1198 _mapActiveServiceToServiceModelReaction() {
1195 const { activeService } = this.stores.settings.all.service; 1199 const { activeService } = this.stores.settings.all.service;
1196 if (this.allDisplayed.length > 0) { 1200 if (this.allDisplayed.length > 0) {
1197 this.allDisplayed.map(service => 1201 for (const service of this.allDisplayed) {
1198 Object.assign(service, { 1202 this._setIsActive(
1199 isActive: activeService 1203 service,
1204 activeService
1200 ? activeService === service.id 1205 ? activeService === service.id
1201 : this.allDisplayed[0].id === service.id, 1206 : this.allDisplayed[0].id === service.id,
1202 }), 1207 );
1203 ); 1208 }
1204 } 1209 }
1205 } 1210 }
1206 1211
diff --git a/src/stores/SettingsStore.ts b/src/stores/SettingsStore.ts
index e2903c952..811bc6f76 100644
--- a/src/stores/SettingsStore.ts
+++ b/src/stores/SettingsStore.ts
@@ -100,8 +100,11 @@ export default class SettingsStore extends TypedStore {
100 }); 100 });
101 } 101 }
102 debug('Get appSettings resolves', resp.type, resp.data); 102 debug('Get appSettings resolves', resp.type, resp.data);
103 Object.assign(this._fileSystemSettingsCache[resp.type], resp.data); 103 this.actions.settings.update({
104 this.loaded = true; 104 type: resp.type,
105 data: resp.data,
106 });
107 this.setLoaded();
105 ipcRenderer.send('initialAppSettings', resp); 108 ipcRenderer.send('initialAppSettings', resp);
106 }); 109 });
107 110
@@ -148,6 +151,10 @@ export default class SettingsStore extends TypedStore {
148 }; 151 };
149 } 152 }
150 153
154 @action async setLoaded(): Promise<void> {
155 this.loaded = true;
156 }
157
151 @action async _update({ type, data }): Promise<void> { 158 @action async _update({ type, data }): Promise<void> {
152 const appSettings = this.all; 159 const appSettings = this.all;
153 if (!this.fileSystemSettingsTypes.includes(type)) { 160 if (!this.fileSystemSettingsTypes.includes(type)) {
diff --git a/src/stores/lib/Request.js b/src/stores/lib/Request.js
index e58341790..60c943a42 100644
--- a/src/stores/lib/Request.js
+++ b/src/stores/lib/Request.js
@@ -18,6 +18,18 @@ export default class Request {
18 18
19 @observable wasExecuted = false; 19 @observable wasExecuted = false;
20 20
21 @action _reset() {
22 this.error = null;
23 this.result = null;
24 this.isExecuting = false;
25 this.isError = false;
26 this.wasExecuted = false;
27 this._isWaitingForResponse = false;
28 this._promise = Promise;
29
30 return this;
31 }
32
21 _promise = Promise; 33 _promise = Promise;
22 34
23 _api = {}; 35 _api = {};
@@ -139,15 +151,5 @@ export default class Request {
139 for (const hook of Request._hooks) hook(this); 151 for (const hook of Request._hooks) hook(this);
140 } 152 }
141 153
142 reset = () => { 154 reset = () => this._reset();
143 this.error = null;
144 this.result = null;
145 this.isExecuting = false;
146 this.isError = false;
147 this.wasExecuted = false;
148 this._isWaitingForResponse = false;
149 this._promise = Promise;
150
151 return this;
152 };
153} 155}
diff --git a/src/stores/lib/TypedStore.ts b/src/stores/lib/TypedStore.ts
index e44eadd32..0a669e669 100644
--- a/src/stores/lib/TypedStore.ts
+++ b/src/stores/lib/TypedStore.ts
@@ -1,4 +1,10 @@
1import { computed, IReactionPublic, makeObservable, observable } from 'mobx'; 1import {
2 action,
3 computed,
4 IReactionPublic,
5 makeObservable,
6 observable,
7} from 'mobx';
2import { Actions } from '../../actions/lib/actions'; 8import { Actions } from '../../actions/lib/actions';
3import { ApiInterface } from '../../api'; 9import { ApiInterface } from '../../api';
4import { Stores } from '../../@types/stores.types'; 10import { Stores } from '../../@types/stores.types';
@@ -15,6 +21,10 @@ export default abstract class TypedStore {
15 21
16 actions: Actions; 22 actions: Actions;
17 23
24 @action _setResetStatus() {
25 this._status = null;
26 }
27
18 @computed get actionStatus() { 28 @computed get actionStatus() {
19 return this._status || []; 29 return this._status || [];
20 } 30 }
@@ -49,6 +59,6 @@ export default abstract class TypedStore {
49 } 59 }
50 60
51 resetStatus(): void { 61 resetStatus(): void {
52 this._status = null; 62 this._setResetStatus();
53 } 63 }
54} 64}