From 723bcf873528f21a47a963453794e005f2e81734 Mon Sep 17 00:00:00 2001 From: Oliver Date: Sat, 8 Nov 2025 19:07:01 -0700 Subject: [PATCH] Add notification and submission tracking for the QueryManager --- langs/en-ca.json | 1 + module/utils/QueryManager.mjs | 53 ++++++++++++++++++++++++++--------- 2 files changed, 40 insertions(+), 14 deletions(-) diff --git a/langs/en-ca.json b/langs/en-ca.json index 425e065..1854bf9 100644 --- a/langs/en-ca.json +++ b/langs/en-ca.json @@ -34,6 +34,7 @@ }, "notifs": { "error": { + "missing-id": "An ID must be provided", "invalid-socket": "Invalid socket data received, this means a module or system bug is present.", "unknown-socket-event": "An unknown socket event was received: {event}", "malformed-socket-payload": "Socket event \"{event}\" received with malformed payload. Details: {details}" diff --git a/module/utils/QueryManager.mjs b/module/utils/QueryManager.mjs index 2dfc381..b56b813 100644 --- a/module/utils/QueryManager.mjs +++ b/module/utils/QueryManager.mjs @@ -1,13 +1,24 @@ /** - * @typedef Apple + * @typedef QueryData * @property {string[]} users * @property {Function} resolve * @property {Record} responses + * @property {(() => Promise)|null} onSubmit */ -const { randomID } = foundry.utils; +import { filePath } from "../consts.mjs"; + +async function sendBasicNotification(userID, answers) { + const content = await foundry.applications.handlebars.renderTemplate( + filePath(`templates/query-response.hbs`), + { answers }, + ); + + QueryManager.notify(userID, content, { includeGM: false }); +}; export class QueryManager { + /** @type {Map} */ static #queries = new Map(); static #promises = new Map(); @@ -15,8 +26,18 @@ export class QueryManager { return this.#queries.has(requestID); }; - static async query(request, users = null, config = undefined) { - request.id ??= randomID(); + static async query( + request, + { + onSubmit = sendBasicNotification, + users = null, + config = undefined, + } = {}, + ) { + if (!request.id) { + ui.notifications.error(game.i18n.localize(`taf.notifs.error.missing-id`)); + return; + }; game.socket.emit(`system.taf`, { event: `query.prompt`, @@ -39,32 +60,36 @@ export class QueryManager { users: users ?? game.users.filter(u => u.id !== game.user.id), resolve, responses: {}, + onSubmit, }, ); }); return promise; }; - static async submit(requestID, answers) { - game.socket.emit(`system.taf`, { - event: `query.submit`, - payload: { - id: requestID, - answers, - }, - }); - }; - static async addResponse(requestID, userID, answers) { const data = this.#queries.get(requestID); data.responses[userID] = answers; + await data.onSubmit?.(userID, answers); + // Validate for responses from everyone if (data.users.length === Object.keys(data.responses).length) { data.resolve(data.responses); }; }; + static async notify(userID, content, { includeGM = false } = {}) { + game.socket.emit(`system.taf`, { + event: `query.notify`, + payload: { + userID, + content, + includeGM, + }, + }); + } + static async cancel(requestID) { // prevent cancelling other people's queries if (!this.#queries.has(requestID)) { return };