ChatMessage.create est async, il faut donc de préférence l'appeler avec un await. Des effets secondaires avaient lieu (ordre de messages, updates ultérieurs parfois pas pris en compte)
246 lines
7.9 KiB
JavaScript
246 lines
7.9 KiB
JavaScript
import { Misc } from "./misc.js";
|
|
import { renderTemplate, SYSTEM_RDD, SYSTEM_SOCKET_ID } from "./constants.js";
|
|
import { RdDTimestamp } from "./time/rdd-timestamp.js";
|
|
import { RdDTextEditor } from "./apps/rdd-text-roll-editor.js";
|
|
|
|
|
|
/**
|
|
* Class providing helper methods around the Chat message
|
|
*/
|
|
export class ChatUtility {
|
|
|
|
static async init() {
|
|
Hooks.on("renderChatMessageHTML", async (app, html, msg) => await ChatUtility.onRenderChatMessage(app, html, msg))
|
|
Hooks.on("createChatMessage", async (chatMessage, options, id) => await ChatUtility.onCreateChatMessage(chatMessage, options, id))
|
|
}
|
|
|
|
/* -------------------------------------------- */
|
|
static onSocketMessage(sockmsg) {
|
|
switch (sockmsg.msg) {
|
|
case "msg_gm_chat_message": return ChatUtility.handleGMChatMessage(sockmsg.data)
|
|
case "msg_delete_chat_message": return ChatUtility.onRemoveMessages(sockmsg.data)
|
|
case "msg_user_ui_notifications": return ChatUtility.onNotifyUser(sockmsg.data)
|
|
}
|
|
}
|
|
|
|
/* -------------------------------------------- */
|
|
static notifyUser(userId, level = 'info', message) {
|
|
const socketData = {
|
|
userId: userId, level: level, message: message
|
|
};
|
|
if (game.user.id == userId) {
|
|
ChatUtility.onNotifyUser(socketData);
|
|
}
|
|
else {
|
|
game.socket.emit(SYSTEM_SOCKET_ID, {
|
|
msg: "msg_user_ui_notifications", data: socketData
|
|
});
|
|
}
|
|
}
|
|
|
|
static onNotifyUser(socketData) {
|
|
if (game.user.id == socketData.userId) {
|
|
switch (socketData.level) {
|
|
case 'warn': ui.notifications.warn(socketData.message); break;
|
|
case 'error': ui.notifications.error(socketData.message); break;
|
|
default: ui.notifications.info(socketData.message); break;
|
|
}
|
|
}
|
|
}
|
|
|
|
/* -------------------------------------------- */
|
|
static onRemoveMessages(socketData) {
|
|
if (Misc.isFirstConnectedGM()) {
|
|
if (socketData.part) {
|
|
const toDelete = game.messages.filter(it => it.content.includes(socketData.part));
|
|
toDelete.forEach(it => it.delete());
|
|
}
|
|
if (socketData.messageId) {
|
|
game.messages.get(socketData.messageId)?.delete();
|
|
}
|
|
}
|
|
}
|
|
|
|
/* -------------------------------------------- */
|
|
static removeMessages(socketData) {
|
|
if (Misc.isFirstConnectedGM()) {
|
|
ChatUtility.onRemoveMessages(socketData);
|
|
}
|
|
else {
|
|
game.socket.emit(SYSTEM_SOCKET_ID, { msg: "msg_delete_chat_message", data: socketData });
|
|
}
|
|
}
|
|
|
|
/* -------------------------------------------- */
|
|
static removeChatMessageContaining(part) {
|
|
ChatUtility.removeMessages({ part: part });
|
|
}
|
|
|
|
static remover(chatMessage) {
|
|
const messageId = chatMessage.id;
|
|
if (messageId) {
|
|
return (..._) => ChatUtility.removeMessages({ messageId: messageId });
|
|
|
|
}
|
|
return (..._) => { }
|
|
}
|
|
|
|
static removeChatMessageId(messageId) {
|
|
if (messageId) {
|
|
ChatUtility.removeMessages({ messageId: messageId });
|
|
}
|
|
}
|
|
|
|
/* -------------------------------------------- */
|
|
static adaptVisibility( messageData, options = { actor: undefined, rollMode: undefined }) {
|
|
foundry.utils.mergeObject(options, { rollMode: game.settings.get("core", "rollMode") }, { overwrite: false });
|
|
switch (options.rollMode) {
|
|
case "blindroll": // GM only
|
|
if (!game.user.isGM) {
|
|
ChatUtility.blindMessageToGM(messageData)
|
|
messageData.whisper = [game.user]
|
|
messageData.content = "Message envoyé en aveugle au Gardien";
|
|
}
|
|
else {
|
|
messageData.whisper = ChatUtility.getGMs()
|
|
}
|
|
break;
|
|
case "gmroll":
|
|
messageData.whisper = options.actor ? ChatUtility.getOwners(options.actor) : ChatUtility.getUserAndGMs()
|
|
break;
|
|
case "selfroll":
|
|
messageData.whisper = [game.user]
|
|
break
|
|
}
|
|
messageData.alias = messageData.alias ?? options.actor?.name ?? game.user.name
|
|
return messageData
|
|
}
|
|
|
|
static async tellToUser(message) {
|
|
await ChatMessage.create({ content: message, user: game.user.id, whisper: [game.user.id] });
|
|
}
|
|
|
|
static async tellToGM(message) {
|
|
await ChatMessage.create({
|
|
user: game.user.id,
|
|
content: message,
|
|
whisper: ChatUtility.getGMs()
|
|
})
|
|
}
|
|
|
|
static async tellToUserAndGM(message) {
|
|
await ChatMessage.create({
|
|
user: game.user.id,
|
|
content: message,
|
|
whisper: ChatUtility.getUserAndGMs()
|
|
})
|
|
}
|
|
|
|
static getOwners(document) {
|
|
return document ? game.users.filter(it => document.getUserLevel(it) == CONST.DOCUMENT_OWNERSHIP_LEVELS.OWNER) : [game.user]
|
|
}
|
|
|
|
static getUserAndGMs() {
|
|
return [game.user, ...ChatUtility.getGMs()]
|
|
}
|
|
|
|
/* -------------------------------------------- */
|
|
static getMultipleActorsOwners(...actors) {
|
|
return Misc.concat(actors.map(it => it == undefined ? [] : ChatUtility.getOwners(it)))
|
|
}
|
|
|
|
/* -------------------------------------------- */
|
|
static getUsers(filter) {
|
|
return game.users.filter(filter)
|
|
}
|
|
|
|
static getGMs() {
|
|
return game.users.filter(user => user.isGM)
|
|
}
|
|
|
|
static applyRollMode(chatMessageData = {}, rollMode = game.settings.get("core", "rollMode")) {
|
|
switch (rollMode) {
|
|
case "blindroll":
|
|
chatMessageData.blind = true
|
|
chatMessageData.whisper = ChatUtility.getGMs()
|
|
break
|
|
case "gmroll":
|
|
chatMessageData.whisper = ChatUtility.getGMs()
|
|
chatMessageData.blind = false
|
|
break
|
|
case "roll":
|
|
chatMessageData.whisper = ChatUtility.getUsers(user => user.active)
|
|
chatMessageData.blind = false
|
|
break
|
|
case "selfroll":
|
|
chatMessageData.whisper = [game.user]
|
|
chatMessageData.blind = false
|
|
break
|
|
}
|
|
return chatMessageData
|
|
}
|
|
|
|
/* -------------------------------------------- */
|
|
static blindMessageToGM(chatOptions) {
|
|
const chatGM = foundry.utils.duplicate(chatOptions)
|
|
chatGM.content = "Message aveugle de " + game.user.name + "<br>" + chatOptions.content
|
|
console.log("blindMessageToGM", chatGM)
|
|
game.socket.emit(SYSTEM_SOCKET_ID, { msg: "msg_gm_chat_message", data: chatGM })
|
|
}
|
|
|
|
/* -------------------------------------------- */
|
|
static handleGMChatMessage(socketData) {
|
|
console.log("blindMessageToGM", socketData);
|
|
if (Misc.isFirstConnectedGM()) {
|
|
ChatMessage.create({
|
|
user: game.user.id,
|
|
whisper: ChatUtility.getGMs(),
|
|
content: socketData.content
|
|
})
|
|
}
|
|
}
|
|
|
|
static async setMessageData(chatMessage, key, flag) {
|
|
if (flag && chatMessage.isAuthor) {
|
|
await chatMessage.setFlag(SYSTEM_RDD, key, flag)
|
|
}
|
|
}
|
|
|
|
static getMessageData(chatMessage, key) {
|
|
return chatMessage.getFlag(SYSTEM_RDD, key);
|
|
}
|
|
|
|
static getChatMessage(event) {
|
|
const chatMessageId = $(event.currentTarget).closest('.chat-message').attr('data-message-id');
|
|
return game.messages.get(chatMessageId);
|
|
}
|
|
|
|
static async onRenderChatMessage(chatMessage, html, data) {
|
|
const rddTimestamp = chatMessage.getFlag(SYSTEM_RDD, 'rdd-timestamp')
|
|
const heureRdD = $(html).find('header.message-header .heure-rdd')
|
|
if (rddTimestamp && heureRdD.length == 0) {
|
|
const messageTimestamp = $(html).find('header.message-header .message-timestamp');
|
|
const timestamp = new RdDTimestamp(rddTimestamp);
|
|
const timestampData = timestamp.toCalendrier();
|
|
const dateHeure = await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/common/date-heure.hbs', timestampData);
|
|
messageTimestamp.after(dateHeure)
|
|
}
|
|
}
|
|
|
|
static async onCreateChatMessage(chatMessage, options, id) {
|
|
if (chatMessage.isAuthor) {
|
|
await ChatUtility.setTimestamp(chatMessage)
|
|
await chatMessage.update({ content: await RdDTextEditor.enrichHTML(chatMessage.content, undefined, { showLink: false }) })
|
|
}
|
|
}
|
|
|
|
static async setTimestamp(chatMessage) {
|
|
await chatMessage.setFlag(SYSTEM_RDD, 'rdd-timestamp', game.system.rdd.calendrier.getTimestamp());
|
|
}
|
|
|
|
static getISODate(chatMessage) {
|
|
const date = new Date(chatMessage.timestamp);
|
|
return date?.toISOString().substring(0, 10)
|
|
}
|
|
}
|