This commit is contained in:
WBHarry 2025-07-01 17:58:29 +02:00
parent a1f7e0d2c5
commit 3462b3bd77
8 changed files with 159 additions and 131 deletions

View file

@ -1,5 +1,6 @@
import { countdownTypes } from '../config/generalConfig.mjs';
import { GMUpdateEvent, RefreshType, socketEvent } from '../helpers/socket.mjs';
import constructHTMLButton from '../helpers/utils.mjs';
import OwnershipSelection from './ownershipSelection.mjs';
const { HandlebarsApplicationMixin, ApplicationV2 } = foundry.applications.api;
@ -25,14 +26,15 @@ class Countdowns extends HandlebarsApplicationMixin(ApplicationV2) {
frame: true,
title: 'Countdowns',
resizable: true,
minimizable: true
minimizable: false
},
actions: {
addCountdown: this.addCountdown,
removeCountdown: this.removeCountdown,
editImage: this.onEditImage,
openOwnership: this.openOwnership,
openCountdownOwnership: this.openCountdownOwnership
openCountdownOwnership: this.openCountdownOwnership,
toggleSimpleView: this.toggleSimpleView
},
form: { handler: this.updateData, submitOnChange: true }
};
@ -53,11 +55,44 @@ class Countdowns extends HandlebarsApplicationMixin(ApplicationV2) {
});
}
async _onFirstRender(context, options) {
super._onFirstRender(context, options);
async _preFirstRender(context, options) {
options.position =
game.user.getFlag(SYSTEM.id, SYSTEM.FLAGS.countdown.position) ?? Countdowns.DEFAULT_OPTIONS.position;
this.element.querySelector('.expanded-view').classList.toggle('hidden');
this.element.querySelector('.minimized-view').classList.toggle('hidden');
const viewSetting = game.user.getFlag(SYSTEM.id, SYSTEM.FLAGS.countdown.simple) ?? !game.user.isGM;
this.simpleView =
game.user.isGM || !this.testUserPermission(CONST.DOCUMENT_OWNERSHIP_LEVELS.OBSERVER) ? viewSetting : true;
}
_onPosition(position) {
game.user.setFlag(SYSTEM.id, SYSTEM.FLAGS.countdown.position, position);
}
async _renderFrame(options) {
const frame = await super._renderFrame(options);
if (this.testUserPermission(CONST.DOCUMENT_OWNERSHIP_LEVELS.OBSERVER)) {
const button = constructHTMLButton({
label: '',
classes: ['header-control', 'icon', 'fa-solid', 'fa-wrench'],
dataset: { action: 'toggleSimpleView', tooltip: 'DAGGERHEART.Countdown.ToggleSimple' }
});
this.window.controls.after(button);
}
return frame;
}
testUserPermission(level, exact, altSettings) {
if (game.user.isGM) return true;
const settings =
altSettings ?? game.settings.get(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.Countdowns)[this.basePath];
const defaultAllowed = exact ? settings.ownership.default === level : settings.ownership.default >= level;
const userAllowed = exact
? settings.playerOwnership[game.user.id]?.value === level
: settings.playerOwnership[game.user.id]?.value >= level;
return defaultAllowed || userAllowed;
}
async _prepareContext(_options) {
@ -67,15 +102,17 @@ class Countdowns extends HandlebarsApplicationMixin(ApplicationV2) {
context.isGM = game.user.isGM;
context.base = this.basePath;
context.canCreate = countdownData.playerOwnership[game.user.id].value === CONST.DOCUMENT_OWNERSHIP_LEVELS.OWNER;
context.canCreate = this.testUserPermission(CONST.DOCUMENT_OWNERSHIP_LEVELS.OWNER, true);
context.source = {
...countdownData,
countdowns: Object.keys(countdownData.countdowns).reduce((acc, key) => {
const countdown = countdownData.countdowns[key];
const ownershipValue = countdown.playerOwnership[game.user.id].value;
if (ownershipValue > CONST.DOCUMENT_OWNERSHIP_LEVELS.NONE) {
acc[key] = { ...countdown, canEdit: ownershipValue === CONST.DOCUMENT_OWNERSHIP_LEVELS.OWNER };
if (this.testUserPermission(CONST.DOCUMENT_OWNERSHIP_LEVELS.LIMITED, false, countdown)) {
acc[key] = {
...countdown,
canEdit: this.testUserPermission(CONST.DOCUMENT_OWNERSHIP_LEVELS.OWNER, true, countdown)
};
}
return acc;
@ -83,7 +120,7 @@ class Countdowns extends HandlebarsApplicationMixin(ApplicationV2) {
};
context.systemFields = countdownData.schema.fields;
context.countdownFields = context.systemFields.countdowns.element.fields;
context.minimized = this.minimized || _options.isFirstRender;
context.simple = this.simpleView;
return context;
}
@ -110,28 +147,6 @@ class Countdowns extends HandlebarsApplicationMixin(ApplicationV2) {
}
}
async minimize() {
await super.minimize();
this.element.querySelector('.expanded-view').classList.toggle('hidden');
this.element.querySelector('.minimized-view').classList.toggle('hidden');
}
async maximize() {
if (this.minimized) {
const settings = game.settings.get(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.Countdowns)[this.basePath];
if (settings.playerOwnership[game.user.id].value <= CONST.DOCUMENT_OWNERSHIP_LEVELS.LIMITED) {
ui.notifications.info(game.i18n.localize('DAGGERHEART.Countdown.Notifications.LimitedOwnership'));
return;
}
this.element.querySelector('.expanded-view').classList.toggle('hidden');
this.element.querySelector('.minimized-view').classList.toggle('hidden');
}
await super.maximize();
}
async updateSetting(update) {
if (game.user.isGM) {
await game.settings.set(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.Countdowns, update);
@ -213,11 +228,17 @@ class Countdowns extends HandlebarsApplicationMixin(ApplicationV2) {
});
}
static toggleSimpleView() {
this.simpleView = !this.simpleView;
game.user.setFlag(SYSTEM.id, SYSTEM.FLAGS.countdown.simple, this.simpleView);
this.render();
}
async updateCountdownValue(event, increase) {
const countdownSetting = game.settings.get(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.Countdowns);
const countdown = countdownSetting[this.basePath].countdowns[event.currentTarget.dataset.countdown];
if (countdown.playerOwnership[game.user.id] < CONST.DOCUMENT_OWNERSHIP_LEVELS.OWNER) {
if (!this.testUserPermission(CONST.DOCUMENT_OWNERSHIP_LEVELS.OWNER)) {
return;
}

View file

@ -1 +1,5 @@
export const displayDomainCardsAsList = 'displayDomainCardsAsList';
export const countdown = {
simple: 'countdown-simple',
position: 'countdown-position'
};

View file

@ -36,7 +36,8 @@ class DhCountdownData extends foundry.abstract.DataModel {
})
})
)
})
}),
window: new fields.SchemaField({})
};
}

View file

@ -225,10 +225,10 @@ export const getDeleteKeys = (property, innerProperty, innerPropertyDefaultValue
// Fix on Foundry native formula replacement for DH
const nativeReplaceFormulaData = Roll.replaceFormulaData;
Roll.replaceFormulaData = function (formula, data={}, { missing, warn = false } = {}) {
Roll.replaceFormulaData = function (formula, data = {}, { missing, warn = false } = {}) {
const terms = Object.keys(SYSTEM.GENERAL.multiplierTypes).map(type => {
return { term: type, default: 1}
})
return { term: type, default: 1 };
});
formula = terms.reduce((a, c) => a.replaceAll(`@${c.term}`, data[c.term] ?? c.default), formula);
return nativeReplaceFormulaData(formula, data, { missing, warn });
};
@ -258,3 +258,25 @@ export const damageKeyToNumber = key => {
return 0;
}
};
export default function constructHTMLButton({
label,
dataset = {},
classes = [],
icon = '',
type = 'button',
disabled = false
}) {
const button = document.createElement('button');
button.type = type;
for (const [key, value] of Object.entries(dataset)) {
button.dataset[key] = value;
}
button.classList.add(...classes);
if (icon) icon = `<i class="${icon}"></i> `;
if (disabled) button.disabled = true;
button.innerHTML = `${icon}${label}`;
return button;
}