import { CalendarApp } from './CalendarApp.js'; import { CalendarConfigDialog } from './CalendarConfigDialog.js'; import { JournalNoteDialog } from './JournalNoteDialog.js'; import { getDefaultCalendar, formatImperialDate, formatRealDate } from './calendarDate.js'; const MODULE_ID = 'mgt2-compendium-amiral-denisov'; const ChatLogV2 = foundry.applications.sidebar.tabs.ChatLog; let _calendarApp = null; function readCalendar() { return { year: game.settings.get(MODULE_ID, 'calendarYear'), day: game.settings.get(MODULE_ID, 'calendarDay'), hour: game.settings.get(MODULE_ID, 'calendarHour'), minute: game.settings.get(MODULE_ID, 'calendarMinute'), planet: game.settings.get(MODULE_ID, 'calendarPlanet'), }; } async function writeCalendar(data) { await game.settings.set(MODULE_ID, 'calendarYear', data.year); await game.settings.set(MODULE_ID, 'calendarDay', data.day); await game.settings.set(MODULE_ID, 'calendarHour', data.hour); await game.settings.set(MODULE_ID, 'calendarMinute', data.minute); await game.settings.set(MODULE_ID, 'calendarPlanet', data.planet); } function applyCalendar(data) { if (_calendarApp) { _calendarApp.updateDisplay(data); } } async function broadcastCalendar(data) { if (!game.socket?.emit) return; game.socket.emit(`module.${MODULE_ID}`, { _type: 'calendarSync', ...data, }); } function openCalendarApp() { if (_calendarApp) { _calendarApp.bringToTop(); return; } const data = readCalendar(); _calendarApp = new CalendarApp({ onConfig: () => openCalendarConfig(), onNote: () => openJournalNote(), onClose: () => { _calendarApp = null; }, }); _calendarApp.updateDisplay(data); _calendarApp.render({ force: true }); } function openCalendarConfig() { const data = readCalendar(); const dialog = new CalendarConfigDialog({ data, onApply: async (newData) => { await writeCalendar(newData); applyCalendar(newData); broadcastCalendar(newData); dialog.close(); }, }); dialog.render({ force: true }); } async function appendJournalNote(content, { dateLabel, realLabel } = {}) { if (!content) return false; const journalName = game.settings.get(MODULE_ID, 'calendarJournalName') || 'Journal de bord'; let journal = game.journal.getName(journalName); if (!journal) { journal = await JournalEntry.create({ name: journalName }); if (!journal) { ui.notifications.error('Impossible de créer le journal'); return false; } } if (!dateLabel || !realLabel) { const c = readCalendar(); dateLabel = formatImperialDate(c); realLabel = formatRealDate(); } const safeContent = $('
').text(content).html().replace(/\n/g, '
'); const noteHtml = `

${realLabel} — ${dateLabel}

${safeContent}

`; let page = journal.pages.contents[0]; if (!page) { [page] = await journal.createEmbeddedDocuments('JournalEntryPage', [{ name: 'Notes', text: { content: '' } }]); } if (!page) { ui.notifications.error('Impossible de créer une page dans le journal'); return false; } const existing = page.text?.content || ''; await page.update({ 'text.content': existing + '\n' + noteHtml }); ui.notifications.info(`Note ajoutée au journal « ${journalName} »`); return true; } function openJournalNote() { const calendar = readCalendar(); const dateLabel = formatImperialDate(calendar); const realLabel = formatRealDate(); const dialog = new JournalNoteDialog({ imperialDate: dateLabel, realDate: realLabel, onSave: async (content) => { const ok = await appendJournalNote(content, { dateLabel, realLabel }); if (ok) dialog.close(); }, }); dialog.render({ force: true }); } function registerCalCommand() { if (!ChatLogV2?.CHAT_COMMANDS) return; ChatLogV2.CHAT_COMMANDS.cal = { rgx: /^\/cal(?:\s+(.*))?$/i, fn: () => { openCalendarApp(); return false; }, }; console.log(`${MODULE_ID} | Commande /cal enregistrée via ChatLog.CHAT_COMMANDS`); } Hooks.once('init', () => { const def = getDefaultCalendar(); game.settings.register(MODULE_ID, 'calendarYear', { name: 'Année impériale', scope: 'world', config: false, type: Number, default: def.year, }); game.settings.register(MODULE_ID, 'calendarDay', { name: 'Jour impérial (1-365)', scope: 'world', config: false, type: Number, default: def.day, }); game.settings.register(MODULE_ID, 'calendarHour', { name: 'Heure locale', scope: 'world', config: false, type: Number, default: def.hour, }); game.settings.register(MODULE_ID, 'calendarMinute', { name: 'Minute locale', scope: 'world', config: false, type: Number, default: def.minute, }); game.settings.register(MODULE_ID, 'calendarPlanet', { name: 'Planète', scope: 'world', config: false, type: String, default: def.planet, }); game.settings.register(MODULE_ID, 'calendarAutoOpen', { name: 'Calendrier impérial : auto-ouverture', hint: 'Ouvre automatiquement la fenêtre du calendrier au démarrage', scope: 'world', config: true, type: Boolean, default: true, }); game.settings.register(MODULE_ID, 'calendarJournalName', { name: 'Journal de bord', hint: 'Nom du journal utilisé pour les notes de session. Créé automatiquement s\'il n\'existe pas.', scope: 'world', config: true, type: String, default: 'Journal de bord', }); game.settings.register(MODULE_ID, 'calendarPosition', { scope: 'client', config: false, type: Object, default: {}, }); const loadTemplatesFn = foundry.applications?.handlebars?.loadTemplates || loadTemplates; if (loadTemplatesFn) { loadTemplatesFn([ `modules/${MODULE_ID}/templates/calendar-app.hbs`, `modules/${MODULE_ID}/templates/calendar-config.hbs`, `modules/${MODULE_ID}/templates/journal-note-dialog.hbs`, ]); } registerCalCommand(); console.log(`${MODULE_ID} | Calendrier impérial initialisé`); }); Hooks.once('ready', () => { game.socket.on(`module.${MODULE_ID}`, (data) => { if (game.user?.isGM) return; if (data?._type !== 'calendarSync') return; if (!_calendarApp) { const { year, day, hour, minute, planet } = data; _calendarApp = new CalendarApp({ onClose: () => { _calendarApp = null; }, }); _calendarApp.updateDisplay({ year, day, hour, minute, planet }); _calendarApp.render({ force: true }); return; } _calendarApp.updateDisplay(data); }); if (game.settings.get(MODULE_ID, 'calendarAutoOpen')) { openCalendarApp(); } }); Hooks.on('preCreateChatMessage', (message, data, options) => { const content = message.content?.trim()?.toLowerCase(); if (content === '/cal' || content?.startsWith('/cal ')) { openCalendarApp(); return false; } }); Hooks.on('chatMessage', (...args) => { let message; if (args[0]?.content !== undefined) { message = args[0].content; } else if (typeof args[1] === 'string') { message = args[1]; } else { return; } const trimmed = message?.trim()?.toLowerCase(); if (trimmed === '/cal' || trimmed?.startsWith('/cal ')) { openCalendarApp(); return false; } }); Hooks.on('renderChatInput', (app, html, data) => { let input; if (html?.element) { input = $(html.element).find('textarea[name="content"]'); } else if (html?.find) { input = html.find('textarea[name="content"]'); } else { input = $(html).find('textarea[name="content"]'); } if (input.data('mgt2-cal-listener')) return; input.data('mgt2-cal-listener', true); input.on('keydown', (event) => { if (event.key === 'Enter' && !event.shiftKey) { const content = input.val()?.trim(); if (content === '/cal' || content?.startsWith('/cal ')) { event.preventDefault(); event.stopImmediatePropagation(); openCalendarApp(); input.val(''); } } }); });