You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
vizality/renderer/src/api/settings/store/Store.js

122 lines
3.2 KiB

import { existsSync, readdirSync, readFileSync, mkdirSync, writeFileSync } from 'fs';
import { debounce } from 'lodash';
import { join } from 'path';
import { Directories, ActionTypes } from '@vizality/constants';
import { Flux, FluxDispatcher } from '@vizality/webpack';
/**
* Failsafe to make sure a settings folder exists.
*/
if (!existsSync(Directories.SETTINGS)) {
mkdirSync(Directories.SETTINGS, { recursive: true });
}
function loadSettings (file) {
const categoryId = file.split('.')[0];
try {
return [
file.split('.')[0],
JSON.parse(
readFileSync(join(Directories.SETTINGS, file), 'utf8')
)
];
} catch (err) {
/**
* Possibly corrupted settings; let's consider them empty.
*/
return [ categoryId, {} ];
}
}
const settings = Object.fromEntries(
readdirSync(Directories.SETTINGS)
.filter(f => !f.startsWith('.') && f.endsWith('.json'))
.map(loadSettings)
);
function updateSettings (category, newSettings) {
if (!settings[category]) {
settings[category] = {};
}
Object.assign(settings[category], newSettings);
}
function updateSetting (category, setting, value) {
if (!settings[category]) {
settings[category] = {};
}
if (value === void 0) {
delete settings[category][setting];
} else {
settings[category][setting] = value;
}
}
function toggleSetting (category, setting, defaultValue) {
if (!settings[category]) {
settings[category] = {};
}
const previous = settings[category][setting];
if (previous === void 0) {
settings[category][setting] = !defaultValue;
} else {
settings[category][setting] = !previous;
}
}
function deleteSetting (category, setting) {
if (!settings[category]) {
settings[category] = {};
}
delete settings[category][setting];
}
class SettingsStore extends Flux.Store {
constructor (Dispatcher, handlers) {
super(Dispatcher, handlers);
this._persist = debounce(this._persist.bind(this), 1000);
this.addChangeListener(this._persist);
}
getAllSettings () {
return settings;
}
getSettings (category) {
return settings[category] || {};
}
getSetting (category, nodePath, defaultValue) {
const nodePaths = nodePath.split('.');
let currentNode = this.getSettings(category);
for (const fragment of nodePaths) {
currentNode = currentNode[fragment];
}
return (currentNode === void 0 || currentNode === null)
? defaultValue
: currentNode;
}
getSettingsKeys (category) {
return Object.keys(this.getSettings(category));
}
_persist () {
for (const category in settings) {
const file = join(Directories.SETTINGS, `${category}.json`);
const data = JSON.stringify(settings[category], null, 2);
writeFileSync(file, data);
}
}
}
export default new SettingsStore(FluxDispatcher, {
[ActionTypes.VIZALITY_UPDATE_SETTINGS]: ({ category, settings }) => updateSettings(category, settings),
[ActionTypes.VIZALITY_TOGGLE_SETTING]: ({ category, setting, defaultValue }) => toggleSetting(category, setting, defaultValue),
[ActionTypes.VIZALITY_UPDATE_SETTING]: ({ category, setting, value }) => updateSetting(category, setting, value),
[ActionTypes.VIZALITY_DELETE_SETTING]: ({ category, setting }) => deleteSetting(category, setting)
});