/** * MGT2 Commerce – Point d'entrée du module * * Chargé par FoundryVTT via "esmodules" dans module.json. * Enregistre la commande /commerce dans le chat. * Compatible Foundry VTT v13 et v14 */ import { CommerceDialog } from './CommerceDialog.js'; import './mgt2eMigration.js'; import './startupNotice.js'; const MODULE_ID = 'mgt2-compendium-amiral-denisov'; const COMMERCE_COMMAND = 'commerce'; const ChatLogV2 = foundry.applications.sidebar.tabs.ChatLog; function openCommerceDialog() { new CommerceDialog().render({ force: true }); } function registerCommerceCommand() { if (!ChatLogV2?.CHAT_COMMANDS) { console.warn(`${MODULE_ID} | ChatLog.CHAT_COMMANDS indisponible, commande /${COMMERCE_COMMAND} non enregistrée`); return; } ChatLogV2.CHAT_COMMANDS[COMMERCE_COMMAND] = { rgx: /^\/commerce(?:\s+(.*))?$/i, fn: () => { openCommerceDialog(); return false; }, }; console.log(`${MODULE_ID} | Commande /${COMMERCE_COMMAND} enregistrée via ChatLog.CHAT_COMMANDS`); } Hooks.once('init', () => { console.log(`${MODULE_ID} | Commerce module initialisé`); // Pré-charge les templates Handlebars // Compatibilité v13 et v14 const loadTemplatesFn = foundry.applications?.handlebars?.loadTemplates || loadTemplates; if (loadTemplatesFn) { loadTemplatesFn([ `modules/${MODULE_ID}/templates/commerce-dialog.hbs`, `modules/${MODULE_ID}/templates/commerce-result.hbs`, ]); } registerCommerceCommand(); }); Hooks.once('ready', () => { console.log(`${MODULE_ID} | Commerce module prêt – tapez /commerce dans le chat`); }); /** * Solution pour Foundry v14 : Intercepte les commandes AVANT la validation * Utilise renderChatInput pour modifier le comportement de l'input * Compatible v13 (jQuery) et v14 (DOM element) */ Hooks.on('renderChatInput', (app, html, data) => { // Foundry v14 passe un objet avec element, v13 passe jQuery let input; // Vérifie si html est un objet avec element (v14) if (html?.element) { input = $(html.element).find('textarea[name="content"]'); } else if (html?.find) { // v13 ou déjà jQuery input = html.find('textarea[name="content"]'); } else { // Dernier recours : suppose que html est l'élément input = $(html).find('textarea[name="content"]'); } // Évite les doublons d'écouteurs if (input.data('mgt2-commerce-listener')) return; input.data('mgt2-commerce-listener', true); input.on('keydown', (event) => { // Intercepte Entrée (13) et vérifie si c'est une de nos commandes if (event.key === 'Enter' && !event.shiftKey) { const content = input.val()?.trim(); if (content?.startsWith('/commerce')) { event.preventDefault(); event.stopImmediatePropagation(); openCommerceDialog(); input.val(''); } } }); }); /** * Intercepte les messages de chat commençant par /commerce. * Utilise preCreateChatMessage pour Foundry v14+ (avant que le message ne soit validé) * Compatible avec Foundry v13 et v14 * Retourne false pour empêcher l'envoi du message brut. */ Hooks.on('preCreateChatMessage', (message, data, options) => { const content = message.content?.trim()?.toLowerCase(); if (content === '/commerce' || content?.startsWith('/commerce ')) { openCommerceDialog(); return false; // Empêche la création du message } }); // Gardé pour compatibilité v13 Hooks.on('chatMessage', (...args) => { // Foundry v14 passe un objet ChatMessage en premier paramètre // Foundry v13 passe (chatLog, message, chatData) let message; if (args[0]?.content !== undefined) { // v14: premier argument est ChatMessage message = args[0].content; } else if (typeof args[1] === 'string') { // v13: deuxième argument est la string message message = args[1]; } else { return; } const trimmed = message?.trim()?.toLowerCase(); if (trimmed === '/commerce' || trimmed?.startsWith('/commerce ')) { openCommerceDialog(); return false; } });