Add the ability to select images with the ArtBrowser

This commit is contained in:
Oliver 2026-01-29 23:04:20 -07:00
parent e1606ac2f3
commit 0381df035e
4 changed files with 104 additions and 7 deletions

View file

@ -1,5 +1,6 @@
import { __ID__, filePath } from "../consts.mjs";
import { getFile, lastModifiedAt } from "../utils/fs.mjs";
import { imagePath } from "../utils/imagePath.mjs";
import { paginate } from "../utils/pagination.mjs";
import { ImageApp } from "./ImageApp.mjs";
@ -22,6 +23,7 @@ export class ArtBrowser extends HandlebarsApplicationMixin(ApplicationV2) {
nextPage: this.#nextPage,
prevPage: this.#prevPage,
uploadImage: this.#uploadImage,
select: this.#selectImage,
},
};
@ -40,12 +42,20 @@ export class ArtBrowser extends HandlebarsApplicationMixin(ApplicationV2) {
// #region Instance Data
#page = 1;
#selectCount = 0;
#onSubmit = null;
filters = {
name: ``,
tags: [],
artists: [],
};
constructor({ selectCount = 0, onSubmit = null, ...opts } = {}) {
super(opts);
this.#selectCount = selectCount;
this.#onSubmit = onSubmit;
};
async setPage(page) {
if (this.#page == page) { return };
this.#page = page;
@ -54,6 +64,15 @@ export class ArtBrowser extends HandlebarsApplicationMixin(ApplicationV2) {
};
return;
};
get selectMode() {
if (this.#selectCount === 0) {
return `view`;
} else if (this.#selectCount === 1) {
return `single`;
};
return `multi`;
};
// #endregion Instance Data
// #region Lifecycle
@ -112,8 +131,21 @@ export class ArtBrowser extends HandlebarsApplicationMixin(ApplicationV2) {
};
};
_tearDown(...args) {
super._tearDown(...args);
async close(options) {
this.#submit(null);
return super.close(options);
};
#submitted = false;
async #submit(value) {
if (this.#submitted) return;
this.#onSubmit?.(value);
this.#submitted = true;
this.close();
};
_tearDown(options) {
super._tearDown(options);
Hooks.off(`${__ID__}.imageUploaded`, this.#imageUploadHook);
Hooks.off(`${__ID__}.imageUpdated`, this.#imageUpdateHook);
};
@ -125,7 +157,7 @@ export class ArtBrowser extends HandlebarsApplicationMixin(ApplicationV2) {
meta: {
idp: this.id,
},
selectMode: `view`,
selectMode: this.selectMode,
};
};
@ -227,5 +259,54 @@ export class ArtBrowser extends HandlebarsApplicationMixin(ApplicationV2) {
const app = new ImageApp();
app.render({ force: true });
};
#selected = new Set();
/** @this {ArtBrowser} */
static async #selectImage(event, target) {
if (this.#selectCount === 0) { return };
const imageID = target.closest(`[data-image-id]`)?.dataset.imageId;
const image = this.#imagesDB.data[imageID];
if (!imageID || !image) { return };
const path = imagePath(image);
if (this.#selectCount > 1) {
if (this.#selected.has(path)) {
target.ariaPressed = false;
this.#selected.delete(path);
} else {
target.ariaPressed = true;
this.#selected.add(path);
};
if (this.#selected.size >= this.#selectCount) {
await this.#submit(Array.from(this.#selected));
};
} else {
await this.#submit(path);
};
};
// #endregion Actions
// #region Factories
/**
* Opens an ArtBrowser intended to get the user to select some number
* of tokens.
*
* @param {number} count The amount of tokens that the user needs to
* select
* @returns A promise that resolves to a string, string[], or null
*/
static async select(count = 1) {
if (count < 1) {
throw "Unable to select 0 or fewer tokens";
};
return new Promise((resolve) => {
const app = new this({
selectCount: count,
onSubmit: resolve,
});
app.render({ force: true, });
});
};
// #endregion Factories
};