mac-calendar/app/components/Preferences.js
2021-10-03 09:58:17 +08:00

152 lines
3.8 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

const { ipcMain } = require('electron');
const { resolve } = require('path');
const {
readFile,
writeFile,
readdir,
mkdir,
} = require('fs').promises;
const {
preferencesFile,
customBackgroundsDirectory,
integratedBackgroundsDirectory,
} = require('../paths');
const Window = require('./Window');
const {
PREFERENCES_GET,
PREFERENCES_GET_ALL,
PREFERENCES_GET_BACKGROUND_FILE_CONTENTS,
PREFERENCES_GET_BACKGROUNDS,
PREFERENCES_HIDE,
PREFERENCES_SET,
PREFERENCES_SHOW,
} = require('../views/preferences/ipc');
class Preferences {
constructor(options = {}) {
const {
onChange,
defaults,
logger,
} = options;
this.logger = logger;
this.filePath = preferencesFile;
this.onChange = onChange || (() => {});
this.data = new Map(Object.entries(defaults));
ipcMain.handle(PREFERENCES_GET, (event, key) => this.get(key));
ipcMain.handle(PREFERENCES_GET_ALL, () => this.getAll());
ipcMain.handle(PREFERENCES_GET_BACKGROUND_FILE_CONTENTS, this.getBackgroundFileContents.bind(this));
ipcMain.handle(PREFERENCES_GET_BACKGROUNDS, this.getBackgrounds.bind(this));
ipcMain.on(PREFERENCES_SET, (event, key, value) => this.set(key, value));
ipcMain.on(PREFERENCES_HIDE, () => this.window.hide());
ipcMain.on(PREFERENCES_SHOW, () => this.window.show());
this.window = new Window({
name: 'preferences',
titleBarStyle: 'hidden',
transparent: true,
vibrancy: 'sidebar',
trafficLightPosition: { x: 20, y: 20 },
sourceFile: resolve(__dirname, '../views/preferences/preferences.html'),
webPreferences: {
preload: resolve(__dirname, '../views/preferences/preload.js'),
},
});
this.logger.debug('Preferences module created.');
this.load();
}
async load() {
try {
this.logger.debug(`Trying to load user preferences from “${this.filePath}”.`);
Object
.entries(JSON.parse(await readFile(this.filePath, 'utf8')))
.forEach((item) => this.set(...item, false));
await mkdir(customBackgroundsDirectory);
} catch ({ message }) {
if (/enoent/i.test(message)) {
this.logger.debug('Looks like its the first time starting Timestamp. No user preferences found.');
} else if (/eexist/i.test(message)) {
this.logger.debug('Directory for custom backgrounds has already been created.');
} else {
this.logger.error(message);
}
}
return this;
}
async save() {
await writeFile(this.filePath, JSON.stringify(Object.fromEntries(this.data)));
return this;
}
getAll() {
return new Map(this.data);
}
async getBackgroundFileContents(event, filePath) {
try {
return await readFile(filePath, { encoding: 'utf-8' });
} catch ({ message }) {
if (/enoent/i.test(message)) {
this.logger.warning(`Couldnt find background file “${filePath}”.`);
} else {
this.logger.error(message);
}
}
return '';
}
async getBackgrounds() {
const backgrounds = [];
const directories = [integratedBackgroundsDirectory, customBackgroundsDirectory];
await Promise.all(
directories.map(async (directory) => {
try {
(await readdir(directory)).forEach(
(background) => backgrounds.push(resolve(directory, background)),
);
} catch ({ message }) {
this.logger.warn(message);
}
}),
);
return backgrounds;
}
get(key) {
return this.data.get(key);
}
set(key, value, persist = true) {
this.logger.debug(`Setting value for preference with key ”${key}” to “${value}”.`);
this.data.set(key, value);
this.onChange(key, value);
if (persist) {
this.save();
}
return this;
}
}
module.exports = Preferences;