From e20df693d76f9dbf72174d057abdfba97b3f9fc3 Mon Sep 17 00:00:00 2001 From: "centron\\schwoerer" Date: Tue, 25 Nov 2025 09:23:49 +0100 Subject: [PATCH] chore: bump tracking ledger version to 1.3.0 --- .../scripts/gowlers-tracking-ledger.js | 93 ++++++++++++------- 1 file changed, 62 insertions(+), 31 deletions(-) diff --git a/src/macros_new/gowlers-tracking-ledger/foundry.gowlershome.dyndns.org/modules/gowlers-tracking-ledger/scripts/gowlers-tracking-ledger.js b/src/macros_new/gowlers-tracking-ledger/foundry.gowlershome.dyndns.org/modules/gowlers-tracking-ledger/scripts/gowlers-tracking-ledger.js index 74bdd603..14281f16 100644 --- a/src/macros_new/gowlers-tracking-ledger/foundry.gowlershome.dyndns.org/modules/gowlers-tracking-ledger/scripts/gowlers-tracking-ledger.js +++ b/src/macros_new/gowlers-tracking-ledger/foundry.gowlershome.dyndns.org/modules/gowlers-tracking-ledger/scripts/gowlers-tracking-ledger.js @@ -1,6 +1,6 @@ const MODULE_ID = "gowlers-tracking-ledger"; -const MODULE_VERSION = "1.2.1"; +const MODULE_VERSION = "1.3.0"; const TRACK_SETTING = "actorSettings"; const FLAG_SCOPE = "world"; const MAX_HISTORY_ROWS = 100; @@ -2095,6 +2095,7 @@ class TrackingLedgerConfig extends FormApplication { this._pageMeta = { totalPages: 1, hasPrev: false, hasNext: false }; this._actorRefs = null; this._filterDebounceTimer = null; + this._pendingFilterCaret = null; } get pageSize() { @@ -2248,6 +2249,10 @@ class TrackingLedgerConfig extends FormApplication { this._page = 0; TrackingLedgerConfig._lastFilter = this._filter; TrackingLedgerConfig._lastPage = this._page; + const el = event.currentTarget; + const selStart = Number.isFinite(el.selectionStart) ? el.selectionStart : (this._filter?.length ?? 0); + const selEnd = Number.isFinite(el.selectionEnd) ? el.selectionEnd : selStart; + this._pendingFilterCaret = { start: selStart, end: selEnd }; // Debounce render to preserve focus clearTimeout(this._filterDebounceTimer); @@ -2255,8 +2260,17 @@ class TrackingLedgerConfig extends FormApplication { this.render(false); }, 300); }); - // Keep focus on filter input after render - filterInput.trigger("focus"); + // Keep focus/caret on filter input after render + setTimeout(() => { + const el = filterInput[0]; + if (!el) return; + const caret = this._pendingFilterCaret; + el.focus(); + const posStart = Number.isFinite(caret?.start) ? caret.start : el.value.length; + const posEnd = Number.isFinite(caret?.end) ? caret.end : posStart; + try { el.setSelectionRange(posStart, posEnd); } catch (e) { /* ignore */ } + this._pendingFilterCaret = null; + }, 0); html.find("[data-page-size]").on("change", (event) => { const value = event.currentTarget.value; @@ -2399,38 +2413,21 @@ async function clearDocumentHistory(doc) { DAMAGE_DEALT_FLAG, ENCOUNTER_FLAG, ]; - for (const key of flagKeys) { - try { - await doc.unsetFlag(FLAG_SCOPE, key); - } catch (err) { - console.warn(`[GowlersTracking] Failed to clear flag ${key} for ${doc.name ?? doc.id}`, err); - } - } + await Promise.all( + flagKeys.map(async (key) => { + try { + await doc.unsetFlag(FLAG_SCOPE, key); + } catch (err) { + console.warn(`[GowlersTracking] Failed to clear flag ${key} for ${doc.name ?? doc.id}`, err); + } + }) + ); + primeDocBaseline(doc); } async function clearAllHistoriesWithProgress() { try { - const targets = new Map(); - - // Core actors in the directory - for (const actor of collectAllActorDocuments()) { - const key = `actor:${actor.uuid ?? actor.id}`; - if (!targets.has(key)) targets.set(key, { doc: actor, label: actor.name ?? actor.id }); - } - - // Tokens on scenes (covers unlinked NPCs) and their embedded actor documents - for (const token of collectAllTokens()) { - const tokenKey = `token:${token.uuid ?? token.id}:${token.parent?.uuid ?? "scene"}`; - if (!targets.has(tokenKey)) targets.set(tokenKey, { doc: token, label: token.name ?? token.id }); - - const tokenActor = token.actor; - if (tokenActor) { - const actorKey = `actor:${tokenActor.uuid ?? tokenActor.id}`; - if (!targets.has(actorKey)) targets.set(actorKey, { doc: tokenActor, label: tokenActor.name ?? tokenActor.id }); - } - } - - const entries = Array.from(targets.values()); + const entries = collectClearTargets(); if (!entries.length) { ui.notifications?.info?.("No actor or token histories found to clear."); return; @@ -2473,6 +2470,40 @@ async function clearAllHistoriesWithProgress() { } } +function collectClearTargets() { + const targets = new Map(); + + // Core actors in the directory (player characters and linked NPCs) + for (const actor of collectAllActorDocuments()) { + const key = `actor:${actor.uuid ?? actor.id}`; + if (!targets.has(key)) targets.set(key, { doc: actor, label: `${actor.name ?? actor.id} (Actor)` }); + } + + // Tokens on scenes (covers unlinked NPCs and token-specific flags) + for (const token of collectAllTokens()) { + const tokenKey = `token:${token.uuid ?? token.id}:${token.parent?.uuid ?? "scene"}`; + if (!targets.has(tokenKey)) { + const sceneName = token.parent?.name ? ` - ${token.parent.name}` : ""; + targets.set(tokenKey, { doc: token, label: `${token.name ?? token.id}${sceneName} (Token)` }); + } + + // Include the token's actor (unlinked actor copies need clearing too) + const tokenActor = token.actor; + if (tokenActor) { + const actorKey = `actor:${tokenActor.uuid ?? tokenActor.id}`; + if (!targets.has(actorKey)) targets.set(actorKey, { doc: tokenActor, label: `${tokenActor.name ?? tokenActor.id} (Actor)` }); + } + } + + return Array.from(targets.values()); +} + +function primeDocBaseline(doc) { + if (!doc) return; + const actor = doc instanceof Actor ? doc : doc.actor; + if (actor) primeActor(actor); +} + function collectAllActorDocuments() { const actors = new Map(); for (const a of game.actors.contents ?? []) {