diff --git a/module/apps/ArtBrowser.mjs b/module/apps/ArtBrowser.mjs index bf80b3b..0960d30 100644 --- a/module/apps/ArtBrowser.mjs +++ b/module/apps/ArtBrowser.mjs @@ -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 }; diff --git a/module/utils/imagePath.mjs b/module/utils/imagePath.mjs new file mode 100644 index 0000000..e25983d --- /dev/null +++ b/module/utils/imagePath.mjs @@ -0,0 +1,5 @@ +import { filePath } from "../consts.mjs"; + +export function imagePath(image) { + return filePath(image.path); +}; diff --git a/templates/ArtBrowser/image/grid.hbs b/templates/ArtBrowser/image/grid.hbs index 2c7fe5a..595b998 100644 --- a/templates/ArtBrowser/image/grid.hbs +++ b/templates/ArtBrowser/image/grid.hbs @@ -1,11 +1,23 @@ -