Data Request API helper #10

Merged
Oliver merged 94 commits from feat/data-requests into main 2025-11-22 02:51:15 +00:00
2 changed files with 56 additions and 12 deletions
Showing only changes of commit c014e17da2 - Show all commits

View file

@ -0,0 +1,18 @@
import { DialogManager } from "../../utils/DialogManager.mjs";
export async function queryCancel(payload) {
const { id } = payload;
if (!id) {
ui.notifications.error(game.i18n.format(
`taf.notifs.error.malformed-socket-payload`,
{
event: `query.cancel`,
details: `A request ID must be provided`,
Oliver marked this conversation as resolved

Localizing this would be nice

Localizing this would be nice
}),
);
return;
};
await DialogManager.close(id);
};

View file

@ -1,7 +1,14 @@
import { filePath } from "../consts.mjs";
import { Logger } from "./Logger.mjs";
import { QueryStatus } from "../apps/QueryStatus.mjs";
/** /**
* An object containing information about the current status for all users involved * An object containing information about the current status for all
* with the data request. * users involved with the data request.
* @typedef {Record<string, "finished"|"waiting"|"cancelled"|"disconnected"|"unprompted">} UserStatus * @typedef {Record<
* string,
* "finished" | "waiting" | "cancelled" | "disconnected" | "unprompted"
* >} UserStatus
*/ */
/** /**
@ -16,9 +23,13 @@
* @property {object} config The data used to create the initial config * @property {object} config The data used to create the initial config
*/ */
import { filePath } from "../consts.mjs"; /**
import { Logger } from "./Logger.mjs"; * This internal API is used in order to prevent the query.notify event
import { QueryStatus } from "../apps/QueryStatus.mjs"; * from being fired off in situations where the user hasn't responded,
* wasn't part of the query, or has already been notified.
* @type {Set<string>}
*/
export const respondedToQueries = new Set();
/** @type {Map<string, QueryData>} */ /** @type {Map<string, QueryData>} */
const queries = new Map(); const queries = new Map();
@ -26,13 +37,13 @@ const queries = new Map();
/** @type {Map<string, Promise>} */ /** @type {Map<string, Promise>} */
const promises = new Map(); const promises = new Map();
async function sendBasicNotification(userID, answers) { async function sendBasicNotification(requestID, userID, answers) {
const content = await foundry.applications.handlebars.renderTemplate( const content = await foundry.applications.handlebars.renderTemplate(
filePath(`templates/query-response.hbs`), filePath(`templates/query-response.hbs`),
{ answers }, { answers },
); );
await notify(userID, content, { includeGM: false }); await notify(requestID, userID, content, { includeGM: false });
}; };
export function has(requestID) { export function has(requestID) {
@ -138,10 +149,19 @@ export async function requery(requestID, users) {
export async function addResponse(requestID, userID, answers) { export async function addResponse(requestID, userID, answers) {
const data = queries.get(requestID); const data = queries.get(requestID);
Oliver marked this conversation as resolved Outdated

Add check to ensure that the query isn't undefined

Add check to ensure that the query isn't undefined
// User closed the popup manually
if (answers == null) {
data.status[userID] = `unprompted`;
}
// User submitted the answers as expected
else {
data.responses[userID] = answers; data.responses[userID] = answers;
data.status[userID] = `finished`; data.status[userID] = `finished`;
await data.onSubmit?.(requestID, userID, answers);
};
await data.onSubmit?.(userID, answers);
await maybeResolve(requestID); await maybeResolve(requestID);
}; };
@ -180,10 +200,14 @@ async function maybeResolve(requestID) {
}; };
}; };
export async function notify(userID, content, { includeGM = false } = {}) { export async function notify(requestID, userID, content, { includeGM = false } = {}) {
// Prevent sending notifications for not-your queries
if (!queries.has(requestID)) { return };
game.socket.emit(`system.taf`, { game.socket.emit(`system.taf`, {
event: `query.notify`, event: `query.notify`,
payload: { payload: {
id: requestID,
userID, userID,
content, content,
includeGM, includeGM,
@ -196,6 +220,7 @@ export async function finish(requestID) {
if (!queries.has(requestID)) { return }; if (!queries.has(requestID)) { return };
const query = queries.get(requestID); const query = queries.get(requestID);
query.app?.close();
query.resolve(query.responses); query.resolve(query.responses);
queries.delete(requestID); queries.delete(requestID);
promises.delete(requestID); promises.delete(requestID);
@ -211,6 +236,7 @@ export async function cancel(requestID) {
if (!queries.has(requestID)) { return }; if (!queries.has(requestID)) { return };
const query = queries.get(requestID); const query = queries.get(requestID);
query.app?.close();
query.resolve(null); query.resolve(null);
queries.delete(requestID); queries.delete(requestID);
promises.delete(requestID); promises.delete(requestID);