1
0
mirror of https://github.com/koloml/philomena-tagging-assistant.git synced 2026-05-09 07:12:19 +00:00

Merge pull request #168 from koloml/feature/tag-profile-popup-cancel

Tagging Profiles: Cancel pending submission in popup if user decides to cancel their changes
This commit is contained in:
2026-04-05 10:27:17 -04:00
committed by GitHub
6 changed files with 38 additions and 26 deletions

View File

@@ -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

View File

@@ -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<string, string> | null;
}

View File

@@ -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<HTMLElement>('.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;
}

View File

@@ -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();
}
}

View File

@@ -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<string>) {
#onPopupStateChanged(stateChangeEvent: CustomEvent<ProfilePopupState>) {
// TODO Replace those with FontAwesome icons later. Those icons can probably be sourced from the website itself.
switch (stateChangeEvent.detail) {
case "ready":

View File

@@ -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;