feat: calendrier impérial et conversions calendaires
- calendrier impérial : fenêtre compacte (260px), affichage date - commande /cal, auto-ouverture paramétrable dans les settings - socket calendarSync : mise à jour temps réel pour les joueurs - config MJ : année, jour (label live), heure:minute, planète - boutons +1 jour et +1 heure (report 24h→jour, 365→1) - conversions : Solomani, Vilani, Zhodani (Olympiade), Aslan, K'Kree, Hiver - formules wiki.travellerrpg.com/Date_Conversion, section repliable - fix: renderChatInput /cal trop large → exact match - fix: fenêtre refermable (onClose nullifie la référence) - fix: socket joueur lit data direct au lieu de readCalendar()
This commit is contained in:
@@ -0,0 +1,116 @@
|
||||
import { getDayLabel, computeConversions } from './calendarDate.js';
|
||||
|
||||
const { ApplicationV2, HandlebarsApplicationMixin } = foundry.applications.api;
|
||||
const MODULE_ID = 'mgt2-compendium-amiral-denisov';
|
||||
|
||||
export class CalendarConfigDialog extends HandlebarsApplicationMixin(ApplicationV2) {
|
||||
static DEFAULT_OPTIONS = {
|
||||
id: 'mgt2-calendar-config',
|
||||
classes: ['mgt2-calendar'],
|
||||
position: { width: 300, height: 'auto' },
|
||||
window: {
|
||||
icon: 'fas fa-cog',
|
||||
title: 'Configurer le calendrier',
|
||||
resizable: false,
|
||||
},
|
||||
};
|
||||
|
||||
static PARTS = {
|
||||
main: {
|
||||
template: `modules/${MODULE_ID}/templates/calendar-config.hbs`,
|
||||
root: true,
|
||||
},
|
||||
};
|
||||
|
||||
constructor({ data, onApply } = {}) {
|
||||
super();
|
||||
this._data = { ...data };
|
||||
this._onApply = onApply;
|
||||
}
|
||||
|
||||
get title() {
|
||||
return 'Configurer le calendrier';
|
||||
}
|
||||
|
||||
async _prepareContext() {
|
||||
return {
|
||||
year: this._data.year,
|
||||
day: this._data.day,
|
||||
hour: this._data.hour,
|
||||
minute: this._data.minute,
|
||||
planet: this._data.planet ?? '',
|
||||
dayLabel: getDayLabel(this._data.day),
|
||||
conversions: computeConversions(this._data.year),
|
||||
};
|
||||
}
|
||||
|
||||
async _onRender(context, options) {
|
||||
await super._onRender(context, options);
|
||||
const html = $(this.element);
|
||||
|
||||
html.find('[name="day"]').on('input', () => {
|
||||
const day = parseInt(html.find('[name="day"]').val(), 10);
|
||||
if (day >= 1 && day <= 365) {
|
||||
html.find('.mgt2-cal-day-label').text(getDayLabel(day));
|
||||
}
|
||||
});
|
||||
|
||||
html.find('[name="year"]').on('input', () => {
|
||||
const year = parseInt(html.find('[name="year"]').val(), 10) || 0;
|
||||
const conv = computeConversions(year);
|
||||
html.find('.mgt2-cal-conv-val[data-cal="solomani"]').text(conv.solomani);
|
||||
html.find('.mgt2-cal-conv-val[data-cal="vilani"]').text(conv.vilani);
|
||||
html.find('.mgt2-cal-conv-val[data-cal="zhodani"]').text(conv.zhodani);
|
||||
html.find('.mgt2-cal-conv-val[data-cal="aslan"]').text(conv.aslan);
|
||||
html.find('.mgt2-cal-conv-val[data-cal="kkree"]').text(conv.kkree);
|
||||
html.find('.mgt2-cal-conv-val[data-cal="hiver"]').text(conv.hiver);
|
||||
});
|
||||
|
||||
html.find('[data-action="day-inc"]').on('click', () => {
|
||||
const input = html.find('[name="day"]');
|
||||
let day = parseInt(input.val(), 10) || 1;
|
||||
day = day >= 365 ? 1 : day + 1;
|
||||
input.val(day);
|
||||
html.find('.mgt2-cal-day-label').text(getDayLabel(day));
|
||||
});
|
||||
|
||||
html.find('[data-action="hour-inc"]').on('click', () => {
|
||||
const dayInput = html.find('[name="day"]');
|
||||
const hourInput = html.find('[name="hour"]');
|
||||
const minuteInput = html.find('[name="minute"]');
|
||||
let day = parseInt(dayInput.val(), 10) || 1;
|
||||
let hour = parseInt(hourInput.val(), 10) || 0;
|
||||
let minute = parseInt(minuteInput.val(), 10) || 0;
|
||||
|
||||
hour += 1;
|
||||
if (hour >= 24) {
|
||||
hour = 0;
|
||||
day = day >= 365 ? 1 : day + 1;
|
||||
}
|
||||
|
||||
hourInput.val(hour);
|
||||
dayInput.val(day);
|
||||
html.find('.mgt2-cal-day-label').text(getDayLabel(day));
|
||||
});
|
||||
|
||||
html.find('[data-action="apply"]').on('click', () => {
|
||||
this._readAndApply(html);
|
||||
});
|
||||
}
|
||||
|
||||
_readAndApply(html) {
|
||||
const year = parseInt(html.find('[name="year"]').val(), 10) || 1116;
|
||||
const day = Math.min(365, Math.max(1, parseInt(html.find('[name="day"]').val(), 10) || 1));
|
||||
const hour = Math.min(23, Math.max(0, parseInt(html.find('[name="hour"]').val(), 10) || 0));
|
||||
const minute = Math.min(59, Math.max(0, parseInt(html.find('[name="minute"]').val(), 10) || 0));
|
||||
const planet = html.find('[name="planet"]').val()?.trim() ?? '';
|
||||
|
||||
const data = { year, day, hour, minute, planet };
|
||||
this._onApply?.(data);
|
||||
}
|
||||
|
||||
close() {
|
||||
this._onApply = null;
|
||||
return super.close();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user