Files
Foundry-VTT-Docker/resources/app/client-esm/applications/sheets/user-config.mjs
2025-01-04 00:34:03 +01:00

119 lines
3.4 KiB
JavaScript

import DocumentSheetV2 from "../api/document-sheet.mjs";
import HandlebarsApplicationMixin from "../api/handlebars-application.mjs";
/**
* The User configuration application.
* @extends DocumentSheetV2
* @mixes HandlebarsApplication
* @alias UserConfig
*/
export default class UserConfig extends HandlebarsApplicationMixin(DocumentSheetV2) {
/** @inheritDoc */
static DEFAULT_OPTIONS = {
classes: ["user-config"],
position: {
width: 480,
height: "auto"
},
actions: {
releaseCharacter: UserConfig.#onReleaseCharacter
},
form: {
closeOnSubmit: true
}
};
/** @override */
static PARTS = {
form: {
id: "form",
template: "templates/sheets/user-config.hbs"
}
}
/* -------------------------------------------- */
/** @inheritDoc */
get title() {
return `${game.i18n.localize("PLAYERS.ConfigTitle")}: ${this.document.name}`;
}
/* -------------------------------------------- */
/** @override */
async _prepareContext(_options) {
return {
user: this.document,
source: this.document.toObject(),
fields: this.document.schema.fields,
characterWidget: this.#characterChoiceWidget.bind(this)
}
}
/* -------------------------------------------- */
/**
* Render the Character field as a choice between observed Actors.
* @returns {HTMLDivElement}
*/
#characterChoiceWidget(field, _groupConfig, inputConfig) {
// Create the form field
const fg = document.createElement("div");
fg.className = "form-group stacked character";
const ff = fg.appendChild(document.createElement("div"));
ff.className = "form-fields";
fg.insertAdjacentHTML("beforeend", `<p class="hint">${field.hint}</p>`);
// Actor select
const others = game.users.reduce((s, u) => {
if ( u.character && !u.isSelf ) s.add(u.character.id);
return s;
}, new Set());
const options = [];
const ownerGroup = game.i18n.localize("OWNERSHIP.OWNER");
const observerGroup = game.i18n.localize("OWNERSHIP.OBSERVER");
for ( const actor of game.actors ) {
if ( !actor.testUserPermission(this.document, "OBSERVER") ) continue;
const a = {value: actor.id, label: actor.name, disabled: others.has(actor.id)};
options.push({group: actor.isOwner ? ownerGroup : observerGroup, ...a});
}
const input = foundry.applications.fields.createSelectInput({...inputConfig,
name: field.fieldPath,
options,
blank: "",
sort: true
});
ff.appendChild(input);
// Player character
const c = this.document.character;
if ( c ) {
ff.insertAdjacentHTML("afterbegin", `<img class="avatar" src="${c.img}" alt="${c.name}">`);
const release = `<button type="button" class="icon fa-solid fa-ban" data-action="releaseCharacter"
data-tooltip="USER.SHEET.BUTTONS.RELEASE"></button>`
ff.insertAdjacentHTML("beforeend", release);
}
return fg;
}
/* -------------------------------------------- */
/**
* Handle button clicks to release the currently selected character.
* @param {PointerEvent} event
*/
static #onReleaseCharacter(event) {
event.preventDefault();
const button = event.target;
const fields = button.parentElement;
fields.querySelector("select[name=character]").value = "";
fields.querySelector("img.avatar").remove();
button.remove();
this.setPosition({height: "auto"});
}
}