From 9d353543c695b3a2a7fc3d168b19f784d2f38b4f Mon Sep 17 00:00:00 2001 From: Zhell Date: Sun, 1 Dec 2024 21:46:44 +0100 Subject: [PATCH] Update "whisper users" for v12 --- tools/whisper-users.js | 43 +++++++++++++++++++++++ tools/whisper_players.js | 76 ---------------------------------------- 2 files changed, 43 insertions(+), 76 deletions(-) create mode 100644 tools/whisper-users.js delete mode 100644 tools/whisper_players.js diff --git a/tools/whisper-users.js b/tools/whisper-users.js new file mode 100644 index 0000000..783d9aa --- /dev/null +++ b/tools/whisper-users.js @@ -0,0 +1,43 @@ +/** + * Send a message to specific users. The selection will be initially determined + * by which tokens are selected. + */ + +const {HTMLField, SetField, StringField} = foundry.data.fields; +const usersField = new SetField(new StringField({ + choices: game.users.reduce((acc, user) => { + if (user !== game.user) acc[user.id] = user.name; + return acc; + }, {}), +}), {}).toFormGroup({ + label: "Users", + hint: "Select the users that should receive the message.", + classes: ["stacked"] +}, { + name: "users", + type: "checkboxes", + value: game.users.filter(user => { + if (!user.character) return false; + if (user === game.user) return false; + return canvas.tokens.controlled.some(token => token.actor === user.character); + }).map(user => user.id) +}).outerHTML; +const textField = new HTMLField().toFormGroup({ + label: "Message", +}, { + name: "message", + compact: true, + height: 300, +}).outerHTML; + +const config = await foundry.applications.api.DialogV2.prompt({ + content: `
${usersField}${textField}
`, + modal: true, + rejectClose: false, + position: {width: 550, height: "auto"}, + window: {title: "Whisper Users", icon: "fa-solid fa-comments"}, + ok: {callback: (event, button) => new FormDataExtended(button.form).object}, +}); +if (!config || !config.message) return; + +ChatMessage.implementation.create({whisper: config.users, content: config.message}); diff --git a/tools/whisper_players.js b/tools/whisper_players.js deleted file mode 100644 index 3cd0750..0000000 --- a/tools/whisper_players.js +++ /dev/null @@ -1,76 +0,0 @@ -// Provides a dialog to whisper specific players. If you have tokens selected, it will automatically default to try and whisper those players. - -// get every user id that is not you. -const users = game.users.filter(u => u.id !== game.user.id); - -// get every assigned character. -const characterIds = users.map(u => u.character?.id).filter(i => !!i); - -// get every assigned character you have selected. -const selectedPlayerIds = canvas.tokens.controlled.map(i => i.actor.id).filter(i => characterIds.includes(i)); - -// Build checkbox list for all active players -const options = users.reduce((acc, {id, name, character}) => { - // should be checked by default. - const checked = (!!character && selectedPlayerIds.includes(character.id)) ? "selected" : ""; - - return acc + `${name}`; -}, `
`) + `
`; - - -const style = ` -`; - -new Dialog({ - title: "Whisper", - content: style + ` -

Whisper to:

${options}
- - -
`, - buttons: { - go: { - icon: ``, - label: "Whisper", - callback: async (html) => { - const whisperIds = new Set(); - for (let {id} of users) { - if (!!html[0].querySelector(`span[id="${id}"].selected`)) { - whisperIds.add(id); - } - } - const content = html[0].querySelector("textarea[id=message]").value; - if (!whisperIds.size) return; - const whisper = Array.from(whisperIds); - await ChatMessage.create({content, whisper}); - } - } - }, - render: (html) => { - html.css("height", "auto"); - for (let playerName of html[0].querySelectorAll(".whisper-dialog-player-name")) { - playerName.addEventListener("click", () => { - playerName.classList.toggle("selected"); - }); - } - } -}).render(true);