From 0a410944fe297501665015fb7a662112dec74c86 Mon Sep 17 00:00:00 2001 From: KoloMl Date: Sat, 30 Mar 2024 21:28:52 +0400 Subject: [PATCH] Rewriting maintenance popup from web component to simple class --- src/content/listing.js | 8 +- src/lib/components/MaintenancePopup.js | 131 +++++++++++++++++++++++++ 2 files changed, 133 insertions(+), 6 deletions(-) create mode 100644 src/lib/components/MaintenancePopup.js diff --git a/src/content/listing.js b/src/content/listing.js index c56e4af..ebcd68e 100644 --- a/src/content/listing.js +++ b/src/content/listing.js @@ -1,9 +1,5 @@ -import "$styles/content/listing.scss"; - -import "$lib/web-components/MaintenancePopupComponent.js"; +import {createMaintenancePopup} from "$lib/components/MaintenancePopup.js"; document.querySelectorAll('.media-box').forEach(mediaBoxElement => { - mediaBoxElement.appendChild( - document.createElement('maintenance-popup') - ); + mediaBoxElement.appendChild(createMaintenancePopup()); }); diff --git a/src/lib/components/MaintenancePopup.js b/src/lib/components/MaintenancePopup.js new file mode 100644 index 0000000..70e8f27 --- /dev/null +++ b/src/lib/components/MaintenancePopup.js @@ -0,0 +1,131 @@ +import MaintenanceSettings from "$lib/extension/settings/MaintenanceSettings.js"; +import MaintenanceProfile from "$entities/MaintenanceProfile.js"; + +export class MaintenancePopup { + /** @type {HTMLElement} */ + #container; + + /** @type {HTMLElement} */ + #tagsListElement; + + /** @type {HTMLElement[]} */ + #tagsList = []; + + /** @type {MaintenanceProfile|null} */ + #activeProfile = null; + + /** + * @param {HTMLElement} container + */ + constructor(container) { + this.#container = container; + } + + build() { + this.#container.innerHTML = ''; + this.#container.classList.add('maintenance-popup'); + + this.#tagsListElement = document.createElement('div'); + this.#tagsListElement.classList.add('tags-list'); + + this.#container.append( + this.#tagsListElement, + ); + + return this; + } + + init() { + MaintenancePopup.#watchActiveProfile(activeProfile => { + this.#activeProfile = activeProfile; + this.#refreshTagsList(); + }); + } + + #refreshTagsList() { + /** @type {string[]} */ + const activeProfileTagsList = this.#activeProfile?.settings.tags || []; + + for (let tagElement of this.#tagsList) { + tagElement.remove(); + } + + this.#tagsList = new Array(activeProfileTagsList.length); + + activeProfileTagsList + .sort((a, b) => a.localeCompare(b)) + .forEach((tagName, index) => { + const tagElement = MaintenancePopup.#buildTagElement(tagName); + this.#tagsList[index] = tagElement; + this.#tagsListElement.appendChild(tagElement); + }); + } + + /** + * @param {string} tagName + * @return {HTMLElement} + */ + static #buildTagElement(tagName) { + const tagElement = document.createElement('span'); + tagElement.classList.add('tag'); + tagElement.innerText = tagName; + + return tagElement; + } + + /** + * Controller with maintenance settings. + * @type {MaintenanceSettings} + */ + static #maintenanceSettings = new MaintenanceSettings(); + + /** + * Subscribe to all necessary feeds to watch for every active profile change. Additionally, will execute the callback + * at the very start to retrieve the currently active profile. + * @param {function(MaintenanceProfile|null):void} callback Callback to execute whenever selection of active profile + * or profile itself has been changed. + * @return {function(): void} Unsubscribe function. Call it to stop watching for changes. + */ + static #watchActiveProfile(callback) { + let lastActiveProfileId = null; + + const unsubscribeFromProfilesChanges = MaintenanceProfile.subscribe(profiles => { + if (lastActiveProfileId) { + callback( + profiles.find(profile => profile.id === lastActiveProfileId) || null + ); + } + }); + + const unsubscribeFromMaintenanceSettings = MaintenanceSettings.subscribe(settings => { + if (settings.activeProfileId === lastActiveProfileId) { + return; + } + + lastActiveProfileId = settings.activeProfileId; + + this.#maintenanceSettings + .resolveActiveProfileAsObject() + .then(callback); + }); + + this.#maintenanceSettings + .resolveActiveProfileAsObject() + .then(callback); + + return () => { + unsubscribeFromProfilesChanges(); + unsubscribeFromMaintenanceSettings(); + } + } +} + +export function createMaintenancePopup() { + const container = document.createElement('div'); + + new MaintenancePopup(container) + .build() + .init(); + + return container; +}