From f8c21ac8d8aecfd2b72f4d27344d7773626a7495 Mon Sep 17 00:00:00 2001 From: Oliver Date: Sat, 22 Nov 2025 00:08:19 -0700 Subject: [PATCH 1/3] Begin working on an attempt to make the required setting, but be blocked by Foundry for listening to open/close events on the prose-mirror editor --- langs/en-ca.json | 4 ++++ module/apps/PlayerSheet.mjs | 29 ++++++++++++++++++++++++++ module/hooks/init.mjs | 2 ++ module/settings/user.mjs | 12 +++++++++++ scripts/macros/testRequest.mjs | 34 +++++++++++++++++++++++++++++++ templates/PlayerSheet/content.hbs | 2 +- 6 files changed, 82 insertions(+), 1 deletion(-) create mode 100644 module/settings/user.mjs create mode 100644 scripts/macros/testRequest.mjs diff --git a/langs/en-ca.json b/langs/en-ca.json index 1136454..95d9e86 100644 --- a/langs/en-ca.json +++ b/langs/en-ca.json @@ -9,6 +9,10 @@ "canPlayersManageAttributes": { "name": "Players Can Manage Attributes", "hint": "This allows players who have edit access to a document to be able to edit what attributes those characters have via the attribute editor" + }, + "openSheetInEdit": { + "name": "Open Sheets in Edit Mode", + "hint": "This makes the default when you open an Actor sheet for the first time each session to put the text editor into edit mode instead of read-only mode. On subsequent opens, the sheet" } }, "sheet-names": { diff --git a/module/apps/PlayerSheet.mjs b/module/apps/PlayerSheet.mjs index 257182a..d677532 100644 --- a/module/apps/PlayerSheet.mjs +++ b/module/apps/PlayerSheet.mjs @@ -64,6 +64,33 @@ export class PlayerSheet extends HandlebarsApplicationMixin(ActorSheetV2) { return super._initializeApplicationOptions(options); }; + /** @type {boolean | null} */ + #inEditMode = null; + async _onFirstRender(context, options) { + super._onFirstRender(context, options); + console.log(`_onFirstRender`) + this.#inEditMode ??= game.settings.get(__ID__, `openSheetInEdit`) ?? false; + this.element.querySelectorAll(`prose-mirror`).forEach(editor => { + editor.open = this.#inEditMode; + }); + }; + + async _onRender(context, options) { + super._onRender(context, options); + + if (options.parts?.includes(`content`)) { + const el = this.element.querySelector(`prose-mirror[name="system.content"]`); + el?.addEventListener(`open`, () => { + console.log(`event: open`); + this.#inEditMode = true; + }); + el?.addEventListener(`close`, () => { + console.log(`event: close`); + this.#inEditMode = false; + }); + }; + }; + _getHeaderControls() { const controls = super._getHeaderControls(); @@ -125,7 +152,9 @@ export class PlayerSheet extends HandlebarsApplicationMixin(ActorSheetV2) { ctx.attrs = attrs.toSorted(attributeSorter); }; + /** @type {boolean | null} */ async _prepareContent(ctx) { + const TextEditor = foundry.applications.ux.TextEditor.implementation; ctx.enriched = { system: { diff --git a/module/hooks/init.mjs b/module/hooks/init.mjs index f3db2fb..d12f5e3 100644 --- a/module/hooks/init.mjs +++ b/module/hooks/init.mjs @@ -10,6 +10,7 @@ import { TAFItem } from "../documents/Item.mjs"; import { TAFTokenDocument } from "../documents/Token.mjs"; // Settings +import { registerUserSettings } from "../settings/user.mjs"; import { registerWorldSettings } from "../settings/world.mjs"; // Utils @@ -41,6 +42,7 @@ Hooks.on(`init`, () => { ); registerWorldSettings(); + registerUserSettings(); registerSockets(); registerCustomComponents(); diff --git a/module/settings/user.mjs b/module/settings/user.mjs new file mode 100644 index 0000000..e8b26d6 --- /dev/null +++ b/module/settings/user.mjs @@ -0,0 +1,12 @@ +import { __ID__ } from "../consts.mjs"; + +export function registerUserSettings() { + game.settings.register(__ID__, `openSheetInEdit`, { + name: `taf.settings.openSheetInEdit.name`, + hint: `taf.settings.openSheetInEdit.hint`, + config: true, + type: Boolean, + default: false, + scope: `user`, + }); +}; diff --git a/scripts/macros/testRequest.mjs b/scripts/macros/testRequest.mjs new file mode 100644 index 0000000..1ac661f --- /dev/null +++ b/scripts/macros/testRequest.mjs @@ -0,0 +1,34 @@ +const rolls = {}; + +const response = await taf.QueryManager.query( + { + id: `test-data-request`, + question: `Test Data`, + inputs: [ + { + type: `input`, + inputType: `number`, + key: `statBase`, + label: `Stat Base`, + } + ], + }, + { + onSubmit: async (userID, answers) => { + + rolls[userID] = []; + + const diceHTML = []; + for (let i = 0; i < answers.statBase; i++) { + const rolled = Math.floor(Math.random() * 6) + 1; + rolls[userID].push(rolled); + diceHTML.push(`
  • ${rolled}
  • `); + }; + + const content = `Rolls:
      ${diceHTML.join(`\n`)}
    `; + + await taf.QueryManager.notify(userID, content); + }, + } +); +console.log({ response, rolls }); diff --git a/templates/PlayerSheet/content.hbs b/templates/PlayerSheet/content.hbs index c7b547d..771cf79 100644 --- a/templates/PlayerSheet/content.hbs +++ b/templates/PlayerSheet/content.hbs @@ -6,7 +6,7 @@ value="{{system.content}}" collaborate="true" data-document-uuid="{{actor.uuid}}" - toggled="true" + toggled > {{{ enriched.system.content }}} From 6f04910d2cfd63b9fca659f0ad3bf72dc8c07ab4 Mon Sep 17 00:00:00 2001 From: Oliver Date: Fri, 9 Jan 2026 01:31:26 -0700 Subject: [PATCH 2/3] Update the implementation to use an extended sheet class instead of a setting --- langs/en-ca.json | 7 ++----- module/apps/PlayerSheet.mjs | 30 ++------------------------- module/apps/SingleModePlayerSheet.mjs | 8 +++++++ module/hooks/init.mjs | 8 +++++-- module/settings/user.mjs | 12 ----------- templates/PlayerSheet/content.hbs | 4 ++-- 6 files changed, 20 insertions(+), 49 deletions(-) create mode 100644 module/apps/SingleModePlayerSheet.mjs delete mode 100644 module/settings/user.mjs diff --git a/langs/en-ca.json b/langs/en-ca.json index 95d9e86..f944549 100644 --- a/langs/en-ca.json +++ b/langs/en-ca.json @@ -9,14 +9,11 @@ "canPlayersManageAttributes": { "name": "Players Can Manage Attributes", "hint": "This allows players who have edit access to a document to be able to edit what attributes those characters have via the attribute editor" - }, - "openSheetInEdit": { - "name": "Open Sheets in Edit Mode", - "hint": "This makes the default when you open an Actor sheet for the first time each session to put the text editor into edit mode instead of read-only mode. On subsequent opens, the sheet" } }, "sheet-names": { - "PlayerSheet": "Player Sheet" + "PlayerSheet": "Player Sheet", + "SingleModePlayerSheet": "Player Sheet (Always Editing)" }, "misc": { "Key": "Key", diff --git a/module/apps/PlayerSheet.mjs b/module/apps/PlayerSheet.mjs index d677532..36e6697 100644 --- a/module/apps/PlayerSheet.mjs +++ b/module/apps/PlayerSheet.mjs @@ -64,33 +64,6 @@ export class PlayerSheet extends HandlebarsApplicationMixin(ActorSheetV2) { return super._initializeApplicationOptions(options); }; - /** @type {boolean | null} */ - #inEditMode = null; - async _onFirstRender(context, options) { - super._onFirstRender(context, options); - console.log(`_onFirstRender`) - this.#inEditMode ??= game.settings.get(__ID__, `openSheetInEdit`) ?? false; - this.element.querySelectorAll(`prose-mirror`).forEach(editor => { - editor.open = this.#inEditMode; - }); - }; - - async _onRender(context, options) { - super._onRender(context, options); - - if (options.parts?.includes(`content`)) { - const el = this.element.querySelector(`prose-mirror[name="system.content"]`); - el?.addEventListener(`open`, () => { - console.log(`event: open`); - this.#inEditMode = true; - }); - el?.addEventListener(`close`, () => { - console.log(`event: close`); - this.#inEditMode = false; - }); - }; - }; - _getHeaderControls() { const controls = super._getHeaderControls(); @@ -152,8 +125,9 @@ export class PlayerSheet extends HandlebarsApplicationMixin(ActorSheetV2) { ctx.attrs = attrs.toSorted(attributeSorter); }; - /** @type {boolean | null} */ async _prepareContent(ctx) { + // Whether or not the prose-mirror is toggled or always-edit + ctx.toggled = true; const TextEditor = foundry.applications.ux.TextEditor.implementation; ctx.enriched = { diff --git a/module/apps/SingleModePlayerSheet.mjs b/module/apps/SingleModePlayerSheet.mjs new file mode 100644 index 0000000..8c16f5c --- /dev/null +++ b/module/apps/SingleModePlayerSheet.mjs @@ -0,0 +1,8 @@ +import { PlayerSheet } from "./PlayerSheet.mjs"; + +export class SingleModePlayerSheet extends PlayerSheet { + async _prepareContent(ctx) { + await super._prepareContent(ctx); + ctx.toggled = false; + }; +}; diff --git a/module/hooks/init.mjs b/module/hooks/init.mjs index d12f5e3..9bdfc34 100644 --- a/module/hooks/init.mjs +++ b/module/hooks/init.mjs @@ -1,5 +1,6 @@ // Apps import { PlayerSheet } from "../apps/PlayerSheet.mjs"; +import { SingleModePlayerSheet } from "../apps/SingleModePlayerSheet.mjs"; // Data Models import { PlayerData } from "../data/Player.mjs"; @@ -10,7 +11,6 @@ import { TAFItem } from "../documents/Item.mjs"; import { TAFTokenDocument } from "../documents/Token.mjs"; // Settings -import { registerUserSettings } from "../settings/user.mjs"; import { registerWorldSettings } from "../settings/world.mjs"; // Utils @@ -40,9 +40,13 @@ Hooks.on(`init`, () => { label: `taf.sheet-names.PlayerSheet`, }, ); + foundry.documents.collections.Actors.registerSheet( + __ID__, + SingleModePlayerSheet, + { label: `taf.sheet-names.SingleModePlayerSheet` }, + ); registerWorldSettings(); - registerUserSettings(); registerSockets(); registerCustomComponents(); diff --git a/module/settings/user.mjs b/module/settings/user.mjs deleted file mode 100644 index e8b26d6..0000000 --- a/module/settings/user.mjs +++ /dev/null @@ -1,12 +0,0 @@ -import { __ID__ } from "../consts.mjs"; - -export function registerUserSettings() { - game.settings.register(__ID__, `openSheetInEdit`, { - name: `taf.settings.openSheetInEdit.name`, - hint: `taf.settings.openSheetInEdit.hint`, - config: true, - type: Boolean, - default: false, - scope: `user`, - }); -}; diff --git a/templates/PlayerSheet/content.hbs b/templates/PlayerSheet/content.hbs index 771cf79..a22f5a1 100644 --- a/templates/PlayerSheet/content.hbs +++ b/templates/PlayerSheet/content.hbs @@ -6,11 +6,11 @@ value="{{system.content}}" collaborate="true" data-document-uuid="{{actor.uuid}}" - toggled + {{ifThen toggled "toggled" ""}} > {{{ enriched.system.content }}} {{else}} {{{ enriched.system.content }}} {{/if}} - \ No newline at end of file + From c7775e7a99eaab810ea16d1c7f68014ae4489b2f Mon Sep 17 00:00:00 2001 From: Oliver Date: Fri, 9 Jan 2026 01:33:53 -0700 Subject: [PATCH 3/3] Remove unneeded macro --- scripts/macros/testRequest.mjs | 34 ---------------------------------- 1 file changed, 34 deletions(-) delete mode 100644 scripts/macros/testRequest.mjs diff --git a/scripts/macros/testRequest.mjs b/scripts/macros/testRequest.mjs deleted file mode 100644 index 1ac661f..0000000 --- a/scripts/macros/testRequest.mjs +++ /dev/null @@ -1,34 +0,0 @@ -const rolls = {}; - -const response = await taf.QueryManager.query( - { - id: `test-data-request`, - question: `Test Data`, - inputs: [ - { - type: `input`, - inputType: `number`, - key: `statBase`, - label: `Stat Base`, - } - ], - }, - { - onSubmit: async (userID, answers) => { - - rolls[userID] = []; - - const diceHTML = []; - for (let i = 0; i < answers.statBase; i++) { - const rolled = Math.floor(Math.random() * 6) + 1; - rolls[userID].push(rolled); - diceHTML.push(`
  • ${rolled}
  • `); - }; - - const content = `Rolls:
      ${diceHTML.join(`\n`)}
    `; - - await taf.QueryManager.notify(userID, content); - }, - } -); -console.log({ response, rolls });