183 lines
6.1 KiB
JavaScript
183 lines
6.1 KiB
JavaScript
const { ApplicationV2, HandlebarsApplicationMixin } = foundry.applications.api;
|
|
|
|
export class CountdownTrackerApp extends HandlebarsApplicationMixin(ApplicationV2) {
|
|
static instance;
|
|
|
|
constructor(options = {}) {
|
|
super(options);
|
|
this._dragData = {
|
|
isDragging: false,
|
|
startX: 0,
|
|
startY: 0,
|
|
startLeft: 0,
|
|
startTop: 0
|
|
};
|
|
}
|
|
|
|
static DEFAULT_OPTIONS = {
|
|
id: "dh-improved-countdowns-app",
|
|
tag: "div",
|
|
classes: ["dh-improved-countdowns"],
|
|
window: {
|
|
frame: false,
|
|
positioned: true,
|
|
},
|
|
position: {
|
|
width: "auto",
|
|
height: "auto",
|
|
},
|
|
actions: {
|
|
increaseCountdown: CountdownTrackerApp.#onIncrease,
|
|
decreaseCountdown: CountdownTrackerApp.#onDecrease,
|
|
addCountdown: CountdownTrackerApp.#onAdd,
|
|
toggleViewMode: CountdownTrackerApp.#onToggleView,
|
|
toggleLock: CountdownTrackerApp.#onToggleLock
|
|
}
|
|
};
|
|
|
|
static PARTS = {
|
|
content: {
|
|
template: "modules/dh-improved-countdowns/templates/countdown-tracker.hbs",
|
|
},
|
|
};
|
|
|
|
static initialize() {
|
|
this.instance = new CountdownTrackerApp();
|
|
const pos = game.settings.get("dh-improved-countdowns", "position");
|
|
this.instance.render(true, { position: pos });
|
|
}
|
|
|
|
async _prepareContext(options) {
|
|
const isGM = game.user.isGM;
|
|
const isMinimized = game.settings.get("dh-improved-countdowns", "minimized");
|
|
const isLocked = game.settings.get("dh-improved-countdowns", "locked");
|
|
|
|
// Fetch countdowns from system settings
|
|
const systemCountdownSetting = game.settings.get("daggerheart", "Countdowns");
|
|
const countdowns = {};
|
|
|
|
if (systemCountdownSetting && systemCountdownSetting.countdowns) {
|
|
for (const [id, countdown] of Object.entries(systemCountdownSetting.countdowns)) {
|
|
const ownership = this.#getPlayerOwnership(game.user, systemCountdownSetting, countdown);
|
|
if (ownership !== CONST.DOCUMENT_OWNERSHIP_LEVELS.NONE) {
|
|
countdowns[id] = {
|
|
...countdown,
|
|
editable: isGM || ownership === CONST.DOCUMENT_OWNERSHIP_LEVELS.OWNER
|
|
};
|
|
}
|
|
}
|
|
}
|
|
|
|
return {
|
|
countdowns,
|
|
isGM,
|
|
isMinimized,
|
|
isLocked
|
|
};
|
|
}
|
|
|
|
#getPlayerOwnership(user, setting, countdown) {
|
|
const playerOwnership = countdown.ownership[user.id];
|
|
return playerOwnership === undefined || playerOwnership === CONST.DOCUMENT_OWNERSHIP_LEVELS.INHERIT
|
|
? setting.defaultOwnership
|
|
: playerOwnership;
|
|
}
|
|
|
|
static async #onIncrease(event, target) {
|
|
const id = target.dataset.id;
|
|
Hooks.call("editCountdown", true, { id });
|
|
// The Daggerheart system has a static method for this, let's try to use it if available
|
|
if (typeof game.system.api.applications.ui.DhCountdowns?.editCountdown === "function") {
|
|
await game.system.api.applications.ui.DhCountdowns.editCountdown(true, { id });
|
|
}
|
|
}
|
|
|
|
static async #onDecrease(event, target) {
|
|
const id = target.dataset.id;
|
|
if (typeof game.system.api.applications.ui.DhCountdowns?.editCountdown === "function") {
|
|
await game.system.api.applications.ui.DhCountdowns.editCountdown(false, { id });
|
|
}
|
|
}
|
|
|
|
static async #onAdd(event, target) {
|
|
if (!game.user.isGM) return;
|
|
if (game.system.api.applications.ui.CountdownEdit) {
|
|
new game.system.api.applications.ui.CountdownEdit().render(true);
|
|
}
|
|
}
|
|
|
|
static async #onToggleView(event, target) {
|
|
const current = game.settings.get("dh-improved-countdowns", "minimized");
|
|
await game.settings.set("dh-improved-countdowns", "minimized", !current);
|
|
this.instance.render();
|
|
}
|
|
|
|
static async #onToggleLock(event, target) {
|
|
const current = game.settings.get("dh-improved-countdowns", "locked");
|
|
await game.settings.set("dh-improved-countdowns", "locked", !current);
|
|
this.instance.render();
|
|
}
|
|
|
|
_onRender(context, options) {
|
|
this.#setupDragging();
|
|
}
|
|
|
|
#setupDragging() {
|
|
if (game.settings.get("dh-improved-countdowns", "locked")) return;
|
|
|
|
const dragHandle = this.element.querySelector('.drag-handle');
|
|
if (!dragHandle) return;
|
|
|
|
dragHandle.addEventListener('mousedown', this.#onDragStart.bind(this));
|
|
}
|
|
|
|
#onDragStart(e) {
|
|
if (e.button !== 0) return;
|
|
|
|
this._dragData.isDragging = true;
|
|
this._dragData.startX = e.clientX;
|
|
this._dragData.startY = e.clientY;
|
|
|
|
const rect = this.element.getBoundingClientRect();
|
|
this._dragData.startLeft = rect.left;
|
|
this._dragData.startTop = rect.top;
|
|
|
|
this.element.style.cursor = 'grabbing';
|
|
|
|
window.addEventListener('mousemove', this.#onDragging.bind(this));
|
|
window.addEventListener('mouseup', this.#onDragEnd.bind(this));
|
|
}
|
|
|
|
#onDragging(e) {
|
|
if (!this._dragData.isDragging) return;
|
|
|
|
const dx = e.clientX - this._dragData.startX;
|
|
const dy = e.clientY - this._dragData.startY;
|
|
|
|
const newLeft = this._dragData.startLeft + dx;
|
|
const newTop = this._dragData.startTop + dy;
|
|
|
|
this.element.style.left = `${newLeft}px`;
|
|
this.element.style.top = `${newTop}px`;
|
|
}
|
|
|
|
#onDragEnd() {
|
|
if (!this._dragData.isDragging) return;
|
|
this._dragData.isDragging = false;
|
|
this.element.style.cursor = '';
|
|
|
|
window.removeEventListener('mousemove', this.#onDragging.bind(this));
|
|
window.removeEventListener('mouseup', this.#onDragEnd.bind(this));
|
|
|
|
const rect = this.element.getBoundingClientRect();
|
|
const pos = {
|
|
top: rect.top,
|
|
left: rect.left
|
|
};
|
|
|
|
this.position.top = pos.top;
|
|
this.position.left = pos.left;
|
|
|
|
game.settings.set("dh-improved-countdowns", "position", pos);
|
|
}
|
|
}
|