Dialog: Provide hints for the sender name
The dialog form has a simple text input for the sender's name. This can lead to typos or mistakes if the GM wants to send a message using the same sender name as a previous message. Add a new function that goes through all the players' histories and compiles a list of all unique senders, which we can then use to build a list of hints that will be used to show suggestions when the GM fills the sender name in the form. This is currently quite ineficcient as it re-does all the work for every single dialog. A better way would be to cache it or store it explicitly somewhere when we send a message, but this would require a way for the GM to edit it.
This commit is contained in:
parent
30c0324799
commit
d2b14dbe94
3 changed files with 64 additions and 0 deletions
|
@ -31,6 +31,8 @@ each page containing the messages from one specific recipient.
|
||||||
Both the journals and pages will be created automatically.
|
Both the journals and pages will be created automatically.
|
||||||
Players only have observer permissions on their own journal, which will take the name of their
|
Players only have observer permissions on their own journal, which will take the name of their
|
||||||
character, or their own if they don't control one yet.
|
character, or their own if they don't control one yet.
|
||||||
|
If the history is enabled, the message form will go look for previous senders' names and provide
|
||||||
|
a list for autocompletion.
|
||||||
|
|
||||||
The GM can send a message to an offline player, which will add it to its history if it is enabled,
|
The GM can send a message to an offline player, which will add it to its history if it is enabled,
|
||||||
but won't show up as a pop-up when they next log in.
|
but won't show up as a pop-up when they next log in.
|
||||||
|
|
|
@ -3,6 +3,10 @@
|
||||||
* so they can be used in the main module.
|
* so they can be used in the main module.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import { get_existing_senders } from "./utils.mjs";
|
||||||
|
|
||||||
|
const sender_hints_id = "sender_hints"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @typedef {Object} MessageFormResponse
|
* @typedef {Object} MessageFormResponse
|
||||||
* @property {string[]} recipients The list of player IDs the message will be sent to
|
* @property {string[]} recipients The list of player IDs the message will be sent to
|
||||||
|
@ -16,6 +20,23 @@
|
||||||
* @property {MessageFormResponse} form_response The response form the dialog form
|
* @property {MessageFormResponse} form_response The response form the dialog form
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate the HTML for a <datalist> whose options are the provided senders.
|
||||||
|
* @param {String} hints_id The ID to use for the <datalist> providing the hints
|
||||||
|
* @param {String[]} senders The list of existing senders, or an empty string if invalid.
|
||||||
|
*/
|
||||||
|
function generate_sender_hints(hints_id, senders) {
|
||||||
|
// Both arguments need to be usable to generate something useful.
|
||||||
|
if (!hints_id || !senders || senders.length === 0) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
let sender_hints_html = `<datalist id="${hints_id}">`
|
||||||
|
for (let sender of senders) {
|
||||||
|
sender_hints_html += `<option value="${sender}">`;
|
||||||
|
}
|
||||||
|
return sender_hints_html + "</datalist>";
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Given that "required" does not seem to have much impact, check that everything
|
* Given that "required" does not seem to have much impact, check that everything
|
||||||
* has been properly filled.
|
* has been properly filled.
|
||||||
|
@ -88,6 +109,22 @@ export function prepare_send_message_html(existing_values = null, chain = false)
|
||||||
localize: true
|
localize: true
|
||||||
})
|
})
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If we can find previous senders in player's histories, create a datalist
|
||||||
|
* with them so that the names can appear as autocompletion when filling the form.
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
* TODO: This is very silly : it re-computes everything for every form that is opened.
|
||||||
|
* Find a way to cache it or store the senders list it explicitly rather than deduce it
|
||||||
|
* from the history.
|
||||||
|
*/
|
||||||
|
let existing_senders = get_existing_senders();
|
||||||
|
if (existing_senders.length > 0) {
|
||||||
|
sender_input.setAttribute("list", sender_hints_id)
|
||||||
|
// This keeps the datalist withing the input group as proper HTML.
|
||||||
|
sender_group.insertAdjacentHTML("beforeend", generate_sender_hints(sender_hints_id, existing_senders))
|
||||||
|
}
|
||||||
|
|
||||||
const message_input = foundry.applications.elements.HTMLProseMirrorElement.create({
|
const message_input = foundry.applications.elements.HTMLProseMirrorElement.create({
|
||||||
name: "message",
|
name: "message",
|
||||||
required: true,
|
required: true,
|
||||||
|
|
|
@ -50,3 +50,28 @@ export async function create_history_journal(user) {
|
||||||
return user.setFlag(module_id, history_flag, journal.id).then(() => journal);
|
return user.setFlag(module_id, history_flag, journal.id).then(() => journal);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Go through all the user's histories to build a list of existing senders,
|
||||||
|
* so that they can be displayed or re-used.
|
||||||
|
* The final list is sorted and does not contain duplicates, as one sender
|
||||||
|
* can send messages to multiple players at once.
|
||||||
|
* @returns {String[]} A sorted array of the sender names, if any
|
||||||
|
*/
|
||||||
|
export function get_existing_senders() {
|
||||||
|
/** @type {String[]} */
|
||||||
|
let senders = []
|
||||||
|
for (let user of game.users.players) {
|
||||||
|
/** @type {JournalEntry} */
|
||||||
|
let history = game.journal.get(user.getFlag(module_id, history_flag))
|
||||||
|
if (!history) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
for (let page of history.pages) {
|
||||||
|
if (!senders.includes(page.name)) {
|
||||||
|
senders.push(page.name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return senders.sort();
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue