From 5a60418b2d93bdd904f765b2dbeca329e831d3d3 Mon Sep 17 00:00:00 2001 From: p4535992 Date: Mon, 19 Feb 2024 12:49:11 +0100 Subject: [PATCH 1/6] add logger helper (code more readable) --- README.md | 15 +- src/lang/en.json | 4 +- src/module.js | 36 +- src/module.json | 5 +- src/scripts/Theatre.js | 606 ++++++++++++++---------------- src/scripts/TheatreActorConfig.js | 42 +-- src/scripts/lib/Logger.js | 123 ++++++ src/scripts/lib/lib.js | 107 ------ src/scripts/settings.js | 17 +- src/scripts/socket.js | 4 +- src/scripts/theatre-helpers.js | 67 ++-- 11 files changed, 498 insertions(+), 528 deletions(-) create mode 100644 src/scripts/lib/Logger.js diff --git a/README.md b/README.md index 6070756..401381c 100644 --- a/README.md +++ b/README.md @@ -24,7 +24,7 @@ This module uses the [libWrapper](https://github.com/ruipin/fvtt-lib-wrapper) li ### socketlib -This module uses the [socketlib](https://github.com/manuelVo/foundryvtt-socketlib) library for wrapping core methods. It is a optional dependency and it is recommended for the best experience and compatibility with other modules. +This module uses the [socketlib](https://github.com/manuelVo/foundryvtt-socketlib) library for wrapping core methods. It is a hard dependency and it is recommended for the best experience and compatibility with other modules. ### Key Binds Theatre inserts now supports keybinds through the keybind API. The default keybinds are as follows (on windows): @@ -54,19 +54,6 @@ Another button next to chat, the Megaphone, causes a black box to appear in the ## For a detailed list of instructions, checkout the [WIKI](/wiki/instructions/home.md) -# Build fast note - -### Prepare a release - -In the 99% of the case for prepare a release you must: - -- Launch `npm run build` this will generate all the code under the `dist` folder. -- Launch `npm package` for zip all the contents on the `dist` folder, and build the zip file with the correct name under the `package` folder. - -### Developing a release - -- Use `npm run build:watch` and `npm run build:link` and check some tutorial online - # Build ## Install all packages diff --git a/src/lang/en.json b/src/lang/en.json index d03f2be..870fa8d 100644 --- a/src/lang/en.json +++ b/src/lang/en.json @@ -91,7 +91,9 @@ "2": "【Fāngtóu Kuòhào】", "3": "「Kagikakko」", "4": "『Nijū Kagiyamakakko』" - } + }, + "debug": "Enable debugging", + "debugHint": "Prints debug messages to the console" }, "Keybinds": { "unfocusTextArea": "Unfocus Text Area", diff --git a/src/module.js b/src/module.js index 15b098a..68ca784 100644 --- a/src/module.js +++ b/src/module.js @@ -2,8 +2,8 @@ import API from "./scripts/API/api.js"; import KHelpers from "./scripts/KHelpers.js"; import { Theatre } from "./scripts/Theatre.js"; import CONSTANTS from "./scripts/constants/constants.js"; -import { debug, log, warn } from "./scripts/lib/lib.js"; import { registerKeybindings } from "./scripts/settings.js"; +import Logger from "./scripts/lib/Logger.js"; /** * Concat helper @@ -66,7 +66,7 @@ Hooks.on("sidebarCollapse", function (a, collapsed) { if (!Theatre.instance) { return; } - debug("collapse? : ", a, collapsed); + Logger.debug("collapse? : ", a, collapsed); let sideBar = document.getElementById("sidebar"); let primeBar = document.getElementById("theatre-prime-bar"); let secondBar = document.getElementById("theatre-second-bar"); @@ -106,7 +106,7 @@ Hooks.on("createCombat", function () { return; } if (!!game.combats.active && game.combats.active.round == 0 && Theatre.instance.isSuppressed) { - debug("COMBAT CREATED"); + Logger.debug("COMBAT CREATED"); // if suppressed, change opacity to 0.05 //Theatre.instance.theatreGroup.style.opacity = "0.05"; Theatre.instance.theatreDock.style.opacity = "1"; @@ -124,7 +124,7 @@ Hooks.on("deleteCombat", function () { return; } if (!game.combats.active && Theatre.instance.isSuppressed) { - debug("COMBAT DELETED"); + Logger.debug("COMBAT DELETED"); // if suppressed, change opacity to 0.25 //Theatre.instance.theatreGroup.style.opacity = "0.25"; Theatre.instance.theatreDock.style.opacity = "0.20"; @@ -146,7 +146,7 @@ Hooks.on("preCreateChatMessage", function (chatMessage, data) { flags: {}, }, }; - debug("preCreateChatMessage", chatMessage); + Logger.debug("preCreateChatMessage", chatMessage); // If theatre isn't even ready, then just no if (!Theatre.instance) { return; @@ -170,19 +170,19 @@ Hooks.on("preCreateChatMessage", function (chatMessage, data) { let insert = Theatre.instance.getInsertById(theatreId); let actorId = theatreId.replace(CONSTANTS.PREFIX_ACTOR_ID, ""); let actor = game.actors.get(actorId) || null; - debug("speakingAs %s", theatreId); + Logger.debug("speakingAs %s", theatreId); if (insert && chatMessage.speaker) { let label = Theatre.instance._getLabelFromInsert(insert); let name = label.text; let theatreColor = Theatre.instance.getPlayerFlashColor(chatMessage.user.id, insert.textColor); - debug("name is %s", name); + Logger.debug("name is %s", name); chatData.speaker.alias = name; //chatData.flags.theatreColor = theatreColor; chatData.type = CONST.CHAT_MESSAGE_TYPES.IC; // if delay emote is active if (Theatre.instance.isDelayEmote && Theatre.instance.delayedSentState == 1) { - debug("setting emote now! as %s", insert.emote); + Logger.debug("setting emote now! as %s", insert.emote); Theatre.instance.delayedSentState = 2; Theatre.instance.setUserEmote(game.user._id, theatreId, "emote", insert.emote, false); Theatre.instance.delayedSentState = 0; @@ -196,7 +196,7 @@ Hooks.on("preCreateChatMessage", function (chatMessage, data) { chatData.type = CONST.CHAT_MESSAGE_TYPES.IC; // if delay emote is active if (Theatre.instance.isDelayEmote && Theatre.instance.delayedSentState == 1) { - debug("setting emote now! as %s", insert.emote); + Logger.debug("setting emote now! as %s", insert.emote); Theatre.instance.delayedSentState = 2; Theatre.instance.setUserEmote(game.user._id, theatreId, "emote", insert.emote, false); Theatre.instance.delayedSentState = 0; @@ -213,7 +213,7 @@ Hooks.on("preCreateChatMessage", function (chatMessage, data) { } // alter message data // append chat emote braces - debug("speaker? ", chatMessage.speaker); + Logger.debug("speaker? ", chatMessage.speaker); if ( Theatre.instance.isQuoteAuto && chatMessage.speaker && @@ -232,7 +232,7 @@ Hooks.on("preCreateChatMessage", function (chatMessage, data) { * Chat message Binding */ Hooks.on("createChatMessage", function (chatEntity, _, userId) { - debug("createChatMessage"); + Logger.debug("createChatMessage"); let theatreId = null; // If theatre isn't even ready, then just no @@ -280,7 +280,7 @@ Hooks.on("createChatMessage", function (chatEntity, _, userId) { textBox.style["overflow-y"] = "scroll"; textBox.style["overflow-x"] = "hidden"; - // debug("all tweens", TweenMax.getAllTweens()); + // Logger.debug("all tweens", TweenMax.getAllTweens()); textBox.textContent = ""; if (insert) { @@ -359,7 +359,7 @@ Hooks.on("createChatMessage", function (chatEntity, _, userId) { insertFontColor = Theatre.instance.theatreNarrator.getAttribute("textcolor"); } let fontSize = Number(textBox.getAttribute("osize") || 28); - //debug("font PRE(%s): ",insertFontSize,fontSize) + // Logger.debug("font PRE(%s): ",insertFontSize,fontSize) switch (insertFontSize) { case 3: fontSize *= 1.5; @@ -370,7 +370,7 @@ Hooks.on("createChatMessage", function (chatEntity, _, userId) { default: break; } - debug("font size is (%s): ", insertFontSize, fontSize); + Logger.debug("font size is (%s): ", insertFontSize, fontSize); // If polyglot is active, and message contains its flag (e.g. not an emote), begin processing if (typeof polyglot !== "undefined" && typeof chatData.flags.polyglot !== "undefined") { // Get current language being processed @@ -394,7 +394,7 @@ Hooks.on("createChatMessage", function (chatEntity, _, userId) { charSpans = Theatre.splitTextBoxToChars(textContent, textBox); - debug("animating text: " + textContent); + Logger.debug("animating text: " + textContent); Theatre.textFlyinAnimation(insertFlyinMode || "typewriter").call( this, @@ -439,9 +439,9 @@ Hooks.on("renderChatLog", function (app, html, data) { } // window may not be ready? - // log("%cTheatre Inserts", "font-weight: bold; font-size: 30px; font-style: italic; color: black;"); + // Logger.log("%cTheatre Inserts", "font-weight: bold; font-size: 30px; font-style: italic; color: black;"); // NOTE: Closed alpha/beta is currently all rights reserved! - // log("%c-- Theatre is Powered by Free Open Source GPLv3 Software --", "font-weight: bold; font-size: 12"); + // Logger.log("%c-- Theatre is Powered by Free Open Source GPLv3 Software --", "font-weight: bold; font-size: 12"); }); /** @@ -510,7 +510,7 @@ Hooks.once("ready", () => { if (!game.modules.get("socketlib")?.active && game.user?.isGM) { let word = "install and activate"; if (game.modules.get("socketlib")) word = "activate"; - warn(`It is recommended to intall the 'socketlib' module. Please ${word} it.`); + Logger.warn(`It is recommended to intall the 'socketlib' module. Please ${word} it.`); } if (!game.settings.get(CONSTANTS.MODULE_ID, "autoHideBottom")) { return; diff --git a/src/module.json b/src/module.json index 5f4aac8..99e2dd6 100644 --- a/src/module.json +++ b/src/module.json @@ -158,9 +158,7 @@ "type": "module", "manifest": "https://github.com/ruipin/fvtt-lib-wrapper/releases/latest/download/module.json", "compatibility": {} - } - ], - "recommends": [ + }, { "id": "socketlib", "type": "module", @@ -168,6 +166,7 @@ "compatibility": {} } ], + "recommends": [], "conflicts": [] } } diff --git a/src/scripts/Theatre.js b/src/scripts/Theatre.js index 2f3f965..2a59de2 100644 --- a/src/scripts/Theatre.js +++ b/src/scripts/Theatre.js @@ -1,29 +1,9 @@ -/** - * Theatre.js - * - * Copyright (c) 2019 Ken L. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - import API from "./API/api.js"; import KHelpers from "./KHelpers.js"; import { TheatreActor } from "./TheatreActor.js"; import { TheatreActorConfig } from "./TheatreActorConfig.js"; import CONSTANTS from "./constants/constants.js"; -import { debug, error, info, log, warn } from "./lib/lib.js"; +import Logger from "./lib/Logger.js"; import { registerSettings } from "./settings.js"; import { registerSocket, theatreSocket } from "./socket.js"; import { TheatreHelpers } from "./theatre-helpers.js"; @@ -150,8 +130,8 @@ export class Theatre { this.theatreDock = this._initTheatreDockCanvas(); this.theatreToolTip = this._initTheatreToolTip(); if (!this.theatreDock || !this.theatreToolTip) { - error("Theatre encountered a FATAL error during initialization", true); - error(game.i18n.localize("Theatre.UI.Notification.Fatal"), true); + Logger.error("Theatre encountered a FATAL error during initialization", true); + Logger.error(game.i18n.localize("Theatre.UI.Notification.Fatal"), true); return; } @@ -368,7 +348,7 @@ export class Theatre { * @param theatreStyle (String) : The theatre Style to apply */ configTheatreStyle(theatreStyle) { - debug("SWITCHING THEATRE BAR MODE : %s from %s", theatreStyle, this.settings.theatreStyle); + Logger.debug("SWITCHING THEATRE BAR MODE : %s from %s", theatreStyle, this.settings.theatreStyle); let oldStyle = this.settings.theatreStyle; let primeBar = document.getElementById("theatre-prime-bar"); let secondBar = document.getElementById("theatre-second-bar"); @@ -476,51 +456,33 @@ export class Theatre { */ _initSocket() { // module socket - if (game.modules.get("socketlib")?.active) { - Hooks.once("socketlib.ready", registerSocket); - registerSocket(); - theatreSocket.register("processEvent", (payload) => { - debug("Received packet", payload); - switch (payload.type) { - case "sceneevent": - this._processSceneEvent(payload.senderId, payload.subtype, payload.data); - break; - case "typingevent": - this._processTypingEvent(payload.senderId, payload.data); - break; - case "resyncevent": - this._processResyncEvent(payload.subtype, payload.senderId, payload.data); - break; - case "reqresync": - this._processResyncRequest(payload.subtype, payload.senderId, payload.data); - break; - default: - log("UNKNOWN THEATRE EVENT TYPE %s", payload.type, payload); - break; + Hooks.once("socketlib.ready", registerSocket); + registerSocket(); + theatreSocket.register("processEvent", (payload) => { + Logger.debug("Received packet", payload); + switch (payload.type) { + case "sceneevent": { + this._processSceneEvent(payload.senderId, payload.subtype, payload.data); + break; } - }); - } else { - game.socket.on(CONSTANTS.SOCKET, (payload) => { - debug("Received packet", payload); - switch (payload.type) { - case "sceneevent": - this._processSceneEvent(payload.senderId, payload.subtype, payload.data); - break; - case "typingevent": - this._processTypingEvent(payload.senderId, payload.data); - break; - case "resyncevent": - this._processResyncEvent(payload.subtype, payload.senderId, payload.data); - break; - case "reqresync": - this._processResyncRequest(payload.subtype, payload.senderId, payload.data); - break; - default: - error("UNKNOWN THEATRE EVENT TYPE %s", false, payload.type, payload); - break; + case "typingevent": { + this._processTypingEvent(payload.senderId, payload.data); + break; } - }); - } + case "resyncevent": { + this._processResyncEvent(payload.subtype, payload.senderId, payload.data); + break; + } + case "reqresync": { + this._processResyncRequest(payload.subtype, payload.senderId, payload.data); + break; + } + default: { + Logger.log("UNKNOWN THEATRE EVENT TYPE %s", payload.type, payload); + break; + } + } + }); } /** @@ -551,25 +513,16 @@ export class Theatre { * @private */ _sendSceneEvent(eventType, eventData) { - debug("Sending Scene state %s with payload: ", eventType, eventData); + Logger.debug("Sending Scene state %s with payload: ", eventType, eventData); // Do we even need verification? There's no User Input outside of // cookie cutter responses - if (game.modules.get("socketlib")?.active) { - theatreSocket.executeForEveryone("processEvent", { - senderId: game.user.id, - type: "sceneevent", - subtype: eventType, - data: eventData, - }); - } else { - game.socket.emit(CONSTANTS.SOCKET, { - senderId: game.user.id, - type: "sceneevent", - subtype: eventType, - data: eventData, - }); - } + theatreSocket.executeForEveryone("processEvent", { + senderId: game.user.id, + type: "sceneevent", + subtype: eventType, + data: eventData, + }); } /** @@ -582,7 +535,7 @@ export class Theatre { * @private */ _sendTypingEvent() { - debug("Sending Typing Event"); + Logger.debug("Sending Typing Event"); let insert = this.getInsertById(this.speakingAs); let insertEmote = this._getEmoteFromInsert(insert); @@ -621,25 +574,14 @@ export class Theatre { textcolor: insertTextColor, }; - if (game.modules.get("socketlib")?.active) { - theatreSocket.executeForEveryone("processEvent", { - senderId: game.user.id, - type: "typingevent", - data: { - insertid: this.speakingAs, - emotions: emotedata, - }, - }); - } else { - game.socket.emit(CONSTANTS.SOCKET, { - senderId: game.user.id, - type: "typingevent", - data: { - insertid: this.speakingAs, - emotions: emotedata, - }, - }); - } + theatreSocket.executeForEveryone("processEvent", { + senderId: game.user.id, + type: "typingevent", + data: { + insertid: this.speakingAs, + emotions: emotedata, + }, + }); } /** @@ -652,31 +594,18 @@ export class Theatre { */ _sendResyncEvent(targetId) { let insertData = this._buildResyncData(); - debug("Sending RESYNC Event (isGM)%s (to)%s: ", game.user.isGM, targetId, insertData); - - if (game.modules.get("socketlib")?.active) { - theatreSocket.executeForEveryone("processEvent", { - senderId: game.user.id, - type: "resyncevent", - subtype: game.user.isGM ? "gm" : "player", - data: { - targetid: targetId, - insertdata: insertData, - narrator: this.isNarratorActive, - }, - }); - } else { - game.socket.emit(CONSTANTS.SOCKET, { - senderId: game.user.id, - type: "resyncevent", - subtype: game.user.isGM ? "gm" : "player", - data: { - targetid: targetId, - insertdata: insertData, - narrator: this.isNarratorActive, - }, - }); - } + Logger.debug("Sending RESYNC Event (isGM)%s (to)%s: ", game.user.isGM, targetId, insertData); + + theatreSocket.executeForEveryone("processEvent", { + senderId: game.user.id, + type: "resyncevent", + subtype: game.user.isGM ? "gm" : "player", + data: { + targetid: targetId, + insertdata: insertData, + narrator: this.isNarratorActive, + }, + }); } /** @@ -736,7 +665,7 @@ export class Theatre { * @private */ _sendResyncRequest(type) { - debug("Sending RESYNC Request ", type); + Logger.debug("Sending RESYNC Request ", type); // If there's a GM, request to resync from them let data = {}; @@ -745,26 +674,17 @@ export class Theatre { data.narrator = this.isNarratorActive; } - if (game.modules.get("socketlib")?.active) { - theatreSocket.executeForEveryone("processEvent", { - senderId: game.user.id, - type: "reqresync", - subtype: type || "any", - data: data, - }); - } else { - game.socket.emit(CONSTANTS.SOCKET, { - senderId: game.user.id, - type: "reqresync", - subtype: type || "any", - data: data, - }); - } + theatreSocket.executeForEveryone("processEvent", { + senderId: game.user.id, + type: "reqresync", + subtype: type || "any", + data: data, + }); if (type != "players") { this.resync.type = type; this.resync.timeoutId = window.setTimeout(() => { - log("RESYNC REQUEST TIMEOUT"); + Logger.log("RESYNC REQUEST TIMEOUT"); this.resync.timeoutId = null; }, 5000); } @@ -786,10 +706,10 @@ export class Theatre { * @private */ _processResyncRequest(type, senderId, data) { - debug("Processing resync request"); + Logger.debug("Processing resync request"); // If the dock is not active, no need to send anything if (type == "any" && this.dockActive <= 0 && !this.isNarratorActive) { - warn("OUR DOCK IS NOT ACTIVE, Not responding to reqresync"); + Logger.warn("OUR DOCK IS NOT ACTIVE, Not responding to reqresync"); return; } else if (type == "gm" && !game.user.isGM) { return; @@ -820,7 +740,7 @@ export class Theatre { * @private */ _processResyncEvent(type, senderId, data) { - debug("Processing resync event %s :", type, data, game.users.get(senderId)); + Logger.debug("Processing resync event %s :", type, data, game.users.get(senderId)); // if we're resyncing and it's us that's the target if (this.resync.timeoutId && (data.targetid == game.user.id || ("gm" == this.resync.type) == type)) { // drop all other resync responses, first come, first process @@ -831,9 +751,9 @@ export class Theatre { for (let insert of this.portraitDocks) this.removeInsertById(insert.imgId, true); if (type == "gm") { - info(game.i18n.localize("Theatre.UI.Notification.ResyncGM"), true); + Logger.info(game.i18n.localize("Theatre.UI.Notification.ResyncGM"), true); } else { - info(game.i18n.localize("Theatre.UI.Notification.ResyncPlayer") + game.users.get(senderId).name, true); + Logger.info(game.i18n.localize("Theatre.UI.Notification.ResyncPlayer") + game.users.get(senderId).name, true); } let theatreId, insert, port, actorId, actor, params; let toInject = []; @@ -843,7 +763,7 @@ export class Theatre { params = this._getInsertParamsFromActorId(actorId); if (!params) continue; - debug("params + emotions: ", params, dat.emotions); + Logger.debug("params + emotions: ", params, dat.emotions); toInject.push({ params: params, emotions: dat.emotions }); } // let the clearing animation complete @@ -922,17 +842,17 @@ export class Theatre { window.setTimeout(() => { for (let dat of data.insertdata) { insert = this.getInsertById(dat.insertid); - //debug("attempting to apply position to ",insert,dat.insertid,dat); + //Logger.debug("attempting to apply position to ",insert,dat.insertid,dat); if (insert) { - debug("insert active post resync add, appying position"); + Logger.debug("insert active post resync add, appying position"); // apply mirror state /* if (Boolean(dat.position.mirror) != insert.mirrored) this._mirrorInsert(port,true); */ - debug("Mirror ? %s : %s", dat.position.mirror, insert.mirrored); + Logger.debug("Mirror ? %s : %s", dat.position.mirror, insert.mirrored); if (Boolean(dat.position.mirror) != insert.mirrored) { - debug("no match!"); + Logger.debug("no match!"); insert.mirrored = Boolean(dat.position.mirror); } // apply positioning data @@ -982,12 +902,12 @@ export class Theatre { * @private */ async _processSceneEvent(senderId, type, data) { - debug("Processing scene event %s", type, data); + Logger.debug("Processing scene event %s", type, data); let insert, actorId, params, emote, port, emotions, resName, app, insertEmote, render; switch (type) { case "enterscene": { - debug("enterscene: aid:%s", actorId); + Logger.debug("enterscene: aid:%s", actorId); actorId = data.insertid.replace(CONSTANTS.PREFIX_ACTOR_ID, ""); params = this._getInsertParamsFromActorId(actorId); emotions = data.emotions @@ -1000,25 +920,29 @@ export class Theatre { textSize: null, textColor: null, }; - if (!params) return; - debug("params: ", params); - if (data.isleft) + if (!params) { + return; + } + Logger.debug("params: ", params); + if (data.isleft) { await this.injectLeftPortrait(params.src, params.name, params.imgId, params.optalign, emotions, true); - else await this.injectRightPortrait(params.src, params.name, params.imgId, params.optalign, emotions, true); + } else { + await this.injectRightPortrait(params.src, params.name, params.imgId, params.optalign, emotions, true); + } break; } case "exitscene": { - debug("exitscene: tid:%s", data.insertid); + Logger.debug("exitscene: tid:%s", data.insertid); this.removeInsertById(data.insertid, true); break; } case "positionupdate": { - debug("positionupdate: tid:%s", data.insertid); + Logger.debug("positionupdate: tid:%s", data.insertid); insert = this.getInsertById(data.insertid); if (insert) { // apply mirror state - debug("mirroring desired: %s , current mirror %s", data.position.mirror, insert.mirrored); + Logger.debug("mirroring desired: %s , current mirror %s", data.position.mirror, insert.mirrored); if (Boolean(data.position.mirror) != insert.mirrored) { insert.mirrored = data.position.mirror; } @@ -1041,22 +965,22 @@ export class Theatre { break; } case "push": { - debug("insertpush: tid:%s", data.insertid); + Logger.debug("insertpush: tid:%s", data.insertid); this.pushInsertById(data.insertid, data.tofront, true); break; } case "swap": { - debug("insertswap: tid1:%s tid2:%s", data.insertid1, data.insertid2); + Logger.debug("insertswap: tid1:%s tid2:%s", data.insertid1, data.insertid2); this.swapInsertsById(data.insertid1, data.insertid2, true); break; } case "move": { - debug("insertmove: tid1:%s tid2:%s", data.insertid1, data.insertid2); + Logger.debug("insertmove: tid1:%s tid2:%s", data.insertid1, data.insertid2); this.moveInsertById(data.insertid1, data.insertid2, true); break; } case "emote": { - debug("emote:", data); + Logger.debug("emote:", data); emote = data.emotions.emote; let textFlyin = data.emotions.textflyin; let textStanding = data.emotions.textstanding; @@ -1075,7 +999,7 @@ export class Theatre { break; } case "addtexture": { - debug("texturereplace:", data); + Logger.debug("texturereplace:", data); insert = this.getInsertById(data.insertid); actorId = data.insertid.replace(CONSTANTS.PREFIX_ACTOR_ID, ""); params = this._getInsertParamsFromActorId(actorId); @@ -1090,9 +1014,9 @@ export class Theatre { const resources = await this._AddTextureResource(data.imgsrc, data.resname, data.insertid, data.emote, true); // if oure emote is active and we're replacing the emote texture, or base is active, and we're replacing the base texture - debug("add replacement complete! ", resources[data.resname], insertEmote, data.emote, render); + Logger.debug("add replacement complete! ", resources[data.resname], insertEmote, data.emote, render); if (render && app && insert && insert.dockContainer) { - debug("RE-RENDERING with NEW texture resource %s : %s", data.resname, data.imgsrc); + Logger.debug("RE-RENDERING with NEW texture resource %s : %s", data.resname, data.imgsrc); // bubble up dataum from the update insert.optAlign = params.optalign; @@ -1114,7 +1038,7 @@ export class Theatre { break; } case "addalltextures": { - debug("textureallreplace:", data); + Logger.debug("textureallreplace:", data); insert = this.getInsertById(data.insertid); actorId = data.insertid.replace(CONSTANTS.PREFIX_ACTOR_ID, ""); params = this._getInsertParamsFromActorId(actorId); @@ -1136,9 +1060,9 @@ export class Theatre { ); // if oure emote is active and we're replacing the emote texture, or base is active, and we're replacing the base texture - debug("add all textures complete! ", data.emote, data.eresname, params.emotes[data.emote]); + Logger.debug("add all textures complete! ", data.emote, data.eresname, params.emotes[data.emote]); if (render && app && insert && insert.dockContainer && data.eresname) { - debug("RE-RENDERING with NEW texture resource %s", data.eresname); + Logger.debug("RE-RENDERING with NEW texture resource %s", data.eresname); // bubble up dataum from the update insert.optAlign = params.optalign; @@ -1161,17 +1085,17 @@ export class Theatre { break; } case "stage": { - debug("staging insert", data.insertid); + Logger.debug("staging insert", data.insertid); this.stageInsertById(data.insertid, true); break; } case "narrator": { - debug("toggle narrator bar", data.active); + Logger.debug("toggle narrator bar", data.active); this.toggleNarratorBar(data.active, true); break; } case "decaytext": { - debug("decay textbox", data.insertid); + Logger.debug("decay textbox", data.insertid); this.decayTextBoxById(data.insertid, true); break; } @@ -1181,7 +1105,7 @@ export class Theatre { break; } default: { - warn("UNKNOWN SCENE EVENT: %s with data: ", false, type, data); + Logger.warn("UNKNOWN SCENE EVENT: %s with data: ", false, type, data); } } } @@ -1408,7 +1332,7 @@ export class Theatre { insert.delayedOldEmote = insert.emote; this.delayedSentState = 1; } - debug("DELAYING EMOTE %s, 'showing' %s", value, insert.delayedOldEmote); + Logger.debug("DELAYING EMOTE %s, 'showing' %s", value, insert.delayedOldEmote); } else { insert.delayedOldEmote = insert.emote; this.setEmoteForInsertById(value, theatreId, remote); @@ -1421,9 +1345,9 @@ export class Theatre { break; } // Send to socket - debug("SEND EMOTE PACKET %s,%s ??", this.isDelayEmote, this.delayedSentState); + Logger.debug("SEND EMOTE PACKET %s,%s ??", this.isDelayEmote, this.delayedSentState); if (!remote && (!this.isDelayEmote || this.delayedSentState == 2) && (insert || theatreId == CONSTANTS.NARRATOR)) { - debug("SENDING EMOTE PACKET %s,%s", this.isDelayEmote, this.delayedSentState); + Logger.debug("SENDING EMOTE PACKET %s,%s", this.isDelayEmote, this.delayedSentState); this._sendSceneEvent("emote", { insertid: insert ? insert.imgId : CONSTANTS.NARRATOR, emotions: { @@ -1585,7 +1509,7 @@ export class Theatre { } userTyping.timeoutId = window.setTimeout(() => { - debug("%s typing timeout", userId); + Logger.debug("%s typing timeout", userId); this.removeUserTyping(userId); }, 6000); } @@ -1596,7 +1520,7 @@ export class Theatre { * @param userId (String) : The userId to remove as 'typing'. */ removeUserTyping(userId) { - debug("removeUserTyping: ", this.usersTyping[userId]); + Logger.debug("removeUserTyping: ", this.usersTyping[userId]); if (!this.usersTyping[userId]) { this.usersTyping[userId] = {}; return; @@ -1648,7 +1572,7 @@ export class Theatre { } } - debug("%s is no longer typing (removed)", userId); + Logger.debug("%s is no longer typing (removed)", userId); window.clearTimeout(this.usersTyping[userId].timeoutId); this.usersTyping[userId].timeoutId = null; } @@ -1665,10 +1589,10 @@ export class Theatre { _getInsertParamsFromActorId(actorId) { let actor = game.actors.get(actorId); if (!!!actor) { - error("ERROR, ACTOR %s DOES NOT EXIST!", true, actorId); + Logger.error("ERROR, ACTOR %s DOES NOT EXIST!", true, actorId); return null; } - //debug("getting params from actor: ",actor); + //Logger.debug("getting params from actor: ",actor); let theatreId = `theatre-${actor._id}`; let portrait = actor.img ? actor.img : CONSTANTS.DEFAULT_PORTRAIT; @@ -1711,13 +1635,15 @@ export class Theatre { let actor = game.actors.get(actorId); if (!!!actor) { - error("ERROR, ACTOR %s DOES NOT EXIST!", true, actorId); + Logger.error("ERROR, ACTOR %s DOES NOT EXIST!", true, actorId); return null; } - debug("isDefaultDisabled ", actor); + Logger.debug("isDefaultDisabled ", actor); - if (actor.flags.theatre && actor.flags.theatre.disabledefault) return true; + if (actor.flags.theatre && actor.flags.theatre.disabledefault) { + return true; + } return false; } @@ -1737,14 +1663,15 @@ export class Theatre { let actor = game.actors.get(actorId); if (!!!actor) { - error("ERROR, ACTOR %s DOES NOT EXIST!", true, actorId); + Logger.error("ERROR, ACTOR %s DOES NOT EXIST!", true, actorId); return false; } if ( (actor.ownership[userId] && actor.ownership[userId] >= 3) || (actor.ownership["default"] && actor.ownership["default"] >= 3) - ) + ) { return true; + } return false; } @@ -1762,7 +1689,7 @@ export class Theatre { let user; if (!!!actor) { - error("ERROR, ACTOR %s DOES NOT EXIST!", true, actorId); + Logger.error("ERROR, ACTOR %s DOES NOT EXIST!", true, actorId); return; } for (let perm in actor.ownership) { @@ -1821,7 +1748,7 @@ export class Theatre { let canvas = app.view; if (!canvas) { - error("FAILED TO INITILIZE TOOLTIP CANVAS!", true); + Logger.error("FAILED TO INITILIZE TOOLTIP CANVAS!", true); return null; } @@ -1859,7 +1786,7 @@ export class Theatre { let params = this._getInsertParamsFromActorId(actorId); if (!params) { - error("ERROR actor no longer exists for %s", true, theatreId); + Logger.error("ERROR actor no longer exists for %s", true, theatreId); return; } @@ -1869,7 +1796,7 @@ export class Theatre { const texture = await PIXI.Assets.load(resName); if (!texture) { - error("ERROR could not load texture (for tooltip) %s", true, resName); + Logger.error("ERROR could not load texture (for tooltip) %s", true, resName); return; } @@ -1922,7 +1849,7 @@ export class Theatre { sprite.x = 0; sprite.y = 0; - //debug("Tooltip Portrait loaded with w:%s h:%s scale:%s",portWidth,portHeight,ratio,sprite); + //Logger.debug("Tooltip Portrait loaded with w:%s h:%s scale:%s",portWidth,portHeight,ratio,sprite); // render and show the tooltip app.render(); @@ -1930,10 +1857,10 @@ export class Theatre { // face detect /* faceapi.detectSingleFace(app.view,new faceapi.TinyFaceDetectorOptions()).then((detection)=>{ - debug("face detected: ", detection); + Logger."face detected: ", detection); if (detection) { let box = detection.box; - debug("successful preview face detection: ", box); + Logger.debug("successful preview face detection: ", box); let graphics = new PIXI.Graphics(); graphics.lineStyle (2,0xFFFFFF,1); @@ -1953,7 +1880,7 @@ export class Theatre { app.stage.addChild(graphics); app.render(); } else { - error("FAILED TO FIND PREVIEW FACE", false); + Logger.error("FAILED TO FIND PREVIEW FACE", false); } this.theatreToolTip.style.opacity = 1; }); @@ -1999,7 +1926,7 @@ export class Theatre { let canvas = app.view; if (!canvas) { - error("FAILED TO INITILIZE DOCK CANVAS!", true); + Logger.error("FAILED TO INITILIZE DOCK CANVAS!", true); return null; } @@ -2038,14 +1965,14 @@ export class Theatre { // PIXI.v6 The renderer should not clear the canvas on rendering this.pixiCTX.renderer.render(insert.dockContainer, { clear: false }); } else { - error("INSERT HAS NO CONTAINER! _renderTheatre : HOT-EJECTING it! ", true, insert); + Logger.error("INSERT HAS NO CONTAINER! _renderTheatre : HOT-EJECTING it! ", true, insert); this._destroyPortraitDock(insert.imgId); } } if (this.renderAnims > 0) { requestAnimationFrame(this._renderTheatre.bind(this)); } else { - debug("RENDERING LOOP STOPPED"); + Logger.debug("RENDERING LOOP STOPPED"); this.rendering = false; } } @@ -2064,7 +1991,7 @@ export class Theatre { let insert = this.getInsertById(imgId); if (!insert || !insert.dockContainer) { // if dockContainer is destroyed, destroy the tween we were trying to add - error("Invalid Tween for %s", false, imgId); + Logger.error("Invalid Tween for %s", false, imgId); if (tween) tween.kill(); return; } @@ -2085,7 +2012,7 @@ export class Theatre { // Kick renderer if we need to if (!this.rendering) { - debug("RENDERING LOOP STARTED"); + Logger.debug("RENDERING LOOP STARTED"); this.rendering = true; this._renderTheatre(performance.now()); } @@ -2123,8 +2050,8 @@ export class Theatre { //sanit check if (this.renderAnims < 0) { - error("ERROR RENDER ANIM < 0 from %s of %s", true, tweenId, insert ? insert.name : imgId); - error("ERROR RENDER ANIM < 0 ", true); + Logger.error("ERROR RENDER ANIM < 0 from %s of %s", true, tweenId, insert ? insert.name : imgId); + Logger.error("ERROR RENDER ANIM < 0 ", true); } } @@ -2196,11 +2123,11 @@ export class Theatre { // track the dockContainer if (!!this.getInsertById(imgId)) { // this dockContainer should be destroyed - debug("PRE-EXISTING PIXI CONTAINER FOR %s ", imgId); + Logger.debug("PRE-EXISTING PIXI CONTAINER FOR %s ", imgId); this._destroyPortraitDock(imgId); } - //debug("Creating PortraintPIXIContainer with emotions: ",emotions); + //Logger.debug("Creating PortraintPIXIContainer with emotions: ",emotions); let ename, textFlyin, textStanding, textFont, textSize, textColor; if (emotions) { @@ -2243,20 +2170,20 @@ export class Theatre { resname: "modules/theatre/assets/graphics/typing.png", }); imgSrcs.push({ imgpath: imgPath, resname: imgPath }); - debug("Adding %s with src %s", portName, imgPath); + Logger.debug("Adding %s with src %s", portName, imgPath); // get actor, load all emote images let actorId = imgId.replace(CONSTANTS.PREFIX_ACTOR_ID, ""); let params = this._getInsertParamsFromActorId(actorId); if (!params) { - error("ERROR: Actor does not exist for %s", false, actorId); + Logger.error("ERROR: Actor does not exist for %s", false, actorId); this._destroyPortraitDock(imgId); return null; } // load all rigging assets let rigResources = Theatre.getActorRiggingResources(actorId); - debug("RigResources for %s :", portName, rigResources); + Logger.debug("RigResources for %s :", portName, rigResources); for (let rigResource of rigResources) imgSrcs.push({ imgpath: rigResource.path, resname: rigResource.path }); @@ -2269,7 +2196,7 @@ export class Theatre { const resources = await this._addSpritesToPixi(imgSrcs); // PIXI Container is ready! // Setup the dockContainer to display the base insert - debug("Sprites added to PIXI _createPortraitPIXIContainer", resources); + Logger.debug("Sprites added to PIXI _createPortraitPIXIContainer", resources); let portWidth = ename && params.emotes[ename] && params.emotes[ename].insert ? resources[params.emotes[ename].insert].width @@ -2307,8 +2234,8 @@ export class Theatre { let insert = this.getInsertById(imgId); if (!insert || !insert.dockContainer) { - error("ERROR PIXI Container was destroyed before setup could execute for %s", true, imgId); - error( + Logger.error("ERROR PIXI Container was destroyed before setup could execute for %s", true, imgId); + Logger.error( `${game.i18n.localize("Theatre.UI.Notification.ImageLoadFail_P1")} ${imgId} ${game.i18n.localize( "Theatre.UI.Notification.ImageLoadFail_P2" )} ${resName}`, @@ -2319,8 +2246,8 @@ export class Theatre { } if (!resources[resName]) { - error("ERROR could not load texture %s", true, resName, resources); - error( + Logger.error("ERROR could not load texture %s", true, resName, resources); + Logger.error( `${game.i18n.localize("Theatre.UI.Notification.ImageLoadFail_P1")} ${imgId} ${game.i18n.localize( "Theatre.UI.Notification.ImageLoadFail_P2" )} ${resName}`, @@ -2444,13 +2371,13 @@ export class Theatre { break; } - debug("Portrait loaded with w:%s h:%s", portWidth, portHeight, sprite); + Logger.debug("Portrait loaded with w:%s h:%s", portWidth, portHeight, sprite); // run rigging animations if we have have any if (insert.emote) { let actorId = insert.imgId.replace(CONSTANTS.PREFIX_ACTOR_ID, ""); let defaultDisabled = this.isDefaultDisabled(insert.imgId); - debug("is default disabled? : %s", defaultDisabled); + Logger.debug("is default disabled? : %s", defaultDisabled); let emotes = Theatre.getActorEmotes(actorId, defaultDisabled); let rigResMap = Theatre.getActorRiggingResources(actorId); if (emotes[insert.emote] && emotes[insert.emote].rigging) { @@ -2602,7 +2529,7 @@ export class Theatre { */ _repositionInsertElements(insert) { if (!insert || !insert.portrait) { - error("ERROR: No insert, or portrait available ", false, insert); + Logger.error("ERROR: No insert, or portrait available ", false, insert); return; } // re-align the dockContainer to the textBox and its nameOrientation @@ -2741,7 +2668,7 @@ export class Theatre { // src check, not fine at all! if (!(await srcExists(imgSrc))) { - error("ERROR (_AddTextureResource) : Replacement texture does not exist %s ", false, imgSrc); + Logger.error("ERROR (_AddTextureResource) : Replacement texture does not exist %s ", false, imgSrc); return; } @@ -2751,7 +2678,7 @@ export class Theatre { } let imgSrcs = [{ resname: resName, imgpath: imgSrc }]; - debug("replace textures", imgSrcs); + Logger.debug("replace textures", imgSrcs); // Send to socket if (!remote) { @@ -2803,7 +2730,7 @@ export class Theatre { // src check, not fine at all! for (let src of imgSrcs) if (!(await srcExists(src.imgpath))) { - error("ERROR (_AddAllTextureResources) : Replacement texture does not exist %s ", false, src); + Logger.error("ERROR (_AddAllTextureResources) : Replacement texture does not exist %s ", false, src); return; } @@ -2812,7 +2739,7 @@ export class Theatre { return {}; } - debug("replace textures", imgSrcs); + Logger.debug("replace textures", imgSrcs); // Send to socket if (!remote) { @@ -2896,7 +2823,7 @@ export class Theatre { // assignment insert.dockContainer = dockContainer; insert.portraitContainer = portraitContainer; - debug("saving ox: %s, oy: %s", ox, oy); + Logger.debug("saving ox: %s, oy: %s", ox, oy); // label is NOT re-attached, must be done by the clearer // typingBubble is NOT re-attached, must be done by the clearer // mirror-state is NOT restored, must be done by the clearer @@ -2912,7 +2839,7 @@ export class Theatre { * @private */ async _addSpritesToPixi(imgSrcs) { - debug("adding sprite to dockContainer"); + Logger.debug("adding sprite to dockContainer"); const resources = {}; await Promise.all( @@ -2920,7 +2847,7 @@ export class Theatre { resources[resname] = resources[imgpath] = await PIXI.Assets.load(imgpath); }) ); - debug("resources", resources); + Logger.debug("resources", resources); return resources; } @@ -2944,7 +2871,7 @@ export class Theatre { // load all rigging assets let rigResources = Theatre.getActorRiggingResources(actorId); - debug("RigResources for %s :", params.name, rigResources); + Logger.debug("RigResources for %s :", params.name, rigResources); for (let rigResource of rigResources) imgSrcs.push({ imgpath: rigResource.path, resname: rigResource.path }); @@ -2971,14 +2898,14 @@ export class Theatre { if (!params) { return; } - //debug("params: ",params); + //Logger.debug("params: ",params); // kick asset loader to cache the portrait + emotes let imgSrcs = []; //imgSrcs.push({imgpath: params.src, resname: `portrait-${theatreId}`}); // get actor, load all emote images if (!params) { - error("ERROR: Actor does not exist for %s", false, actorId); + Logger.error("ERROR: Actor does not exist for %s", false, actorId); return null; } @@ -2987,7 +2914,7 @@ export class Theatre { // load all rigging assets let rigResources = Theatre.getActorRiggingResources(actorId); - debug("RigResources for %s :", params.name, rigResources); + Logger.debug("RigResources for %s :", params.name, rigResources); for (let rigResource of rigResources) imgSrcs.push({ imgpath: rigResource.path, resname: rigResource.path }); @@ -2999,7 +2926,7 @@ export class Theatre { // load in the sprites await this._addSpritesToPixi(imgSrcs); - debug("staging complete for %s", theatreId); + Logger.debug("staging complete for %s", theatreId); // Send socket event if (!remote) Theatre.instance._sendSceneEvent("stage", { insertid: theatreId }); @@ -3077,11 +3004,11 @@ export class Theatre { imgSrcs.push({ imgpath: emotes[ename].insert, resname: emoteResName }); // add sprites const resources = await this._addSpritesToPixi(imgSrcs); - debug("emote insert loaded", resources); + Logger.debug("emote insert loaded", resources); // Error loading the sprite if (!resources[emoteResName] || resources[emoteResName].error) { - error("ERROR loading resource %s : %s : %s", true, insert.imgId, emoteResName, emotes[ename].insert); - error( + Logger.error("ERROR loading resource %s : %s : %s", true, insert.imgId, emoteResName, emotes[ename].insert); + Logger.error( game.i18n.localize("Theatre.UI.Notification.ImageLoadFail_P1") + +emoteResName + game.i18n.localize("Theatre.UI.Notification.ImageLoadFail_P2") + @@ -3116,11 +3043,11 @@ export class Theatre { imgSrcs.push({ imgpath: baseInsert, resname: baseInsert }); const resources = await this._addSpritesToPixi(imgSrcs); - debug("base insert loaded", resources); + Logger.debug("base insert loaded", resources); // Error loading the sprite if (!resources[baseInsert] || resources[baseInsert].error) { - error("ERROR loading resource %s : %s : %s", true, insert.imgId, baseInsert, baseInsert); - error( + Logger.error("ERROR loading resource %s : %s : %s", true, insert.imgId, baseInsert, baseInsert); + Logger.error( game.i18n.localize("Theatre.UI.Notification.ImageLoadFail_P1") + +baseInsert + game.i18n.localize("Theatre.UI.Notification.ImageLoadFail_P2") + @@ -3278,7 +3205,7 @@ export class Theatre { if (textBoxes.length == 0) { // no dock // Should be impossible - debug("REMOVE TEXTBOX ERROR, NO TEXTBOXES", textBox, this.theatreBar); + Logger.debug("REMOVE TEXTBOX ERROR, NO TEXTBOXES", textBox, this.theatreBar); } else if (textBoxes.length == 1) { // single dock // 1. Remove the text Box, and close the primary bar @@ -3354,7 +3281,7 @@ export class Theatre { */ async injectLeftPortrait(imgPath, portName, imgId, optAlign, emotions, remote) { if (!!this.getInsertById(imgId)) { - warn('ID "%s" already exists! Refusing to inject %s', false, imgId, portName); + Logger.warn('ID "%s" already exists! Refusing to inject %s', false, imgId, portName); return; } if (this.portraitDocks.length == 1) { @@ -3416,7 +3343,7 @@ export class Theatre { */ async injectRightPortrait(imgPath, portName, imgId, optAlign, emotions, remote) { if (!!this.getInsertById(imgId)) { - warn('ID "%s" already exists! Refusing to inject %s', false, imgId, portName); + Logger.warn('ID "%s" already exists! Refusing to inject %s', false, imgId, portName); return; } if (this.portraitDocks.length == 0) { @@ -3550,7 +3477,7 @@ export class Theatre { let isOwner = this.isActorOwner(game.user.id, toRemoveInsert.imgId); // permission check if (!remote && !isOwner) { - info(game.i18n.localize("Theatre.UI.Notification.DoNotControl"), true); + Logger.info(game.i18n.localize("Theatre.UI.Notification.DoNotControl"), true); return null; } @@ -3573,7 +3500,7 @@ export class Theatre { skel["flags.theatre.settings.textsize"] = toRemoveInsert.textSize; skel["flags.theatre.settings.textcolor"] = toRemoveInsert.textColor; actor.update(skel).then((response) => { - debug("updated with resp: ", response); + Logger.debug("updated with resp: ", response); }); } } @@ -3934,19 +3861,19 @@ export class Theatre { tsib1p = textBox1.previousSibling, tsib2n = textBox2.nextSibling, tsib2p = textBox2.previousSibling; - //debug("SWAP",textBox1,textBox2); + //Logger.debug("SWAP",textBox1,textBox2); let adjSwap = false; // permission check if (!remote && (!this.isPlayerOwned(insert1.imgId) || !this.isPlayerOwned(insert2.imgId))) { - info(game.i18n.localize("Theatre.UI.Notification.CannotSwapControlled"), true); + Logger.info(game.i18n.localize("Theatre.UI.Notification.CannotSwapControlled"), true); return; } else if ( !remote && !this.isActorOwner(game.user.id, insert1.imgId) && !this.isActorOwner(game.user.id, insert2.imgId) ) { - info(game.i18n.localize("Theatre.UI.Notification.CannotSwapOwner"), true); + Logger.info(game.i18n.localize("Theatre.UI.Notification.CannotSwapOwner"), true); return; } @@ -3973,25 +3900,31 @@ export class Theatre { secondBar.appendChild(textBox2); } else { // full bar case - if (tsib1n) KHelpers.insertBefore(textBox2, tsib1n); - else if (tsib1p && tsib1p != textBox2) KHelpers.insertAfter(textBox2, tsib1p); - else { - debug("NO TSIB1 and PRIOR"); + if (tsib1n) { + KHelpers.insertBefore(textBox2, tsib1n); + } else if (tsib1p && tsib1p != textBox2) { + KHelpers.insertAfter(textBox2, tsib1p); + } else { + Logger.debug("NO TSIB1 and PRIOR"); KHelpers.insertAfter(textBox2, textBox1); adjSwap = true; } if (!adjSwap) { - if (tsib2n) KHelpers.insertBefore(textBox1, tsib2n); - else if (tsib2p && tsib2p != textBox1) KHelpers.insertAfter(textBox1, tsib2p); - else { - debug("NO TSIB2 and PRIOR"); + if (tsib2n) { + KHelpers.insertBefore(textBox1, tsib2n); + } else if (tsib2p && tsib2p != textBox1) { + KHelpers.insertAfter(textBox1, tsib2p); + } else { + Logger.debug("NO TSIB2 and PRIOR"); KHelpers.insertAfter(textBox1, textBox2); } } } - if (this.reorderTOId) window.clearTimeout(this.reorderTOId); + if (this.reorderTOId) { + window.clearTimeout(this.reorderTOId); + } this.reorderTOId = window.setTimeout(() => { Theatre.reorderInserts(); @@ -4052,15 +3985,15 @@ export class Theatre { tsib1p = textBox1.previousSibling, tsib2n = textBox2.nextSibling, tsib2p = textBox2.previousSibling; - //debug("SWAP",textBox1,textBox2); + //Logger.debug("SWAP",textBox1,textBox2); let adjSwap = false; // permission check if (!remote && !this.isActorOwner(game.user.id, insert2.imgId)) { - info(game.i18n.localize("Theatre.UI.Notification.CannotMoveOwner"), true); + Logger.info(game.i18n.localize("Theatre.UI.Notification.CannotMoveOwner"), true); return; } else if (!remote && (!this.isPlayerOwned(insert1.imgId) || !this.isPlayerOwned(insert2.imgId))) { - info(game.i18n.localize("Theatre.UI.Notification.CannotMoveControlled"), true); + Logger.info(game.i18n.localize("Theatre.UI.Notification.CannotMoveControlled"), true); return; } @@ -4222,13 +4155,13 @@ export class Theatre { // permission check if (!remote && !this.isActorOwner(game.user.id, insert.imgId)) { - info(game.i18n.localize("Theatre.UI.Notification.DoNotControl"), true); + Logger.info(game.i18n.localize("Theatre.UI.Notification.DoNotControl"), true); return; } else if (!remote && (isLeft ? !this.isPlayerOwned(firstInsert.imgId) : !this.isPlayerOwned(lastInsert.imgId))) { if (isLeft) { - info(game.i18n.localize("Theatre.UI.Notification.CannotPushFront"), true); + Logger.info(game.i18n.localize("Theatre.UI.Notification.CannotPushFront"), true); } else { - info(game.i18n.localize("Theatre.UI.Notification.CannotPushBack"), true); + Logger.info(game.i18n.localize("Theatre.UI.Notification.CannotPushBack"), true); } return; } @@ -4307,7 +4240,7 @@ export class Theatre { _mirrorInsert(insert, remote) { // permission check if (!remote && !this.isActorOwner(game.user.id, insert.imgId)) { - info(game.i18n.localize("Theatre.UI.Notification.DoNotControl"), true); + Logger.info(game.i18n.localize("Theatre.UI.Notification.DoNotControl"), true); return; } @@ -4388,7 +4321,7 @@ export class Theatre { _resetPortraitPosition(insert, remote) { // permission check if (!remote && !this.isActorOwner(game.user.id, insert.imgId)) { - info(game.i18n.localize("Theatre.UI.Notification.DoNotControl"), true); + Logger.info(game.i18n.localize("Theatre.UI.Notification.DoNotControl"), true); return; } @@ -4402,7 +4335,7 @@ export class Theatre { ease: Power3.easeOut, onComplete: function (ctx, imgId, tweenId) { // decrement the rendering accumulator - debug("portrait move onComplete %s", tweenId); + Logger.debug("portrait move onComplete %s", tweenId); ctx._removeDockTween(imgId, this, tweenId); }, onCompleteParams: [this, insert.imgId, tweenId], @@ -4440,10 +4373,10 @@ export class Theatre { let resTarget = resMap.find((e) => e.name == tweenParams[0].resName); let texture = await PIXI.Assets.load(resTarget.path); - debug("Adding tweens for animation '%s' from syntax: %s with params: ", animName, animSyntax, tweenParams); - // debug("Resource path is %s, resource: ", resTarget.path, resource); + Logger.debug("Adding tweens for animation '%s' from syntax: %s with params: ", animName, animSyntax, tweenParams); + // Logger.debug("Resource path is %s, resource: ", resTarget.path, resource); if (!texture) { - error( + Logger.error( 'ERROR: resource name : "%s" with path "%s" does not exist!', false, tweenParams[idx].resName, @@ -4469,7 +4402,7 @@ export class Theatre { let yoyoEase = null; let noMirror = false; // Not Implemented if (advOptions) { - debug("adv options arg: ", advOptions); + Logger.debug("adv options arg: ", advOptions); yoyo = advOptions.yoyo ? true : false; noMirror = advOptions.noMirror ? true : false; delay = advOptions.delay ? Number(advOptions.delay) : delay; @@ -4501,7 +4434,7 @@ export class Theatre { prop.final = Number(prop.final.match(/-*\d+\.*\d*/)[0] || 0); } - debug( + Logger.debug( "new %s : %s,%s : w:%s,h:%s", prop.name, prop.initial, @@ -4539,10 +4472,10 @@ export class Theatre { yoyo: yoyo, yoyoEase: yoyoEase, /*onRepeat: function() { - debug("ANIMATION tween is repeating!",this); + Logger.debug("ANIMATION tween is repeating!",this); }, */ onComplete: function (ctx, imgId, tweenId) { - debug("ANIMATION tween complete!"); + Logger.debug("ANIMATION tween complete!"); // decrement the rendering accumulator ctx._removeDockTween(imgId, this, tweenId); // remove our own reference from the dockContainer tweens @@ -4572,7 +4505,7 @@ export class Theatre { * @private */ _getInitialEmotionSetFromInsertParams(params, useDefault) { - debug("use default? %s", !useDefault); + Logger.debug("use default? %s", !useDefault); let emotions = { emote: (!useDefault && params.settings.emote ? params.settings.emote : null) || @@ -4644,7 +4577,7 @@ export class Theatre { let params = this._getInsertParamsFromActorId(actorId); - debug(" set as active"); + Logger.debug(" set as active"); // set as user active // If the insert does not exist in the dock, add it, // If it does, then simply toggle it as active if it isn't already @@ -4725,16 +4658,22 @@ export class Theatre { let emotions; // determine if to launch with actor saves or default settings - if (ev && ev.altKey) emotions = Theatre.instance._getInitialEmotionSetFromInsertParams(params, true); - else emotions = Theatre.instance._getInitialEmotionSetFromInsertParams(params); - - debug("ACTIVATING AND INJECTING with Emotions: ", emotions); + if (ev && ev.altKey) { + emotions = Theatre.instance._getInitialEmotionSetFromInsertParams(params, true); + } else { + emotions = Theatre.instance._getInitialEmotionSetFromInsertParams(params); + } + Logger.debug("ACTIVATING AND INJECTING with Emotions: ", emotions); if (ev && !ev.shiftKey) { - if (game.user.isGM) await this.injectLeftPortrait(src, name, id, optAlign, emotions); - else await this.injectRightPortrait(src, name, id, optAlign, emotions); - } else await this.injectRightPortrait(src, name, id, optAlign, emotions); - + if (game.user.isGM) { + await this.injectLeftPortrait(src, name, id, optAlign, emotions); + } else { + await this.injectRightPortrait(src, name, id, optAlign, emotions); + } + } else { + await this.injectRightPortrait(src, name, id, optAlign, emotions); + } this.speakingAs = id; KHelpers.addClass(navItem, "theatre-control-nav-bar-item-speakingas"); TweenMax.to(Theatre.instance.theatreNavBar, 0.4, { @@ -4794,7 +4733,7 @@ export class Theatre { if (!textBox || !insert) return; if (!remote && !this.isActorOwner(game.user.id, theatreId)) { - info(game.i18n.localize("Theatre.UI.Notification.DoNotControl"), true); + Logger.info(game.i18n.localize("Theatre.UI.Notification.DoNotControl"), true); return; } // clear last speaking if present @@ -4856,19 +4795,30 @@ export class Theatre { green = Math.min(green + 75, 255); blue = Math.min(blue + 75, 255); - debug("color %s : red: %s:%s, green %s:%s, blue %s:%s", color, red, darkred, green, darkgreen, blue, darkblue); + Logger.debug( + "color %s : red: %s:%s, green %s:%s, blue %s:%s", + color, + red, + darkred, + green, + darkgreen, + blue, + darkblue + ); // style specific settings switch (this.settings.theatreStyle) { - case "clearbox": + case "clearbox": { textBox.style.cssText += `background: linear-gradient(transparent 0%, rgba(${red},${green},${blue},0.30) 40%, rgba(${red},${green},${blue},0.30) 60%, transparent 100%); box-shadow: 0px 5px 2px 1px rgba(${darkred}, ${darkgreen}, ${darkblue}, 0.30)`; break; + } case "mangabubble": case "lightbox": case "textbox": - default: + default: { textBox.style.cssText += `background: linear-gradient(transparent 0%, rgba(${red},${green},${blue},0.10) 40%, rgba(${red},${green},${blue},0.10) 60%, transparent 100%); box-shadow: 0px 5px 2px 1px rgba(${darkred}, ${darkgreen}, ${darkblue}, .2)`; break; + } } } @@ -4899,7 +4849,7 @@ export class Theatre { green = green.toString(16); blue = blue.toString(16); - debug(`#${red}${green}${blue}`); + Logger.debug(`#${red}${green}${blue}`); return `#${red}${green}${blue}`; } @@ -4926,7 +4876,7 @@ export class Theatre { if (active) { // spawn it let narratorBackdrop = Theatre.instance.theatreNarrator.getElementsByClassName("theatre-narrator-backdrop")[0]; - debug("NarratorBackdrop ", narratorBackdrop, Theatre.instance.theatreNarrator); + Logger.debug("NarratorBackdrop ", narratorBackdrop, Theatre.instance.theatreNarrator); narratorBackdrop.style.width = "100%"; Theatre.instance.theatreNarrator.style.opacity = "1"; Theatre.instance.isNarratorActive = true; @@ -5016,7 +4966,7 @@ export class Theatre { // remove it let narratorBackdrop = Theatre.instance.theatreNarrator.getElementsByClassName("theatre-narrator-backdrop")[0]; let narratorContent = Theatre.instance.theatreNarrator.getElementsByClassName("theatre-narrator-content")[0]; - debug("NarratorBackdrop ", narratorBackdrop, Theatre.instance.theatreNarrator); + Logger.debug("NarratorBackdrop ", narratorBackdrop, Theatre.instance.theatreNarrator); narratorBackdrop.style.width = "0%"; Theatre.instance.theatreNarrator.style.opacity = "0"; Theatre.instance.isNarratorActive = false; @@ -5030,7 +4980,7 @@ export class Theatre { narratorContent.style["overflow-y"] = "scroll"; narratorContent.style["overflow-x"] = "hidden"; - // debug("all tweens", TweenMax.getAllTweens()); + // Logger.debug("all tweens", TweenMax.getAllTweens()); narratorContent.textContent = ""; if (game.user.isGM) { @@ -5073,19 +5023,19 @@ export class Theatre { textStanding, fonts, }).then((template) => { - debug("emote window template rendered"); + Logger.debug("emote window template rendered"); Theatre.instance.theatreEmoteMenu.style.top = `${Theatre.instance.theatreControls.offsetTop - 410}px`; Theatre.instance.theatreEmoteMenu.innerHTML = template; let wheelFunc = function (ev) { - //debug("wheel on text-box",ev.currentTarget.scrollTop,ev.deltaY,ev.deltaMode); + //Logger.debug("wheel on text-box",ev.currentTarget.scrollTop,ev.deltaY,ev.deltaMode); let pos = ev.deltaY > 0; ev.currentTarget.scrollTop += pos ? 10 : -10; ev.preventDefault(); ev.stopPropagation(); }; let wheelFunc2 = function (ev) { - //debug("wheel on text-anim",ev.currentTarget.parentNode.scrollTop,ev.deltaY,ev.deltaMode); + //Logger.debug("wheel on text-anim",ev.currentTarget.parentNode.scrollTop,ev.deltaY,ev.deltaMode); let pos = ev.deltaY > 0; ev.currentTarget.parentNode.scrollTop += pos ? 10 : -10; ev.preventDefault(); @@ -5096,7 +5046,7 @@ export class Theatre { let sizeSelect = Theatre.instance.theatreEmoteMenu.getElementsByClassName("sizeselect")[0]; let colorSelect = Theatre.instance.theatreEmoteMenu.getElementsByClassName("colorselect")[0]; let fontSelect = Theatre.instance.theatreEmoteMenu.getElementsByClassName("fontselect")[0]; - //debug("Selectors found: ",sizeSelect,colorSelect,fontSelect); + //Logger.debug("Selectors found: ",sizeSelect,colorSelect,fontSelect); // assign font from insert if (insert && insert.textFont) { @@ -5201,7 +5151,7 @@ export class Theatre { child.addEventListener("mouseover", (ev) => { let text = ev.currentTarget.getAttribute("otext"); let anim = ev.currentTarget.getAttribute("name"); - //debug("child text: ",text,ev.currentTarget); + //Logger.debug("child text: ",text,ev.currentTarget); ev.currentTarget.textContent = ""; let charSpans = Theatre.splitTextBoxToChars(text, ev.currentTarget); textFlyin[anim].func.call(this, charSpans, 0.5, 0.05, null); @@ -5215,7 +5165,7 @@ export class Theatre { TweenMax.killTweensOf(child); child.style["overflow-y"] = "scroll"; child.style["overflow-x"] = "hidden"; - //debug("all tweens",TweenMax.getAllTweens()); + //Logger.debug("all tweens",TweenMax.getAllTweens()); ev.currentTarget.textContent = ev.currentTarget.getAttribute("otext"); }); // bind text anim type @@ -5278,7 +5228,7 @@ export class Theatre { child.addEventListener("mouseover", (ev) => { let text = ev.currentTarget.getAttribute("otext"); let anim = ev.currentTarget.getAttribute("name"); - //debug("child text: ",text,ev.currentTarget); + //Logger.debug("child text: ",text,ev.currentTarget); ev.currentTarget.textContent = ""; let charSpans = Theatre.splitTextBoxToChars(text, ev.currentTarget); textFlyin["typewriter"].func.call( @@ -5298,7 +5248,7 @@ export class Theatre { TweenMax.killTweensOf(child); child.style["overflow-y"] = "scroll"; child.style["overflow-x"] = "hidden"; - //debug("all tweens",TweenMax.getAllTweens()); + //Logger.debug("all tweens",TweenMax.getAllTweens()); ev.currentTarget.textContent = ev.currentTarget.getAttribute("otext"); }); // bind text anim type @@ -5370,7 +5320,7 @@ export class Theatre { child.addEventListener("mouseup", (ev) => { if (ev.button == 0) { let emName = ev.currentTarget.getAttribute("name"); - debug("em name: %s was clicked", emName); + Logger.debug("em name: %s was clicked", emName); if (KHelpers.hasClass(ev.currentTarget, "emote-active")) { KHelpers.removeClass(ev.currentTarget, "emote-active"); // if speaking set to base @@ -5504,7 +5454,7 @@ export class Theatre { * @param ev (Event) : The Event that triggered this handler */ handleBtnEmoteClick(ev) { - debug("emote click"); + Logger.debug("emote click"); if (KHelpers.hasClass(ev.currentTarget, "theatre-control-btn-down")) { Theatre.instance.theatreEmoteMenu.style.display = "none"; @@ -5561,12 +5511,16 @@ export class Theatre { !ev.repeat && //&& Theatre.instance.speakingAs ev.key == "Control" - ) + ) { KHelpers.addClass(Theatre.instance.theatreChatCover, "theatre-control-chat-cover-ooc"); - - if (now - Theatre.instance.lastTyping < 3000) return; - if (ev.key == "Enter" || ev.key == "Alt" || ev.key == "Shift" || ev.key == "Control") return; - debug("keydown in chat-message"); + } + if (now - Theatre.instance.lastTyping < 3000) { + return; + } + if (ev.key == "Enter" || ev.key == "Alt" || ev.key == "Shift" || ev.key == "Control") { + return; + } + Logger.debug("keydown in chat-message"); Theatre.instance.lastTyping = now; Theatre.instance.setUserTyping(game.user.id, Theatre.instance.speakingAs); Theatre.instance._sendTypingEvent(); @@ -5584,7 +5538,7 @@ export class Theatre { * @param ev (Event) : The Event that triggered this handler */ handleBtnNarratorClick(ev) { - debug("narrator click"); + Logger.debug("narrator click"); if (KHelpers.hasClass(ev.currentTarget, "theatre-control-nav-bar-item-speakingas")) { Theatre.instance.toggleNarratorBar(false); @@ -5599,14 +5553,14 @@ export class Theatre { * @param ev (Event) : The Event that triggered this handler */ handleBtnCinemaClick(ev) { - debug("cinema click"); - info(game.i18n.localize("Theatre.NotYet"), true); + Logger.debug("cinema click"); + Logger.info(game.i18n.localize("Theatre.NotYet"), true); /* if (KHelpers.hasClass(ev.currentTarget,"theatre-control-small-btn-down")) { KHelpers.removeClass(ev.currentTarget,"theatre-control-small-btn-down"); } else { KHelpers.addClass(ev.currentTarget,"theatre-control-small-btn-down"); - info(game.i18n.localize("Theatre.NotYet"), true); + Logger.info(game.i18n.localize("Theatre.NotYet"), true); } */ } @@ -5617,15 +5571,17 @@ export class Theatre { * @param ev (Event) : The Event that triggered this handler */ handleBtnDelayEmoteClick(ev) { - debug("delay emote click"); + Logger.debug("delay emote click"); if (Theatre.instance.isDelayEmote) { - if (KHelpers.hasClass(ev.currentTarget, "theatre-control-small-btn-down")) + if (KHelpers.hasClass(ev.currentTarget, "theatre-control-small-btn-down")) { KHelpers.removeClass(ev.currentTarget, "theatre-control-small-btn-down"); + } Theatre.instance.isDelayEmote = false; } else { - if (!KHelpers.hasClass(ev.currentTarget, "theatre-control-small-btn-down")) + if (!KHelpers.hasClass(ev.currentTarget, "theatre-control-small-btn-down")) { KHelpers.addClass(ev.currentTarget, "theatre-control-small-btn-down"); + } Theatre.instance.isDelayEmote = true; } // push focus to chat-message @@ -5639,7 +5595,7 @@ export class Theatre { * @param ev (Event) : The Event that triggered this handler */ handleBtnQuoteClick(ev) { - debug("quote click"); + Logger.debug("quote click"); if (Theatre.instance.isQuoteAuto) { if (KHelpers.hasClass(ev.currentTarget, "theatre-control-small-btn-down")) @@ -5661,10 +5617,10 @@ export class Theatre { * @param ev (Event) : The Event that triggered this handler */ handleBtnResyncClick(ev) { - debug("resync click"); + Logger.debug("resync click"); if (game.user.isGM) { Theatre.instance._sendResyncRequest("players"); - info(game.i18n.localize("Theatre.UI.Notification.ResyncGM"), true); + Logger.info(game.i18n.localize("Theatre.UI.Notification.ResyncGM"), true); } else { Theatre.instance._sendResyncRequest("gm"); } @@ -5676,7 +5632,7 @@ export class Theatre { * @param ev (Event) : The Event that triggered this handler */ handleBtnSuppressClick(ev) { - debug("suppression click"); + Logger.debug("suppression click"); if (Theatre.instance.isSuppressed) { if (KHelpers.hasClass(ev.currentTarget, "theatre-control-btn-down")) { KHelpers.removeClass(ev.currentTarget, "theatre-control-btn-down"); @@ -5734,7 +5690,7 @@ export class Theatre { * @param ev (Event) : The Event that triggered this handler */ handleTextBoxMouseDoubleClick(ev) { - debug("MOUSE DOUBLE CLICK"); + Logger.debug("MOUSE DOUBLE CLICK"); let id = ev.currentTarget.getAttribute("imgId"); Theatre.instance.resetInsertById(id); } @@ -5746,7 +5702,7 @@ export class Theatre { */ handleWindowMouseUp(ev) { // finish moving insert - debug("WINDOW MOUSE UP"); + Logger.debug("WINDOW MOUSE UP"); let x = ev.clientX || ev.pageX; let y = ev.clientY || ev.pageY; @@ -5766,7 +5722,7 @@ export class Theatre { if (dy > box.maxtop) dy = box.maxtop; if (dy < box.mintop) dy = box.mintop; - debug( + Logger.debug( "WINDOW MOUSE UP FINAL x: " + x + " y: " + @@ -5789,7 +5745,7 @@ export class Theatre { //insert.portraitContainer.x = dx; //insert.portraitContainer.y = dy; if (!insert.dockContainer || !insert.portraitContainer) { - error("ERROR: insert dockContainer or portrait is INVALID"); + Logger.error("ERROR: insert dockContainer or portrait is INVALID"); window.removeEventListener("mouseup", Theatre.instance.handleWindowMouseUp); return; } @@ -5826,14 +5782,14 @@ export class Theatre { * @param ev (Event) : The Event that triggered this handler */ handleTextBoxMouseDown(ev) { - debug("MOUSE DOWN ", ev.buttons, ev.button); + Logger.debug("MOUSE DOWN ", ev.buttons, ev.button); let id = ev.currentTarget.getAttribute("imgId"); if (ev.button == 0) { if (!ev.ctrlKey && !ev.shiftKey && !ev.altKey) { // if old dragPoint exists reset the style, and clear any interval that may exist if (!!Theatre.instance.dragPoint && !!Theatre.instance.dragPoint.insert) { - warn("PREXISTING DRAGPOINT!", false); + Logger.warn("PREXISTING DRAGPOINT!", false); //Theatre.instance.dragPoint.port.style.transition = "top 0.5s ease, left 0.5s ease, transform 0.5s ease"; } // calculate bouding box @@ -5842,7 +5798,7 @@ export class Theatre { // permission check if (!Theatre.instance.isActorOwner(game.user.id, insert.imgId)) { - info(game.i18n.localize("Theatre.UI.Notification.DoNotControl"), true); + Logger.info(game.i18n.localize("Theatre.UI.Notification.DoNotControl"), true); return; } @@ -5860,7 +5816,7 @@ export class Theatre { let origX = insert.portraitContainer.x; let origY = insert.portraitContainer.y; - debug("STORING DRAG POINT", ev.clientX || ev.pageX, ev.clientY || ev.PageY, boundingBox, origX, origY); + Logger.debug("STORING DRAG POINT", ev.clientX || ev.pageX, ev.clientY || ev.PageY, boundingBox, origX, origY); // change the transition style while we're dragging //port.style.transition = "top 0.5s ease, left 0.5s ease, transform 0.5s ease"; @@ -5891,7 +5847,7 @@ export class Theatre { * @param ev (Event) : The Event that triggered this handler */ handleTextBoxMouseUp(ev) { - debug("MOUSE UP ", ev.buttons, ev.button); + Logger.debug("MOUSE UP ", ev.buttons, ev.button); let id = ev.currentTarget.getAttribute("imgId"); let chatMessage = document.getElementById("chat-message"); if (ev.button == 0) { @@ -5994,13 +5950,13 @@ export class Theatre { let actorId = id.replace(CONSTANTS.PREFIX_ACTOR_ID, ""); let params = Theatre.instance._getInsertParamsFromActorId(actorId); if (!params) { - error("ERROR, actorId %s does not exist!", true, actorId); + Logger.error("ERROR, actorId %s does not exist!", true, actorId); // remove the nav Item ev.currentTarget.parentNode.removeChild(ev.currentTarget); return; } - debug("Button UP on nav add?", ev.button); + Logger.debug("Button UP on nav add?", ev.button); switch (ev.button) { case 0: diff --git a/src/scripts/TheatreActorConfig.js b/src/scripts/TheatreActorConfig.js index 5925cde..708aaac 100644 --- a/src/scripts/TheatreActorConfig.js +++ b/src/scripts/TheatreActorConfig.js @@ -21,7 +21,7 @@ import KHelpers from "./KHelpers.js"; import { Theatre } from "./Theatre.js"; import CONSTANTS from "./constants/constants.js"; -import { debug, error, info } from "./lib/lib.js"; +import Logger from "./lib/Logger.js"; /** * ============================================================ @@ -142,15 +142,15 @@ export class TheatreActorConfig extends FormApplication { let labelPath = mch + ".label"; let cflagPath = mch + ".custom"; let namePath = mch + ".name"; - debug("found %s", k, mch, cflagPath, namePath); + Logger.debug("found %s", k, mch, cflagPath, namePath); // if label is both the formData as well as the object, reject the submission let emoteProp = getProperty(this.object, mch); let labelProp = null; if (emoteProp) labelProp = getProperty(this.object, labelPath); if ((!labelProp || labelProp == "") && (!formData[labelPath] || formData[labelPath] == "")) { - error("ERROR: No label for custom emote defined!", true); - error(game.i18n.localize("Theatre.UI.Notification.BadCustomEmote"), true); + Logger.error("ERROR: No label for custom emote defined!", true); + Logger.error(game.i18n.localize("Theatre.UI.Notification.BadCustomEmote"), true); return false; } @@ -220,7 +220,7 @@ export class TheatreActorConfig extends FormApplication { formData["_id"] = this.object._id; // if our baseinsert value was updated.. - debug(formData); + Logger.debug(formData); let insertDirty = false; let baseInsert = formData["flags.theatre.baseinsert"]; let optAlign = formData["flags.theatre.optalign"]; @@ -236,7 +236,7 @@ export class TheatreActorConfig extends FormApplication { let cImg = Theatre.instance.getTheatreCoverPortrait(); if (baseInsert != this.object.flags.theatre.baseinsert) { - debug("baseinsert changed!"); + Logger.debug("baseinsert changed!"); insertDirty = true; newBaseInsert = baseInsert == "" ? (this.object.img ? this.object.img : CONSTANTS.DEFAULT_PORTRAIT) : baseInsert; if (navItem) { @@ -245,13 +245,13 @@ export class TheatreActorConfig extends FormApplication { } } if (optAlign != this.object.flags.theatre.optalign) { - debug("optalign changed!"); + Logger.debug("optalign changed!"); insertDirty = true; newAlign = optAlign == "" ? "top" : optAlign; if (navItem) navItem.setAttribute("optalign", newAlign); } if (name != this.object.flags.theatre.name) { - debug("name changed!"); + Logger.debug("name changed!"); insertDirty = true; newName = name == "" ? this.object.name : name; if (navItem) { @@ -266,7 +266,7 @@ export class TheatreActorConfig extends FormApplication { if (!resForms) { return; } - debug("Form data AFTER verification: ", resForms); + Logger.debug("Form data AFTER verification: ", resForms); let revisedFormData = resForms.revisedFormData; let emoteFormData = resForms.emoteFormData; @@ -308,8 +308,8 @@ export class TheatreActorConfig extends FormApplication { // ensure resource exists if (!(await srcExists(resName))) { - error("ERROR: Path %s does not exist!", true, resName); - error(game.i18n.localize("Theatre.UI.Notification.BadFilepath") + `"${resName}"`, true); + Logger.error("ERROR: Path %s does not exist!", true, resName); + Logger.error(game.i18n.localize("Theatre.UI.Notification.BadFilepath") + `"${resName}"`, true); return; } @@ -329,13 +329,13 @@ export class TheatreActorConfig extends FormApplication { } // send the emote parent in bulk to get rid of unwanted children revisedFormData["flags.theatre.emotes"] = nEmotes; - debug("Final Push Config update:", revisedFormData); + Logger.debug("Final Push Config update:", revisedFormData); this.object.update(revisedFormData).then((response) => { // perform texture updates if needed if (imgSrcs.length > 0) { // we know the active emote, thus all we need is the new source image - debug("sending imgSrcs for replaceAllTextures", imgSrcs); + Logger.debug("sending imgSrcs for replaceAllTextures", imgSrcs); Theatre.instance._AddAllTextureResources( imgSrcs, theatreId, @@ -343,10 +343,10 @@ export class TheatreActorConfig extends FormApplication { newSrcImg, (loader, resources) => { // if our emote is active and we're replacing the emote texture, or base is active, and we're replacing the base texture - debug("texture additions complete! ", newSrcImg, insertEmote); + Logger.debug("texture additions complete! ", newSrcImg, insertEmote); if (app && container && newSrcImg) { - debug("RE-RENDERING with NEW texture resource %s ", newSrcImg); + Logger.debug("RE-RENDERING with NEW texture resource %s ", newSrcImg); let resName = CONSTANTS.DEFAULT_PORTRAIT; if ( @@ -386,7 +386,7 @@ export class TheatreActorConfig extends FormApplication { // if the insert is dirty, clear and setup if (insertDirty && insert) { - debug("Insert is dirty, re-render it!"); + Logger.debug("Insert is dirty, re-render it!"); let resName = CONSTANTS.DEFAULT_PORTRAIT; if ( insert.emote && @@ -437,8 +437,8 @@ export class TheatreActorConfig extends FormApplication { * @private */ _onAddEmoteLine(ev) { - debug("Add Emote Pressed!"); - //info(game.i18n.localize("Theatre.NotYet"), true); + Logger.debug("Add Emote Pressed!"); + //Logger.info(game.i18n.localize("Theatre.NotYet"), true); // We need to get a custom emote name for storage purposes, this is a running index from // 1-> MAXINT oh which the upper bound we don't account for, to get the correct custom @@ -678,7 +678,7 @@ export class TheatreActorConfig extends FormApplication { * @private */ _onUndoDockDelete(ev) { - debug("undo delete!"); + Logger.debug("undo delete!"); ev.stopPropagation(); ev.currentTarget.removeAttribute("todelete"); ev.currentTarget.style.left = "0"; @@ -709,7 +709,7 @@ export class TheatreActorConfig extends FormApplication { * @private */ _onEditEmoteLine(ev) { - debug("Emote config pressed for %s!", ev.currentTarget.getAttribute("name")); - info(game.i18n.localize("Theatre.NotYet"), true); + Logger.debug("Emote config pressed for %s!", ev.currentTarget.getAttribute("name")); + Logger.info(game.i18n.localize("Theatre.NotYet"), true); } } diff --git a/src/scripts/lib/Logger.js b/src/scripts/lib/Logger.js new file mode 100644 index 0000000..552699c --- /dev/null +++ b/src/scripts/lib/Logger.js @@ -0,0 +1,123 @@ +import CONSTANTS from "../constants/constants"; + +// ================================ +// Logger utility +// ================================ +export default class Logger { + static get DEBUG() { + return ( + game.settings.get(CONSTANTS.MODULE_ID, "debug") || + game.modules.get("_dev-mode")?.api?.getPackageDebugValue(CONSTANTS.MODULE_ID, "boolean") + ); + } + // export let debugEnabled = 0; + // 0 = none, warnings = 1, debug = 2, all = 3 + + static debug(msg, ...args) { + try { + if ( + game.settings.get(CONSTANTS.MODULE_ID, "debug") || + game.modules.get("_dev-mode")?.api?.getPackageDebugValue(CONSTANTS.MODULE_ID, "boolean") + ) { + console.log(`DEBUG | ${CONSTANTS.MODULE_ID} | ${msg}`, ...args); + } + } catch (e) { + console.error(e.message); + } + return msg; + } + + static logObject(...args) { + return this.log("", args); + } + + static log(message, ...args) { + try { + message = `${CONSTANTS.MODULE_ID} | ${message}`; + console.log(message.replace("
", "\n"), ...args); + } catch (e) { + console.error(e.message); + } + return message; + } + + static notify(message, ...args) { + try { + message = `${CONSTANTS.MODULE_ID} | ${message}`; + ui.notifications?.notify(message); + console.log(message.replace("
", "\n"), ...args); + } catch (e) { + console.error(e.message); + } + return message; + } + + static info(info, notify = false, ...args) { + try { + info = `${CONSTANTS.MODULE_ID} | ${info}`; + if (notify) { + ui.notifications?.info(info); + } + console.log(info.replace("
", "\n"), ...args); + } catch (e) { + console.error(e.message); + } + return info; + } + + static warn(warning, notify = false, ...args) { + try { + warning = `${CONSTANTS.MODULE_ID} | ${warning}`; + if (notify) { + ui.notifications?.warn(warning); + } + console.warn(warning.replace("
", "\n"), ...args); + } catch (e) { + console.error(e.message); + } + return warning; + } + + static errorObject(...args) { + return this.error("", false, args); + } + + static error(error, notify = true, ...args) { + try { + error = `${CONSTANTS.MODULE_ID} | ${error}`; + if (notify) { + ui.notifications?.error(error); + } + console.error(error.replace("
", "\n"), ...args); + } catch (e) { + console.error(e.message); + } + return new Error(error.replace("
", "\n")); + } + + static timelog(message) { + this.warn(Date.now(), message); + } + + static i18n = (key) => { + return game.i18n.localize(key)?.trim(); + }; + + static i18nFormat = (key, data = {}) => { + return game.i18n.format(key, data)?.trim(); + }; + + // setDebugLevel = (debugText): void => { + // debugEnabled = { none: 0, warn: 1, debug: 2, all: 3 }[debugText] || 0; + // // 0 = none, warnings = 1, debug = 2, all = 3 + // if (debugEnabled >= 3) CONFIG.debug.hooks = true; + // }; + + static dialogWarning(message, icon = "fas fa-exclamation-triangle") { + return `

+

+ ${CONSTANTS.MODULE_ID} +

${message} +

`; + } +} diff --git a/src/scripts/lib/lib.js b/src/scripts/lib/lib.js index 28a9566..3b39b99 100644 --- a/src/scripts/lib/lib.js +++ b/src/scripts/lib/lib.js @@ -1,112 +1,5 @@ import CONSTANTS from "../constants/constants.js"; -// ================================= -// Logger Utility -// ================================ - -// export let debugEnabled = 0; -// 0 = none, warnings = 1, debug = 2, all = 3 - -export function debug(msg, ...args) { - try { - if ( - game.settings.get(CONSTANTS.MODULE_ID, "debug") || - game.modules.get("_dev-mode")?.api?.getPackageDebugValue(CONSTANTS.MODULE_ID, "boolean") - ) { - console.log(`DEBUG | ${CONSTANTS.MODULE_ID} | ${msg}`, ...args); - } - } catch (e) { - console.error(e.message); - } - return msg; -} - -export function log(message, ...args) { - try { - message = `${CONSTANTS.MODULE_ID} | ${message}`; - console.log(message.replace("
", "\n"), ...args); - } catch (e) { - console.error(e.message); - } - return message; -} - -export function notify(message, ...args) { - try { - message = `${CONSTANTS.MODULE_ID} | ${message}`; - ui.notifications?.notify(message); - console.log(message.replace("
", "\n"), ...args); - } catch (e) { - console.error(e.message); - } - return message; -} - -export function info(info, notify = false, ...args) { - try { - info = `${CONSTANTS.MODULE_ID} | ${info}`; - if (notify) { - ui.notifications?.info(info); - } - console.log(info.replace("
", "\n"), ...args); - } catch (e) { - console.error(e.message); - } - return info; -} - -export function warn(warning, notify = false, ...args) { - try { - warning = `${CONSTANTS.MODULE_ID} | ${warning}`; - if (notify) { - ui.notifications?.warn(warning); - } - console.warn(warning.replace("
", "\n"), ...args); - } catch (e) { - console.error(e.message); - } - return warning; -} - -export function error(error, notify = true, ...args) { - try { - error = `${CONSTANTS.MODULE_ID} | ${error}`; - if (notify) { - ui.notifications?.error(error); - } - console.error(error.replace("
", "\n"), ...args); - } catch (e) { - console.error(e.message); - } - return new Error(error.replace("
", "\n")); -} - -export function timelog(message) { - warn(Date.now(), message); -} - -export const i18n = (key) => { - return game.i18n.localize(key)?.trim(); -}; - -export const i18nFormat = (key, data = {}) => { - return game.i18n.format(key, data)?.trim(); -}; - -// export const setDebugLevel = (debugText): void => { -// debugEnabled = { none: 0, warn: 1, debug: 2, all: 3 }[debugText] || 0; -// // 0 = none, warnings = 1, debug = 2, all = 3 -// if (debugEnabled >= 3) CONFIG.debug.hooks = true; -// }; - -export function dialogWarning(message, icon = "fas fa-exclamation-triangle") { - return `

-

- ${CONSTANTS.MODULE_ID} -

${message} -

`; -} - // ================================================================================ export function isEmptyObject(obj) { diff --git a/src/scripts/settings.js b/src/scripts/settings.js index e27b925..c4700a2 100644 --- a/src/scripts/settings.js +++ b/src/scripts/settings.js @@ -1,5 +1,6 @@ import { Theatre } from "./Theatre.js"; import CONSTANTS from "./constants/constants.js"; +import Logger from "./lib/Logger.js"; export const registerSettings = function () { let settingsCustom = {}; @@ -103,15 +104,15 @@ export const registerSettings = function () { default: 30, type: Number, onChange: (textDecayMin) => { - debug("Text decay minimum set to %s", textDecayMin); + Logger.debug("Text decay minimum set to %s", textDecayMin); textDecayMin = Number(textDecayMin); if (isNaN(textDecayMin) || textDecayMin <= 0) { - info(game.i18n.localize("Theatre.UI.Notification.InvalidDecayMin"), true); + Logger.info(game.i18n.localize("Theatre.UI.Notification.InvalidDecayMin"), true); game.settings.set(CONSTANTS.MODULE_ID, "textDecayMin", 30); return; } if (textDecayMin > 600) { - info(game.i18n.localize("Theatre.UI.Notification.TooLongDecayMin"), true); + Logger.info(game.i18n.localize("Theatre.UI.Notification.TooLongDecayMin"), true); game.settings.set(CONSTANTS.MODULE_ID, "textDecayMin", 600); return; } @@ -128,17 +129,17 @@ export const registerSettings = function () { default: 1, type: Number, onChange: (textDecayRate) => { - debug("Text decay rate set to %s", textDecayRate); + Logger.debug("Text decay rate set to %s", textDecayRate); textDecayRate = Number(textDecayRate); if (isNaN(textDecayRate) || textDecayRate <= 0) { textDecayRate = 1; - info(game.i18n.localize("Theatre.UI.Notification.InvalidDecayRate"), true); + Logger.info(game.i18n.localize("Theatre.UI.Notification.InvalidDecayRate"), true); game.settings.set(CONSTANTS.MODULE_ID, "textDecayRate", 1); return; } if (textDecayRate > 10) { textDecayRate = 10; - info(game.i18n.localize("Theatre.UI.Notification.TooLongDecayRate"), true); + Logger.info(game.i18n.localize("Theatre.UI.Notification.TooLongDecayRate"), true); game.settings.set(CONSTANTS.MODULE_ID, "textDecayRate", 10); return; } @@ -233,8 +234,8 @@ export const registerSettings = function () { }); game.settings.register(CONSTANTS.MODULE_ID, "debug", { - name: `Theatre.UI.debug.title`, - hint: `Theatre.UI.debug.hint`, + name: `Theatre.UI.Settings.debug`, + hint: `Theatre.UI.Settings.debugHint`, scope: "client", config: true, default: false, diff --git a/src/scripts/socket.js b/src/scripts/socket.js index e05f3fd..be1e4bd 100644 --- a/src/scripts/socket.js +++ b/src/scripts/socket.js @@ -1,11 +1,11 @@ import API from "./API/api.js"; import CONSTANTS from "./constants/constants.js"; -import { debug } from "./lib/lib.js"; +import Logger from "./lib/Logger.js"; export let theatreSocket; export function registerSocket() { - debug("Registered theatreSocket"); + Logger.debug("Registered theatreSocket"); if (theatreSocket) { return theatreSocket; } diff --git a/src/scripts/theatre-helpers.js b/src/scripts/theatre-helpers.js index 6aa4646..510b859 100644 --- a/src/scripts/theatre-helpers.js +++ b/src/scripts/theatre-helpers.js @@ -3,7 +3,7 @@ import { Theatre } from "./Theatre.js"; import { TheatreActor } from "./TheatreActor.js"; import { TheatreActorConfig } from "./TheatreActorConfig.js"; import CONSTANTS from "./constants/constants.js"; -import { debug, error, info, log, warn } from "./lib/lib.js"; +import Logger from "./lib/Logger.js"; export class TheatreHelpers { /** @@ -20,7 +20,7 @@ export class TheatreHelpers { let containerWidth = Theatre.instance.theatreDock.offsetWidth; // Min 22px, max 32px, scale for all values inbetween let fontSize = Math.floor(Math.max((Math.min(containerWidth / boxes.length, 500) / 500) * 28, 18)); - debug("Reorder CALCUALTED FONT SIZE: ", fontSize); + Logger.debug("Reorder CALCUALTED FONT SIZE: ", fontSize); for (let textBox of boxes) { let theatreId = textBox.getAttribute("imgid"); @@ -33,13 +33,13 @@ export class TheatreHelpers { // if somehow the containers are not setup, skip and hope the next re-order has them ready if (!insert.portrait || !insert.label) { - warn("WARN: %s : %s was not ready!", false, insert.name, insert.imgId); + Logger.warn("WARN: %s : %s was not ready!", false, insert.name, insert.imgId); continue; } // if the insert/textBox pair is in the process of being removed. if (textBox.getAttribute("deleting")) continue; - debug("repositioning %s :", theatreId, insert); + Logger.debug("repositioning %s :", theatreId, insert); let offset = KHelpers.offset(textBox); //left calc let leftPos = Math.round( @@ -51,7 +51,7 @@ export class TheatreHelpers { //insert.dockContainer.width = textBox.offsetWidth; if (insert.exitOrientation == "left") { - debug( + Logger.debug( "LEFT (name: %s): ", insert.nameOrientation, leftPos, @@ -59,11 +59,11 @@ export class TheatreHelpers { Theatre.instance.theatreBar.offsetWidth / 2 ); if (leftPos + insert.dockContainer.width / 2 > Theatre.instance.theatreBar.offsetWidth / 2) { - log("swapping " + insert.name + " to right alignment from left"); + Logger.log("swapping " + insert.name + " to right alignment from left"); insert.exitOrientation = "right"; } } else { - debug( + Logger.debug( "RIGHT (name: %s): ", insert.nameOrientation, leftPos, @@ -72,7 +72,7 @@ export class TheatreHelpers { ); //right if (leftPos + insert.dockContainer.width / 2 <= Theatre.instance.theatreBar.offsetWidth / 2) { - debug("swapping " + insert.name + " to left alignment from right"); + Logger.debug("swapping " + insert.name + " to left alignment from right"); insert.exitOrientation = "left"; } } @@ -392,7 +392,7 @@ export class TheatreHelpers { if (!str || typeof str != "string") { return null; } - debug("verifying syntax %s", str); + Logger.debug("verifying syntax %s", str); let tweenParams = []; try { @@ -420,7 +420,9 @@ export class TheatreHelpers { advOptions = {}; for (let advPart of advParts) { let components = advPart.split(":"); - if (components.length != 2) throw "component properties definition : " + advPart + " is incorrect"; + if (components.length !== 2) { + throw Logger.error("component properties definition : " + advPart + " is incorrect"); + } let advPropName = components[0].trim(); let advPropValue = components[1].trim(); advOptions[advPropName] = advPropValue; @@ -429,31 +431,38 @@ export class TheatreHelpers { targets = []; propDefs = []; - for (idx; idx < parts.length; ++idx) targets.push(parts[idx]); - + for (idx; idx < parts.length; ++idx) { + targets.push(parts[idx]); + } for (let target of targets) { let components = target.split(":"); - if (components.length != 2) throw "component properties definition : " + target + " is incorrect"; + if (components.length !== 2) { + throw Logger.error("component properties definition : " + target + " is incorrect"); + } let propName = components[0]; let scomps = components[1].split(","); - if (scomps.length != 2) throw "component properties definition : " + target + " is incorrect"; + if (scomps.length !== 2) { + throw Logger.error("component properties definition : " + target + " is incorrect"); + } let init = scomps[0]; let fin = scomps[1]; if (verifyTarget(propName, init, fin)) { let propDef = { name: propName, initial: init, final: fin }; propDefs.push(propDef); - } else throw "component properties definition : " + target + " is incorrect"; + } else { + throw Logger.error("component properties definition : " + target + " is incorrect"); + } } - debug("Animation Syntax breakdown of %s : ", sections[sdx], duration, advOptions, propDefs); + Logger.debug("Animation Syntax breakdown of %s : ", sections[sdx], duration, advOptions, propDefs); tweenParams.push({ resName: resName, duration: duration, advOptions: advOptions, props: propDefs }); } } catch (e) { - error("BAD ANIMATION SYNTAX: %s", true, e); + Logger.error("BAD ANIMATION SYNTAX: %s", true, e); return tweenParams; } - debug("tween params are valid with: ", tweenParams); + Logger.debug("tween params are valid with: ", tweenParams); return tweenParams; } @@ -2254,7 +2263,7 @@ export class TheatreHelpers { static onConfigureInsert(ev, actorSheet) { ev.preventDefault(); - debug("Click Event on Configure Theatre!!!", actorSheet, actorSheet.actor, actorSheet.position); + Logger.debug("Click Event on Configure Theatre!!!", actorSheet, actorSheet.actor, actorSheet.position); if (!actorSheet.actor.flags.theatre) { actorSheet.actor.flags.theatre = { baseinsert: "", name: "" }; @@ -2273,7 +2282,7 @@ export class TheatreHelpers { * @params ev (Event) : The event that triggered adding to the NavBar staging area. */ static onAddToNavBar(ev, actorSheet, removeLabelSheetHeader) { - debug("Click Event on Add to NavBar!!", actorSheet, actorSheet.actor, actorSheet.position); + Logger.debug("Click Event on Add to NavBar!!", actorSheet, actorSheet.actor, actorSheet.position); const actor = actorSheet.object; const addLabel = removeLabelSheetHeader ? "" : game.i18n.localize("Theatre.UI.Config.AddToStage"); const removeLabel = removeLabelSheetHeader ? "" : game.i18n.localize("Theatre.UI.Config.RemoveFromStage"); @@ -2303,7 +2312,7 @@ export class TheatreHelpers { if (!actor) { return; } - debug("actor is valid!"); + Logger.debug("actor is valid!"); // if already on stage, dont add it again // create nav-list-item // set picture as actor.img @@ -2318,7 +2327,7 @@ export class TheatreHelpers { let name = actor.name; if (!Theatre.instance.isActorOwner(game.user.id, theatreId)) { - info(game.i18n.localize("Theatre.UI.Notification.DoNotControl"), true); + Logger.info(game.i18n.localize("Theatre.UI.Notification.DoNotControl"), true); return; } @@ -2336,11 +2345,11 @@ export class TheatreHelpers { } if (Theatre.instance.stage[theatreId]) { - info(actor.name + game.i18n.localize("Theatre.UI.Notification.AlreadyStaged"), true); + Logger.info(actor.name + game.i18n.localize("Theatre.UI.Notification.AlreadyStaged"), true); return; } - debug("new theatre id: " + theatreId); + Logger.debug("new theatre id: " + theatreId); let navItem = document.createElement("img"); KHelpers.addClass(navItem, "theatre-control-nav-bar-item"); @@ -2732,7 +2741,7 @@ export class TheatreHelpers { top: -100, ease: Power4.easeOut, onComplete: () => { - debug("completeAll"); + Logger.debug("completeAll"); if (textBox) { textBox.style["overflow-y"] = "scroll"; textBox.style["overflow-x"] = "hidden"; @@ -2801,7 +2810,7 @@ export class TheatreHelpers { left: 150, ease: Power4.easeOut, onComplete: () => { - debug("completeAll"); + Logger.debug("completeAll"); if (textBox) { textBox.style["overflow-y"] = "scroll"; textBox.style["overflow-x"] = "hidden"; @@ -2852,7 +2861,7 @@ export class TheatreHelpers { rotation: -1080, ease: Power4.easeOut, onComplete: () => { - debug("completeAll"); + Logger.debug("completeAll"); if (textBox) { textBox.style["overflow-y"] = "scroll"; textBox.style["overflow-x"] = "hidden"; @@ -2906,12 +2915,12 @@ export class TheatreHelpers { }); } if (textBox) { - debug("vortext all start"); + Logger.debug("vortext all start"); TweenMax.from(textBox, 0.1, { delay: speed * charSpans.length + animTime, //opacity: 1, onComplete: function () { - debug("vortex all complete"); + Logger.debug("vortex all complete"); if (this.targets().length) { this.targets()[0].style["overflow-y"] = "scroll"; this.targets()[0].style["overflow-x"] = "visible"; From 464f8cf9a091f1c89283cd2ce4203e4e6565d0df Mon Sep 17 00:00:00 2001 From: p4535992 Date: Mon, 19 Feb 2024 12:50:02 +0100 Subject: [PATCH 2/6] little fix on import --- src/scripts/API/api.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/scripts/API/api.js b/src/scripts/API/api.js index 2a46ca4..b533263 100644 --- a/src/scripts/API/api.js +++ b/src/scripts/API/api.js @@ -1,7 +1,6 @@ import KHelpers from "../KHelpers.js"; import { Theatre } from "../Theatre.js"; import CONSTANTS from "../constants/constants.js"; -import { debug, error, info, log, warn } from "../lib/lib.js"; import { TheatreHelpers } from "../theatre-helpers.js"; const API = { From cc6693d61fd57690b0fcefa2f573ebada49f6757 Mon Sep 17 00:00:00 2001 From: p4535992 Date: Mon, 19 Feb 2024 13:07:38 +0100 Subject: [PATCH 3/6] add check --- src/module.js | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/module.js b/src/module.js index 68ca784..6a39633 100644 --- a/src/module.js +++ b/src/module.js @@ -507,10 +507,16 @@ Hooks.on("theatreDockActive", (insertCount) => { * If Argon is active, wrap CombatHudCanvasElement#toggleMacroPlayers to prevent playesr list and macro hotbar from being shown */ Hooks.once("ready", () => { + // Do anything once the module is ready + if (!game.modules.get("lib-wrapper")?.active && game.user?.isGM) { + let word = "install and activate"; + if (game.modules.get("lib-wrapper")) word = "activate"; + throw Logger.error(`Requires the 'libWrapper' module. Please ${word} it.`); + } if (!game.modules.get("socketlib")?.active && game.user?.isGM) { let word = "install and activate"; if (game.modules.get("socketlib")) word = "activate"; - Logger.warn(`It is recommended to intall the 'socketlib' module. Please ${word} it.`); + throw Logger.error(`Requires the 'socketlib' module. Please ${word} it.`); } if (!game.settings.get(CONSTANTS.MODULE_ID, "autoHideBottom")) { return; From 3249082b95a81da3ab04aab5f15b29864f68e95c Mon Sep 17 00:00:00 2001 From: p4535992 Date: Fri, 29 Mar 2024 14:07:50 +0100 Subject: [PATCH 4/6] some bug fixing --- src/scripts/Theatre.js | 15 ++++--- src/scripts/TheatreActorConfig.js | 69 +++++++++++++++++++------------ 2 files changed, 52 insertions(+), 32 deletions(-) diff --git a/src/scripts/Theatre.js b/src/scripts/Theatre.js index 2a59de2..b6eaaaf 100644 --- a/src/scripts/Theatre.js +++ b/src/scripts/Theatre.js @@ -2985,13 +2985,17 @@ export class Theatre { return; } let baseInsert = actor.img ? actor.img : CONSTANTS.DEFAULT_PORTRAIT; - if (actor.flags.theatre) baseInsert = actor.flags.theatre.baseinsert ? actor.flags.theatre.baseinsert : baseInsert; + if (actor.flags.theatre) { + baseInsert = actor.flags.theatre.baseinsert ? actor.flags.theatre.baseinsert : baseInsert; + } let emotes = Theatre.getActorEmotes(actorId); // emote already active //if ((this.speakingAs != insert.imgId && !this.isDelayEmote) || this.delayedSentState > 2) - if (remote || !this.isDelayEmote) if (aEmote == ename || (ename == null && aEmote == null)) return; - + if (remote || !this.isDelayEmote) + if (aEmote == ename || (ename == null && aEmote == null)) { + return; + } // if emote insert exists let app = this.pixiCTX; if (!!ename && emotes[ename] && emotes[ename].insert && emotes[ename].insert != "") { @@ -5010,8 +5014,9 @@ export class Theatre { : null; let insert = Theatre.instance.getInsertById(Theatre.instance.speakingAs); let actor; - if (actorId) actor = game.actors.get(actorId); - + if (actorId) { + actor = game.actors.get(actorId); + } let emotes = Theatre.getActorEmotes(actorId); let fonts = Theatre.FONTS; let textFlyin = Theatre.FLYIN_ANIMS; diff --git a/src/scripts/TheatreActorConfig.js b/src/scripts/TheatreActorConfig.js index 708aaac..cb7ef8e 100644 --- a/src/scripts/TheatreActorConfig.js +++ b/src/scripts/TheatreActorConfig.js @@ -235,25 +235,25 @@ export class TheatreActorConfig extends FormApplication { let navItem = Theatre.instance.getNavItemById(theatreId); let cImg = Theatre.instance.getTheatreCoverPortrait(); - if (baseInsert != this.object.flags.theatre.baseinsert) { + if (baseInsert !== this.object.flags.theatre.baseinsert) { Logger.debug("baseinsert changed!"); insertDirty = true; - newBaseInsert = baseInsert == "" ? (this.object.img ? this.object.img : CONSTANTS.DEFAULT_PORTRAIT) : baseInsert; + newBaseInsert = baseInsert === "" ? (this.object.img ? this.object.img : CONSTANTS.DEFAULT_PORTRAIT) : baseInsert; if (navItem) { navItem.setAttribute("src", newBaseInsert); cImg.setAttribute("src", newBaseInsert); } } - if (optAlign != this.object.flags.theatre.optalign) { + if (optAlign !== this.object.flags.theatre.optalign) { Logger.debug("optalign changed!"); insertDirty = true; - newAlign = optAlign == "" ? "top" : optAlign; + newAlign = optAlign === "" ? "top" : optAlign; if (navItem) navItem.setAttribute("optalign", newAlign); } - if (name != this.object.flags.theatre.name) { + if (name !== this.object.flags.theatre.name) { Logger.debug("name changed!"); insertDirty = true; - newName = name == "" ? this.object.name : name; + newName = name === "" ? this.object.name : name; if (navItem) { navItem.setAttribute("name", newName); navItem.setAttribute("title", newName + (newName == this.object.name ? "" : ` (${this.object.name})`)); @@ -271,7 +271,7 @@ export class TheatreActorConfig extends FormApplication { let emoteFormData = resForms.emoteFormData; // check all image resources, if they differ the actor's, we need to replace the texture, and then tell all other clients to do so as well! - //let inserts = formData.filter((e,k) => {return k.endsWith("insert") || k.endsWith("baseinsert")}); + // let inserts = formData.filter((e,k) => {return k.endsWith("insert") || k.endsWith("baseinsert")}); let insert = Theatre.instance.getInsertById(theatreId); let container = insert ? insert.dockContainer : null; let app = Theatre.instance.pixiCTX; @@ -279,22 +279,22 @@ export class TheatreActorConfig extends FormApplication { let newSrcImg = null; let imgSrcs = []; - for (let k in formData) + for (let k in formData) { if (k.endsWith("insert") || k.endsWith("baseinsert")) { let oldValue = getProperty(this.object, k); // if the old value does not exist, we will continue - if (formData[k] != oldValue) { + if (formData[k] !== oldValue) { let emote = k.match(/emotes\.[a-z0-9\-]+/); if (emote) emote = emote[0].replace(/emotes\./, ""); let resName = formData[k]; // A special case exists where the baseportrait is removed, and replaced with either // null or an empty string, we can set this value, but we need to change the re-render // behavior to take the sheet portrait or 'mystery man' image - if (!resName || resName == "") { + if (!resName || resName === "") { // try to restore baseinsert let formBaseInsert = formData["flags.theatre.baseinsert"]; if (k.endsWith("insert") && !k.endsWith("baseinsert")) { - if (formBaseInsert && formBaseInsert != "") { + if (formBaseInsert && formBaseInsert !== "") { resName = formBaseInsert; } else if (this.object.flags.theatre.baseinsert && this.object.flags.theatre.baseinsert != "") { resName = this.object.flags.theatre.baseinsert; @@ -315,16 +315,21 @@ export class TheatreActorConfig extends FormApplication { // to prevent firing off X number of packets on a save submit imgSrcs.push({ imgpath: resName, resname: resName }); - if (insertEmote == emote || !emote) newSrcImg = resName; + if (insertEmote == emote || !emote) { + newSrcImg = resName; + } } } + } // check for null'd emotes, push the objects up a level if one exists const newData = mergeObject(this.object, emoteFormData, { inplace: false }); let emMerge = newData.flags.theatre.emotes; let nEmotes = {}; for (let emProp in emMerge) { - if (emMerge[emProp] == null) continue; + if (emMerge[emProp] == null) { + continue; + } nEmotes[emProp] = emMerge[emProp]; } // send the emote parent in bulk to get rid of unwanted children @@ -352,13 +357,14 @@ export class TheatreActorConfig extends FormApplication { if ( insert.emote && this.object.flags.theatre.emotes[insert.emote].insert && - this.object.flags.theatre.emotes[insert.emote].insert != "" - ) + this.object.flags.theatre.emotes[insert.emote].insert !== "" + ) { resName = this.object.flags.theatre.emotes[insert.emote].insert; - else if (this.object.flags.theatre.baseinsert && this.object.flags.theatre.baseinsert != "") + } else if (this.object.flags.theatre.baseinsert && this.object.flags.theatre.baseinsert !== "") { resName = this.object.flags.theatre.baseinsert; - else if (this.object.img && this.object.img != "") resName = this.object.img; - + } else if (this.object.img && this.object.img !== "") { + resName = this.object.img; + } // bubble up dataum from the update insert.optAlign = newAlign; insert.name = newName; @@ -372,7 +378,9 @@ export class TheatreActorConfig extends FormApplication { Theatre.instance._repositionInsertElements(insert); - if (!Theatre.instance.rendering) Theatre.instance._renderTheatre(performance.now()); + if (!Theatre.instance.rendering) { + Theatre.instance._renderTheatre(performance.now()); + } } }, false @@ -391,13 +399,14 @@ export class TheatreActorConfig extends FormApplication { if ( insert.emote && this.object.flags.theatre.emotes[insert.emote].insert && - this.object.flags.theatre.emotes[insert.emote].insert != "" - ) + this.object.flags.theatre.emotes[insert.emote].insert !== "" + ) { resName = this.object.flags.theatre.emotes[insert.emote].insert; - else if (this.object.flags.theatre.baseinsert && this.object.flags.theatre.baseinsert != "") + } else if (this.object.flags.theatre.baseinsert && this.object.flags.theatre.baseinsert !== "") { resName = this.object.flags.theatre.baseinsert; - else if (this.object.img && this.object.img != "") resName = this.object.img; - + } else if (this.object.img && this.object.img !== "") { + resName = this.object.img; + } // bubble up dataum from the update insert.optAlign = newAlign; insert.name = newName; @@ -420,12 +429,18 @@ export class TheatreActorConfig extends FormApplication { Theatre.instance._repositionInsertElements(insert); - if (!Theatre.instance.rendering) Theatre.instance._renderTheatre(performance.now()); + if (!Theatre.instance.rendering) { + Theatre.instance._renderTheatre(performance.now()); + } } - if (theatreId == Theatre.instance.speakingAs); + if (theatreId === Theatre.instance.speakingAs) { + return; + } Theatre.instance.renderEmoteMenu(); - if (insertDirty) Theatre.instance._sendSceneEvent("renderinsert", { insertid: theatreId }); + if (insertDirty) { + Theatre.instance._sendSceneEvent("renderinsert", { insertid: theatreId }); + } }); } From 87516797c0c6963f82ac8c1e46bff777309af38f Mon Sep 17 00:00:00 2001 From: p4535992 Date: Tue, 9 Apr 2024 13:43:16 +0200 Subject: [PATCH 5/6] update some configurations --- .eslintignore | 18 ++++++ .eslintrc.json | 148 +++++++++++++++++++++++++++++++++++++++++--- .github/FUNDING.yml | 1 + .prettierignore | 1 + .prettierrc | 18 ------ .prettierrc.json | 40 ++++++++++++ package.json | 64 ++++++++++--------- vite.config.mjs | 14 ++--- 8 files changed, 242 insertions(+), 62 deletions(-) create mode 100644 .eslintignore create mode 100644 .github/FUNDING.yml delete mode 100644 .prettierrc create mode 100644 .prettierrc.json diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 0000000..e028f02 --- /dev/null +++ b/.eslintignore @@ -0,0 +1,18 @@ +gulpfile.js +.eslintrc.js +.prettierrc.js +jsconfig.json +/.pnp.js +/.yarn/ + +.github/ +dist/ +docs/ +external/ +src/languages/ +src/assets/ +src/lang/ +src/scripts/ +src/styles/ +src/templates/ +src/**/*.svelte \ No newline at end of file diff --git a/.eslintrc.json b/.eslintrc.json index cebade4..076e436 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -1,29 +1,44 @@ { "env": { "browser": true, - "es2022": true, + "es6": true, "node": true, "jquery": true }, + "extends": [ + "eslint:recommended", + "plugin:@typescript-eslint/recommended", + "prettier" + ], + "parser": "@babel/eslint-parser", "parserOptions": { "requireConfigFile": false, + "ecmaVersion": 2018, "sourceType": "module" }, - "plugins": [ - "jsdoc" + "ignorePatterns": [ + "dist/" ], "rules": { + "prettier/prettier": "error", + "no-console": "off", + "no-plusplus": [ + "error", + { + "allowForLoopAfterthoughts": true + } + ], "array-bracket-spacing": ["warn", "never"], "array-callback-return": "warn", "arrow-spacing": "warn", - "comma-dangle": ["warn", "never"], + "comma-dangle": ["warn", "always-multiline"], "comma-style": "warn", "computed-property-spacing": "warn", "constructor-super": "error", "default-param-last": "warn", "dot-location": ["warn", "property"], "eol-last": ["error", "always"], - "eqeqeq": ["warn", "smart"], + "eqeqeq": "error", "func-call-spacing": "warn", "func-names": ["warn", "never"], "getter-return": "warn", @@ -86,7 +101,12 @@ "no-unreachable-loop": "warn", "no-unsafe-negation": ["warn", {"enforceForOrderingRelations": true}], "no-unsafe-optional-chaining": ["warn", {"disallowArithmeticOperators": true}], - "no-unused-expressions": "warn", + "no-unused-expressions": [ + "error", + { + "allowShortCircuit": true + } + ], "no-useless-backreference": "warn", "no-useless-call": "warn", "no-useless-catch": "warn", @@ -121,7 +141,7 @@ }], "comma-spacing": "warn", "dot-notation": "warn", - "indent": ["warn", 2, {"SwitchCase": 1}], + "indent": ["warn", 4, {"SwitchCase": 1}], "key-spacing": "warn", "keyword-spacing": ["warn", {"overrides": {"catch": {"before": true, "after": false}}}], "max-len": ["warn", { @@ -153,7 +173,43 @@ "named": "never", "asyncArrow": "always" }], - "spaced-comment": "warn", + "spaced-comment": [ + "error", + "always", + { + "markers": [ + "/" + ] + } + ], + "@typescript-eslint/ban-ts-comment": "error", + "@typescript-eslint/ban-types": "off", + "@typescript-eslint/explicit-module-boundary-types": "off", + "@typescript-eslint/lines-between-class-members": [ + "error", + "always", + { + "exceptAfterSingleLine": true + } + ], + "@typescript-eslint/prefer-namespace-keyword": "off", + "@typescript-eslint/no-empty-function": "off", + "@typescript-eslint/no-explicit-any": "error", + "@typescript-eslint/no-namespace": [ + "error", + { + "allowDeclarations": true + } + ], + "@typescript-eslint/no-non-null-assertion": "off", + "@typescript-eslint/no-unsafe-declaration-merging": "off", + "@typescript-eslint/no-unused-vars": "off", + "@typescript-eslint/array-type": [ + "error", + { + "default": "array" + } + ], "jsdoc/check-access": "warn", "jsdoc/check-alignment": "warn", "jsdoc/check-examples": "off", @@ -196,6 +252,11 @@ "jsdoc/require-yields-check": "warn", "jsdoc/valid-types": "off" }, + "plugins": [ + "jsdoc", + "prettier", + "@typescript-eslint" + ], "settings": { "jsdoc": { "preferredTypes": { @@ -208,5 +269,76 @@ "augments": "extends" } } + }, + "overrides": [ + { + "files": "tests/**/*", + "rules": { + "global-require": "off" + } + } + ], + "globals": { + "globalThis": true, + "canvas": true, + "Hooks": true, + "game": true, + "Handlebars": true, + "Babele": true, + "foundry": true, + "CONFIG": true, + "libWrapper": true, + "socketlib": true, + "DatabaseBackend": true, + "Actor": true, + "Adventure": true, + "Cards": true, + "ChatMessage": true, + "Combat": true, + "Dice": true, + "FogExploration": true, + "Folder": true, + "Item": true, + "JournalEntry": true, + "Macro": true, + "Playlist": true, + "RollTable": true, + "Scene": true, + "Setting": true, + "User": true, + "Canvas": true, + "canvasTextStyle": true, + "weatherEffects": true, + "controlIcons": true, + "fontDefinitions": true, + "_fontFamilies": true, + "defaultFontFamily": true, + "statusEffects": true, + "specialStatusEffects": true, + "sounds": true, + "supportedLanguages": true, + "i18n": true, + "time": true, + "ActiveEffect": true, + "ActorDelta": true, + "Card": true, + "TableResult": true, + "JournalEntryPage": true, + "PlaylistSound": true, + "AmbientLight": true, + "AmbientSound": true, + "Combatant": true, + "Drawing": true, + "MeasuredTemplate": true, + "Note": true, + "Tile": true, + "Token": true, + "Wall": true, + "TinyMCE": true, + "TextEditor": true, + "WebRTC": true, + "ui": true, + "DND5E": true } } + diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1 @@ + diff --git a/.prettierignore b/.prettierignore index 9c39c0c..befa2ca 100644 --- a/.prettierignore +++ b/.prettierignore @@ -6,3 +6,4 @@ /.idea .vite-cache/** **/*.md +/src/packs \ No newline at end of file diff --git a/.prettierrc b/.prettierrc deleted file mode 100644 index 2561174..0000000 --- a/.prettierrc +++ /dev/null @@ -1,18 +0,0 @@ -{ - "tabWidth": 2, - "useTabs": false, - "singleQuote": false, - "trailingComma": "es5", - "semi": true, - "printWidth": 120, - "bracketSpacing": true, - "overrides": [ - { - "files": ["*.scss", "*.css"], - "options": { - "requirePragma": false, - "parser": "scss" - } - } - ] -} diff --git a/.prettierrc.json b/.prettierrc.json new file mode 100644 index 0000000..60bf782 --- /dev/null +++ b/.prettierrc.json @@ -0,0 +1,40 @@ +{ + "printWidth": 120, + "tabWidth": 4, + "overrides": [ + { + "files": [ + "*.scss", + "*.css" + ], + "options": { + "requirePragma": false, + "parser": "scss" + } + }, + { + "files": [ + "*.yml" + ], + "options": { + "tabWidth": 2 + } + }, + { + "files": "*.html", + "options": { + "requirePragma": false, + "parser": "html", + "htmlWhitespaceSensitivity": "ignore" + } + }, + { + "files": "*.hbs", + "options": { + "requirePragma": false, + "parser": "angular", + "htmlWhitespaceSensitivity": "ignore" + } + } + ] +} diff --git a/package.json b/package.json index 7f04103..0b3036d 100644 --- a/package.json +++ b/package.json @@ -14,53 +14,59 @@ "#standard/*": "@typhonjs-fvtt/svelte-standard/*" }, "dependencies": { - "@fortawesome/fontawesome-svg-core": "^6.4.0", - "@fortawesome/free-solid-svg-icons": "^6.4.0", + "@fortawesome/fontawesome-svg-core": "^6.5.1", + "@fortawesome/free-solid-svg-icons": "^6.5.1", "@fortawesome/react-fontawesome": "^0.2.0", - "@rollup/plugin-node-resolve": "^15.2.1", + "@rollup/plugin-node-resolve": "^15.2.3", "@typhonjs-fvtt/runtime": "^0.1.2", "@typhonjs-fvtt/svelte-standard": "^0.1.0", - "moment": "^2.29.4", - "svelte": "^4.1.2", - "svelte-select": "^5.7.0", - "svelte-virtual-scroll-list": "^1.1.0" + "moment": "^2.30.1", + "svelte": "^4.2.12", + "svelte-select": "^5.8.3", + "svelte-virtual-scroll-list": "^1.3.0" }, "devDependencies": { - "@babel/eslint-parser": "^7.22.15", - "@rollup/plugin-node-resolve": "^15.2.1", - "@typhonjs-config/eslint-config": "^0.6.0", + "@babel/eslint-parser": "^7.23.10", + "@foundryvtt/foundryvtt-cli": "^1.0.2", + "@rollup/plugin-node-resolve": "^15.2.3", + "@typescript-eslint/eslint-plugin": "^7.1.1", + "@typhonjs-config/eslint-config": "^0.6.3", "@typhonjs-fvtt/eslint-config-foundry.js": "^0.8.0", - "eslint": "^8.46.0", - "eslint-plugin-jsdoc": "^46.5.0", + "eslint": "^8.57.0", + "eslint-config-prettier": "^9.1.0", + "eslint-plugin-jsdoc": "^46.10.1", + "eslint-plugin-prettier": "^5.1.3", + "fancy-log": "^2.0.0", "husky": "^8.0.3", - "jquery": "^3.6.4", + "jquery": "^3.7.1", "jsdoc": "^4.0.2", - "lint-staged": "^13.2.1", - "prettier": "^2.8.7", - "sass": "^1.63.6", - "svelte-dnd-action": "^0.9.18", - "svelte-preprocess": "^5.0.4", - "vite": "^4.4.8", + "less": "^4.2.0", + "less-watch-compiler": "^1.16.3", + "lint-staged": "^13.3.0", + "prettier": "^3.2.5", + "rollup": "^3.29.4", + "sass": "^1.71.1", + "svelte-dnd-action": "^0.9.40", + "svelte-preprocess": "^5.1.3", + "vite": "^4.5.3", "vite-plugin-clean": "^1.0.0", - "vite-plugin-run": "^0.4.1", - "vite-plugin-static-copy": "^0.16.0" + "vite-plugin-run": "^0.5.1", + "vite-plugin-static-copy": "^0.17.0", + "yargs": "^17.7.2" }, "browserslist": [ ">5%", "not IE 11" ], "scripts": { - "build": "vite build", - "build:watch": "vite build --watch", - "build:clean": "node ./utils/packs.mjs package clean", - "build:db": "node ./utils/packs.mjs package pack", - "build:json": "node ./utils/packs.mjs package unpack", - "dev": "vite", + "build": "node ./utils/clean.mjs && vite build", + "build:watch": "node ./utils/clean.mjs && vite build --watch --mode development", + "dev": "vite serve", "eslint": "eslint .", "prepare": "husky install", - "prettier-format": "prettier --config .prettierrc --write \"./src/**/*.{js,mjs,json,scss,css}\"", + "prettier-format": "prettier --config .prettierrc.json --write \"./src/**/*.{js,mjs,json,scss,css}\"", "lint": "eslint --ext .js ./src", - "lint:fix": "eslint --ext .js ./src --fix" + "lint:fix": "eslint --ext .js ./src --fix" }, "lint-staged": { "*.{js,css}": "prettier --write" diff --git a/vite.config.mjs b/vite.config.mjs index 594315c..322a636 100644 --- a/vite.config.mjs +++ b/vite.config.mjs @@ -61,8 +61,8 @@ export default () => { css: { // Creates a standard configuration for PostCSS with autoprefixer & postcss-preset-env. - postcss: postcssConfig({ - compress: s_COMPRESS, + postcss: postcssConfig({ + compress: s_COMPRESS, sourceMap: s_SOURCEMAPS }), }, @@ -92,7 +92,7 @@ export default () => { "/socket.io": { target: "ws://127.0.0.1:30000", ws: true }, }, }, - + build: { outDir: normalizePath( path.resolve(__dirname, `./dist/${s_MODULE_ID}`)), // __dirname, emptyOutDir: false, @@ -153,14 +153,14 @@ export default () => { dest: normalizePath(path.resolve(__dirname, `./dist/${s_MODULE_ID}/styles`)), }, { - src: normalizePath(path.resolve(__dirname, './src/packs')) + '/[!.]*', + src: normalizePath(path.resolve(__dirname, './src/packs')) + '/[!.^(_?.*)]*', // + '/[!.^(_source)]*', dest: normalizePath(path.resolve(__dirname, `./dist/${s_MODULE_ID}/packs`)), }, { src: normalizePath(path.resolve(__dirname, './src/module.json')), dest: normalizePath(path.resolve(__dirname, `./dist/${s_MODULE_ID}/`)), }, - { + { src: normalizePath(path.resolve(__dirname, './src/scripts/libs')) + '/[!.]*', dest: normalizePath(path.resolve(__dirname, `./dist/${s_MODULE_ID}/scripts/libs`)), }, @@ -181,14 +181,14 @@ export default () => { if (warning.message.includes(` element should have an href attribute`)) { return; } - + // Let Rollup handle all other warnings normally. handler(warning); }, }), resolve(s_RESOLVE_CONFIG), // Necessary when bundling npm-linked packages. - + // When s_TYPHONJS_MODULE_LIB is true transpile against the Foundry module version of TRL. s_TYPHONJS_MODULE_LIB && typhonjsRuntime(), From 2b557c2b99f8ce3270aecb9a3eba979cf2de6ab6 Mon Sep 17 00:00:00 2001 From: p4535992 Date: Wed, 1 May 2024 11:04:21 +0200 Subject: [PATCH 6/6] update packs from nedb to level db and exported the sources --- .editorconfig | 22 +- .gitattributes | 14 +- .github/FUNDING.yml | 1 - .gitignore | 3 +- package.json | 4 + src/module.json | 2 +- .../add-owned-tokens-to-stage.json | 17 ++ .../add-selected-tokens-to-stage.json | 17 ++ src/packs/theatre-inserts-macros/000013.ldb | Bin 0 -> 688 bytes src/packs/theatre-inserts-macros/CURRENT | 1 + src/packs/theatre-inserts-macros/LOCK | 0 src/packs/theatre-inserts-macros/LOG | 14 + src/packs/theatre-inserts-macros/LOG.old | 3 + .../theatre-inserts-macros/MANIFEST-000009 | Bin 0 -> 334 bytes utils/clean.mjs | 17 ++ utils/packs.mjs | 282 ++++++++++++++++++ .../backupnedb}/theatre-inserts-macros.db | 0 17 files changed, 375 insertions(+), 22 deletions(-) create mode 100644 src/packs/_source/theatre-inserts-macros/add-owned-tokens-to-stage.json create mode 100644 src/packs/_source/theatre-inserts-macros/add-selected-tokens-to-stage.json create mode 100644 src/packs/theatre-inserts-macros/000013.ldb create mode 100644 src/packs/theatre-inserts-macros/CURRENT create mode 100644 src/packs/theatre-inserts-macros/LOCK create mode 100644 src/packs/theatre-inserts-macros/LOG create mode 100644 src/packs/theatre-inserts-macros/LOG.old create mode 100644 src/packs/theatre-inserts-macros/MANIFEST-000009 create mode 100644 utils/clean.mjs create mode 100644 utils/packs.mjs rename {src/packs => wiki/backupnedb}/theatre-inserts-macros.db (100%) diff --git a/.editorconfig b/.editorconfig index 3afd20d..28e442a 100644 --- a/.editorconfig +++ b/.editorconfig @@ -1,11 +1,11 @@ -root = true - -[*] -indent_style = space -indent_size = 4 -end_of_line = lf -charset = utf-8 -trim_trailing_whitespace = true -insert_final_newline = true -[*.yml] -indent_size = 2 +root = true + +[*] +indent_style = space +indent_size = 4 +end_of_line = lf +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true +[*.yml] +indent_size = 2 diff --git a/.gitattributes b/.gitattributes index 2376a0d..815a562 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,7 +1,7 @@ -.github export-ignore -FUNDING.yml export-ignore - -.gitattributes export-ignore -README.md export-ignore -preview.jpg export-ignore -patchnotes.md export-ignore +.github export-ignore +FUNDING.yml export-ignore + +.gitattributes export-ignore +README.md export-ignore +preview.jpg export-ignore +patchnotes.md export-ignore diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml index 8b13789..e69de29 100644 --- a/.github/FUNDING.yml +++ b/.github/FUNDING.yml @@ -1 +0,0 @@ - diff --git a/.gitignore b/.gitignore index b11559e..6325faa 100644 --- a/.gitignore +++ b/.gitignore @@ -119,5 +119,4 @@ foundry.js /dist /package /.vite-cache -/package-lock.json -/dist +/package-lock.json \ No newline at end of file diff --git a/package.json b/package.json index 0b3036d..b003805 100644 --- a/package.json +++ b/package.json @@ -61,7 +61,11 @@ "scripts": { "build": "node ./utils/clean.mjs && vite build", "build:watch": "node ./utils/clean.mjs && vite build --watch --mode development", + "build:watchWithDb": "node ./utils/clean.mjs && npm run build:db && vite build --watch --mode development", "dev": "vite serve", + "build:clean": "node ./utils/packs.mjs package clean", + "build:db": "node ./utils/packs.mjs package pack", + "build:json": "node ./utils/packs.mjs package unpack", "eslint": "eslint .", "prepare": "husky install", "prettier-format": "prettier --config .prettierrc.json --write \"./src/**/*.{js,mjs,json,scss,css}\"", diff --git a/src/module.json b/src/module.json index 99e2dd6..c12d664 100644 --- a/src/module.json +++ b/src/module.json @@ -116,7 +116,7 @@ { "name": "theatre-inserts-macros", "label": "Theatre Inserts Macros", - "path": "packs/theatre-inserts-macros.db", + "path": "packs/theatre-inserts-macros", "type": "Macro", "private": false, "ownership": { diff --git a/src/packs/_source/theatre-inserts-macros/add-owned-tokens-to-stage.json b/src/packs/_source/theatre-inserts-macros/add-owned-tokens-to-stage.json new file mode 100644 index 0000000..bd3f24f --- /dev/null +++ b/src/packs/_source/theatre-inserts-macros/add-owned-tokens-to-stage.json @@ -0,0 +1,17 @@ +{ + "name": "Add Owned Tokens to Stage", + "type": "script", + "author": "2eCcEi9HdTwCxqFx", + "img": "icons/svg/dice-target.svg", + "scope": "global", + "command": "const ownedActors = game.actors.filter(a => a.permission === 3);\nconst ownedTokens = ownedActors.map(a => a.getActiveTokens());\n\nfor (const tokenArray of ownedTokens) {\n tokenArray.forEach(t => Theatre.addToNavBar(t.actor));\n}", + "folder": null, + "sort": 0, + "permission": { + "default": 0, + "2eCcEi9HdTwCxqFx": 3 + }, + "flags": {}, + "_id": "O4bIjZLeC6KYwdj2", + "_key": "!macros!O4bIjZLeC6KYwdj2" +} diff --git a/src/packs/_source/theatre-inserts-macros/add-selected-tokens-to-stage.json b/src/packs/_source/theatre-inserts-macros/add-selected-tokens-to-stage.json new file mode 100644 index 0000000..9e1d2ae --- /dev/null +++ b/src/packs/_source/theatre-inserts-macros/add-selected-tokens-to-stage.json @@ -0,0 +1,17 @@ +{ + "name": "Add Selected Tokens to Stage", + "type": "script", + "author": "2eCcEi9HdTwCxqFx", + "img": "icons/svg/dice-target.svg", + "scope": "global", + "command": "for (const tkn of canvas.tokens.controlled) {\n Theatre.addToNavBar(tkn.actor);\n}", + "folder": null, + "sort": 0, + "permission": { + "default": 0, + "2eCcEi9HdTwCxqFx": 3 + }, + "flags": {}, + "_id": "SiNOxyDFzz7V1ptf", + "_key": "!macros!SiNOxyDFzz7V1ptf" +} diff --git a/src/packs/theatre-inserts-macros/000013.ldb b/src/packs/theatre-inserts-macros/000013.ldb new file mode 100644 index 0000000000000000000000000000000000000000..a89661643031aa006c7af179a87c979652e74adc GIT binary patch literal 688 zcmaJ-&ubGw6rM>o>iVOo2v%ufGDJxr-PTmAP1$JErd2FSvBA<3km=6sX4~1BI6Fy` zmOxJ`2wuE+QTz}5FT}gxMZD?Bizg9;>a2oCA3T`%zVCbQ&3ACL573u%HX@#qakg=F z>(2J(3R{@DyRl2ROE3*G@LP8u3lcG0#`Bb-#;#x#HRTQyG13yPX%aA8#Cp(4D6yx) zjy5&v>b6v-Q(_BVEu6hgo4X7Bhf95fg;8LD(32vbjC;W(4LvrYi3*r@Ol=skCo>Hi zaJfaeDLolQL{KA2G#W|x_{O}arHYY@0&|>0G9ynMKjfOJJV9;+5vRjc6vlBV1#(>% zO&8``V!V3l9dMmhaMFoL=gduHR+>R!kJ$w)Ux2qpTf&zL!epDDzELgnV>y1xBHS)W{ePB&dtZ9 z(zrZT#1}r~aCsk7=94bBFM?75-`!0EphJDl|xr&~_7 zYb*~%l}i~d{c*qa!aAF%l3Ac4$R}W@G5qy6z;o*#w*D#}d1Fm|w$3N5|Ht~zgQvOf G^2gs`D#ZK% literal 0 HcmV?d00001 diff --git a/src/packs/theatre-inserts-macros/CURRENT b/src/packs/theatre-inserts-macros/CURRENT new file mode 100644 index 0000000..6ba31a3 --- /dev/null +++ b/src/packs/theatre-inserts-macros/CURRENT @@ -0,0 +1 @@ +MANIFEST-000009 diff --git a/src/packs/theatre-inserts-macros/LOCK b/src/packs/theatre-inserts-macros/LOCK new file mode 100644 index 0000000..e69de29 diff --git a/src/packs/theatre-inserts-macros/LOG b/src/packs/theatre-inserts-macros/LOG new file mode 100644 index 0000000..c5cfd9c --- /dev/null +++ b/src/packs/theatre-inserts-macros/LOG @@ -0,0 +1,14 @@ +2024/05/01-11:03:44.884 419c Recovering log #8 +2024/05/01-11:03:44.962 419c Delete type=0 #8 +2024/05/01-11:03:44.963 419c Delete type=3 #7 +2024/05/01-11:03:45.000 2378 Level-0 table #12: started +2024/05/01-11:03:45.044 2378 Level-0 table #12: 688 bytes OK +2024/05/01-11:03:45.085 2378 Delete type=0 #10 +2024/05/01-11:03:45.085 2378 Manual compaction at level-0 from '!macros!O4bIjZLeC6KYwdj2' @ 72057594037927935 : 1 .. '!macros!SiNOxyDFzz7V1ptf' @ 0 : 0; will stop at '!macros!SiNOxyDFzz7V1ptf' @ 2 : 1 +2024/05/01-11:03:45.085 2378 Compacting 2@0 + 0@1 files +2024/05/01-11:03:45.126 2378 Generated table #13@0: 2 keys, 688 bytes +2024/05/01-11:03:45.126 2378 Compacted 2@0 + 0@1 files => 688 bytes +2024/05/01-11:03:45.161 2378 compacted to: files[ 0 1 0 0 0 0 0 ] +2024/05/01-11:03:45.161 2378 Delete type=2 #5 +2024/05/01-11:03:45.161 2378 Delete type=2 #12 +2024/05/01-11:03:45.161 2378 Manual compaction at level-0 from '!macros!SiNOxyDFzz7V1ptf' @ 2 : 1 .. '!macros!SiNOxyDFzz7V1ptf' @ 0 : 0; will stop at (end) diff --git a/src/packs/theatre-inserts-macros/LOG.old b/src/packs/theatre-inserts-macros/LOG.old new file mode 100644 index 0000000..2eb93a6 --- /dev/null +++ b/src/packs/theatre-inserts-macros/LOG.old @@ -0,0 +1,3 @@ +2024/05/01-11:03:26.864 356c Recovering log #6 +2024/05/01-11:03:26.938 356c Delete type=0 #6 +2024/05/01-11:03:26.938 356c Delete type=3 #4 diff --git a/src/packs/theatre-inserts-macros/MANIFEST-000009 b/src/packs/theatre-inserts-macros/MANIFEST-000009 new file mode 100644 index 0000000000000000000000000000000000000000..cc34d6fdfc027d80eb8ea3adaa11b9320993bff2 GIT binary patch literal 334 zcmWGEbT3F|U}TiaNi9pwNlDUksw_z@&n!-L&d)7KEJ`fNFJfn4eaot#n46eflwYjq zZ<6Gh73GuaY~~$Vo|0w6$jAT&a0S7ce*P7eE^bv-=3#~fC25RI5CydpdHOgQ7@4>@ z8JM|Qn69%G_xc05+(0fb3ky2~&jvh}FcY$b1)@MUs_k$E)Koqe7FGs=&SGO=Wn path.resolve(outDir, dirName)); + for (const file of filesToClean) { + fs.rmSync(file, { recursive: true }); + } +} else { + fs.mkdirSync(outDir); +} + +// Delete static/packs dir to prevent overwrite during rebuilds (temporary backwards compatibility) +// const oldPacksDir = path.resolve(process.cwd(), "static/packs"); +// fs.rmSync(oldPacksDir, { recursive: true, force: true }); diff --git a/utils/packs.mjs b/utils/packs.mjs new file mode 100644 index 0000000..2fc7550 --- /dev/null +++ b/utils/packs.mjs @@ -0,0 +1,282 @@ + +import fs from "fs"; +import { readdir, readFile, writeFile } from "node:fs/promises"; +import logger from "fancy-log"; +import path from "path"; +import yargs from "yargs"; +import { hideBin } from "yargs/helpers"; +import { compilePack, extractPack } from "@foundryvtt/foundryvtt-cli"; +import { fileURLToPath } from "url"; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = path.dirname(__filename); + +const BASE_FULL_PATH_MODULE = path.resolve(path.join(path.resolve(__dirname, '..'),"src")); +const MODULE_JSON_FULL_PATH = path.join(BASE_FULL_PATH_MODULE,"module.json"); // MOD 4535992 + +/** + * Folder where the compiled compendium packs should be located relative to the + * base module folder. + * @type {string} + */ +const PACK_DEST = path.join(BASE_FULL_PATH_MODULE,"packs"); + +/** + * Folder where source JSON files should be located relative to the module folder. + * @type {string} + */ +const PACK_SRC = path.join(BASE_FULL_PATH_MODULE,"packs/_source"); + + +// eslint-disable-next-line +const argv = yargs(hideBin(process.argv)) + .command(packageCommand()) + .help().alias("help", "h") + .argv; + + +// eslint-disable-next-line +function packageCommand() { + return { + command: "package [action] [pack] [entry]", + describe: "Manage packages", + builder: yargs => { + yargs.positional("action", { + describe: "The action to perform.", + type: "string", + choices: ["unpack", "pack", "clean"] + }); + yargs.positional("pack", { + describe: "Name of the pack upon which to work.", + type: "string" + }); + yargs.positional("entry", { + describe: "Name of any entry within a pack upon which to work. Only applicable to extract & clean commands.", + type: "string" + }); + }, + handler: async argv => { + const { action, pack, entry } = argv; + switch ( action ) { + case "clean": + return await cleanPacks(pack, entry); + case "pack": + return await compilePacks(pack); + case "unpack": + return await extractPacks(pack, entry); + } + } + }; +} + + +/* ----------------------------------------- */ +/* Clean Packs */ +/* ----------------------------------------- */ + +/** + * Removes unwanted flags, permissions, and other data from entries before extracting or compiling. + * @param {object} data Data for a single entry to clean. + * @param {object} [options={}] + * @param {boolean} [options.clearSourceId=true] Should the core sourceId flag be deleted. + * @param {number} [options.ownership=0] Value to reset default ownership to. + */ +function cleanPackEntry(data, { clearSourceId=true, ownership=0 }={}) { + if ( data.ownership ) data.ownership = { default: ownership }; + if ( clearSourceId ) delete data.flags?.core?.sourceId; + delete data.flags?.importSource; + delete data.flags?.exportSource; + if ( data._stats?.lastModifiedBy ) data._stats.lastModifiedBy = "packsbuilder0000"; + + // Remove empty entries in flags + if ( !data.flags ) data.flags = {}; + Object.entries(data.flags).forEach(([key, contents]) => { + if (contents && Object.keys(contents).length === 0 ) delete data.flags[key]; + }); + + if ( data.system?.activation?.cost === 0 ) data.system.activation.cost = null; + if ( data.system?.duration?.value === "0" ) data.system.duration.value = ""; + if ( data.system?.target?.value === 0 ) data.system.target.value = null; + if ( data.system?.target?.width === 0 ) data.system.target.width = null; + if ( data.system?.range?.value === 0 ) data.system.range.value = null; + if ( data.system?.range?.long === 0 ) data.system.range.long = null; + if ( data.system?.uses?.value === 0 ) data.system.uses.value = null; + if ( data.system?.uses?.max === "0" ) data.system.duration.value = ""; + if ( data.system?.save?.dc === 0 ) data.system.save.dc = null; + if ( data.system?.capacity?.value === 0 ) data.system.capacity.value = null; + if ( data.system?.strength === 0 ) data.system.strength = null; + + // Remove mystery-man.svg from Actors + if ( ["character", "npc"].includes(data.type) && data.img === "icons/svg/mystery-man.svg" ) { + data.img = ""; + data.prototypeToken.texture.src = ""; + } + + if ( data.effects ) data.effects.forEach(i => cleanPackEntry(i, { clearSourceId: false })); + if ( data.items ) data.items.forEach(i => cleanPackEntry(i, { clearSourceId: false })); + if ( data.pages ) data.pages.forEach(i => cleanPackEntry(i, { ownership: -1 })); + if ( data.system?.description?.value ) data.system.description.value = cleanString(data.system.description.value); + if ( data.label ) data.label = cleanString(data.label); + if ( data.name ) data.name = cleanString(data.name); +} + + +/** + * Removes invisible whitespace characters and normalizes single- and double-quotes. + * @param {string} str The string to be cleaned. + * @returns {string} The cleaned string. + */ +function cleanString(str) { + return str.replace(/\u2060/gu, "").replace(/[‘’]/gu, "'").replace(/[“”]/gu, '"'); +} + + +/** + * Cleans and formats source JSON files, removing unnecessary permissions and flags and adding the proper spacing. + * @param {string} [packName] Name of pack to clean. If none provided, all packs will be cleaned. + * @param {string} [entryName] Name of a specific entry to clean. + * + * - `npm run build:clean` - Clean all source JSON files. + * - `npm run build:clean -- classes` - Only clean the source files for the specified compendium. + * - `npm run build:clean -- classes Barbarian` - Only clean a single item from the specified compendium. + */ +async function cleanPacks(packName, entryName) { + entryName = entryName?.toLowerCase(); + const folders = fs.readdirSync(PACK_SRC, { withFileTypes: true }).filter(file => + file.isDirectory() && ( !packName || (packName === file.name) ) + ); + + /** + * Walk through directories to find JSON files. + * @param {string} directoryPath + * @yields {string} + */ + async function* _walkDir(directoryPath) { + const directory = await readdir(directoryPath, { withFileTypes: true }); + for ( const entry of directory ) { + const entryPath = path.join(directoryPath, entry.name); + if ( entry.isDirectory() ) yield* _walkDir(entryPath); + else if ( path.extname(entry.name) === ".json" ) yield entryPath; + } + } + + for ( const folder of folders ) { + logger.info(`Cleaning pack ${folder.name}`); + for await ( const src of _walkDir(path.join(PACK_SRC, folder.name)) ) { + const json = JSON.parse(await readFile(src, { encoding: "utf8" })); + if ( entryName && (entryName !== json.name.toLowerCase()) ) continue; + if ( !json._id || !json._key ) { + console.log(`Failed to clean \x1b[31m${src}\x1b[0m, must have _id and _key.`); + continue; + } + cleanPackEntry(json); + fs.rmSync(src, { force: true }); + writeFile(src, `${JSON.stringify(json, null, 2)}\n`, { mode: 0o664 }); + } + } +} + + +/* ----------------------------------------- */ +/* Compile Packs */ +/* ----------------------------------------- */ + +/** + * Compile the source JSON files into compendium packs. + * @param {string} [packName] Name of pack to compile. If none provided, all packs will be packed. + * + * - `npm run build:db` - Compile all JSON files into their LevelDB files. + * - `npm run build:db -- classes` - Only compile the specified pack. + */ +async function compilePacks(packName) { + // Determine which source folders to process + const folders = fs.readdirSync(PACK_SRC, { withFileTypes: true }).filter(file => + file.isDirectory() && ( !packName || (packName === file.name) ) + ); + + for ( const folder of folders ) { + const src = path.join(PACK_SRC, folder.name); + const dest = path.join(PACK_DEST, folder.name); + logger.info(`Compiling pack ${folder.name}`); + await compilePack(src, dest, { recursive: true, log: true, transformEntry: cleanPackEntry }); + } +} + + +/* ----------------------------------------- */ +/* Extract Packs */ +/* ----------------------------------------- */ + +/** + * Extract the contents of compendium packs to JSON files. + * @param {string} [packName] Name of pack to extract. If none provided, all packs will be unpacked. + * @param {string} [entryName] Name of a specific entry to extract. + * + * - `npm build:json - Extract all compendium LevelDB files into JSON files. + * - `npm build:json -- classes` - Only extract the contents of the specified compendium. + * - `npm build:json -- classes Barbarian` - Only extract a single item from the specified compendium. + */ +async function extractPacks(packName, entryName) { + entryName = entryName?.toLowerCase(); + + // Load module.json. + const module = JSON.parse(fs.readFileSync(MODULE_JSON_FULL_PATH, { encoding: "utf8" })); // MOD 4535992 /src/module.json instead ./system.json and rename system to module + + // Determine which source packs to process. + const packs = module.packs.filter(p => !packName || p.name === packName); + + for ( const packInfo of packs ) { + const dest = path.join(PACK_SRC, packInfo.name); + const packInfoPath = path.join(PACK_DEST, packInfo.name); // MOD 4535992 + logger.info(`Extracting pack ${packInfo.name} from ${packInfoPath} to ${dest}`); + + const folders = {}; + const containers = {}; + await extractPack(packInfoPath, dest, { + log: false, transformEntry: e => { + if ( e._key.startsWith("!folders") ) folders[e._id] = { name: slugify(e.name), folder: e.folder }; + else if ( e.type === "container" ) containers[e._id] = { + name: slugify(e.name), container: e.system?.container, folder: e.folder + }; + return false; + } + }); + const buildPath = (collection, entry, parentKey) => { + let parent = collection[entry[parentKey]]; + entry.path = entry.name; + while ( parent ) { + entry.path = path.join(parent.name, entry.path); + parent = collection[parent[parentKey]]; + } + }; + Object.values(folders).forEach(f => buildPath(folders, f, "folder")); + Object.values(containers).forEach(c => { + buildPath(containers, c, "container"); + const folder = folders[c.folder]; + if ( folder ) c.path = path.join(folder.path, c.path); + }); + + await extractPack(packInfoPath, dest, { + log: true, transformEntry: entry => { + if ( entryName && (entryName !== entry.name.toLowerCase()) ) return false; + cleanPackEntry(entry); + }, transformName: entry => { + if ( entry._id in folders ) return path.join(folders[entry._id].path, "_folder.json"); + if ( entry._id in containers ) return path.join(containers[entry._id].path, "_container.json"); + const outputName = slugify(entry.name); + const parent = containers[entry.system?.container] ?? folders[entry.folder]; + return path.join(parent?.path ?? "", `${outputName}.json`); + } + }); + } +} + + +/** + * Standardize name format. + * @param {string} name + * @returns {string} + */ +function slugify(name) { + return name.toLowerCase().replace("'", "").replace(/[^a-z0-9]+/gi, " ").trim().replace(/\s+|-{2,}/g, "-"); +} diff --git a/src/packs/theatre-inserts-macros.db b/wiki/backupnedb/theatre-inserts-macros.db similarity index 100% rename from src/packs/theatre-inserts-macros.db rename to wiki/backupnedb/theatre-inserts-macros.db