Update the popover management to work with origin rerenders, and rerendering the popovers directly.

This commit is contained in:
Oliver-Akins 2025-03-15 18:35:24 -06:00
parent 69bf712eca
commit 96e4d09e7b
4 changed files with 93 additions and 29 deletions

View file

@ -82,22 +82,16 @@ export class HeroSkillsCardV1 extends GenericAppMixin(HandlebarsApplicationMixin
);
};
/** @type {Map<string, PopoverEventManager>} */
#popoverManagers = new Map();
/** @type {Map<number, string>} */
#hookIDs = new Map();
/** @this {HeroSkillsCardV1} */
static async _createPopoverListeners() {
const ammoInfoIcon = this.element.querySelector(`.ammo-info-icon`);
const idPrefix = this.actor.uuid;
this.#popoverManagers.set(
`.ammo-info-icon`,
new PopoverEventManager(ammoInfoIcon, AmmoTracker),
);
this.#hookIDs.set(Hooks.on(`get${AmmoTracker.name}Options`, (opts) => {
opts.ammo = this.actor.itemTypes.ammo;
}), `get${AmmoTracker.name}Options`);
const manager = new PopoverEventManager(`${idPrefix}.ammo-info-icon`, ammoInfoIcon, AmmoTracker);
this._popoverManagers.set(`.ammo-info-icon`, manager);
this._hookIDs.set(Hooks.on(`prepare${manager.id}Context`, (ctx) => {
ctx.ammos = this.actor.itemTypes.ammo;
}), `prepare${manager.id}Context`);
};
async _preparePartContext(partId, ctx, opts) {
@ -194,17 +188,6 @@ export class HeroSkillsCardV1 extends GenericAppMixin(HandlebarsApplicationMixin
}
return ctx;
};
_tearDown(options) {
for (const manager of this.#popoverManagers.values()) {
manager.destroy();
};
this.#popoverManagers.clear();
for (const [id, hook] of this.#hookIDs.entries()) {
Hooks.off(hook, id);
}
super._tearDown(options);
};
// #endregion
// #region Actions

View file

@ -31,6 +31,13 @@ export function GenericAppMixin(HandlebarsApp) {
};
// #endregion
// #region Instance Data
/** @type {Map<string, PopoverEventManager>} */
_popoverManagers = new Map();
/** @type {Map<number, string>} */
_hookIDs = new Map();
// #endregion
// #region Lifecycle
/**
* @override
@ -45,6 +52,13 @@ export function GenericAppMixin(HandlebarsApp) {
};
};
async _onRender() {
await super._onRender();
for (const manager of this._popoverManagers.values()) {
manager.render();
};
};
async _preparePartContext(partId, ctx, opts) {
ctx = await super._preparePartContext(partId, ctx, opts);
delete ctx.document;
@ -60,6 +74,22 @@ export function GenericAppMixin(HandlebarsApp) {
return ctx;
};
_tearDown(options) {
// Clear all popovers associated with the app
for (const manager of this._popoverManagers.values()) {
manager.destroy();
};
this._popoverManagers.clear();
// Remove any hooks added for this app
for (const [id, hook] of this._hookIDs.entries()) {
Hooks.off(hook, id);
};
this._hookIDs.clear();
super._tearDown(options);
};
// #endregion
// #region Actions

View file

@ -3,7 +3,10 @@ const { ApplicationV2 } = foundry.applications.api;
/**
* This mixin provides the ability to designate an Application as a "popover",
* which means that it will spawn near the x/y coordinates provided it won't
* overflow the bounds of the screen.
* overflow the bounds of the screen. This also implements a _preparePartContext
* in order to allow the parent application passing new data into the popover
* whenever it rerenders; how the popover handles this data is up to the
* specific implementation.
*/
export function GenericPopoverMixin(HandlebarsApp) {
class GenericRipCryptPopover extends HandlebarsApp {
@ -29,7 +32,6 @@ export function GenericPopoverMixin(HandlebarsApp) {
popover.framed ??= true;
popover.locked ??= false;
if (popover.framed) {
options.window ??= {};
options.window.frame = true;
@ -151,6 +153,17 @@ export function GenericPopoverMixin(HandlebarsApp) {
scale,
};
};
/**
* This is here in order allow things that are not this Application
* to provide / augment the context data for the lifecycle of the app.
*/
async _prepareContext(_partId, _context, options) {
const context = {};
Hooks.callAll(`prepare${this.constructor.name}Context`, context, options);
Hooks.callAll(`prepare${this.popover.managerId}Context`, context, options);
return context;
};
};
return GenericRipCryptPopover;
};