From d2e87e4eb9edeb0d60235f9c083118e87df5508e Mon Sep 17 00:00:00 2001 From: WBHarry <89362246+WBHarry@users.noreply.github.com> Date: Tue, 16 Jun 2026 22:23:13 +0200 Subject: [PATCH] [Feature] CountdownsType Split (#1990) * Toggle pills * Finished animation framework * . * Fixed localization * Fixed iconOnly * Updated SRD Action Countdown types * feat: add shimmer animation when change countdown value * Fixed so that hidden countdowns don't take up space * Fixed countdowns.hbs part using wrong context for iconOnly * Restored glow animation for category chip * Changed back to a single sheen effect * [Review] Move visible countdown types to getter (#1999) * Move visible countdown types to getter * Punchier shimmer animation * Restored encounter/narrative * Lang cleanup * . --------- Co-authored-by: Murilo Brito Co-authored-by: Carlos Fernandez --- lang/en.json | 7 +- module/applications/ui/countdownEdit.mjs | 6 +- module/applications/ui/countdowns.mjs | 135 +++++++++++++++--- module/config/flagsConfig.mjs | 3 +- module/config/generalConfig.mjs | 36 ++--- module/data/countdowns.mjs | 19 ++- module/data/fields/action/countdownField.mjs | 4 +- module/systemRegistration/handlebars.mjs | 1 + module/systemRegistration/migrations.mjs | 4 +- module/systemRegistration/settings.mjs | 5 +- styles/less/ui/countdown/countdown.less | 68 ++++++++- .../ui/{ => countdowns}/countdown-edit.hbs | 4 +- templates/ui/countdowns/countdowns-view.hbs | 24 ++++ .../ui/{ => countdowns/parts}/countdowns.hbs | 28 ++-- 14 files changed, 267 insertions(+), 77 deletions(-) rename templates/ui/{ => countdowns}/countdown-edit.hbs (97%) create mode 100644 templates/ui/countdowns/countdowns-view.hbs rename templates/ui/{ => countdowns/parts}/countdowns.hbs (70%) diff --git a/lang/en.json b/lang/en.json index 9f16828e..5bab0e64 100755 --- a/lang/en.json +++ b/lang/en.json @@ -484,7 +484,6 @@ "startFormula": "Randomized Start Value Formula", "currentCountdownCurrent": "Current: {value}", "currentCountdownStart": "Start: {value}", - "category": "Category", "progressionType": "Progression", "decreasing": "Decreasing", "looping": "Looping", @@ -1162,7 +1161,7 @@ "autoAppliedByLabel": "Max Stress" } }, - "CountdownType": { + "CountdownProgressType": { "actionRoll": "Action Roll", "characterAttack": "Character Attack", "characterSpotlight": "Character Spotlight", @@ -1170,6 +1169,10 @@ "fear": "Fear", "spotlight": "Spotlight" }, + "CountdownType": { + "encounter": { "label": "Short Term", "shortLabel": "Short" }, + "narrative": { "label": "Long Term", "shortLabel": "Long" } + }, "DaggerheartDiceAnimationEvents": { "critical": { "name": "Critical" }, "higher": { "name": "Highest Roll" } diff --git a/module/applications/ui/countdownEdit.mjs b/module/applications/ui/countdownEdit.mjs index 5974e1f2..1dbc56be 100644 --- a/module/applications/ui/countdownEdit.mjs +++ b/module/applications/ui/countdownEdit.mjs @@ -35,7 +35,7 @@ export default class CountdownEdit extends HandlebarsApplicationMixin(Applicatio static PARTS = { countdowns: { - template: 'systems/daggerheart/templates/ui/countdown-edit.hbs', + template: 'systems/daggerheart/templates/ui/countdowns/countdown-edit.hbs', scrollable: ['.expanded-view', '.edit-content'] } }; @@ -45,7 +45,7 @@ export default class CountdownEdit extends HandlebarsApplicationMixin(Applicatio 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.countdownProgressionTypes = CONFIG.DH.GENERAL.countdownProgressionTypes; context.countdownLoopingTypes = CONFIG.DH.GENERAL.countdownLoopingTypes; context.hideNewCountdowns = this.hideNewCountdowns; @@ -62,7 +62,7 @@ export default class CountdownEdit extends HandlebarsApplicationMixin(Applicatio const randomizeValid = !new Roll(countdown.progress.startFormula ?? '').isDeterministic; acc[key] = { ...countdown, - typeName: game.i18n.localize(CONFIG.DH.GENERAL.countdownBaseTypes[countdown.type].label), + typeName: game.i18n.localize(CONFIG.DH.GENERAL.countdownTypes[countdown.type].label), progress: { ...countdown.progress, typeName: game.i18n.localize( diff --git a/module/applications/ui/countdowns.mjs b/module/applications/ui/countdowns.mjs index 2a2a113e..73e36241 100644 --- a/module/applications/ui/countdowns.mjs +++ b/module/applications/ui/countdowns.mjs @@ -11,9 +11,15 @@ const { HandlebarsApplicationMixin, ApplicationV2 } = foundry.applications.api; */ export default class DhCountdowns extends HandlebarsApplicationMixin(ApplicationV2) { + previousCountdownData = null; + changedCountdownsForAnimation = new Set(); + countdownChangeAnimationTimeout = null; + constructor(options = {}) { super(options); + this.previousCountdownData = + game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Countdowns).countdowns; this.setupHooks(); } @@ -32,6 +38,7 @@ export default class DhCountdowns extends HandlebarsApplicationMixin(Application }, actions: { toggleViewMode: DhCountdowns.#onToggleViewMode, + toggleCountdownTypes: DhCountdowns.#onToggleCountdownTypes, editCountdowns: DhCountdowns.#onEditCountdowns, loopCountdown: DhCountdowns.#onLoopCountdown, decreaseCountdown: (_, target) => this.editCountdown(false, target), @@ -48,11 +55,20 @@ export default class DhCountdowns extends HandlebarsApplicationMixin(Application static PARTS = { resources: { root: true, - template: 'systems/daggerheart/templates/ui/countdowns.hbs' + template: 'systems/daggerheart/templates/ui/countdowns/countdowns-view.hbs' } }; - /**@inheritdoc */ + /** + * Returns all visible countdown types + * @returns {string[]} + */ + get visibleCountdownTypes() { + const { encounter, narrative } = CONFIG.DH.GENERAL.countdownTypes; + return game.user.getFlag(CONFIG.DH.id, CONFIG.DH.FLAGS.userFlags.countdownTypeModes) + ?? [encounter.id, narrative.id]; + } + async _renderFrame(options) { const frame = await super._renderFrame(options); @@ -65,6 +81,51 @@ export default class DhCountdowns extends HandlebarsApplicationMixin(Application return frame; } + + async _onRender(context, options) { + await super._onRender(context, options); + + /* Handle rendering/hiding/positioning of the countdown UI */ + this.element.hidden = !game.user.isGM && this.#getCountdowns().length === 0; + if (options?.force) { + document.getElementById('ui-right-column-1')?.appendChild(this.element); + } + + this.previousCountdownData = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Countdowns) + .countdowns; + + /* Handle animations to draw attention to countdown values changing */ + if (this.changedCountdownsForAnimation.size) { + if (this.countdownChangeAnimationTimeout) + clearTimeout(this.countdownChangeAnimationTimeout); + + this.countdownChangeAnimationTimeout = setTimeout(() => { + this.changedCountdownsForAnimation.clear(); + const selector = '.countdown-container, .header-type-toggles .header-type'; + for (const element of this.element.querySelectorAll(selector)) { + element.classList.remove('change-glow'); + } + }, 3000); + + /* If the countdown is not currently visible, add a glow to the CountdownType pill */ + const visibleTypes = this.visibleCountdownTypes; + for (const countdownKey of this.changedCountdownsForAnimation) { + const countdown = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Countdowns) + .countdowns[countdownKey]; + if (!visibleTypes.includes(countdown?.type)) { + this.element.querySelector(`.header-type-toggles .header-type[data-type="${countdown.type}"]`) + .classList.add('change-glow'); + } + + /* If the countdown element is not rendered the user doesn't have permissions to it. No animation needed on the elment itself */ + const countdownElement = this.element.querySelector(`.countdown-container[data-countdown="${countdownKey}"]`); + if (!countdownElement) continue; + + countdownElement.classList.add('change-glow'); + } + } + } + /** Returns countdown data filtered by ownership */ #getCountdowns() { const setting = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Countdowns); @@ -76,16 +137,10 @@ export default class DhCountdowns extends HandlebarsApplicationMixin(Application return values.filter(v => v.ownership !== CONST.DOCUMENT_OWNERSHIP_LEVELS.NONE); } - /** @override */ - async _prepareContext(options) { - const context = await super._prepareContext(options); - context.isGM = game.user.isGM; - - context.iconOnly = - game.user.getFlag(CONFIG.DH.id, CONFIG.DH.FLAGS.userFlags.countdownMode) === - CONFIG.DH.GENERAL.countdownAppMode.iconOnly; + _getCountdownData() { const setting = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Countdowns); - context.countdowns = this.#getCountdowns().reduce((acc, { key, countdown, ownership }) => { + + return this.#getCountdowns().reduce((acc, { key, countdown, ownership }) => { const playersWithAccess = game.users.reduce((acc, user) => { const ownership = DhCountdowns.#getPlayerOwnership(user, setting, countdown); if (!user.isGM && ownership && ownership !== CONST.DOCUMENT_OWNERSHIP_LEVELS.NONE) { @@ -108,7 +163,7 @@ export default class DhCountdowns extends HandlebarsApplicationMixin(Application !countdownEditable || (isLooping && (countdown.progress.current > 0 || countdown.progress.start === '0')); - acc[key] = { + acc[countdown.type][key] = { ...countdown, editable: countdownEditable, noPlayerAccess: nonGmPlayers.length && playersWithAccess.length === 0, @@ -117,7 +172,38 @@ export default class DhCountdowns extends HandlebarsApplicationMixin(Application loopTooltip: isLooping && game.i18n.localize(loopTooltip) }; return acc; - }, {}); + }, Object.keys(CONFIG.DH.GENERAL.countdownTypes).reduce((acc, key) => { + acc[key] = {}; + return acc; + }, {})); + } + + /** @override */ + async _prepareContext(options) { + const context = await super._prepareContext(options); + context.isGM = game.user.isGM; + + context.iconOnly = + game.user.getFlag(CONFIG.DH.id, CONFIG.DH.FLAGS.userFlags.countdownMode) + === CONFIG.DH.GENERAL.countdownAppMode.iconOnly; + + context.userCountdownTypes = this.visibleCountdownTypes; + + context.typeToggles = + Object.values(CONFIG.DH.GENERAL.countdownTypes).map(type => ({ + type: type.id, + label: game.i18n.localize(type.shortLabel), + active: context.userCountdownTypes.includes(type.id) + })); + + context.countdowns = this._getCountdownData(); + context.countdownTypesWithVisibleEntries = this.#getCountdowns().reduce((acc, data) => { + if (context.userCountdownTypes.includes(data.countdown.type) && !acc.includes(data.countdown.type)) + acc.push(data.countdown.type); + + return acc; + }, []); + return context; } @@ -147,6 +233,7 @@ export default class DhCountdowns extends HandlebarsApplicationMixin(Application return true; } + /** @this {DhCountdowns} */ static async #onToggleViewMode() { const currentMode = game.user.getFlag(CONFIG.DH.id, CONFIG.DH.FLAGS.userFlags.countdownMode); const appMode = CONFIG.DH.GENERAL.countdownAppMode; @@ -158,10 +245,24 @@ export default class DhCountdowns extends HandlebarsApplicationMixin(Application this.render(); } + /** @this {DhCountdowns} */ + static async #onToggleCountdownTypes(event, target) { + const currentTypes = this.visibleCountdownTypes; + const { type } = target.dataset; + const newTypes = event.shiftKey ? + [type] : + currentTypes.includes(type) ? currentTypes.filter(x => x !== type) : [...currentTypes, type]; + await game.user.setFlag(CONFIG.DH.id, CONFIG.DH.FLAGS.userFlags.countdownTypeModes, newTypes); + + this.render(); + } + + /** @this {DhCountdowns} */ static async #onEditCountdowns() { new game.system.api.applications.ui.CountdownEdit().render(true); } + /** @this {DhCountdowns} */ static async #onLoopCountdown(_, target) { if (!DhCountdowns.canPerformEdit()) return; @@ -269,12 +370,4 @@ export default class DhCountdowns extends HandlebarsApplicationMixin(Application refreshType: RefreshType.Countdown }); } - - async _onRender(context, options) { - await super._onRender(context, options); - this.element.hidden = !game.user.isGM && this.#getCountdowns().length === 0; - if (options?.force) { - document.getElementById('ui-right-column-1')?.appendChild(this.element); - } - } } diff --git a/module/config/flagsConfig.mjs b/module/config/flagsConfig.mjs index 817ac89d..cb05bd72 100644 --- a/module/config/flagsConfig.mjs +++ b/module/config/flagsConfig.mjs @@ -24,7 +24,8 @@ export const itemAttachmentSource = 'attachmentSource'; export const userFlags = { welcomeMessage: 'welcome-message', - countdownMode: 'countdown-mode' + countdownMode: 'countdown-mode', + countdownTypeModes: 'countdown-type-modes' }; export const combatToggle = 'combat-toggle-origin'; diff --git a/module/config/generalConfig.mjs b/module/config/generalConfig.mjs index 6fc85ec5..188efafb 100644 --- a/module/config/generalConfig.mjs +++ b/module/config/generalConfig.mjs @@ -867,27 +867,27 @@ export const abilityCosts = { export const countdownProgressionTypes = { actionRoll: { id: 'actionRoll', - label: 'DAGGERHEART.CONFIG.CountdownType.actionRoll' + label: 'DAGGERHEART.CONFIG.CountdownProgressType.actionRoll' }, characterAttack: { id: 'characterAttack', - label: 'DAGGERHEART.CONFIG.CountdownType.characterAttack' + label: 'DAGGERHEART.CONFIG.CountdownProgressType.characterAttack' }, characterSpotlight: { id: 'characterSpotlight', - label: 'DAGGERHEART.CONFIG.CountdownType.characterSpotlight' + label: 'DAGGERHEART.CONFIG.CountdownProgressType.characterSpotlight' }, custom: { id: 'custom', - label: 'DAGGERHEART.CONFIG.CountdownType.custom' + label: 'DAGGERHEART.CONFIG.CountdownProgressType.custom' }, fear: { id: 'fear', - label: 'DAGGERHEART.CONFIG.CountdownType.fear' + label: 'DAGGERHEART.CONFIG.CountdownProgressType.fear' }, spotlight: { id: 'spotlight', - label: 'DAGGERHEART.CONFIG.CountdownType.spotlight' + label: 'DAGGERHEART.CONFIG.CountdownProgressType.spotlight' } }; export const rollTypes = { @@ -935,17 +935,6 @@ export const simpleOwnershiplevels = { ...basicOwnershiplevels }; -export const countdownBaseTypes = { - narrative: { - id: 'narrative', - label: 'DAGGERHEART.APPLICATIONS.Countdown.types.narrative' - }, - encounter: { - id: 'encounter', - label: 'DAGGERHEART.APPLICATIONS.Countdown.types.encounter' - } -}; - export const countdownLoopingTypes = { noLooping: { id: 'noLooping', @@ -970,6 +959,19 @@ export const countdownAppMode = { iconOnly: 'icon-only' }; +export const countdownTypes = { + encounter: { + id: 'encounter', + label: 'DAGGERHEART.CONFIG.CountdownType.encounter.label', + shortLabel: 'DAGGERHEART.CONFIG.CountdownType.encounter.shortLabel' + }, + narrative: { + id: 'narrative', + label: 'DAGGERHEART.CONFIG.CountdownType.narrative.label', + shortLabel: 'DAGGERHEART.CONFIG.CountdownType.narrative.shortLabel' + } +}; + export const sceneRangeMeasurementSetting = { disable: { id: 'disable', diff --git a/module/data/countdowns.mjs b/module/data/countdowns.mjs index 54971d34..6630c302 100644 --- a/module/data/countdowns.mjs +++ b/module/data/countdowns.mjs @@ -13,6 +13,20 @@ export default class DhCountdowns extends foundry.abstract.DataModel { }) }; } + + handleChange() { + const previousCountdowns = foundry.ui.countdowns.previousCountdownData; + const changedCountdowns = Object.entries(this.countdowns).reduce((acc, [key, countdown]) => { + const previousCountdown = previousCountdowns[key]; + if (!previousCountdown || (previousCountdown.progress.current !== countdown.progress.current)) { + acc.push(key); + } + + return acc; + }, []); + + foundry.ui.countdowns.changedCountdownsForAnimation.add(...changedCountdowns); + } } export class DhCountdown extends foundry.abstract.DataModel { @@ -21,7 +35,8 @@ export class DhCountdown extends foundry.abstract.DataModel { return { type: new fields.StringField({ required: true, - choices: CONFIG.DH.GENERAL.countdownBaseTypes, + choices: CONFIG.DH.GENERAL.countdownTypes, + initial: CONFIG.DH.GENERAL.countdownTypes.encounter.id, label: 'DAGGERHEART.GENERAL.type' }), name: new fields.StringField({ @@ -85,7 +100,7 @@ export class DhCountdown extends foundry.abstract.DataModel { : undefined; return { - type: type ?? CONFIG.DH.GENERAL.countdownBaseTypes.narrative.id, + type: type ?? CONFIG.DH.GENERAL.countdownTypes.encounter.id, name: game.i18n.localize('DAGGERHEART.APPLICATIONS.Countdown.newCountdown'), img: 'icons/magic/time/hourglass-yellow-green.webp', ownership: ownership, diff --git a/module/data/fields/action/countdownField.mjs b/module/data/fields/action/countdownField.mjs index 96d9dd91..53e132c9 100644 --- a/module/data/fields/action/countdownField.mjs +++ b/module/data/fields/action/countdownField.mjs @@ -8,8 +8,8 @@ export default class CountdownField extends fields.ArrayField { ...game.system.api.data.countdowns.DhCountdown.defineSchema(), type: new fields.StringField({ required: true, - choices: CONFIG.DH.GENERAL.countdownBaseTypes, - initial: CONFIG.DH.GENERAL.countdownBaseTypes.encounter.id, + choices: CONFIG.DH.GENERAL.countdownTypes, + initial: CONFIG.DH.GENERAL.countdownTypes.encounter.id, label: 'DAGGERHEART.GENERAL.type' }), name: new fields.StringField({ diff --git a/module/systemRegistration/handlebars.mjs b/module/systemRegistration/handlebars.mjs index 1b08e0ad..bf315358 100644 --- a/module/systemRegistration/handlebars.mjs +++ b/module/systemRegistration/handlebars.mjs @@ -50,6 +50,7 @@ export const preloadHandlebarsTemplates = async function () { 'systems/daggerheart/templates/ui/chat/parts/target-part.hbs', 'systems/daggerheart/templates/ui/chat/parts/button-part.hbs', 'systems/daggerheart/templates/ui/itemBrowser/itemContainer.hbs', + 'systems/daggerheart/templates/ui/countdowns/parts/countdowns.hbs', 'systems/daggerheart/templates/scene/dh-config.hbs', 'systems/daggerheart/templates/settings/appearance-settings/diceSoNiceTab.hbs', 'systems/daggerheart/templates/sheets/activeEffect/typeChanges/armorChange.hbs' diff --git a/module/systemRegistration/migrations.mjs b/module/systemRegistration/migrations.mjs index b718a127..ec546c92 100644 --- a/module/systemRegistration/migrations.mjs +++ b/module/systemRegistration/migrations.mjs @@ -178,8 +178,8 @@ export async function runMigrations() { await countdownSettings.updateSource({ countdowns: { - ...getCountdowns(countdownSettings.narrative, CONFIG.DH.GENERAL.countdownBaseTypes.narrative.id), - ...getCountdowns(countdownSettings.encounter, CONFIG.DH.GENERAL.countdownBaseTypes.encounter.id) + ...getCountdowns(countdownSettings.narrative, 'narrative'), + ...getCountdowns(countdownSettings.encounter, 'encounter') } }); await game.settings.set(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Countdowns, countdownSettings); diff --git a/module/systemRegistration/settings.mjs b/module/systemRegistration/settings.mjs index a66323c7..1a985274 100644 --- a/module/systemRegistration/settings.mjs +++ b/module/systemRegistration/settings.mjs @@ -199,7 +199,10 @@ const registerNonConfigSettings = () => { game.settings.register(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Countdowns, { scope: 'world', config: false, - type: DhCountdowns + type: DhCountdowns, + onChange: value => { + value.handleChange(); + } }); game.settings.register(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.CompendiumBrowserSettings, { diff --git a/styles/less/ui/countdown/countdown.less b/styles/less/ui/countdown/countdown.less index 63e539ba..d7cc83ff 100644 --- a/styles/less/ui/countdown/countdown.less +++ b/styles/less/ui/countdown/countdown.less @@ -22,7 +22,6 @@ pointer-events: all; align-self: flex-end; transition: 0.3s right ease-in-out; - display: flex; flex-direction: column; @@ -65,12 +64,35 @@ padding: 0 0.5rem; overflow: hidden; font-size: var(--font-size-13); + .window-title { font-family: @font-body; - flex: 1; } - .header-control + .header-control { - margin-left: 8px; + + + .header-type-toggles { + flex: 1; + display: flex; + align-items: center; + gap: 4px; + + .header-type { + flex: 1; + border: 1px solid @beige; + border-radius: 12px; + padding: 2px 4px; + text-align: center; + background-color: @dark-blue; + color: @beige; + + &.inactive { + opacity: 0.4; + } + + &.change-glow { + animation: glow 1s ease-in-out infinite; + } + } } } @@ -82,9 +104,27 @@ overflow: auto; max-height: 312px; + .countdown-category-container { + display: flex; + flex-direction: column; + gap: 8px; + + &.hidden { + display: none; + } + } + .countdown-container { display: flex; width: 100%; + border-radius: 6px; + + &.change-glow { + animation: shimmer 1s ease-out; + background: linear-gradient(-45deg, transparent 30%, light-dark(@dark-blue-40, @golden-40) 35%, transparent 40%); + background-size: 300%; + background-position-x: 100% + } &.icon-only { gap: 8px; @@ -105,6 +145,7 @@ display: flex; align-items: center; gap: 16px; + border-radius: 6px; img { width: 2.75rem; @@ -184,4 +225,23 @@ // } } } + + @keyframes glow { + 0% { + box-shadow: 0 0 1px 1px @golden; + } + + 100% { + box-shadow: 0 0 2px 2px @golden; + } + } + + @keyframes shimmer { + from { + background-position-x: 98%; + } + to { + background-position-x: 0% + } + } } diff --git a/templates/ui/countdown-edit.hbs b/templates/ui/countdowns/countdown-edit.hbs similarity index 97% rename from templates/ui/countdown-edit.hbs rename to templates/ui/countdowns/countdown-edit.hbs index 6b7d22d4..eebefe11 100644 --- a/templates/ui/countdown-edit.hbs +++ b/templates/ui/countdowns/countdown-edit.hbs @@ -78,9 +78,9 @@
- +
diff --git a/templates/ui/countdowns/countdowns-view.hbs b/templates/ui/countdowns/countdowns-view.hbs new file mode 100644 index 00000000..7727c4b6 --- /dev/null +++ b/templates/ui/countdowns/countdowns-view.hbs @@ -0,0 +1,24 @@ +
+
+ + {{#unless iconOnly}} + {{localize "DAGGERHEART.UI.Countdowns.title"}} + {{/unless}} +
+ {{#each typeToggles as |type|}} + {{localize type.label}} + {{/each}} +
+ {{#if isGM}} + + + + {{/if}} + + + +
+
+ {{> "systems/daggerheart/templates/ui/countdowns/parts/countdowns.hbs" }} +
+
\ No newline at end of file diff --git a/templates/ui/countdowns.hbs b/templates/ui/countdowns/parts/countdowns.hbs similarity index 70% rename from templates/ui/countdowns.hbs rename to templates/ui/countdowns/parts/countdowns.hbs index 4a77dfd7..4f0ee086 100644 --- a/templates/ui/countdowns.hbs +++ b/templates/ui/countdowns/parts/countdowns.hbs @@ -1,23 +1,11 @@ -
-
- - {{localize "DAGGERHEART.UI.Countdowns.title"}} - {{#if isGM}} - - - - {{/if}} - - - -
-
- {{#each countdowns as | countdown id |}} -
+{{#each countdowns as | category key |}} +
+ {{#each category as |countdown id|}} +
- +
- {{#unless ../iconOnly}} + {{#unless @root.iconOnly}}
{{countdown.name}}
{{/unless}}
@@ -29,7 +17,7 @@ {{#if countdown.editable}}{{/if}}
- {{#if (not ../iconOnly)}} + {{#if (not @root.iconOnly)}} {{#if (and countdown.noPlayerAccess @root.isGM)}} {{/if}} @@ -53,4 +41,4 @@
{{/each}}
-
\ No newline at end of file +{{/each}} \ No newline at end of file