aboutsummaryrefslogtreecommitdiffstats
path: root/src/stores/SettingsStore.ts
diff options
context:
space:
mode:
Diffstat (limited to 'src/stores/SettingsStore.ts')
-rw-r--r--src/stores/SettingsStore.ts230
1 files changed, 230 insertions, 0 deletions
diff --git a/src/stores/SettingsStore.ts b/src/stores/SettingsStore.ts
new file mode 100644
index 000000000..524f2e50c
--- /dev/null
+++ b/src/stores/SettingsStore.ts
@@ -0,0 +1,230 @@
1import { ipcRenderer } from 'electron';
2import { getCurrentWindow } from '@electron/remote';
3import { action, computed, observable, reaction } from 'mobx';
4import localStorage from 'mobx-localstorage';
5import { Stores } from 'src/stores.types';
6import { ApiInterface } from 'src/api';
7import { Actions } from 'src/actions/lib/actions';
8import {
9 DEFAULT_APP_SETTINGS,
10 FILE_SYSTEM_SETTINGS_TYPES,
11 LOCAL_SERVER,
12} from '../config';
13import { hash } from '../helpers/password-helpers';
14import Request from './lib/Request';
15import TypedStore from './lib/TypedStore';
16
17const debug = require('../preload-safe-debug')('Ferdium:SettingsStore');
18
19export default class SettingsStore extends TypedStore {
20 @observable updateAppSettingsRequest = new Request(
21 this.api.local,
22 'updateAppSettings',
23 );
24
25 loaded = false;
26
27 fileSystemSettingsTypes = FILE_SYSTEM_SETTINGS_TYPES;
28
29 @observable _fileSystemSettingsCache = {
30 app: DEFAULT_APP_SETTINGS,
31 proxy: {},
32 };
33
34 constructor(stores: Stores, api: ApiInterface, actions: Actions) {
35 super(stores, api, actions);
36
37 // Register action handlers
38 this.actions.settings.update.listen(this._update.bind(this));
39 this.actions.settings.remove.listen(this._remove.bind(this));
40 }
41
42 async setup(): Promise<void> {
43 await this._migrate();
44
45 reaction(
46 () => this.all.app.autohideMenuBar,
47 () => {
48 const currentWindow = getCurrentWindow();
49 currentWindow.setMenuBarVisibility(!this.all.app.autohideMenuBar);
50 currentWindow.autoHideMenuBar = this.all.app.autohideMenuBar;
51 },
52 );
53
54 reaction(
55 () => this.all.app.server,
56 server => {
57 if (server === LOCAL_SERVER) {
58 ipcRenderer.send('startLocalServer');
59 }
60 },
61 { fireImmediately: true },
62 );
63
64 // Inactivity lock timer
65 let inactivityTimer;
66 getCurrentWindow().on('blur', () => {
67 if (
68 this.all.app.lockingFeatureEnabled &&
69 this.all.app.inactivityLock !== 0
70 ) {
71 inactivityTimer = setTimeout(() => {
72 this.actions.settings.update({
73 type: 'app',
74 data: {
75 locked: true,
76 },
77 });
78 }, this.all.app.inactivityLock * 1000 * 60);
79 }
80 });
81 getCurrentWindow().on('focus', () => {
82 if (inactivityTimer) {
83 clearTimeout(inactivityTimer);
84 }
85 });
86
87 ipcRenderer.on('appSettings', (_, resp) => {
88 // Lock on startup if enabled in settings
89 if (
90 !this.loaded &&
91 resp.type === 'app' &&
92 resp.data.lockingFeatureEnabled
93 ) {
94 process.nextTick(() => {
95 if (!this.all.app.locked) {
96 this.all.app.locked = true;
97 }
98 });
99 }
100 debug('Get appSettings resolves', resp.type, resp.data);
101 Object.assign(this._fileSystemSettingsCache[resp.type], resp.data);
102 this.loaded = true;
103 ipcRenderer.send('initialAppSettings', resp);
104 });
105
106 for (const type of this.fileSystemSettingsTypes) {
107 ipcRenderer.send('getAppSettings', type);
108 }
109 }
110
111 @computed get app() {
112 return this._fileSystemSettingsCache.app || DEFAULT_APP_SETTINGS;
113 }
114
115 @computed get proxy() {
116 return this._fileSystemSettingsCache.proxy || {};
117 }
118
119 @computed get service() {
120 return (
121 localStorage.getItem('service') || {
122 activeService: '',
123 }
124 );
125 }
126
127 @computed get stats() {
128 return (
129 localStorage.getItem('stats') || {
130 activeService: '',
131 }
132 );
133 }
134
135 @computed get migration() {
136 return localStorage.getItem('migration') || {};
137 }
138
139 @computed get all() {
140 return {
141 app: this.app,
142 proxy: this.proxy,
143 service: this.service,
144 stats: this.stats,
145 migration: this.migration,
146 };
147 }
148
149 @action async _update({ type, data }): Promise<void> {
150 const appSettings = this.all;
151 if (!this.fileSystemSettingsTypes.includes(type)) {
152 debug('Update settings', type, data, this.all);
153 localStorage.setItem(type, Object.assign(appSettings[type], data));
154 } else {
155 debug('Update settings on file system', type, data);
156 ipcRenderer.send('updateAppSettings', {
157 type,
158 data,
159 });
160
161 Object.assign(this._fileSystemSettingsCache[type], data);
162 }
163 }
164
165 @action async _remove({ type, key }): Promise<void> {
166 if (type === 'app') return; // app keys can't be deleted
167
168 const appSettings = this.all[type];
169 if (Object.hasOwnProperty.call(appSettings, key)) {
170 delete appSettings[key];
171
172 this.actions.settings.update({
173 type,
174 data: appSettings,
175 });
176 }
177 }
178
179 _ensureMigrationAndMarkDone(migrationName: string, callback: Function): void {
180 if (!this.all.migration[migrationName]) {
181 callback();
182
183 const data = {};
184 data[migrationName] = true;
185 this.actions.settings.update({
186 type: 'migration',
187 data,
188 });
189 }
190 }
191
192 // Helper
193 async _migrate(): Promise<void> {
194 this._ensureMigrationAndMarkDone('password-hashing', () => {
195 if (this.stores.settings.app.lockedPassword !== '') {
196 const legacySettings = localStorage.getItem('app') || {};
197 this.actions.settings.update({
198 type: 'app',
199 data: {
200 lockedPassword: hash(String(legacySettings.lockedPassword)),
201 },
202 });
203 }
204
205 debug('Migrated password-hashing settings');
206 });
207
208 this._ensureMigrationAndMarkDone('5.6.0-beta.6-settings', () => {
209 this.actions.settings.update({
210 type: 'app',
211 data: {
212 searchEngine: DEFAULT_APP_SETTINGS.searchEngine,
213 },
214 });
215
216 debug('Migrated default search engine settings');
217 });
218
219 this._ensureMigrationAndMarkDone('user-agent-settings', () => {
220 this.actions.settings.update({
221 type: 'app',
222 data: {
223 userAgentPref: DEFAULT_APP_SETTINGS.userAgentPref,
224 },
225 });
226
227 debug('Migrated default user-agent settings');
228 });
229 }
230}