From 2d71e61e46394d75d9f52ba1f4c273ed6d3c9cfd Mon Sep 17 00:00:00 2001 From: Ricardo Cino Date: Fri, 24 Jun 2022 21:25:05 +0200 Subject: chore: convert the last few stores to typescript --- src/stores/SettingsStore.ts | 230 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 230 insertions(+) create mode 100644 src/stores/SettingsStore.ts (limited to 'src/stores/SettingsStore.ts') 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 @@ +import { ipcRenderer } from 'electron'; +import { getCurrentWindow } from '@electron/remote'; +import { action, computed, observable, reaction } from 'mobx'; +import localStorage from 'mobx-localstorage'; +import { Stores } from 'src/stores.types'; +import { ApiInterface } from 'src/api'; +import { Actions } from 'src/actions/lib/actions'; +import { + DEFAULT_APP_SETTINGS, + FILE_SYSTEM_SETTINGS_TYPES, + LOCAL_SERVER, +} from '../config'; +import { hash } from '../helpers/password-helpers'; +import Request from './lib/Request'; +import TypedStore from './lib/TypedStore'; + +const debug = require('../preload-safe-debug')('Ferdium:SettingsStore'); + +export default class SettingsStore extends TypedStore { + @observable updateAppSettingsRequest = new Request( + this.api.local, + 'updateAppSettings', + ); + + loaded = false; + + fileSystemSettingsTypes = FILE_SYSTEM_SETTINGS_TYPES; + + @observable _fileSystemSettingsCache = { + app: DEFAULT_APP_SETTINGS, + proxy: {}, + }; + + constructor(stores: Stores, api: ApiInterface, actions: Actions) { + super(stores, api, actions); + + // Register action handlers + this.actions.settings.update.listen(this._update.bind(this)); + this.actions.settings.remove.listen(this._remove.bind(this)); + } + + async setup(): Promise { + await this._migrate(); + + reaction( + () => this.all.app.autohideMenuBar, + () => { + const currentWindow = getCurrentWindow(); + currentWindow.setMenuBarVisibility(!this.all.app.autohideMenuBar); + currentWindow.autoHideMenuBar = this.all.app.autohideMenuBar; + }, + ); + + reaction( + () => this.all.app.server, + server => { + if (server === LOCAL_SERVER) { + ipcRenderer.send('startLocalServer'); + } + }, + { fireImmediately: true }, + ); + + // Inactivity lock timer + let inactivityTimer; + getCurrentWindow().on('blur', () => { + if ( + this.all.app.lockingFeatureEnabled && + this.all.app.inactivityLock !== 0 + ) { + inactivityTimer = setTimeout(() => { + this.actions.settings.update({ + type: 'app', + data: { + locked: true, + }, + }); + }, this.all.app.inactivityLock * 1000 * 60); + } + }); + getCurrentWindow().on('focus', () => { + if (inactivityTimer) { + clearTimeout(inactivityTimer); + } + }); + + ipcRenderer.on('appSettings', (_, resp) => { + // Lock on startup if enabled in settings + if ( + !this.loaded && + resp.type === 'app' && + resp.data.lockingFeatureEnabled + ) { + process.nextTick(() => { + if (!this.all.app.locked) { + this.all.app.locked = true; + } + }); + } + debug('Get appSettings resolves', resp.type, resp.data); + Object.assign(this._fileSystemSettingsCache[resp.type], resp.data); + this.loaded = true; + ipcRenderer.send('initialAppSettings', resp); + }); + + for (const type of this.fileSystemSettingsTypes) { + ipcRenderer.send('getAppSettings', type); + } + } + + @computed get app() { + return this._fileSystemSettingsCache.app || DEFAULT_APP_SETTINGS; + } + + @computed get proxy() { + return this._fileSystemSettingsCache.proxy || {}; + } + + @computed get service() { + return ( + localStorage.getItem('service') || { + activeService: '', + } + ); + } + + @computed get stats() { + return ( + localStorage.getItem('stats') || { + activeService: '', + } + ); + } + + @computed get migration() { + return localStorage.getItem('migration') || {}; + } + + @computed get all() { + return { + app: this.app, + proxy: this.proxy, + service: this.service, + stats: this.stats, + migration: this.migration, + }; + } + + @action async _update({ type, data }): Promise { + const appSettings = this.all; + if (!this.fileSystemSettingsTypes.includes(type)) { + debug('Update settings', type, data, this.all); + localStorage.setItem(type, Object.assign(appSettings[type], data)); + } else { + debug('Update settings on file system', type, data); + ipcRenderer.send('updateAppSettings', { + type, + data, + }); + + Object.assign(this._fileSystemSettingsCache[type], data); + } + } + + @action async _remove({ type, key }): Promise { + 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, + }); + } + } + + _ensureMigrationAndMarkDone(migrationName: string, callback: Function): void { + if (!this.all.migration[migrationName]) { + callback(); + + const data = {}; + data[migrationName] = true; + this.actions.settings.update({ + type: 'migration', + data, + }); + } + } + + // Helper + async _migrate(): Promise { + this._ensureMigrationAndMarkDone('password-hashing', () => { + if (this.stores.settings.app.lockedPassword !== '') { + const legacySettings = localStorage.getItem('app') || {}; + this.actions.settings.update({ + type: 'app', + data: { + lockedPassword: hash(String(legacySettings.lockedPassword)), + }, + }); + } + + debug('Migrated password-hashing settings'); + }); + + this._ensureMigrationAndMarkDone('5.6.0-beta.6-settings', () => { + this.actions.settings.update({ + type: 'app', + data: { + searchEngine: DEFAULT_APP_SETTINGS.searchEngine, + }, + }); + + debug('Migrated default search engine settings'); + }); + + this._ensureMigrationAndMarkDone('user-agent-settings', () => { + this.actions.settings.update({ + type: 'app', + data: { + userAgentPref: DEFAULT_APP_SETTINGS.userAgentPref, + }, + }); + + debug('Migrated default user-agent settings'); + }); + } +} -- cgit v1.2.3-70-g09d2