diff --git a/daggerheart.mjs b/daggerheart.mjs index 55a7d0bf..960c9d6a 100644 --- a/daggerheart.mjs +++ b/daggerheart.mjs @@ -61,6 +61,7 @@ CONFIG.Token.hudClass = applications.hud.DHTokenHUD; CONFIG.ui.combat = applications.ui.DhCombatTracker; CONFIG.ui.chat = applications.ui.DhChatLog; +CONFIG.ui.effectsDisplay = applications.ui.DhEffectsDisplay; CONFIG.ui.hotbar = applications.ui.DhHotbar; CONFIG.ui.sidebar = applications.sidebar.DhSidebar; CONFIG.ui.daggerheartMenu = applications.sidebar.DaggerheartMenu; @@ -167,6 +168,9 @@ Hooks.on('ready', async () => { ui.countdowns.render({ force: true }); } + ui.effectsDisplay = new CONFIG.ui.effectsDisplay(); + ui.effectsDisplay.render({ force: true }); + if (!(ui.compendiumBrowser instanceof applications.ui.ItemBrowser)) ui.compendiumBrowser = new applications.ui.ItemBrowser(); diff --git a/lang/en.json b/lang/en.json index c99cf652..1999f75d 100755 --- a/lang/en.json +++ b/lang/en.json @@ -2585,6 +2585,9 @@ "decreasingLoop": "Decreasing Looping", "increasingLoop": "Increasing Looping" }, + "EffectsDisplay": { + "title": "" + }, "ItemBrowser": { "title": "Daggerheart Compendium Browser", "hint": "Select a Folder in sidebar to start browsing through the compendium", diff --git a/module/applications/ui/_module.mjs b/module/applications/ui/_module.mjs index 35a58566..d5f31906 100644 --- a/module/applications/ui/_module.mjs +++ b/module/applications/ui/_module.mjs @@ -2,6 +2,7 @@ export { default as CountdownEdit } from './countdownEdit.mjs'; export { default as DhCountdowns } from './countdowns.mjs'; export { default as DhChatLog } from './chatLog.mjs'; export { default as DhCombatTracker } from './combatTracker.mjs'; +export { default as DhEffectsDisplay } from './effectsDisplay.mjs'; export { default as DhFearTracker } from './fearTracker.mjs'; export { default as DhHotbar } from './hotbar.mjs'; export { ItemBrowser } from './itemBrowser.mjs'; diff --git a/module/applications/ui/countdowns.mjs b/module/applications/ui/countdowns.mjs index d35f2eb8..55e1843f 100644 --- a/module/applications/ui/countdowns.mjs +++ b/module/applications/ui/countdowns.mjs @@ -14,7 +14,6 @@ export default class DhCountdowns extends HandlebarsApplicationMixin(Application constructor(options = {}) { super(options); - this.sidebarCollapsed = true; this.setupHooks(); } @@ -61,6 +60,8 @@ export default class DhCountdowns extends HandlebarsApplicationMixin(Application async _renderFrame(options) { const frame = await super._renderFrame(options); + frame.classList.add('effects-present'); + const iconOnly = game.user.getFlag(CONFIG.DH.id, CONFIG.DH.FLAGS.userFlags.countdownMode) === CONFIG.DH.GENERAL.countdownAppMode.iconOnly; @@ -98,11 +99,10 @@ export default class DhCountdowns extends HandlebarsApplicationMixin(Application async _prepareContext(options) { const context = await super._prepareContext(options); context.isGM = game.user.isGM; - context.sidebarCollapsed = this.sidebarCollapsed; + context.iconOnly = game.user.getFlag(CONFIG.DH.id, CONFIG.DH.FLAGS.userFlags.countdownMode) === CONFIG.DH.GENERAL.countdownAppMode.iconOnly; - const setting = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Countdowns); context.countdowns = this.#getCountdowns().reduce((acc, { key, countdown, ownership }) => { const playersWithAccess = game.users.reduce((acc, user) => { diff --git a/module/applications/ui/effectsDisplay.mjs b/module/applications/ui/effectsDisplay.mjs new file mode 100644 index 00000000..6f7ca669 --- /dev/null +++ b/module/applications/ui/effectsDisplay.mjs @@ -0,0 +1,116 @@ +import { emitAsGM, GMUpdateEvent, RefreshType, socketEvent } from '../../systemRegistration/socket.mjs'; + +const { HandlebarsApplicationMixin, ApplicationV2 } = foundry.applications.api; + +/** + * A UI element which displays the Active Effects on a selected token. + * + * @extends ApplicationV2 + * @mixes HandlebarsApplication + */ + +export default class DhEffectsDisplay extends HandlebarsApplicationMixin(ApplicationV2) { + constructor(options = {}) { + super(options); + + this.setupHooks(); + } + + /** @inheritDoc */ + static DEFAULT_OPTIONS = { + id: 'effects-display', + tag: 'div', + classes: ['daggerheart', 'dh-style', 'effects-display'], + window: { + frame: false, + positioned: false, + resizable: false, + minimizable: false + }, + actions: {} + }; + + /** @override */ + static PARTS = { + resources: { + root: true, + template: 'systems/daggerheart/templates/ui/effects-display.hbs' + } + }; + + get element() { + return document.body.querySelector('.daggerheart.dh-style.effects-display'); + } + + get hidden() { + return this.element.classList.contains('hidden'); + } + + // /**@inheritdoc */ + // async _renderFrame(options) { + // const frame = await super._renderFrame(options); + + // const header = frame.querySelector('.window-header'); + // header.querySelector('button[data-action="close"]').remove(); + + // if (game.user.isGM) { + // const editTooltip = game.i18n.localize('DAGGERHEART.APPLICATIONS.CountdownEdit.editTitle'); + // const editButton = ``; + // header.insertAdjacentHTML('beforeEnd', editButton); + // } + + // const minimizeTooltip = game.i18n.localize('DAGGERHEART.UI.Countdowns.toggleIconMode'); + // const minimizeButton = ``; + // header.insertAdjacentHTML('beforeEnd', minimizeButton); + + // return frame; + // } + + /** @override */ + async _prepareContext(options) { + const context = await super._prepareContext(options); + context.effects = this.getTokenEffects(); + + return context; + } + + getTokenEffects = token => { + const actor = token + ? token.actor + : canvas.tokens.controlled.length === 0 + ? !game.user.isGM + ? game.user.character + : null + : canvas.tokens.controlled[0].actor; + return actor?.effects ?? []; + }; + + toggleHidden(token, focused) { + const effects = this.getTokenEffects(focused ? token : null); + this.element.hidden = !focused || effects.size === 0; + if (effects.size > 0) this.render(); + } + + setupHooks() { + Hooks.on('controlToken', this.toggleHidden.bind(this)); + // Hooks.on(socketEvent.Refresh, this.cooldownRefresh.bind()); + } + + async close(options) { + /* Opt out of Foundry's standard behavior of closing all application windows marked as UI when Escape is pressed */ + if (options.closeKey) return; + + Hooks.off('controlToken', this.toggleHidden); + // Hooks.off(socketEvent.Refresh, this.cooldownRefresh); + return super.close(options); + } + + async _onRender(context, options) { + await super._onRender(context, options); + + this.element.hidden = context.effects.length === 0; + if (options?.force) { + document.getElementById('ui-right-column-1')?.appendChild(this.element); + } + } +} diff --git a/module/data/fields/action/effectsField.mjs b/module/data/fields/action/effectsField.mjs index d9658736..2233a383 100644 --- a/module/data/fields/action/effectsField.mjs +++ b/module/data/fields/action/effectsField.mjs @@ -51,7 +51,7 @@ export default class EffectsField extends fields.ArrayField { let effects = this.effects; const messageTargets = []; targets.forEach(async baseToken => { - if (this.hasSave && token.saved.success === true) effects = this.effects.filter(e => e.onSave === true); + if (this.hasSave && baseToken.saved.success === true) effects = this.effects.filter(e => e.onSave === true); if (!effects.length) return; const token = diff --git a/styles/less/ui/countdown/countdown.less b/styles/less/ui/countdown/countdown.less index 829a59b5..87f1e8fe 100644 --- a/styles/less/ui/countdown/countdown.less +++ b/styles/less/ui/countdown/countdown.less @@ -12,7 +12,7 @@ } .daggerheart.dh-style.countdowns { - position: initial; + position: relative; border: 0; border-radius: 4px; box-shadow: none; @@ -24,6 +24,10 @@ font-family: @font-body; } + &.effects-present { + right: 180px; + } + &.icon-only { width: 180px; min-width: 180px; diff --git a/styles/less/ui/effects-display/sheet.less b/styles/less/ui/effects-display/sheet.less new file mode 100644 index 00000000..db15365e --- /dev/null +++ b/styles/less/ui/effects-display/sheet.less @@ -0,0 +1,23 @@ +.daggerheart.dh-style.effects-display { + position: absolute; + width: 68px; + max-height: 300px; + overflow: hidden; + + .window-content { + > div { + height: 100%; + } + } + + .effects-display-container { + display: flex; + flex-direction: column; + gap: 8px; + + .effect-container { + img { + } + } + } +} diff --git a/styles/less/ui/index.less b/styles/less/ui/index.less index 743d16ae..7f9ada25 100644 --- a/styles/less/ui/index.less +++ b/styles/less/ui/index.less @@ -31,3 +31,5 @@ @import './sidebar/daggerheartMenu.less'; @import './scene-config/scene-config.less'; + +@import './effects-display/sheet.less'; diff --git a/templates/ui/effects-display.hbs b/templates/ui/effects-display.hbs new file mode 100644 index 00000000..c4eb5d42 --- /dev/null +++ b/templates/ui/effects-display.hbs @@ -0,0 +1,7 @@ +
+ {{#each effects as | effect |}} +
+ +
+ {{/each}} +
\ No newline at end of file