Add the ability to select images with the ArtBrowser
This commit is contained in:
parent
e1606ac2f3
commit
0381df035e
4 changed files with 104 additions and 7 deletions
|
|
@ -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
|
||||
};
|
||||
|
|
|
|||
5
module/utils/imagePath.mjs
Normal file
5
module/utils/imagePath.mjs
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
import { filePath } from "../consts.mjs";
|
||||
|
||||
export function imagePath(image) {
|
||||
return filePath(image.path);
|
||||
};
|
||||
|
|
@ -1,11 +1,23 @@
|
|||
<li class="image grid">
|
||||
<li
|
||||
class="image grid"
|
||||
data-image-id="{{image.id}}"
|
||||
>
|
||||
<img
|
||||
src="{{tb-filePath image.path}}"
|
||||
alt=""
|
||||
>
|
||||
{{#if (eq selectMode "single")}}
|
||||
<button>Select</button>
|
||||
<button
|
||||
data-action="select"
|
||||
>
|
||||
Select
|
||||
</button>
|
||||
{{else if (eq selectMode "multi")}}
|
||||
<input type="checkbox">
|
||||
<button
|
||||
data-action="select"
|
||||
aria-pressed="{{image.selected}}"
|
||||
>
|
||||
Select (Multi)
|
||||
</button>
|
||||
{{/if}}
|
||||
</li>
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@
|
|||
type="button"
|
||||
data-action="openApp"
|
||||
data-app="ArtBrowser"
|
||||
data-select-mode="multi"
|
||||
>
|
||||
View All
|
||||
</button>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue