mirror of
https://github.com/Foundryborne/daggerheart.git
synced 2026-01-12 03:31:07 +01:00
[Feature] 613 - Countdown Improvements (#1184)
* Added CountdownEdit view * Added countdowns UI element * . * Fixed migration of countdowns * . * . * style countdown interface, application and ownership dialog * fix buttons height in ownsership selection * . * Added coloured pips to UI cooldowns to signify player visibility if not every player has it * . * Added max-height and overflow * Sync countdown current with max when equal (#1221) * Update module/applications/ui/countdownEdit.mjs Co-authored-by: Carlos Fernandez <CarlosFdez@users.noreply.github.com> * . --------- Co-authored-by: moliloo <dev.murilobrito@gmail.com> Co-authored-by: Carlos Fernandez <CarlosFdez@users.noreply.github.com>
This commit is contained in:
parent
07cdcf2d78
commit
906c7ac853
24 changed files with 1024 additions and 498 deletions
199
module/applications/ui/countdownEdit.mjs
Normal file
199
module/applications/ui/countdownEdit.mjs
Normal file
|
|
@ -0,0 +1,199 @@
|
|||
import { DhCountdown } from '../../data/countdowns.mjs';
|
||||
import { emitAsGM, GMUpdateEvent, RefreshType, socketEvent } from '../../systemRegistration/socket.mjs';
|
||||
|
||||
const { HandlebarsApplicationMixin, ApplicationV2 } = foundry.applications.api;
|
||||
|
||||
export default class CountdownEdit extends HandlebarsApplicationMixin(ApplicationV2) {
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.data = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Countdowns);
|
||||
this.editingCountdowns = new Set();
|
||||
this.currentEditCountdown = null;
|
||||
this.hideNewCountdowns = false;
|
||||
}
|
||||
|
||||
static DEFAULT_OPTIONS = {
|
||||
classes: ['daggerheart', 'dialog', 'dh-style', 'countdown-edit'],
|
||||
tag: 'form',
|
||||
position: { width: 600 },
|
||||
window: {
|
||||
title: 'DAGGERHEART.APPLICATIONS.CountdownEdit.title',
|
||||
icon: 'fa-solid fa-clock-rotate-left'
|
||||
},
|
||||
actions: {
|
||||
addCountdown: CountdownEdit.#addCountdown,
|
||||
toggleCountdownEdit: CountdownEdit.#toggleCountdownEdit,
|
||||
editCountdownImage: CountdownEdit.#editCountdownImage,
|
||||
editCountdownOwnership: CountdownEdit.#editCountdownOwnership,
|
||||
removeCountdown: CountdownEdit.#removeCountdown
|
||||
},
|
||||
form: { handler: this.updateData, submitOnChange: true }
|
||||
};
|
||||
|
||||
static PARTS = {
|
||||
countdowns: {
|
||||
template: 'systems/daggerheart/templates/ui/countdown-edit.hbs',
|
||||
scrollable: ['.expanded-view', '.edit-content']
|
||||
}
|
||||
};
|
||||
|
||||
async _prepareContext(_options) {
|
||||
const context = await super._prepareContext(_options);
|
||||
context.isGM = game.user.isGM;
|
||||
context.ownershipDefaultOptions = CONFIG.DH.GENERAL.basicOwnershiplevels;
|
||||
context.defaultOwnership = this.data.defaultOwnership;
|
||||
context.countdownBaseTypes = CONFIG.DH.GENERAL.countdownBaseTypes;
|
||||
context.countdownTypes = CONFIG.DH.GENERAL.countdownTypes;
|
||||
context.hideNewCountdowns = this.hideNewCountdowns;
|
||||
context.countdowns = Object.keys(this.data.countdowns).reduce((acc, key) => {
|
||||
const countdown = this.data.countdowns[key];
|
||||
acc[key] = {
|
||||
...countdown,
|
||||
typeName: game.i18n.localize(CONFIG.DH.GENERAL.countdownBaseTypes[countdown.type].name),
|
||||
progress: {
|
||||
...countdown.progress,
|
||||
typeName: game.i18n.localize(CONFIG.DH.GENERAL.countdownTypes[countdown.progress.type].label)
|
||||
},
|
||||
editing: this.editingCountdowns.has(key)
|
||||
};
|
||||
|
||||
return acc;
|
||||
}, {});
|
||||
|
||||
return context;
|
||||
}
|
||||
|
||||
/** @override */
|
||||
async _postRender(_context, _options) {
|
||||
if (this.currentEditCountdown) {
|
||||
setTimeout(() => {
|
||||
const input = this.element.querySelector(
|
||||
`.countdown-edit-container[data-id="${this.currentEditCountdown}"] input`
|
||||
);
|
||||
if (input) {
|
||||
input.select();
|
||||
this.currentEditCountdown = null;
|
||||
}
|
||||
}, 100);
|
||||
}
|
||||
}
|
||||
|
||||
canPerformEdit() {
|
||||
if (game.user.isGM) return true;
|
||||
|
||||
if (!game.users.activeGM) {
|
||||
ui.notifications.warn(game.i18n.localize('DAGGERHEART.UI.Notifications.gmRequired'));
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
async updateSetting(update) {
|
||||
const noGM = !game.users.find(x => x.isGM && x.active);
|
||||
if (noGM) {
|
||||
ui.notifications.warn(game.i18n.localize('DAGGERHEART.UI.Notifications.gmRequired'));
|
||||
return;
|
||||
}
|
||||
|
||||
await this.data.updateSource(update);
|
||||
await emitAsGM(GMUpdateEvent.UpdateCountdowns, this.gmSetSetting.bind(this.data), this.data, null, {
|
||||
refreshType: RefreshType.Countdown
|
||||
});
|
||||
|
||||
this.render();
|
||||
}
|
||||
|
||||
static async updateData(_event, _, formData) {
|
||||
const { hideNewCountdowns, ...settingsData } = foundry.utils.expandObject(formData.object);
|
||||
|
||||
// Sync current and max if max is changing and they were equal before
|
||||
for (const [id, countdown] of Object.entries(settingsData.countdowns ?? {})) {
|
||||
const existing = this.data.countdowns[id];
|
||||
const wasEqual = existing && existing.progress.current === existing.progress.max;
|
||||
if (wasEqual && countdown.progress.max !== existing.progress.max) {
|
||||
countdown.progress.current = countdown.progress.max;
|
||||
} else {
|
||||
countdown.progress.current = Math.min(countdown.progress.current, countdown.progress.max);
|
||||
}
|
||||
}
|
||||
|
||||
this.hideNewCountdowns = hideNewCountdowns;
|
||||
this.updateSetting(settingsData);
|
||||
}
|
||||
|
||||
async gmSetSetting(data) {
|
||||
await game.settings.set(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Countdowns, data),
|
||||
game.socket.emit(`system.${CONFIG.DH.id}`, {
|
||||
action: socketEvent.Refresh,
|
||||
data: { refreshType: RefreshType.Countdown }
|
||||
});
|
||||
Hooks.callAll(socketEvent.Refresh, { refreshType: RefreshType.Countdown });
|
||||
}
|
||||
|
||||
static #addCountdown() {
|
||||
const id = foundry.utils.randomID();
|
||||
this.editingCountdowns.add(id);
|
||||
this.currentEditCountdown = id;
|
||||
this.updateSetting({
|
||||
[`countdowns.${id}`]: DhCountdown.defaultCountdown(null, this.hideNewCountdowns)
|
||||
});
|
||||
}
|
||||
|
||||
static #editCountdownImage(_, target) {
|
||||
const countdown = this.data.countdowns[target.id];
|
||||
const fp = new foundry.applications.apps.FilePicker.implementation({
|
||||
current: countdown.img,
|
||||
type: 'image',
|
||||
callback: async path => this.updateSetting({ [`countdowns.${target.id}.img`]: path }),
|
||||
top: this.position.top + 40,
|
||||
left: this.position.left + 10
|
||||
});
|
||||
return fp.browse();
|
||||
}
|
||||
|
||||
static #toggleCountdownEdit(_, button) {
|
||||
const { countdownId } = button.dataset;
|
||||
|
||||
const isEditing = this.editingCountdowns.has(countdownId);
|
||||
if (isEditing) this.editingCountdowns.delete(countdownId);
|
||||
else {
|
||||
this.editingCountdowns.add(countdownId);
|
||||
this.currentEditCountdown = countdownId;
|
||||
}
|
||||
|
||||
this.render();
|
||||
}
|
||||
|
||||
static async #editCountdownOwnership(_, button) {
|
||||
const countdown = this.data.countdowns[button.dataset.countdownId];
|
||||
const data = await game.system.api.applications.dialogs.OwnershipSelection.configure(
|
||||
countdown.name,
|
||||
countdown.ownership,
|
||||
this.data.defaultOwnership
|
||||
);
|
||||
if (!data) return;
|
||||
|
||||
this.updateSetting({ [`countdowns.${button.dataset.countdownId}`]: data });
|
||||
}
|
||||
|
||||
static async #removeCountdown(event, button) {
|
||||
const { countdownId } = button.dataset;
|
||||
|
||||
if (!event.shiftKey) {
|
||||
const confirmed = await foundry.applications.api.DialogV2.confirm({
|
||||
window: {
|
||||
title: game.i18n.localize('DAGGERHEART.APPLICATIONS.CountdownEdit.removeCountdownTitle')
|
||||
},
|
||||
content: game.i18n.format('DAGGERHEART.APPLICATIONS.CountdownEdit.removeCountdownText', {
|
||||
name: this.data.countdowns[countdownId].name
|
||||
})
|
||||
});
|
||||
if (!confirmed) return;
|
||||
}
|
||||
|
||||
if (this.editingCountdowns.has(countdownId)) this.editingCountdowns.delete(countdownId);
|
||||
this.updateSetting({ [`countdowns.-=${countdownId}`]: null });
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue