szurubooru/client/js/controls/pool_input_control.js

195 lines
6 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"use strict";
const api = require("../api.js");
const pools = require("../pools.js");
const misc = require("../util/misc.js");
const uri = require("../util/uri.js");
const Pool = require("../models/pool.js");
const settings = require("../models/settings.js");
const events = require("../events.js");
const views = require("../util/views.js");
const PoolAutoCompleteControl = require("./pool_auto_complete_control.js");
const KEY_SPACE = 32;
const KEY_RETURN = 13;
const SOURCE_INIT = "init";
const SOURCE_IMPLICATION = "implication";
const SOURCE_USER_INPUT = "user-input";
const SOURCE_CLIPBOARD = "clipboard";
const template = views.getTemplate("pool-input");
function _fadeOutListItemNodeStatus(listItemNode) {
if (listItemNode.classList.length) {
if (listItemNode.fadeTimeout) {
window.clearTimeout(listItemNode.fadeTimeout);
}
listItemNode.fadeTimeout = window.setTimeout(() => {
while (listItemNode.classList.length) {
listItemNode.classList.remove(listItemNode.classList.item(0));
}
listItemNode.fadeTimeout = null;
}, 2500);
}
}
class PoolInputControl extends events.EventTarget {
constructor(hostNode, poolList) {
super();
this.pools = poolList;
this._hostNode = hostNode;
this._poolToListItemNode = new Map();
// dom
const editAreaNode = template();
this._editAreaNode = editAreaNode;
this._poolInputNode = editAreaNode.querySelector("input");
this._poolListNode = editAreaNode.querySelector("ul.compact-pools");
this._autoCompleteControl = new PoolAutoCompleteControl(
this._poolInputNode,
{
getTextToFind: () => {
return this._poolInputNode.value;
},
confirm: (pool) => {
this._poolInputNode.value = "";
this.addPool(pool, SOURCE_USER_INPUT);
},
delete: (pool) => {
this._poolInputNode.value = "";
this.deletePool(pool);
},
verticalShift: -2,
}
);
// show
this._hostNode.style.display = "none";
this._hostNode.parentNode.insertBefore(
this._editAreaNode,
hostNode.nextSibling
);
// add existing pools
for (let pool of [...this.pools]) {
const listItemNode = this._createListItemNode(pool);
this._poolListNode.appendChild(listItemNode);
}
}
addPool(pool, source) {
if (source !== SOURCE_INIT && this.pools.hasPoolId(pool.id)) {
return Promise.resolve();
}
this.pools.add(pool, false);
const listItemNode = this._createListItemNode(pool);
if (!pool.category) {
listItemNode.classList.add("new");
}
this._poolListNode.prependChild(listItemNode);
_fadeOutListItemNodeStatus(listItemNode);
this.dispatchEvent(
new CustomEvent("add", {
detail: { pool: pool, source: source },
})
);
this.dispatchEvent(new CustomEvent("change"));
return Promise.resolve();
}
deletePool(pool) {
if (!this.pools.hasPoolId(pool.id)) {
return;
}
this.pools.removeById(pool.id);
this._hideAutoComplete();
this._deleteListItemNode(pool);
this.dispatchEvent(
new CustomEvent("remove", {
detail: { pool: pool },
})
);
this.dispatchEvent(new CustomEvent("change"));
}
_createListItemNode(pool) {
const className = pool.category
? misc.makeCssName(pool.category, "pool")
: null;
const poolLinkNode = document.createElement("a");
if (className) {
poolLinkNode.classList.add(className);
}
poolLinkNode.setAttribute(
"href",
uri.formatClientLink("pool", pool.names[0])
);
const poolIconNode = document.createElement("i");
poolIconNode.classList.add("fa");
poolIconNode.classList.add("fa-pool");
poolLinkNode.appendChild(poolIconNode);
const searchLinkNode = document.createElement("a");
if (className) {
searchLinkNode.classList.add(className);
}
searchLinkNode.setAttribute(
"href",
uri.formatClientLink("posts", { query: "pool:" + pool.id })
);
searchLinkNode.textContent = pool.names[0] + " ";
const usagesNode = document.createElement("span");
usagesNode.classList.add("pool-usages");
usagesNode.setAttribute("data-pseudo-content", pool.postCount);
const removalLinkNode = document.createElement("a");
removalLinkNode.classList.add("remove-pool");
removalLinkNode.setAttribute("href", "");
removalLinkNode.setAttribute("data-pseudo-content", "×");
removalLinkNode.addEventListener("click", (e) => {
e.preventDefault();
this.deletePool(pool);
});
const listItemNode = document.createElement("li");
listItemNode.appendChild(removalLinkNode);
listItemNode.appendChild(poolLinkNode);
listItemNode.appendChild(searchLinkNode);
listItemNode.appendChild(usagesNode);
for (let name of pool.names) {
this._poolToListItemNode.set(name, listItemNode);
}
return listItemNode;
}
_deleteListItemNode(pool) {
const listItemNode = this._getListItemNode(pool);
if (listItemNode) {
listItemNode.parentNode.removeChild(listItemNode);
}
for (let name of pool.names) {
this._poolToListItemNode.delete(name);
}
}
_getListItemNode(pool) {
return this._poolToListItemNode.get(pool.names[0]);
}
_hideAutoComplete() {
this._autoCompleteControl.hide();
}
}
module.exports = PoolInputControl;