TheMillsMessages/scripts/send_dialog_form.mjs
trotFunky 16e1eab24b Form: Simplify player filtering
The game.users provides a .players member, listing only non-GM
users.

Use this instead of filtering the list manually.
2025-05-27 22:54:09 +01:00

110 lines
4.1 KiB
JavaScript

/*
* This files separates the form-specific validation, creation and types,
* so they can be used in the main module.
*/
/**
* @typedef {Object} MessageFormResponse
* @property {string[]} recipients The list of player IDs the message will be sent to
* @property {string} sender The name to display as the origin of the message, and in the history
* @property {string} message The body of the message, a string of HTML
*/
/**
* @typedef {Object} DialogFormResponse
* @property {boolean} valid Is the response valid ?
* @property {MessageFormResponse} form_response The response form the dialog form
*/
/**
* Given that "required" does not seem to have much impact, check that everything
* has been properly filled.
* To be able to reopen the dialog with the existing inputs, return the result of the check
* as well as the input data.
* @param {MessageFormResponse} form_response The response from the form, pre-processed
* @return {DialogFormResponse} Pass the response through and a validity flag
*/
export function validate_form(form_response) {
let valid = true;
if (form_response.message.length === 0 ||
form_response.recipients.length === 0 ||
form_response.sender.length === 0) {
ui.notifications.warn("MM.Errors.MissingFields", {localize:true});
valid = false;
}
return {valid, form_response};
}
/**
* Prepare the HTML used for the sending message dialog, filling previous values and handling if it is a chained message.
* @param {MessageFormResponse|null} [existing_values=null] Values from a previously filled form
* @param {boolean} [chain=false] If this is a chained message or not
* @returns {string} HTML for the send message Dialog content
*/
export function prepare_send_message_html(existing_values = null, chain = false) {
let players_options = []
for (let user of game.users.players) {
players_options.push({
label: user.character ? user.character.name : user.name,
value: user.id,
})
}
if (existing_values && existing_values.recipients.length > 0) {
players_options
.filter((option) => existing_values.recipients.includes(option.value))
.forEach((option) => {option.selected = true})
}
const recipient_input = foundry.applications.fields.createMultiSelectInput({
name: "recipients_IDs",
required: true,
blank: false,
options: players_options,
/*
* Send chained messages to the same recipients, disallow changing it in this case.
* This is an arbitrary decision that simplifies the process of sending the messages.
*/
disabled: chain,
})
const recipient_group = foundry.applications.fields.createFormGroup({
input: recipient_input,
label: "MM.Dialogs.SendDialog.RecipientsLabel",
hint: chain ? "MM.Dialogs.SendDialog.RecipientsChainHint" : "MM.Dialogs.SendDialog.RecipientsHint",
localize: true,
})
const sender_input = foundry.applications.fields.createTextInput({
name: "sender_name",
required: true,
placeholder: game.i18n.localize("MM.Dialogs.SendDialog.SenderPlaceholder"),
value: existing_values ? existing_values.sender : null,
})
const sender_group = foundry.applications.fields.createFormGroup({
input: sender_input,
label: "MM.Dialogs.SendDialog.SenderLabel",
hint: "MM.Dialogs.SendDialog.SenderHint",
localize: true
})
const message_input = foundry.applications.elements.HTMLProseMirrorElement.create({
name: "message",
required: true,
value: existing_values && existing_values.message ? existing_values.message : "",
editable: true,
compact: true,
collaborate: false,
toggled: false,
height: 350,
})
const message_group = foundry.applications.fields.createFormGroup({
input: message_input,
label: "MM.Dialogs.SendDialog.MessageEditorLabel",
stacked: true,
localize: true,
})
return recipient_group.outerHTML + sender_group.outerHTML + message_group.outerHTML;
}