Merge branch 'main' into feature/683-damage-dialog-options

This commit is contained in:
Dapoolp 2025-08-09 14:33:20 +02:00
commit a1110c15bc
7 changed files with 88 additions and 54 deletions

View file

@ -1,4 +1,5 @@
import DhAppearance from '../../data/settings/Appearance.mjs';
import { getDiceSoNicePreset } from '../../config/generalConfig.mjs';
const { HandlebarsApplicationMixin, ApplicationV2 } = foundry.applications.api;
@ -25,7 +26,8 @@ export default class DHAppearanceSettings extends HandlebarsApplicationMixin(App
},
actions: {
reset: this.reset,
save: this.save
save: this.save,
preview: this.preview
},
form: { handler: this.updateData, submitOnChange: true }
};
@ -89,6 +91,22 @@ export default class DHAppearanceSettings extends HandlebarsApplicationMixin(App
this.render();
}
static async preview() {
const source = this.settings._source.diceSoNice[this.tabGroups.diceSoNice];
let faces = 'd12';
switch (this.tabGroups.diceSoNice) {
case 'advantage':
case 'disadvantage':
faces = 'd6';
}
const preset = await getDiceSoNicePreset(source, faces);
const diceSoNiceRoll = await new Roll(`1${faces}`).evaluate();
diceSoNiceRoll.dice[0].options.appearance = preset.appearance;
diceSoNiceRoll.dice[0].options.modelFile = preset.modelFile;
await game.dice3d.showForRoll(diceSoNiceRoll, game.user, false);
}
static async reset() {
this.settings = new DhAppearance();
this.render();

View file

@ -17,7 +17,7 @@ export class ItemBrowser extends HandlebarsApplicationMixin(ApplicationV2) {
this.config = CONFIG.DH.ITEMBROWSER.compendiumConfig;
this.presets = options.presets;
if(this.presets?.compendium && this.presets?.folder)
if (this.presets?.compendium && this.presets?.folder)
ItemBrowser.selectFolder.call(this, null, null, this.presets.compendium, this.presets.folder);
}
@ -26,7 +26,6 @@ export class ItemBrowser extends HandlebarsApplicationMixin(ApplicationV2) {
id: 'itemBrowser',
classes: ['daggerheart', 'dh-style', 'dialog', 'compendium-browser'],
tag: 'div',
// title: 'Item Browser',
window: {
frame: true,
title: 'Compendium Browser',
@ -41,9 +40,8 @@ export class ItemBrowser extends HandlebarsApplicationMixin(ApplicationV2) {
sortList: this.sortList
},
position: {
top: 330,
left: 120,
width: 800,
left: 100,
width: 850,
height: 600
}
};
@ -88,16 +86,14 @@ export class ItemBrowser extends HandlebarsApplicationMixin(ApplicationV2) {
/** @inheritDoc */
async _preFirstRender(context, options) {
if(context.presets?.render?.noFolder || context.presets?.render?.lite)
options.position.width = 600;
if (context.presets?.render?.noFolder || context.presets?.render?.lite) options.position.width = 600;
await super._preFirstRender(context, options);
}
/** @inheritDoc */
async _preRender(context, options) {
if(context.presets?.render?.noFolder || context.presets?.render?.lite)
if (context.presets?.render?.noFolder || context.presets?.render?.lite)
options.parts.splice(options.parts.indexOf('sidebar'), 1);
await super._preRender(context, options);
@ -111,17 +107,16 @@ export class ItemBrowser extends HandlebarsApplicationMixin(ApplicationV2) {
this._createFilterInputs();
this._createDragProcess();
if(context.presets?.render?.lite)
this.element.classList.add('lite');
if (context.presets?.render?.lite) this.element.classList.add('lite');
if(context.presets?.render?.noFolder)
this.element.classList.add('no-folder');
if (context.presets?.render?.noFolder) this.element.classList.add('no-folder');
if(context.presets?.render?.noFilter)
this.element.classList.add('no-filter');
if (context.presets?.render?.noFilter) this.element.classList.add('no-filter');
if(this.presets?.filter) {
Object.entries(this.presets.filter).forEach(([k,v]) => this.fieldFilter.find(c => c.name === k).value = v.value);
if (this.presets?.filter) {
Object.entries(this.presets.filter).forEach(
([k, v]) => (this.fieldFilter.find(c => c.name === k).value = v.value)
);
await this._onInputFilterBrowser();
}
}
@ -198,6 +193,7 @@ export class ItemBrowser extends HandlebarsApplicationMixin(ApplicationV2) {
formatLabel(item, field) {
const property = foundry.utils.getProperty(item, field.key);
if (Array.isArray(property)) property.join(', ');
if (typeof field.format !== 'function') return property ?? '-';
return field.format(property);
}
@ -315,19 +311,18 @@ export class ItemBrowser extends HandlebarsApplicationMixin(ApplicationV2) {
async _onInputFilterBrowser(event) {
this.#filteredItems.browser.input.clear();
if(event) this.fieldFilter.find(f => f.name === event.target.name).value = event.target.value;
if (event) this.fieldFilter.find(f => f.name === event.target.name).value = event.target.value;
for (const li of this.element.querySelectorAll('.item-container')) {
const itemUUID = li.dataset.itemUuid,
item = this.items.find(i => i.uuid === itemUUID);
if(!item) continue;
if (!item) continue;
const matchesMenu =
this.fieldFilter.length === 0 ||
this.fieldFilter.every(f => (
!f.value && f.value !== false) ||
ItemBrowser.evaluateFilter(item, this.createFilterData(f))
this.fieldFilter.every(
f => (!f.value && f.value !== false) || ItemBrowser.evaluateFilter(item, this.createFilterData(f))
);
if (matchesMenu) this.#filteredItems.browser.input.add(item.id);
@ -345,11 +340,11 @@ export class ItemBrowser extends HandlebarsApplicationMixin(ApplicationV2) {
let docValue = foundry.utils.getProperty(obj, filter.field);
let filterValue = filter.value;
switch (filter.operator) {
case "contains2":
case 'contains2':
filterValue = Array.isArray(filterValue) ? filterValue : [filterValue];
docValue = Array.isArray(docValue) ? docValue : [docValue];
return docValue.some(dv => filterValue.includes(dv));
case "contains3":
case 'contains3':
return docValue.some(f => f.value === filterValue);
default:
return foundry.applications.ux.SearchFilter.evaluateFilter(obj, filter);
@ -373,24 +368,27 @@ export class ItemBrowser extends HandlebarsApplicationMixin(ApplicationV2) {
this.render({ force: true });
}
static getFolderConfig(folder, property = "columns") {
if(!folder) return [];
static getFolderConfig(folder, property = 'columns') {
if (!folder) return [];
return folder[property] ?? CONFIG.DH.ITEMBROWSER.typeConfig[folder.listType]?.[property] ?? [];
}
static sortList(_, target) {
const key = target.dataset.sortKey,
type = !target.dataset.sortType || target.dataset.sortType === "DESC" ? "ASC" : "DESC",
itemListContainer = target.closest(".compendium-results").querySelector(".item-list"),
itemList = itemListContainer.querySelectorAll(".item-container");
type = !target.dataset.sortType || target.dataset.sortType === 'DESC' ? 'ASC' : 'DESC',
itemListContainer = target.closest('.compendium-results').querySelector('.item-list'),
itemList = itemListContainer.querySelectorAll('.item-container');
target.closest(".item-list-header").querySelectorAll('[data-sort-key]').forEach(b => b.dataset.sortType = "");
target
.closest('.item-list-header')
.querySelectorAll('[data-sort-key]')
.forEach(b => (b.dataset.sortType = ''));
target.dataset.sortType = type;
const newOrder = [...itemList].reverse().sort((a, b) => {
const aProp = a.querySelector(`[data-item-key="${key}"]`),
bProp = b.querySelector(`[data-item-key="${key}"]`)
if(type === "DESC") {
bProp = b.querySelector(`[data-item-key="${key}"]`);
if (type === 'DESC') {
return aProp.innerText < bProp.innerText ? 1 : -1;
} else {
return aProp.innerText > bProp.innerText ? 1 : -1;

View file

@ -494,9 +494,7 @@ export const diceSetNumbers = {
flat: 'Flat'
};
export const getDiceSoNicePresets = async (hopeFaces, fearFaces, advantageFaces = 'd6', disadvantageFaces = 'd6') => {
const { diceSoNice } = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.appearance);
const getPreset = async (type, faces) => {
export const getDiceSoNicePreset = async (type, faces) => {
const system = game.dice3d.DiceFactory.systems.get(type.system).dice.get(faces);
if (!system) {
ui.notifications.error(
@ -523,11 +521,14 @@ export const getDiceSoNicePresets = async (hopeFaces, fearFaces, advantageFaces
};
};
export const getDiceSoNicePresets = async (hopeFaces, fearFaces, advantageFaces = 'd6', disadvantageFaces = 'd6') => {
const { diceSoNice } = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.appearance);
return {
hope: await getPreset(diceSoNice.hope, hopeFaces),
fear: await getPreset(diceSoNice.fear, fearFaces),
advantage: await getPreset(diceSoNice.advantage, advantageFaces),
disadvantage: await getPreset(diceSoNice.disadvantage, disadvantageFaces)
hope: await getDiceSoNicePreset(diceSoNice.hope, hopeFaces),
fear: await getDiceSoNicePreset(diceSoNice.fear, fearFaces),
advantage: await getDiceSoNicePreset(diceSoNice.advantage, advantageFaces),
disadvantage: await getDiceSoNicePreset(diceSoNice.disadvantage, disadvantageFaces)
};
};

View file

@ -571,6 +571,16 @@
white-space: nowrap;
}
}
.button-container {
display: grid;
grid-template-columns: 1fr;
gap: 10px;
text-align: center;
display: flex;
justify-content: center;
width: 100%
}
}
footer {

View file

@ -227,14 +227,16 @@
display: flex;
> * {
flex: 1;
flex: 2.5;
text-align: center;
}
.item-list-img {
width: 40px;
flex: unset;
}
.item-list-name {
flex-grow: 3 !important;
flex-grow: 3;
text-align: start;
}
}

View file

@ -69,7 +69,13 @@
{{selectOptions diceSoNiceMaterials selected=diceTab.source.material valueAttr="key" labelAttr="name" localize=true}}
</select>
</div>
</div>
<div class="button-container">
<button data-action="preview">
<i class="fa-solid fa-dice"></i>
<span>{{localize "Preview"}}</span>
</button>
</div>
</div>
</div>
</fieldset>
{{/if}}

View file

@ -11,7 +11,6 @@
{{formGroup settingFields.schema.fields.rangeMeasurement.fields.veryClose value=settingFields._source.rangeMeasurement.veryClose localize=true}}
{{formGroup settingFields.schema.fields.rangeMeasurement.fields.close value=settingFields._source.rangeMeasurement.close localize=true}}
{{formGroup settingFields.schema.fields.rangeMeasurement.fields.far value=settingFields._source.rangeMeasurement.far localize=true}}
{{formGroup settingFields.schema.fields.rangeMeasurement.fields.veryFar value=settingFields._source.rangeMeasurement.veryFar localize=true}}
</fieldset>
<div class="form-group">