diff --git a/src/content/components/events/comms.ts b/src/content/components/events/comms.ts index 7127a25..e5ba62a 100644 --- a/src/content/components/events/comms.ts +++ b/src/content/components/events/comms.ts @@ -1,4 +1,4 @@ -import type { MaintenancePopupEventsMap } from "$content/components/events/maintenance-popup-events"; +import type { TaggingProfilePopupEventsMap } from "$content/components/events/tagging-profile-popup-events"; import { BaseComponent } from "$content/components/base/BaseComponent"; import type { FullscreenViewerEventsMap } from "$content/components/events/fullscreen-viewer-events"; import type { BooruEventsMap } from "$content/components/events/booru-events"; @@ -7,7 +7,7 @@ import type { TagDropdownEvents } from "$content/components/events/tag-dropdown- import type { PresetBlockEventsMap } from "$content/components/events/preset-block-events"; type EventsMapping = - MaintenancePopupEventsMap + TaggingProfilePopupEventsMap & FullscreenViewerEventsMap & BooruEventsMap & TagsFormEventsMap diff --git a/src/content/components/events/maintenance-popup-events.ts b/src/content/components/events/tagging-profile-popup-events.ts similarity index 51% rename from src/content/components/events/maintenance-popup-events.ts rename to src/content/components/events/tagging-profile-popup-events.ts index 95c780f..668c850 100644 --- a/src/content/components/events/maintenance-popup-events.ts +++ b/src/content/components/events/tagging-profile-popup-events.ts @@ -1,13 +1,13 @@ import type TaggingProfile from "$entities/TaggingProfile"; export const EVENT_ACTIVE_PROFILE_CHANGED = 'active-profile-changed'; -export const EVENT_MAINTENANCE_STATE_CHANGED = 'maintenance-state-change'; +export const EVENT_PROFILE_POPUP_STATE_CHANGED = 'maintenance-state-change'; export const EVENT_TAGS_UPDATED = 'tags-updated'; -type MaintenanceState = 'processing' | 'failed' | 'complete' | 'waiting'; +export type ProfilePopupState = 'ready' | 'processing' | 'failed' | 'complete' | 'waiting'; -export interface MaintenancePopupEventsMap { +export interface TaggingProfilePopupEventsMap { [EVENT_ACTIVE_PROFILE_CHANGED]: TaggingProfile | null; - [EVENT_MAINTENANCE_STATE_CHANGED]: MaintenanceState; + [EVENT_PROFILE_POPUP_STATE_CHANGED]: ProfilePopupState; [EVENT_TAGS_UPDATED]: Map | null; } diff --git a/src/content/components/extension/MediaBoxTools.ts b/src/content/components/extension/MediaBoxTools.ts index 0c05ee5..1de65b7 100644 --- a/src/content/components/extension/MediaBoxTools.ts +++ b/src/content/components/extension/MediaBoxTools.ts @@ -2,13 +2,13 @@ import { BaseComponent } from "$content/components/base/BaseComponent"; import { getComponent } from "$content/components/base/component-utils"; import { TaggingProfilePopup } from "$content/components/extension/profiles/TaggingProfilePopup"; import { on } from "$content/components/events/comms"; -import { EVENT_ACTIVE_PROFILE_CHANGED } from "$content/components/events/maintenance-popup-events"; +import { EVENT_ACTIVE_PROFILE_CHANGED } from "$content/components/events/tagging-profile-popup-events"; import type { MediaBox } from "$content/components/philomena/MediaBox"; import type TaggingProfile from "$entities/TaggingProfile"; export class MediaBoxTools extends BaseComponent { #mediaBox: MediaBox | null = null; - #maintenancePopup: TaggingProfilePopup | null = null; + #popup: TaggingProfilePopup | null = null; init() { const mediaBoxElement = this.container.closest('.media-box'); @@ -34,8 +34,8 @@ export class MediaBoxTools extends BaseComponent { component.initialize(); } - if (!this.#maintenancePopup && component instanceof TaggingProfilePopup) { - this.#maintenancePopup = component; + if (!this.#popup && component instanceof TaggingProfilePopup) { + this.#popup = component; } } @@ -46,10 +46,6 @@ export class MediaBoxTools extends BaseComponent { this.container.classList.toggle('has-active-profile', profileChangedEvent.detail !== null); } - get maintenancePopup(): TaggingProfilePopup | null { - return this.#maintenancePopup; - } - get mediaBox(): MediaBox | null { return this.#mediaBox; } diff --git a/src/content/components/extension/profiles/TaggingProfilePopup.ts b/src/content/components/extension/profiles/TaggingProfilePopup.ts index a63b9b4..0b912cd 100644 --- a/src/content/components/extension/profiles/TaggingProfilePopup.ts +++ b/src/content/components/extension/profiles/TaggingProfilePopup.ts @@ -7,9 +7,9 @@ import { tagsBlacklist } from "$config/tags"; import { emitterAt } from "$content/components/events/comms"; import { EVENT_ACTIVE_PROFILE_CHANGED, - EVENT_MAINTENANCE_STATE_CHANGED, + EVENT_PROFILE_POPUP_STATE_CHANGED, EVENT_TAGS_UPDATED -} from "$content/components/events/maintenance-popup-events"; +} from "$content/components/events/tagging-profile-popup-events"; import type { MediaBoxTools } from "$content/components/extension/MediaBoxTools"; import { resolveTagCategoryFromTagName } from "$lib/philomena/tag-utils"; @@ -183,7 +183,20 @@ export class TaggingProfilePopup extends BaseComponent { } this.#isPlanningToSubmit = true; - this.#emitter.emit(EVENT_MAINTENANCE_STATE_CHANGED, 'waiting'); + this.#emitter.emit(EVENT_PROFILE_POPUP_STATE_CHANGED, 'waiting'); + } + + // Whenever user undoes the change they wanted to do in the popup, it's better to not send the submission and just + // do nothing. + if (!this.#tagsToAdd.size && !this.#tagsToRemove.size && this.#isPlanningToSubmit) { + this.#isPlanningToSubmit = false; + this.#emitter.emit(EVENT_PROFILE_POPUP_STATE_CHANGED, 'ready'); + TaggingProfilePopup.#notifyAboutPendingSubmission(false); + + // Probably shouldn't ever happen, but make sure we cancel any delayed submission. + if (this.#tagsSubmissionTimer) { + clearTimeout(this.#tagsSubmissionTimer); + } } } @@ -210,7 +223,7 @@ export class TaggingProfilePopup extends BaseComponent { this.#isPlanningToSubmit = false; this.#isSubmitting = true; - this.#emitter.emit(EVENT_MAINTENANCE_STATE_CHANGED, 'processing'); + this.#emitter.emit(EVENT_PROFILE_POPUP_STATE_CHANGED, 'processing'); let maybeTagsAndAliasesAfterUpdate; @@ -252,7 +265,7 @@ export class TaggingProfilePopup extends BaseComponent { TaggingProfilePopup.#notifyAboutPendingSubmission(false); - this.#emitter.emit(EVENT_MAINTENANCE_STATE_CHANGED, 'failed'); + this.#emitter.emit(EVENT_PROFILE_POPUP_STATE_CHANGED, 'failed'); this.#isSubmitting = false; return; @@ -262,7 +275,7 @@ export class TaggingProfilePopup extends BaseComponent { this.#emitter.emit(EVENT_TAGS_UPDATED, maybeTagsAndAliasesAfterUpdate); } - this.#emitter.emit(EVENT_MAINTENANCE_STATE_CHANGED, 'complete'); + this.#emitter.emit(EVENT_PROFILE_POPUP_STATE_CHANGED, 'complete'); this.#tagsToAdd.clear(); this.#tagsToRemove.clear(); @@ -360,7 +373,7 @@ export class TaggingProfilePopup extends BaseComponent { } }); - const unsubscribeFromMaintenanceSettings = this.#preferences.subscribe(settings => { + const unsubscribeFromPreferences = this.#preferences.subscribe(settings => { if (settings.activeProfile === lastActiveProfileId) { return; } @@ -382,7 +395,7 @@ export class TaggingProfilePopup extends BaseComponent { return () => { unsubscribeFromProfilesChanges(); - unsubscribeFromMaintenanceSettings(); + unsubscribeFromPreferences(); } } diff --git a/src/content/components/extension/profiles/TaggingProfileStatusIcon.ts b/src/content/components/extension/profiles/TaggingProfileStatusIcon.ts index 6e5ab8b..dc77501 100644 --- a/src/content/components/extension/profiles/TaggingProfileStatusIcon.ts +++ b/src/content/components/extension/profiles/TaggingProfileStatusIcon.ts @@ -1,7 +1,10 @@ import { BaseComponent } from "$content/components/base/BaseComponent"; import { getComponent } from "$content/components/base/component-utils"; import { on } from "$content/components/events/comms"; -import { EVENT_MAINTENANCE_STATE_CHANGED } from "$content/components/events/maintenance-popup-events"; +import { + EVENT_PROFILE_POPUP_STATE_CHANGED, + type ProfilePopupState +} from "$content/components/events/tagging-profile-popup-events"; import type { MediaBoxTools } from "$content/components/extension/MediaBoxTools"; export class TaggingProfileStatusIcon extends BaseComponent { @@ -22,10 +25,10 @@ export class TaggingProfileStatusIcon extends BaseComponent { throw new Error('Status icon element initialized outside of the media box!'); } - on(this.#mediaBoxTools, EVENT_MAINTENANCE_STATE_CHANGED, this.#onMaintenanceStateChanged.bind(this)); + on(this.#mediaBoxTools, EVENT_PROFILE_POPUP_STATE_CHANGED, this.#onPopupStateChanged.bind(this)); } - #onMaintenanceStateChanged(stateChangeEvent: CustomEvent) { + #onPopupStateChanged(stateChangeEvent: CustomEvent) { // TODO Replace those with FontAwesome icons later. Those icons can probably be sourced from the website itself. switch (stateChangeEvent.detail) { case "ready": diff --git a/src/content/components/philomena/MediaBox.ts b/src/content/components/philomena/MediaBox.ts index 2403b69..c7b1cc6 100644 --- a/src/content/components/philomena/MediaBox.ts +++ b/src/content/components/philomena/MediaBox.ts @@ -2,7 +2,7 @@ import { BaseComponent } from "$content/components/base/BaseComponent"; import { getComponent } from "$content/components/base/component-utils"; import { buildTagsAndAliasesMap } from "$lib/philomena/tag-utils"; import { on } from "$content/components/events/comms"; -import { EVENT_TAGS_UPDATED } from "$content/components/events/maintenance-popup-events"; +import { EVENT_TAGS_UPDATED } from "$content/components/events/tagging-profile-popup-events"; export class MediaBox extends BaseComponent { #thumbnailContainer: HTMLElement | null = null;