From d46d727a701c9c6101a8df46697462bc73bd29c6 Mon Sep 17 00:00:00 2001 From: Oliver-Akins Date: Sun, 29 Sep 2024 00:03:43 -0600 Subject: [PATCH] Implement the size storable class mixin --- src/sheets/Player/v1.mjs | 4 +- src/sheets/mixins/SizeStorable.mjs | 119 +++++++++++++++++++++++++++++ 2 files changed, 122 insertions(+), 1 deletion(-) create mode 100644 src/sheets/mixins/SizeStorable.mjs diff --git a/src/sheets/Player/v1.mjs b/src/sheets/Player/v1.mjs index 162af4d..8e775f1 100644 --- a/src/sheets/Player/v1.mjs +++ b/src/sheets/Player/v1.mjs @@ -1,4 +1,6 @@ -export class PlayerSheetv1 extends ActorSheet { +import { SizeStorable } from "../mixins/SizeStorable.mjs"; + +export class PlayerSheetv1 extends SizeStorable(ActorSheet) { static get defaultOptions() { let opts = foundry.utils.mergeObject( super.defaultOptions, diff --git a/src/sheets/mixins/SizeStorable.mjs b/src/sheets/mixins/SizeStorable.mjs new file mode 100644 index 0000000..776d0d3 --- /dev/null +++ b/src/sheets/mixins/SizeStorable.mjs @@ -0,0 +1,119 @@ +import { DialogManager } from "../../utils/DialogManager.mjs"; + +/** + * This mixin allows making a class so that it can store the width/height data + * to the sheet or localhost in order to make using the text sheets a lil nicer. + * + * @param {ActorSheet|ItemSheet} cls The Sheet class to augment + * @returns The augmented class + */ +export function SizeStorable(cls) { + return class SizeStorableClass extends cls { + constructor(doc, opts) { + + /* + Find the saved size of the sheet, it takes the following order of precedence + from highest to lowest: + - Locally saved + - Default values on actor + - Default values from constructor + */ + /** @type {string|undefined} */ + let size = localStorage.getItem(`${game.system.id}.size:${doc.uuid}`); + size ??= doc.getFlag(game.system.id, `size`); + + // Apply the saved value to the options + if (size) { + const [ width, height ] = size.split(`,`); + opts.width = width; + opts.height = height; + }; + + super(doc, opts); + }; + + get hasLocalSize() { + return localStorage.getItem(`${game.system.id}.size:${this.object.uuid}`) != null; + }; + + get hasGlobalSize() { + return this.object.getFlag(game.system.id, `size`) != null; + }; + + _getHeaderButtons() { + return [ + { + class: `size-save`, + icon: `fa-solid fa-floppy-disk`, + label: `Save Size`, + onclick: () => { + + const buttons = { + saveGlobal: { + label: `Save Global Size`, + callback: () => { + this.object.setFlag( + game.system.id, + `size`, + `${this.position.width},${this.position.height}`, + ); + }, + }, + saveLocal: { + label: `Save For Me Only`, + callback: () => { + localStorage.setItem( + `${game.system.id}.size:${this.object.uuid}`, + `${this.position.width},${this.position.height}`, + ); + }, + }, + }; + + // Add resets if there is a size already + if (this.hasGlobalSize) { + buttons.resetGlobal = { + label: `Reset Global Size`, + callback: () => { + this.object.unsetFlag(game.system.id, `size`); + }, + }; + }; + + if (this.hasLocalSize) { + buttons.resetLocal = { + label: `Reset Size For Me Only`, + callback: () => { + localStorage.removeItem(`${game.system.id}.size:${this.object.uuid}`); + }, + }; + }; + + // When a non-GM is using this system, we only want to save local sizes + if (!game.user.isGM) { + delete buttons.saveGlobal; + delete buttons.resetGlobal; + }; + + DialogManager.createOrFocus( + `${this.object.uuid}:size-save`, + { + title: `Save size of sheet: ${this.title}`, + content: `Saving the size of this sheet will cause it to open at the size it is when you press the save button`, + buttons, + render: (html) => { + const el = html[2]; + el.style = `display: grid; grid-template-columns: 1fr 1fr; gap: 8px;`; + }, + }, + { + jQuery: true, + }, + ); + }, + }, + ...super._getHeaderButtons(), + ]; + }; + }; +};