aboutsummaryrefslogtreecommitdiffstats
path: root/src/stores/SettingsStore.js
blob: 31165053d7db42cd53ca90818bed30aef1a0476c (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
import { systemPreferences } from 'electron';
import { action, computed, observable } from 'mobx';
import localStorage from 'mobx-localstorage';

import Store from './lib/Store';
import SettingsModel from '../models/Settings';
import Request from './lib/Request';
import CachedRequest from './lib/CachedRequest';

const debug = require('debug')('SettingsStore');

export default class SettingsStore extends Store {
  @observable appSettingsRequest = new CachedRequest(this.api.local, 'getAppSettings');
  @observable updateAppSettingsRequest = new Request(this.api.local, 'updateAppSettings');

  constructor(...args) {
    super(...args);

    // Register action handlers
    this.actions.settings.update.listen(this._update.bind(this));
    this.actions.settings.remove.listen(this._remove.bind(this));
  }

  async setup() {
    // We need to wait until `appSettingsRequest` has been executed once, otherwise we can't patch the result. If we don't wait we'd run into an issue with mobx not reacting to changes of previously not existing keys
    await this.appSettingsRequest._promise;
    await this._migrate();
  }

  @computed get all() {
    return new SettingsModel({
      app: this.appSettingsRequest.execute().result || {},
      service: localStorage.getItem('service') || {},
      group: localStorage.getItem('group') || {},
      stats: localStorage.getItem('stats') || {},
      migration: localStorage.getItem('migration') || {},
    });
  }

  @action async _update({ type, data }) {
    const appSettings = this.all;
    if (type !== 'app') {
      debug('Update settings', type, data, this.all);
      localStorage.setItem(type, Object.assign(appSettings[type], data));
    } else {
      debug('Update settings on file system', type, data);
      this.updateAppSettingsRequest.execute(data);

      this.appSettingsRequest.patch((result) => {
        if (!result) return;
        Object.assign(result, data);
      });
    }
  }

  @action async _remove({ type, key }) {
    if (type === 'app') return; // app keys can't be deleted

    const appSettings = this.all[type];
    if (Object.hasOwnProperty.call(appSettings, key)) {
      delete appSettings[key];

      this.actions.settings.update({
        type,
        data: appSettings,
      });
    }
  }

  // Helper
  async _migrate() {
    const legacySettings = localStorage.getItem('app') || {};

    if (!this.all.migration['5.0.0-beta.17-settings']) {
      this.actions.settings.update({
        type: 'app',
        data: {
          autoLaunchInBackground: legacySettings.autoLaunchInBackground,
          runInBackground: legacySettings.runInBackground,
          enableSystemTray: legacySettings.enableSystemTray,
          minimizeToSystemTray: legacySettings.minimizeToSystemTray,
          isAppMuted: legacySettings.isAppMuted,
          enableGPUAcceleration: legacySettings.enableGPUAcceleration,
          showMessageBadgeWhenMuted: legacySettings.showMessageBadgeWhenMuted,
          showDisabledServices: legacySettings.showDisabledServices,
          enableSpellchecking: legacySettings.enableSpellchecking,
        },
      });

      this.actions.settings.update({
        type: 'service',
        data: {
          activeService: legacySettings.activeService,
        },
      });

      this.actions.settings.update({
        type: 'migration',
        data: {
          '5.0.0-beta.17-settings': true,
        },
      });

      localStorage.removeItem('app');

      debug('Migrated settings to split stores');
    }

    // Enable dark mode once
    if (!this.all.migration['5.0.0-beta.19-settings']) {
      this.actions.settings.update({
        type: 'app',
        data: {
          darkMode: systemPreferences.isDarkMode(),
        },
      });

      this.actions.settings.update({
        type: 'migration',
        data: {
          '5.0.0-beta.19-settings': true,
        },
      });

      localStorage.removeItem('app');

      debug('Set up dark mode');
    }
  }
}