From d5ed86fb4005036d597bc90b860e21ca07d68205 Mon Sep 17 00:00:00 2001 From: KoloMl Date: Thu, 27 Feb 2025 00:50:05 +0400 Subject: [PATCH 1/3] Exposing timer return type globally --- src/app.d.ts | 3 +++ src/lib/components/MaintenancePopup.ts | 2 +- src/lib/extension/CustomCategoriesResolver.ts | 6 ++++-- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/app.d.ts b/src/app.d.ts index 5a58731..e0ceca7 100644 --- a/src/app.d.ts +++ b/src/app.d.ts @@ -4,6 +4,9 @@ import MaintenanceProfile from "$entities/MaintenanceProfile"; import type TagGroup from "$entities/TagGroup"; declare global { + // Helper type to not deal with differences between the setTimeout of @types/node and usual web browser's type. + type Timeout = ReturnType; + namespace App { // interface Error {} // interface Locals {} diff --git a/src/lib/components/MaintenancePopup.ts b/src/lib/components/MaintenancePopup.ts index 718c6a8..fa65ce5 100644 --- a/src/lib/components/MaintenancePopup.ts +++ b/src/lib/components/MaintenancePopup.ts @@ -30,7 +30,7 @@ export class MaintenancePopup extends BaseComponent { #tagsToAdd: Set = new Set(); #isPlanningToSubmit: boolean = false; #isSubmitting: boolean = false; - #tagsSubmissionTimer: number | null = null; + #tagsSubmissionTimer: Timeout | null = null; #emitter = emitterAt(this); /** diff --git a/src/lib/extension/CustomCategoriesResolver.ts b/src/lib/extension/CustomCategoriesResolver.ts index 169833d..4381d53 100644 --- a/src/lib/extension/CustomCategoriesResolver.ts +++ b/src/lib/extension/CustomCategoriesResolver.ts @@ -6,7 +6,7 @@ export default class CustomCategoriesResolver { #tagCategories = new Map(); #compiledRegExps = new Map(); #tagDropdowns: TagDropdownWrapper[] = []; - #nextQueuedUpdate = -1; + #nextQueuedUpdate: Timeout | null = null; constructor() { TagGroup.subscribe(this.#onTagGroupsReceived.bind(this)); @@ -24,7 +24,9 @@ export default class CustomCategoriesResolver { } #queueUpdatingTags() { - clearTimeout(this.#nextQueuedUpdate); + if (this.#nextQueuedUpdate) { + clearTimeout(this.#nextQueuedUpdate); + } this.#nextQueuedUpdate = setTimeout( this.#updateUnprocessedTags.bind(this), From 76e7bf15427b7f3230c6b7f7092459a28b14f65b Mon Sep 17 00:00:00 2001 From: KoloMl Date: Thu, 27 Feb 2025 00:53:44 +0400 Subject: [PATCH 2/3] Fixed missing empty checks for required components --- src/lib/components/ImageShowFullscreenButton.ts | 2 +- src/lib/components/MaintenancePopup.ts | 14 +++++++++----- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/src/lib/components/ImageShowFullscreenButton.ts b/src/lib/components/ImageShowFullscreenButton.ts index 01a1eaf..f2c0993 100644 --- a/src/lib/components/ImageShowFullscreenButton.ts +++ b/src/lib/components/ImageShowFullscreenButton.ts @@ -47,7 +47,7 @@ export class ImageShowFullscreenButton extends BaseComponent { } #onButtonClicked() { - const imageLinks = this.#mediaBoxTools?.mediaBox.imageLinks; + const imageLinks = this.#mediaBoxTools?.mediaBox?.imageLinks; if (!imageLinks) { throw new Error('Failed to resolve image links from media box tools!'); diff --git a/src/lib/components/MaintenancePopup.ts b/src/lib/components/MaintenancePopup.ts index fa65ce5..8792022 100644 --- a/src/lib/components/MaintenancePopup.ts +++ b/src/lib/components/MaintenancePopup.ts @@ -70,6 +70,10 @@ export class MaintenancePopup extends BaseComponent { const mediaBox = this.#mediaBoxTools.mediaBox; + if (!mediaBox) { + throw new Error('Media box component not found!'); + } + mediaBox.on('mouseout', this.#onMouseLeftArea.bind(this)); mediaBox.on('mouseover', this.#onMouseEnteredArea.bind(this)); } @@ -83,7 +87,7 @@ export class MaintenancePopup extends BaseComponent { } #refreshTagsList() { - if (!this.#mediaBoxTools) { + if (!this.#mediaBoxTools?.mediaBox) { return; } @@ -109,11 +113,11 @@ export class MaintenancePopup extends BaseComponent { this.#tagsList[index] = tagElement; this.#tagsListElement.appendChild(tagElement); - const isPresent = currentPostTags.has(tagName); + const isPresent = currentPostTags?.has(tagName); tagElement.classList.toggle('is-present', isPresent); tagElement.classList.toggle('is-missing', !isPresent); - tagElement.classList.toggle('is-aliased', isPresent && currentPostTags.get(tagName) !== tagName); + tagElement.classList.toggle('is-aliased', isPresent && currentPostTags?.get(tagName) !== tagName); // Just to prevent duplication, we need to include this tag to the map of suggested invalid tags if (tagsBlacklist.includes(tagName)) { @@ -193,7 +197,7 @@ export class MaintenancePopup extends BaseComponent { } async #onSubmissionTimerPassed() { - if (!this.#isPlanningToSubmit || this.#isSubmitting || !this.#mediaBoxTools) { + if (!this.#isPlanningToSubmit || this.#isSubmitting || !this.#mediaBoxTools?.mediaBox) { return; } @@ -264,7 +268,7 @@ export class MaintenancePopup extends BaseComponent { } #revealInvalidTags() { - if (!this.#mediaBoxTools) { + if (!this.#mediaBoxTools?.mediaBox) { return; } From 8e843c2b19a118d663b816720ebc817541d8fae0 Mon Sep 17 00:00:00 2001 From: KoloMl Date: Thu, 27 Feb 2025 00:54:00 +0400 Subject: [PATCH 3/3] Fixed element types not being set up for queries --- src/content/header.ts | 2 +- src/content/listing.ts | 3 +-- src/content/tags.ts | 2 +- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/content/header.ts b/src/content/header.ts index 00ccd65..a306a89 100644 --- a/src/content/header.ts +++ b/src/content/header.ts @@ -1,6 +1,6 @@ import { initializeSiteHeader } from "$lib/components/SiteHeaderWrapper"; -const siteHeader = document.querySelector('.header'); +const siteHeader = document.querySelector('.header'); if (siteHeader) { initializeSiteHeader(siteHeader); diff --git a/src/content/listing.ts b/src/content/listing.ts index 985eac1..63a436b 100644 --- a/src/content/listing.ts +++ b/src/content/listing.ts @@ -4,8 +4,7 @@ import { calculateMediaBoxesPositions, initializeMediaBox } from "$lib/component import { createMaintenanceStatusIcon } from "$lib/components/MaintenanceStatusIcon"; import { createImageShowFullscreenButton } from "$lib/components/ImageShowFullscreenButton"; -/** @type {NodeListOf} */ -const mediaBoxes = document.querySelectorAll('.media-box'); +const mediaBoxes = document.querySelectorAll('.media-box'); mediaBoxes.forEach(mediaBoxElement => { initializeMediaBox(mediaBoxElement, [ diff --git a/src/content/tags.ts b/src/content/tags.ts index f8d685b..a4fa996 100644 --- a/src/content/tags.ts +++ b/src/content/tags.ts @@ -1,6 +1,6 @@ import { watchTagDropdownsInTagsEditor, wrapTagDropdown } from "$lib/components/TagDropdownWrapper"; -for (let tagDropdownElement of document.querySelectorAll('.tag.dropdown')) { +for (let tagDropdownElement of document.querySelectorAll('.tag.dropdown')) { wrapTagDropdown(tagDropdownElement); }