From 918dcc8e0023755e929b5d0d63534aeddd73d575 Mon Sep 17 00:00:00 2001 From: KoloMl Date: Sat, 23 Mar 2024 03:09:54 +0400 Subject: [PATCH] Implementing the classes to manipulate settings --- src/lib/extension/ConfigurationController.js | 82 +++++++++++++++++ .../extension/settings/MaintenanceSettings.js | 87 +++++++++++++++++++ 2 files changed, 169 insertions(+) create mode 100644 src/lib/extension/ConfigurationController.js create mode 100644 src/lib/extension/settings/MaintenanceSettings.js diff --git a/src/lib/extension/ConfigurationController.js b/src/lib/extension/ConfigurationController.js new file mode 100644 index 0000000..28aae22 --- /dev/null +++ b/src/lib/extension/ConfigurationController.js @@ -0,0 +1,82 @@ +import StorageHelper from "$lib/chrome/StorageHelper.js"; + +export default class ConfigurationController { + /** @type {string} */ + #configurationName; + + /** + * @param {string} configurationName Name of the configuration to work with. + */ + constructor(configurationName) { + this.#configurationName = configurationName; + } + + /** + * Read the setting with the given name. + * + * @param {string} settingName Setting name. + * @param {any} [defaultValue] Default value to return if the setting does not exist. Defaults to `null`. + * + * @return {Promise} The setting value or the default value if the setting does not exist. + */ + async readSetting(settingName, defaultValue = null) { + const settings = await ConfigurationController.#storageHelper.read(this.#configurationName, {}); + return settings[settingName] ?? defaultValue; + } + + /** + * Write the given value to the setting. + * + * @param {string} settingName Setting name. + * @param {any} value Value to write. + * + * @return {Promise} + */ + async writeSetting(settingName, value) { + const settings = await ConfigurationController.#storageHelper.read(this.#configurationName, {}); + + settings[settingName] = value; + + ConfigurationController.#storageHelper.write(this.#configurationName, settings); + } + + /** + * Delete the specific setting. + * + * @param {string} settingName Setting name to delete. + * + * @return {Promise} + */ + async deleteSetting(settingName) { + const settings = await ConfigurationController.#storageHelper.read(this.#configurationName, {}); + + delete settings[settingName]; + + ConfigurationController.#storageHelper.write(this.#configurationName, settings); + } + + /** + * Subscribe to changes in the configuration. + * + * @param {function(Record)} callback Callback to call when the configuration changes. The new + * configuration is passed as an argument. + * + * @return {function(): void} Unsubscribe function. + */ + subscribeToChanges(callback) { + /** @param {Record} changes */ + const changesSubscriber = changes => { + if (!changes[this.#configurationName]) { + return; + } + + callback(changes[this.#configurationName].newValue); + } + + ConfigurationController.#storageHelper.subscribe(changesSubscriber); + + return () => ConfigurationController.#storageHelper.unsubscribe(changesSubscriber); + } + + static #storageHelper = new StorageHelper(chrome.storage.local); +} \ No newline at end of file diff --git a/src/lib/extension/settings/MaintenanceSettings.js b/src/lib/extension/settings/MaintenanceSettings.js new file mode 100644 index 0000000..9ba75f0 --- /dev/null +++ b/src/lib/extension/settings/MaintenanceSettings.js @@ -0,0 +1,87 @@ +import ConfigurationController from "$lib/extension/ConfigurationController.js"; +import MaintenanceProfile from "$lib/extension/entities/MaintenanceProfile.js"; + +export default class MaintenanceSettings { + #isInitialized = false; + #activeProfileId = null; + + constructor() { + void this.#initializeSettings(); + } + + async #initializeSettings() { + MaintenanceSettings.#controller.subscribeToChanges(settings => { + this.#activeProfileId = settings.activeProfile || null; + }); + + this.#activeProfileId = await MaintenanceSettings.#controller.readSetting("activeProfile", null); + this.#isInitialized = true; + } + + /** + * Set the active maintenance profile. + * + * @return {Promise} + */ + async resolveActiveProfileId() { + if (!this.#isInitialized && !this.#activeProfileId) { + this.#activeProfileId = await MaintenanceSettings.#controller.readSetting( + "activeProfile", + null + ); + } + + if (!this.#activeProfileId) { + return null; + } + + return this.#activeProfileId; + } + + /** + * Get the active maintenance profile if it is set. + * + * @return {Promise} + */ + async resolveActiveProfileAsObject() { + const resolvedProfileId = await this.resolveActiveProfileId(); + + return (await MaintenanceProfile.readAll()) + .find(profile => profile.id === resolvedProfileId) || null; + } + + /** + * Set the active maintenance profile. + * + * @param {string|null} profileId ID of the profile to set as active. If `null`, the active profile will be considered + * unset. + * + * @return {Promise} + */ + async setActiveProfileId(profileId) { + this.#activeProfileId = profileId; + + await MaintenanceSettings.#controller.writeSetting("activeProfile", profileId); + } + + /** + * Controller for interaction with the settings stored in the extension's storage. + * + * @type {ConfigurationController} + */ + static #controller = new ConfigurationController("maintenance"); + + /** + * Subscribe to the changes in the maintenance-related settings. + * + * @param {function({activeProfileId: string|null}): void} callback Callback to call when the settings change. The new settings are + * passed as an argument. + * + * @return {function(): void} Unsubscribe function. + */ + static subscribe(callback) { + return MaintenanceSettings.#controller.subscribeToChanges(settings => { + + }); + } +} \ No newline at end of file